Repository navigation
Dex agents 0.3.0
Dex SDK 1.38.0
- Every package requires Dex SDK 1.38.0 (
dex-python-sdk==1.38.0,@superdurable/dex1.38.0, Gosdk-gov1.38.0) and a Dex Server with protocol 4: server-zd v0.1.17 or later, as with 1.35.0. - Agents CI, the nightly long run, and the publish workflows test against
dexcli1.38.0.
The session graph for Dex Web
- Python and TypeScript cores:
render_session_flow_graph(renderSessionFlowGraph) and thedex-agents-session-graphcommand render the Flow Definition Graph 2.0 file of an agent's session Flow, with the application's Flow type and Action permission. Dex Web loads it with--flow-rendering-dir, draws the session Steps, and offersresolve_interrupt,answer_question,steer_user_message, andcancel_turnas Actions without a condition. Both cores write the same bytes. - The graph is derived from the Python core's registered Flow and source and ships in both packages. The conformance suite adds
session_graph.json, and each core's tests fail when the graph and the session Flow disagree. - Dex Web needs a release that accepts Actions without a condition and calls no RPC for a view without fields.
- Go core: no graph. It registers only part of the session Flow.
- See Show sessions in Dex Web.
Compaction in framework adapters
- The OpenAI Agents SDK (Python and TypeScript), Pydantic AI, LangChain and LangGraph, Google ADK, Vercel AI SDK, and Mastra adapters implement the compaction methods, so
AgentSessionOptions.compactionworks with them. A session compacts with the existingCompactContextStep and stores aContextSummary, so retention can delete messages behind it. Without a policy nothing changes, and a session started on 0.2.0 starts compacting once its Workers have one. - Adapters compact only between turns, before a turn's first model call. A model call that resumes a turn after its tool calls never compacts, because the OpenAI Agents SDK and LangGraph resume from a run state that holds the input.
- The adapters' session flow functions take
compaction,retained_message_limit, andsummary_model(summaryModel). LangGraph needssummary_model, because a compiled graph does not expose its model. The TypeScript OpenAI Agents and Mastra session flow functions now forwardcompactionand the message storage options to the core. - Google ADK: the summary ends with a line that carries the ADK session state and the agent that replied last, so the rebuilt session keeps both.
- Claude Agent SDK: unchanged. Claude Code compacts its own transcript, and the adapter takes no compaction policy.
- Python and TypeScript cores: new helpers for adapters,
estimate_text_tokens,estimate_stored_input_tokens,select_turn_boundary_cutoff,describe_stored_message, andbuild_context_summary_prompt(camelCase in TypeScript). The Stepwise summary texts move to the core's root module and stay exported from Stepwise. CompactionPolicy.reserved_input_tokens(reservedInputTokens), default 0, adds tokens the runner's estimate cannot see.dex_agents.testingand@superdurable/dex-agents/testingaddContextWindowModelScriptandContextWindowSessionScenario.- No stored value changes. The conformance suite adds the summary prompt texts.
- Go core: unchanged.
- See Compaction and the storage bound.
Spend limits
- Python and TypeScript cores: the new
ModelSpendLimitinterface is an application's spend limit. Pass it asAgentSessionOptions.spend_limit(spendLimit), or on a StepwiseAgentDefinition. The session callscheck_model_callbefore each attempt ofRunModelandCompactContext, andreport_model_usagewhen the attempt's model call returns. Without one, nothing changes. Counters and limits belong to the application. - A refused call ends the turn.
AgentState.last_turn_errorstarts with the newMODEL_CALL_REFUSED_ERROR_PREFIX(modelCallRefusedErrorPrefix), then the reason. The session keeps running and checks again on the next message. - A check that raises or takes longer than
SPEND_LIMIT_CALL_TIMEOUT, 30 seconds, fails closed: it fails the attempt, and the Step retries. A report that raises is logged and dropped.ModelUsageReport.report_idis stable per attempt. - Python Claude Agent SDK adapter:
claude_agent_session_flowtakesspend_limit. A harness is checked once per turn segment, and its usage arrives when the segment ends. - No stored value changes. The conformance suite adds the refusal prefix.
- Go core: unchanged. It does not check spend limits.
- See Spend limits.
A configurable RunModel limit
- Python and TypeScript cores:
AgentSessionOptions.run_model_limit(runModelLimit) sets the method timeout and attempts ofRunModel, with the newRunModelLimit. The retry budget moves with them: the method timeout times one less than the attempts, and at least twice the method timeout. The default stays 15 minutes and 3 attempts in 30 minutes.CompactContextand the heartbeat timeout do not change. - Python Claude Agent SDK adapter:
claude_agent_session_flowtakesrun_model_limit. The TypeScript adapter takes it through its session options. A turn segment that needs more than 15 minutes can now finish. A failed segment reruns whole. - No stored value changes. A running session gets the limit on its next
RunModelafter the Worker restarts. - Go core: unchanged.
Sessions are searchable by the Step they wait in
- Python core:
AgentSessionClient.start_sessionsetsFlowConfig.active_step_search_modeto the newAGENT_SESSION_ACTIVE_STEP_SEARCH_MODE(WITH_WAIT_FOR), soActiveStepTypes = "AwaitToolApproval"and"AwaitQuestionAnswer"find a session while it waits and drop it when it moves on. A mode set inoptions.config_overridewins, includingDISABLED. - TypeScript core: the new
startAgentSession(client, flow, sessionId, input, options)does the same, with the newagentSessionActiveStepSearchMode. Until this core supports a Dex SDK withActiveStepSearchMode.WITH_WAIT_FOR, the value isActiveStepSearchMode.DEFAULT, which the server treats the same way.AgentSessionTestClient.startSessioncalls it. Client.startFlowandAsyncClient.start_floware unchanged, so a session they start stays out of this search. So do sessions started on 0.2.0, untilUpdateFlowConfigturns it on. No stored value changes.- Go core: unchanged.
- See Find sessions that need a person.
A session at the state limit fails, with the reason
- Python and TypeScript cores: when a Step fails on
limits.maxFlowStateBytes, the session ends.RecordTurnFailure,RecordToolFailure, andRecordToolOutcomeUnknownrecognize the recovery error (ValueTooLargewith the textrun state of <X> bytes exceeds the maximum of <Y> bytes, oractive run state of ...from a server that counts only active state), set the newAgentState.statusvaluefailedwith that text inlast_turn_error, and close the FlowFAILEDwith the same text in the same commit. A session no longer goes on to pay for model calls whose answers cannot be stored. A value overvalues.maxValueBytesstill fails only its turn. - That commit is checked against the same limit, and it can fail too. The Flow then closes
FAILEDwith the text anyway andAgentStatekeeps its last value, which is also what happens for a Step with no failure route, such asAwaitUserMessage.AgentSessionClient.get_agent_snapshotand the newread_agent_snapshot(readAgentSnapshot) read the Flow's close, so they reportfailedand the reason for any session that stored a state, for one more call to Dex. A session that fails before it stores a state keeps a snapshot with no state. Theget_agent_snapshotRPC alone reads only what was stored. - UI streams: the event SSE generators end once the Flow failed and every event was sent, instead of sending keep-alives forever. A TypeScript UI message stream that finds the Flow failed ends with an
errorpart with the reason andfinishReasonerror.AgentSessionUIMessageshas a newfailurefield. - New messages are refused.
AgentSessionClient.send_user_messageandsteer_user_message, and the newsendAgentUserMessage, raise the newAgentSessionFailedError, aFlowNotActiveOrNotFoundErrorwithreason. A direct RPC call still getsFlowNotActiveOrNotFoundError. - Queued messages never run. They stay readable in
AgentSnapshot.queued_messagesuntil retention deletes the session. - Go core: reads
failedand keeps its behavior. It does not end a session at the limit yet. - See Upgrade agent code while sessions wait for the order of a rolling deploy.
Full changelog: agents/CHANGELOG.md. Changes since 0.2.0: agents/v0.2.0...agents/v0.3.0