@superdurable/dex-agents 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +1568 -62
  2. package/dist/src/agent-built-in-tools.d.ts +81 -0
  3. package/dist/src/agent-built-in-tools.js +246 -0
  4. package/dist/src/agent-built-in-tools.js.map +1 -0
  5. package/dist/src/agent-context-compaction.d.ts +108 -0
  6. package/dist/src/agent-context-compaction.js +39 -0
  7. package/dist/src/agent-context-compaction.js.map +1 -0
  8. package/dist/src/agent-framework-runner.d.ts +456 -16
  9. package/dist/src/agent-framework-runner.js +4 -3
  10. package/dist/src/agent-framework-runner.js.map +1 -1
  11. package/dist/src/agent-plans.d.ts +48 -0
  12. package/dist/src/agent-plans.js +86 -0
  13. package/dist/src/agent-plans.js.map +1 -0
  14. package/dist/src/agent-session-cancellation-steps.d.ts +28 -0
  15. package/dist/src/agent-session-cancellation-steps.js +154 -0
  16. package/dist/src/agent-session-cancellation-steps.js.map +1 -0
  17. package/dist/src/agent-session-codecs.d.ts +65 -4
  18. package/dist/src/agent-session-codecs.js +342 -8
  19. package/dist/src/agent-session-codecs.js.map +1 -1
  20. package/dist/src/agent-session-flow.d.ts +295 -27
  21. package/dist/src/agent-session-flow.js +368 -21
  22. package/dist/src/agent-session-flow.js.map +1 -1
  23. package/dist/src/agent-session-persistence.d.ts +81 -4
  24. package/dist/src/agent-session-persistence.js +33 -2
  25. package/dist/src/agent-session-persistence.js.map +1 -1
  26. package/dist/src/agent-session-settings.d.ts +58 -0
  27. package/dist/src/agent-session-settings.js +81 -0
  28. package/dist/src/agent-session-settings.js.map +1 -0
  29. package/dist/src/agent-session-step-options.d.ts +27 -0
  30. package/dist/src/agent-session-step-options.js +39 -0
  31. package/dist/src/agent-session-step-options.js.map +1 -0
  32. package/dist/src/agent-session-step-types.d.ts +20 -0
  33. package/dist/src/agent-session-step-types.js +28 -0
  34. package/dist/src/agent-session-step-types.js.map +1 -0
  35. package/dist/src/agent-session-steps.d.ts +101 -8
  36. package/dist/src/agent-session-steps.js +936 -197
  37. package/dist/src/agent-session-steps.js.map +1 -1
  38. package/dist/src/agent-session-tracer.d.ts +61 -0
  39. package/dist/src/agent-session-tracer.js +608 -0
  40. package/dist/src/agent-session-tracer.js.map +1 -0
  41. package/dist/src/agent-session-transitions.d.ts +189 -26
  42. package/dist/src/agent-session-transitions.js +680 -32
  43. package/dist/src/agent-session-transitions.js.map +1 -1
  44. package/dist/src/agent-session-values.d.ts +690 -29
  45. package/dist/src/agent-session-values.js +39 -4
  46. package/dist/src/agent-session-values.js.map +1 -1
  47. package/dist/src/agent-session-wait-steps.d.ts +53 -0
  48. package/dist/src/agent-session-wait-steps.js +389 -0
  49. package/dist/src/agent-session-wait-steps.js.map +1 -0
  50. package/dist/src/agent-tracing-options.d.ts +107 -0
  51. package/dist/src/agent-tracing-options.js +20 -0
  52. package/dist/src/agent-tracing-options.js.map +1 -0
  53. package/dist/src/ai-sdk/ai-sdk-model-client.d.ts +40 -0
  54. package/dist/src/ai-sdk/ai-sdk-model-client.js +235 -0
  55. package/dist/src/ai-sdk/ai-sdk-model-client.js.map +1 -0
  56. package/dist/src/ai-sdk/index.d.ts +1 -0
  57. package/dist/src/ai-sdk/index.js +9 -0
  58. package/dist/src/ai-sdk/index.js.map +1 -0
  59. package/dist/src/index.d.ts +9 -3
  60. package/dist/src/index.js +7 -2
  61. package/dist/src/index.js.map +1 -1
  62. package/dist/src/mcp/index.d.ts +3 -0
  63. package/dist/src/mcp/index.js +10 -0
  64. package/dist/src/mcp/index.js.map +1 -0
  65. package/dist/src/mcp/mcp-resource-and-prompt-tools.d.ts +29 -0
  66. package/dist/src/mcp/mcp-resource-and-prompt-tools.js +185 -0
  67. package/dist/src/mcp/mcp-resource-and-prompt-tools.js.map +1 -0
  68. package/dist/src/mcp/mcp-server-config.d.ts +86 -0
  69. package/dist/src/mcp/mcp-server-config.js +38 -0
  70. package/dist/src/mcp/mcp-server-config.js.map +1 -0
  71. package/dist/src/mcp/mcp-tool-source.d.ts +470 -0
  72. package/dist/src/mcp/mcp-tool-source.js +1204 -0
  73. package/dist/src/mcp/mcp-tool-source.js.map +1 -0
  74. package/dist/src/stepwise/agent-definition.d.ts +158 -0
  75. package/dist/src/stepwise/agent-definition.js +9 -0
  76. package/dist/src/stepwise/agent-definition.js.map +1 -0
  77. package/dist/src/stepwise/function-tool.d.ts +130 -0
  78. package/dist/src/stepwise/function-tool.js +75 -0
  79. package/dist/src/stepwise/function-tool.js.map +1 -0
  80. package/dist/src/stepwise/index.d.ts +7 -0
  81. package/dist/src/stepwise/index.js +12 -0
  82. package/dist/src/stepwise/index.js.map +1 -0
  83. package/dist/src/stepwise/json-schema-validation.d.ts +9 -0
  84. package/dist/src/stepwise/json-schema-validation.js +141 -0
  85. package/dist/src/stepwise/json-schema-validation.js.map +1 -0
  86. package/dist/src/stepwise/model-client.d.ts +194 -0
  87. package/dist/src/stepwise/model-client.js +9 -0
  88. package/dist/src/stepwise/model-client.js.map +1 -0
  89. package/dist/src/stepwise/scripted-model-client.d.ts +99 -0
  90. package/dist/src/stepwise/scripted-model-client.js +156 -0
  91. package/dist/src/stepwise/scripted-model-client.js.map +1 -0
  92. package/dist/src/stepwise/stepwise-agent-runner.d.ts +189 -0
  93. package/dist/src/stepwise/stepwise-agent-runner.js +804 -0
  94. package/dist/src/stepwise/stepwise-agent-runner.js.map +1 -0
  95. package/dist/src/stepwise/stepwise-agent-session-flow.d.ts +35 -0
  96. package/dist/src/stepwise/stepwise-agent-session-flow.js +56 -0
  97. package/dist/src/stepwise/stepwise-agent-session-flow.js.map +1 -0
  98. package/dist/src/stepwise/stepwise-input-items.d.ts +12 -0
  99. package/dist/src/stepwise/stepwise-input-items.js +172 -0
  100. package/dist/src/stepwise/stepwise-input-items.js.map +1 -0
  101. package/dist/src/stepwise/tool-source.d.ts +103 -0
  102. package/dist/src/stepwise/tool-source.js +9 -0
  103. package/dist/src/stepwise/tool-source.js.map +1 -0
  104. package/dist/src/testing/agent-session-test-client.d.ts +65 -8
  105. package/dist/src/testing/agent-session-test-client.js +95 -22
  106. package/dist/src/testing/agent-session-test-client.js.map +1 -1
  107. package/dist/src/testing/index.d.ts +1 -0
  108. package/dist/src/testing/index.js +1 -0
  109. package/dist/src/testing/index.js.map +1 -1
  110. package/dist/src/testing/private-dex-engine.d.ts +9 -0
  111. package/dist/src/testing/private-dex-engine.js +9 -1
  112. package/dist/src/testing/private-dex-engine.js.map +1 -1
  113. package/dist/src/testing/scripted-model-client.d.ts +1 -0
  114. package/dist/src/testing/scripted-model-client.js +10 -0
  115. package/dist/src/testing/scripted-model-client.js.map +1 -0
  116. package/dist/src/ui-stream/agent-event-json.d.ts +30 -0
  117. package/dist/src/ui-stream/agent-event-json.js +64 -0
  118. package/dist/src/ui-stream/agent-event-json.js.map +1 -0
  119. package/dist/src/ui-stream/agent-event-sse.d.ts +154 -0
  120. package/dist/src/ui-stream/agent-event-sse.js +159 -0
  121. package/dist/src/ui-stream/agent-event-sse.js.map +1 -0
  122. package/dist/src/ui-stream/agent-event-stream-positions.d.ts +42 -0
  123. package/dist/src/ui-stream/agent-event-stream-positions.js +153 -0
  124. package/dist/src/ui-stream/agent-event-stream-positions.js.map +1 -0
  125. package/dist/src/ui-stream/agent-session-record-reader.d.ts +72 -0
  126. package/dist/src/ui-stream/agent-session-record-reader.js +241 -0
  127. package/dist/src/ui-stream/agent-session-record-reader.js.map +1 -0
  128. package/dist/src/ui-stream/agent-ui-message-stream-responses.d.ts +219 -0
  129. package/dist/src/ui-stream/agent-ui-message-stream-responses.js +440 -0
  130. package/dist/src/ui-stream/agent-ui-message-stream-responses.js.map +1 -0
  131. package/dist/src/ui-stream/agent-ui-message-stream.d.ts +138 -0
  132. package/dist/src/ui-stream/agent-ui-message-stream.js +681 -0
  133. package/dist/src/ui-stream/agent-ui-message-stream.js.map +1 -0
  134. package/dist/src/ui-stream/agent-ui-message-types.d.ts +238 -0
  135. package/dist/src/ui-stream/agent-ui-message-types.js +57 -0
  136. package/dist/src/ui-stream/agent-ui-message-types.js.map +1 -0
  137. package/dist/src/ui-stream/agent-ui-messages.d.ts +66 -0
  138. package/dist/src/ui-stream/agent-ui-messages.js +220 -0
  139. package/dist/src/ui-stream/agent-ui-messages.js.map +1 -0
  140. package/dist/src/ui-stream/agent-ui-stream-cursor.d.ts +64 -0
  141. package/dist/src/ui-stream/agent-ui-stream-cursor.js +186 -0
  142. package/dist/src/ui-stream/agent-ui-stream-cursor.js.map +1 -0
  143. package/dist/src/ui-stream/index.d.ts +14 -0
  144. package/dist/src/ui-stream/index.js +22 -0
  145. package/dist/src/ui-stream/index.js.map +1 -0
  146. package/dist/src/ui-stream/server-sent-event-responses.d.ts +6 -0
  147. package/dist/src/ui-stream/server-sent-event-responses.js +34 -0
  148. package/dist/src/ui-stream/server-sent-event-responses.js.map +1 -0
  149. package/package.json +41 -5
@@ -1,8 +1,27 @@
1
1
  import { type Context, type Flow, type RPCResult } from "@superdurable/dex";
2
- import type { AgentFrameworkRunner, ToolPolicy } from "./agent-framework-runner.js";
2
+ import { type BuiltInTool } from "./agent-built-in-tools.js";
3
+ import { type CompactionPolicy, type ResolvedCompactionPolicy } from "./agent-context-compaction.js";
4
+ import type { AgentFrameworkRunner, DeferredToolOutcome, ToolPolicy } from "./agent-framework-runner.js";
3
5
  import { type AgentSessionPersistence } from "./agent-session-persistence.js";
4
- import type { AgentMessagesPage, AgentSessionStartInput, AgentSnapshot, AgentUserMessage, ListAgentMessagesInput, ResolveInterruptInput, ToolEffect } from "./agent-session-values.js";
5
- /** Tool policies, live events, and approval deadline of one agent, passed to {@link createAgentSessionFlow}. */
6
+ import { messageRolloverMaxBytesPerCommit, messageRolloverMaxChunksPerCommit } from "./agent-session-transitions.js";
7
+ import type { AgentMessagesPage, AgentSessionStartInput, AgentSnapshot, AgentUserMessage, AnswerQuestionRequest, CancelTurnRequest, DeleteQueuedMessageRequest, ExecutePlanRequest, ListAgentMessagesInput, ResolveInterruptInput, SteerUserMessageRequest, ToolEffect, UpdateSessionSettingsRequest } from "./agent-session-values.js";
8
+ import { type AgentTracingOptions, type ResolvedAgentTracingOptions } from "./agent-tracing-options.js";
9
+ export declare const snapshotMessageLimit = 200;
10
+ export declare const defaultMaxDurableWaitMs: number;
11
+ export declare const messagePageLimit = 200;
12
+ /** Default {@link AgentSessionOptions.messageWindowSize}. */
13
+ export declare const defaultMessageWindowSize = 64;
14
+ /** Default {@link AgentSessionOptions.messageChunkSize}. */
15
+ export declare const defaultMessageChunkSize = 32;
16
+ /** Default {@link AgentSessionOptions.messageChunkMaxBytes}: 1 MiB. */
17
+ export declare const defaultMessageChunkMaxBytes = 1048576;
18
+ /** Default {@link AgentSessionOptions.retainedMessageLimit}. */
19
+ export declare const defaultRetainedMessageLimit = 1000;
20
+ export { messageRolloverMaxBytesPerCommit, messageRolloverMaxChunksPerCommit };
21
+ /**
22
+ * Tool policies, built-in tools, live events, interrupt deadline, tracing, and compaction of one agent,
23
+ * passed to {@link createAgentSessionFlow}.
24
+ */
6
25
  export interface AgentSessionOptions {
7
26
  /**
8
27
  * Policies by tool name. A policy overrides framework metadata and {@link defaultToolEffect}.
@@ -20,10 +39,77 @@ export interface AgentSessionOptions {
20
39
  */
21
40
  readonly eventStreamCapacityBytes?: number;
22
41
  /**
23
- * Milliseconds an approval may stay pending before `AwaitToolApproval` rejects it with
24
- * `"approval deadline passed"`. Defaults to no deadline: approvals wait indefinitely.
42
+ * Milliseconds an approval or a question may stay pending before the session rejects it with
43
+ * `"approval deadline passed"` or `"question deadline passed"`. Defaults to no deadline: interrupts wait
44
+ * indefinitely.
25
45
  */
26
46
  readonly interruptDeadlineMs?: number;
47
+ /**
48
+ * OpenTelemetry GenAI span options. Defaults to spans through the global tracer provider when
49
+ * `@opentelemetry/api` is installed, and nothing otherwise. See {@link AgentTracingOptions}.
50
+ */
51
+ readonly tracing?: AgentTracingOptions;
52
+ /**
53
+ * Built-in tools the session handles, such as `["ask_user", "durable_wait"]`. Defaults to none.
54
+ *
55
+ * The runner offers the enabled ones to its model from {@link builtInToolDefinitions}; see
56
+ * {@link BuiltInTool}. An enabled built-in name is reserved: a tool policy for it is refused here, and
57
+ * the session routes every call with that name to the built-in tool. Enable a built-in tool only after
58
+ * every Worker of the Flow type runs a release that supports it.
59
+ */
60
+ readonly builtInTools?: readonly BuiltInTool[];
61
+ /**
62
+ * Longest `durable_wait` in milliseconds; a longer `duration_seconds` fails the call at once.
63
+ * Defaults to 365 days. It must be a positive multiple of 1,000, because Dex Timers take whole seconds.
64
+ * The Python core's `max_durable_wait` is a `timedelta`; this option is the same limit in milliseconds.
65
+ */
66
+ readonly maxDurableWaitMs?: number;
67
+ /**
68
+ * Whether `send_user_message` accepts a message with `planMode`, which starts a `planning` turn that drafts
69
+ * a plan for `execute_plan`. A `draft` plan makes every new turn a `planning` turn until it runs. Defaults
70
+ * to `false`.
71
+ *
72
+ * It requires `write_todos` in {@link builtInTools} and a runner whose
73
+ * {@link AgentFrameworkRunner.supportsPlanMode} is `true`, such as the Stepwise runner.
74
+ */
75
+ readonly planModeEnabled?: boolean;
76
+ /**
77
+ * When to summarize earlier messages so the model input stays under the context window. Defaults to no
78
+ * compaction. It needs a runner that implements {@link AgentFrameworkRunner.estimateInputTokens},
79
+ * {@link AgentFrameworkRunner.selectCompactionCutoff}, and {@link AgentFrameworkRunner.summarizeContext}.
80
+ * The summarized messages stay stored until {@link retainedMessageLimit} deletes them. Enable it only after
81
+ * every Worker of the Flow type runs a release with the `CompactContext` Step. See {@link CompactionPolicy}.
82
+ */
83
+ readonly compaction?: CompactionPolicy;
84
+ /**
85
+ * Most messages the `AgentMessages` window holds. Defaults to 64. When an append takes the window past it,
86
+ * its oldest messages move into immutable `AgentMessageChunks` instances in the same commit, at most
87
+ * {@link messageRolloverMaxChunksPerCommit} chunks per commit. Every Step that stores messages loads the
88
+ * whole window, so it bounds that load. It must be at least {@link messageChunkSize}.
89
+ */
90
+ readonly messageWindowSize?: number;
91
+ /** Most messages one archive chunk holds. Defaults to 32. A change applies to the next chunk written. */
92
+ readonly messageChunkSize?: number;
93
+ /**
94
+ * Most bytes one archive chunk holds, measured on the JSON this core writes. Defaults to 1 MiB, between 1 and
95
+ * 8,388,608. A chunk closes at {@link messageChunkSize} messages or at this size, whichever comes first. A
96
+ * message whose chunk of one, the message plus 15 bytes, would pass it never enters the window: the Step that
97
+ * stores it writes it straight into its own chunk, so a message too large for the server's
98
+ * `values.maxValueBytes` fails that Step instead of a later rollover. Keep it well under that limit.
99
+ */
100
+ readonly messageChunkMaxBytes?: number;
101
+ /**
102
+ * Retention of summarized messages: the session deletes its oldest archive chunk once every message in it is
103
+ * at or before `ContextSummary.lastSequence` and at least this many stored messages come after the chunk.
104
+ * Defaults to 1,000. `null` keeps every message. It applies only with {@link compaction}, so Flow state stays
105
+ * bounded however long the session runs.
106
+ *
107
+ * The newest `retainedMessageLimit` messages and every message after the summary always stay. Deleted
108
+ * messages leave `list_agent_messages` and `get_agent_snapshot`, and each `list_agent_messages` page then
109
+ * carries `deletedBeforeSequence`. An application that keeps the full transcript copies new messages with
110
+ * `list_agent_messages` before more than `retainedMessageLimit` messages follow them.
111
+ */
112
+ readonly retainedMessageLimit?: number | null;
27
113
  }
28
114
  /** Options applied by an {@link AgentSessionFlow}, with every default filled in. */
29
115
  export interface ResolvedAgentSessionOptions {
@@ -33,17 +119,47 @@ export interface ResolvedAgentSessionOptions {
33
119
  readonly defaultToolEffect: ToolEffect;
34
120
  /** Byte budget of the `AgentEvents` Stream. */
35
121
  readonly eventStreamCapacityBytes: number;
36
- /** Approval deadline in milliseconds, or `undefined` for none. */
122
+ /** Approval and question deadline in milliseconds, or `undefined` for none. */
37
123
  readonly interruptDeadlineMs: number | undefined;
124
+ /**
125
+ * Tracing options. A Flow always sets this field; it is optional so that 0.1.0 code that builds these
126
+ * options keeps compiling.
127
+ */
128
+ readonly tracing?: ResolvedAgentTracingOptions;
129
+ /**
130
+ * Enabled built-in tools, in {@link builtInToolDefinitions} order. A Flow always sets this field and
131
+ * the one below; they are optional so that 0.1.0 code that builds these options keeps compiling.
132
+ */
133
+ readonly builtInTools?: readonly BuiltInTool[];
134
+ /** Longest `durable_wait` in milliseconds. */
135
+ readonly maxDurableWaitMs?: number;
136
+ /** Whether plan mode is enabled. A Flow always sets it; it is optional for the same reason. */
137
+ readonly planModeEnabled?: boolean;
138
+ /** The compaction policy with its defaults, or `undefined` when the session never compacts. */
139
+ readonly compaction?: ResolvedCompactionPolicy;
140
+ /** Most messages the `AgentMessages` window holds. A Flow always sets it; optional for 0.1.0 code. */
141
+ readonly messageWindowSize?: number;
142
+ /** Most messages per archive chunk. A Flow always sets it; optional for 0.1.0 code. */
143
+ readonly messageChunkSize?: number;
144
+ /** Most bytes per archive chunk. A Flow always sets it; optional for 0.1.0 code. */
145
+ readonly messageChunkMaxBytes?: number;
146
+ /** The retention limit, or `null` to keep every message. A Flow always sets it; optional for 0.1.0 code. */
147
+ readonly retainedMessageLimit?: number | null;
38
148
  }
39
149
  /**
40
150
  * Durable agent session Flow: one Flow execution is one agent session, and its Flow ID is the session ID.
41
151
  *
42
152
  * Create one per agent with {@link createAgentSessionFlow}, register it in the process `Registry`, and
43
- * call its RPCs with `Client.invokeRPC`. The RPC names are `send_user_message`, `resolve_interrupt`,
44
- * `get_agent_snapshot`, and `list_agent_messages`, the same as the Python core. The session never
45
- * completes on its own: it waits for the next user message after every turn. Stop it with
46
- * `Client.stopFlow`.
153
+ * call its RPCs with `Client.invokeRPC`. The RPC names are `send_user_message`, `steer_user_message`,
154
+ * `delete_queued_message`, `cancel_turn`, `resolve_interrupt`, `answer_question`, `execute_plan`,
155
+ * `update_session_settings`, `get_agent_snapshot`, and `list_agent_messages`, the same as the Python core. The session never completes on its
156
+ * own: it waits for the next user message after every turn. Stop it with `Client.stopFlow`.
157
+ *
158
+ * `steer_user_message` ends the running turn at its next safe Step boundary. It never interrupts a model call or a
159
+ * tool call that has already started. `cancel_turn` aborts the running model call and every wait for a person, a
160
+ * Timer, or a remote task too, but a tool call Step that has started still runs to the end. The calls that have
161
+ * not started record `rejected` with a `cancellationReason`, an abandoned task records `outcome_unknown`, and
162
+ * `ApplyTurnControl` ends the turn. A steered turn is followed by a new turn with the steered messages.
47
163
  *
48
164
  * The Flow's persistence definitions are properties of the Flow; pass them to `Client.getAttributes`
49
165
  * or the Stream reads.
@@ -61,10 +177,11 @@ export interface ResolvedAgentSessionOptions {
61
177
  * interruptId: interrupt.interruptId, approved: true, rejectionMessage: null });
62
178
  * }
63
179
  * ```
180
+ * @typeParam Runner - Type of {@link runner}. It defaults to {@link AgentFrameworkRunner}.
64
181
  */
65
- export interface AgentSessionFlow extends Flow<AgentSessionStartInput>, AgentSessionPersistence {
182
+ export interface AgentSessionFlow<Runner extends AgentFrameworkRunner<DeferredToolOutcome> = AgentFrameworkRunner> extends Flow<AgentSessionStartInput>, AgentSessionPersistence {
66
183
  /** The framework runner passed to {@link createAgentSessionFlow}. */
67
- readonly runner: AgentFrameworkRunner;
184
+ readonly runner: Runner;
68
185
  /** The options this Flow applies, with defaults filled in. */
69
186
  readonly options: ResolvedAgentSessionOptions;
70
187
  /**
@@ -75,45 +192,190 @@ export interface AgentSessionFlow extends Flow<AgentSessionStartInput>, AgentSes
75
192
  *
76
193
  * @param context - RPC Context supplied by Dex.
77
194
  * @param message - Message to queue.
78
- * @returns `true` when queued; `false` when the text is blank.
195
+ * @returns `true` when queued; `false` when the text is blank, or for a `planMode` message when
196
+ * {@link AgentSessionOptions.planModeEnabled} is not set.
79
197
  */
80
198
  sendUserMessage(context: Context, message: AgentUserMessage): RPCResult<boolean>;
81
199
  /**
82
- * RPC `resolve_interrupt`: approves or rejects one pending interrupt.
200
+ * RPC `execute_plan`: approves one plan revision, so the session starts a turn that runs it.
201
+ *
202
+ * Call it after the user reviewed the `draft` plan that a `planMode` message drafted, or to run an `active`
203
+ * plan again. The next `AwaitUserMessage` starts an `executing` turn with every tool, whose user message is
204
+ * `[Dex] The user approved plan revision <n>. Execute it and keep the task statuses current with
205
+ * write_todos.`. A queued message that the session took first runs its turn first; when that turn changes
206
+ * the plan, the approval is stale and never runs.
207
+ *
208
+ * The RPC records the approval in `PendingPlanExecution` until the session starts the turn, so a revision
209
+ * runs once per approval. It locks `PendingPlanExecution`: a concurrent `execute_plan` can make it fail with
210
+ * `RpcLockConflictError`, which is safe to retry.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * const snapshot = await client.invokeRPC(flow.getAgentSnapshot, sessionId);
215
+ * if (snapshot.plan?.status === "draft") {
216
+ * await client.invokeRPC(flow.executePlan, sessionId, { revision: snapshot.plan.revision });
217
+ * }
218
+ * ```
219
+ * @param context - RPC Context supplied by Dex.
220
+ * @param input - The plan revision the user reviewed.
221
+ * @returns `true` when the execution is accepted; `false` unless the session waits for a user message, the
222
+ * plan has this revision and is `draft` or `active`, no execution of it is pending, and no queued or steered
223
+ * message or interrupt is pending.
224
+ */
225
+ executePlan(context: Context, input: ExecutePlanRequest): RPCResult<boolean>;
226
+ /**
227
+ * RPC `steer_user_message`: steers the running turn with new text or with a queued message.
228
+ *
229
+ * A steered message applies at the turn's next safe Step boundary. The session never interrupts a model call or
230
+ * a tool call that has started. It records the calls that have not started as `rejected` with
231
+ * `cancellationReason` `"steered"`, ends the turn, and starts a new turn whose user messages are every steered
232
+ * message, in order.
233
+ *
234
+ * While no turn is active, there is nothing to steer: new `text` is queued like `send_user_message`, so it
235
+ * starts the next turn at once, and a `messageId` that is still queued stays queued. A turn that a Worker
236
+ * without steering started or advanced cannot be steered; see {@link AgentState.acceptsTurnControl}.
237
+ *
238
+ * With `messageId`, the RPC moves that queued message: it deletes it from `QueuedUserMessages` and publishes it
239
+ * to `SteeredUserMessages` in one commit. It locks nothing. When another Step or RPC consumes the message
240
+ * between the RPC's read and its commit, the RPC fails with `ChannelMessageNotFoundError` and commits nothing;
241
+ * reload the snapshot and let the user choose again.
242
+ *
243
+ * @example
244
+ * ```ts
245
+ * const [queued] = (await client.invokeRPC(flow.getAgentSnapshot, sessionId)).queuedMessages ?? [];
246
+ * if (queued !== undefined) {
247
+ * await client.invokeRPC(flow.steerUserMessage, sessionId, { messageId: queued.messageId, text: null });
248
+ * }
249
+ * ```
250
+ * @param context - RPC Context supplied by Dex.
251
+ * @param input - Exactly one of a queued message ID and new text.
252
+ * @returns `true` when the message is steered, or queued while no turn is active; `false` when both or neither
253
+ * field is set, the text is blank, the message is no longer queued, or the active turn does not accept steering.
254
+ */
255
+ steerUserMessage(context: Context, input: SteerUserMessageRequest): RPCResult<boolean>;
256
+ /**
257
+ * RPC `delete_queued_message`: deletes one queued user message before it starts a turn.
258
+ *
259
+ * It locks nothing. When the session consumes the message between the RPC's read and its commit, the RPC fails
260
+ * with `ChannelMessageNotFoundError` and commits nothing.
261
+ *
262
+ * @param context - RPC Context supplied by Dex.
263
+ * @param input - {@link PendingUserMessage.messageId} from `get_agent_snapshot`.
264
+ * @returns `true` when the message was deleted; `false` when it is no longer queued.
265
+ */
266
+ deleteQueuedMessage(context: Context, input: DeleteQueuedMessageRequest): RPCResult<boolean>;
267
+ /**
268
+ * RPC `cancel_turn`: stops the running turn now, with no new turn.
269
+ *
270
+ * The RPC cancels the turn's running model call or compaction, and every Step that waits for an approval, an
271
+ * answer, a `durable_wait` Timer, or a remote task's next poll. A cancelled model call's `cancellationSignal`
272
+ * aborts at once and its answer is dropped. A tool call Step that has started runs to the end, and the turn ends
273
+ * after it. The calls that have not started record `rejected` with `cancellationReason` `"turn_cancelled"`. A
274
+ * started remote task is abandoned: the call records `outcome_unknown`, and a runner that implements
275
+ * {@link AgentFrameworkRunner.cancelToolTask} is asked to cancel the task. Then the session waits for the next
276
+ * user message.
277
+ *
278
+ * The RPC locks `TurnCancellationRequest` and `PendingInterrupts`. No long-running Step locks them, so it never
279
+ * waits for a model call. It can fail with `RpcLockConflictError` while a short Step holds a lock, which is safe
280
+ * to retry. A second call for the same turn changes nothing and returns `true`.
281
+ *
282
+ * @param context - RPC Context supplied by Dex.
283
+ * @param input - The turn to stop, or `turnId` `null` for the active turn.
284
+ * @returns `true` when the request is recorded, although a turn whose model call already committed its final
285
+ * answer completes instead; `false` when no turn is active, `turnId` names another turn, or the active turn does
286
+ * not accept cancellation.
287
+ */
288
+ cancelTurn(context: Context, input: CancelTurnRequest): RPCResult<boolean>;
289
+ /**
290
+ * RPC `update_session_settings`: replaces the session's settings from the next turn on.
291
+ *
292
+ * The new settings apply when the next turn starts, the same boundary at which a `planMode` message takes
293
+ * effect. A running turn keeps the settings it started with for every model call, retry, and compaction, so one
294
+ * turn never mixes two models. The settings replace the old ones; nothing is merged, and `{}` clears them, so
295
+ * `get_agent_snapshot` returns `null`.
296
+ *
297
+ * Settings are stored in the session and returned by `get_agent_snapshot`, and the browser snapshot JSON of
298
+ * `@superdurable/dex-agents/ui-stream` includes them. Never put a secret or anything a browser must not see in
299
+ * them; put a reference, such as a credential name, that the Worker resolves. Call the RPC only after every
300
+ * Worker of the Flow type runs dex-agents 0.2.0.
301
+ *
302
+ * The RPC locks nothing. When two updates race, the one that commits last wins. A turn that starts between
303
+ * this RPC's read and its commit runs with the earlier settings, and the next turn gets these.
304
+ *
305
+ * @example
306
+ * ```ts
307
+ * await client.invokeRPC(flow.updateSessionSettings, sessionId, { sessionSettings: { model: "gpt-5" } });
308
+ * ```
309
+ * @param context - RPC Context supplied by Dex.
310
+ * @param input - The complete new settings.
311
+ * @returns `true` when the settings are stored; `false` before `StartAgentSession` committed, or when the
312
+ * settings are `null` (a missing or `null` field), are not a JSON object, or are larger than
313
+ * `MAX_SESSION_SETTINGS_BYTES` plus `SESSION_SETTINGS_SIZE_TOLERANCE_BYTES`.
314
+ */
315
+ updateSessionSettings(context: Context, input: UpdateSessionSettingsRequest): RPCResult<boolean>;
316
+ /**
317
+ * RPC `resolve_interrupt`: approves or rejects one pending tool approval, or declines one question.
83
318
  *
84
319
  * It removes the interrupt from `PendingInterrupts` and publishes the answer in one commit, so only
85
320
  * one call succeeds per interrupt. It locks `PendingInterrupts`, so a call that races
86
- * `AwaitToolApproval` can fail with `RpcLockConflictError`, which is safe to retry. The
87
- * rejection message is dropped when `approved` is `true`.
321
+ * `AwaitToolApproval`, `AwaitQuestionAnswer`, `ResumeTurn`, `FinishTurnCancellation`, or `cancel_turn` can fail
322
+ * with `RpcLockConflictError`, which is safe to retry. The rejection message is dropped when `approved` is `true`. A question needs an answer, so
323
+ * `approved` `true` on a `question` interrupt is refused; answer it with {@link answerQuestion}.
88
324
  *
89
325
  * @param context - RPC Context supplied by Dex.
90
326
  * @param input - Interrupt ID and decision.
91
327
  * @returns `true` when the interrupt was pending and is now resolved; `false` when it is unknown,
92
- * already resolved, or past its deadline.
328
+ * already resolved, past its deadline, or a question with `approved` `true`.
93
329
  */
94
330
  resolveInterrupt(context: Context, input: ResolveInterruptInput): RPCResult<boolean>;
331
+ /**
332
+ * RPC `answer_question`: answers one pending `question` interrupt.
333
+ *
334
+ * The answer becomes the result of the `ask_user` call, `{"status":"answered","answer":"<text>"}`, so
335
+ * the model continues the same turn. For a tool's question, the tool runs again with the answer. The
336
+ * RPC removes the interrupt and publishes the answer in one commit, so only one call succeeds per
337
+ * question. It locks `PendingInterrupts` and can fail with `RpcLockConflictError`, which is safe to
338
+ * retry. Decline a question with {@link resolveInterrupt} and `approved` `false`.
339
+ *
340
+ * @example
341
+ * ```ts
342
+ * const snapshot = await client.invokeRPC(flow.getAgentSnapshot, sessionId);
343
+ * const question = snapshot.pendingInterrupts.find((interrupt) => interrupt.kind === "question");
344
+ * if (question !== undefined) {
345
+ * await client.invokeRPC(flow.answerQuestion, sessionId, { interruptId: question.interruptId, answer: "blue" });
346
+ * }
347
+ * ```
348
+ * @param context - RPC Context supplied by Dex.
349
+ * @param input - Interrupt ID and answer.
350
+ * @returns `true` when the question was pending and is now answered; `false` when the interrupt is
351
+ * not pending, is not a question, or is past its deadline, and when the answer is blank or is not one
352
+ * of the choices while free text is not allowed.
353
+ */
354
+ answerQuestion(context: Context, input: AnswerQuestionRequest): RPCResult<boolean>;
95
355
  /**
96
356
  * RPC `get_agent_snapshot`: returns the durable session view a UI renders.
97
357
  *
98
358
  * It reads committed state without locks, so it also serves a retained closed session. It loads the
99
- * whole `AgentMessages` map.
359
+ * `AgentMessages` window and every retained `AgentMessageChunks` instance.
100
360
  *
101
361
  * @param context - RPC Context supplied by Dex.
102
- * @returns State, the last 200 messages, pending interrupts, the active turn's tool calls, usage,
103
- * and the queued message count. Before `StartAgentSession` commits, `state` is `null` and the lists
104
- * are empty.
362
+ * @returns State, the last 200 messages, pending interrupts, the active turn's tool calls, usage, the queued
363
+ * message count, the plan, the queued and steered messages with their Channel message IDs, and the context
364
+ * summary; summarized messages stay in `messages` until retention deletes them. Before `StartAgentSession` commits, `state` is `null` and
365
+ * the lists are empty.
105
366
  */
106
367
  getAgentSnapshot(context: Context): RPCResult<AgentSnapshot>;
107
368
  /**
108
369
  * RPC `list_agent_messages`: returns one page of stored messages, oldest first.
109
370
  *
110
371
  * Start with `beforeSequence` `null` for the newest page, then pass each page's
111
- * `nextBeforeSequence` to walk back. It also serves a retained closed session.
372
+ * `nextBeforeSequence` to walk back. It also serves a retained closed session. Messages that retention
373
+ * deleted are gone: the oldest page starts at the oldest stored message.
112
374
  *
113
375
  * @param context - RPC Context supplied by Dex.
114
376
  * @param input - Exclusive upper sequence bound, or `null`, and a page size clamped to 1..200.
115
377
  * @returns Up to `limit` messages below `beforeSequence` in ascending order, and the bound of the
116
- * next older page, or `null` when the page starts at the first message.
378
+ * next older page, or `null` when the page starts at the oldest stored message.
117
379
  */
118
380
  listAgentMessages(context: Context, input: ListAgentMessagesInput): RPCResult<AgentMessagesPage>;
119
381
  }
@@ -137,12 +399,18 @@ export interface AgentSessionFlow extends Flow<AgentSessionStartInput>, AgentSes
137
399
  * const billing = createAgentSessionFlow(billingRunner, "BillingAgent");
138
400
  * const registry = new Registry([triage, billing]);
139
401
  * ```
402
+ * @typeParam Runner - Type of the runner, kept as the Flow's `runner` property type.
140
403
  * @param runner - Framework runner; the Flow owns no other dependency.
141
404
  * @param flowType - Flow type, unique within the Registry, such as `"TriageAgent"`. Keep it stable:
142
405
  * running sessions resume by it.
143
- * @param options - Tool policies, Stream capacity, and approval deadline. Defaults to all defaults.
406
+ * @param options - Tool policies, Stream capacity, approval deadline, and tracing. Defaults to all
407
+ * defaults.
144
408
  * @returns A new Flow to register in one Registry.
145
- * @throws {TypeError} When `flowType` is blank, the runner is incomplete, or an effect is unknown.
146
- * @throws {RangeError} When `eventStreamCapacityBytes` or `interruptDeadlineMs` is not positive.
409
+ * @throws {TypeError} When `flowType` is blank, the runner is incomplete, an effect or built-in tool is
410
+ * unknown, a tool policy names an enabled built-in tool, a tracing option is invalid, `planModeEnabled`
411
+ * is set without `write_todos` or for a runner without {@link AgentFrameworkRunner.supportsPlanMode}, or
412
+ * `compaction` is set for a runner without the compaction methods.
413
+ * @throws {RangeError} When `eventStreamCapacityBytes` or `interruptDeadlineMs` is not positive,
414
+ * `maxDurableWaitMs` is not a positive whole number of seconds, or the compaction policy is out of range.
147
415
  */
148
- export declare function createAgentSessionFlow(runner: AgentFrameworkRunner, flowType: string, options?: AgentSessionOptions): AgentSessionFlow;
416
+ export declare function createAgentSessionFlow<Runner extends AgentFrameworkRunner<DeferredToolOutcome>>(runner: Runner, flowType: string, options?: AgentSessionOptions): AgentSessionFlow<Runner>;