@superdurable/dex-agents 0.4.0 → 0.5.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.
- package/README.md +506 -52
- package/dist/src/agent-context-compaction.d.ts +1 -1
- package/dist/src/agent-framework-runner.d.ts +122 -11
- package/dist/src/agent-framework-runner.js +4 -0
- package/dist/src/agent-framework-runner.js.map +1 -1
- package/dist/src/agent-local-directory-media-store.d.ts +111 -0
- package/dist/src/agent-local-directory-media-store.js +417 -0
- package/dist/src/agent-local-directory-media-store.js.map +1 -0
- package/dist/src/agent-media.d.ts +279 -0
- package/dist/src/agent-media.js +457 -0
- package/dist/src/agent-media.js.map +1 -0
- package/dist/src/agent-session-codecs.d.ts +3 -1
- package/dist/src/agent-session-codecs.js +45 -4
- package/dist/src/agent-session-codecs.js.map +1 -1
- package/dist/src/agent-session-failure.d.ts +4 -2
- package/dist/src/agent-session-failure.js +6 -2
- package/dist/src/agent-session-failure.js.map +1 -1
- package/dist/src/agent-session-flow-graph.d.ts +46 -0
- package/dist/src/agent-session-flow-graph.js +51 -0
- package/dist/src/agent-session-flow-graph.js.map +1 -1
- package/dist/src/agent-session-flow.d.ts +5 -3
- package/dist/src/agent-session-flow.js +10 -1
- package/dist/src/agent-session-flow.js.map +1 -1
- package/dist/src/agent-session-start.d.ts +1 -1
- package/dist/src/agent-session-start.js +2 -2
- package/dist/src/agent-session-start.js.map +1 -1
- package/dist/src/agent-session-steps.d.ts +2 -0
- package/dist/src/agent-session-steps.js +52 -3
- package/dist/src/agent-session-steps.js.map +1 -1
- package/dist/src/agent-session-tracer.js +1 -1
- package/dist/src/agent-session-tracer.js.map +1 -1
- package/dist/src/agent-session-transitions.d.ts +2 -0
- package/dist/src/agent-session-transitions.js +21 -1
- package/dist/src/agent-session-transitions.js.map +1 -1
- package/dist/src/agent-session-values.d.ts +76 -1
- package/dist/src/agent-session-values.js.map +1 -1
- package/dist/src/agent-session-wait-steps.js +14 -2
- package/dist/src/agent-session-wait-steps.js.map +1 -1
- package/dist/src/ai-sdk/ai-sdk-model-client.d.ts +15 -3
- package/dist/src/ai-sdk/ai-sdk-model-client.js +36 -7
- package/dist/src/ai-sdk/ai-sdk-model-client.js.map +1 -1
- package/dist/src/ai-sdk/index.d.ts +1 -1
- package/dist/src/ai-sdk/index.js +1 -1
- package/dist/src/ai-sdk/index.js.map +1 -1
- package/dist/src/{stepwise → builtin-loop}/agent-definition.d.ts +120 -5
- package/dist/src/builtin-loop/agent-definition.js.map +1 -0
- package/dist/src/builtin-loop/builtin-agent-session-flow.d.ts +69 -0
- package/dist/src/{stepwise/stepwise-agent-session-flow.js → builtin-loop/builtin-agent-session-flow.js} +15 -9
- package/dist/src/builtin-loop/builtin-agent-session-flow.js.map +1 -0
- package/dist/src/{stepwise/stepwise-agent-runner.d.ts → builtin-loop/builtin-loop-agent-runner.d.ts} +72 -14
- package/dist/src/{stepwise/stepwise-agent-runner.js → builtin-loop/builtin-loop-agent-runner.js} +284 -41
- package/dist/src/builtin-loop/builtin-loop-agent-runner.js.map +1 -0
- package/dist/src/{stepwise/stepwise-input-items.d.ts → builtin-loop/builtin-loop-input-items.d.ts} +7 -3
- package/dist/src/{stepwise/stepwise-input-items.js → builtin-loop/builtin-loop-input-items.js} +57 -10
- package/dist/src/builtin-loop/builtin-loop-input-items.js.map +1 -0
- package/dist/src/builtin-loop/function-tool.d.ts +282 -0
- package/dist/src/{stepwise → builtin-loop}/function-tool.js +63 -3
- package/dist/src/builtin-loop/function-tool.js.map +1 -0
- package/dist/src/builtin-loop/index.d.ts +8 -0
- package/dist/src/builtin-loop/index.js +13 -0
- package/dist/src/builtin-loop/index.js.map +1 -0
- package/dist/src/builtin-loop/json-schema-validation.js.map +1 -0
- package/dist/src/{stepwise → builtin-loop}/model-client.d.ts +36 -7
- package/dist/src/builtin-loop/model-client.js.map +1 -0
- package/dist/src/{stepwise → builtin-loop}/scripted-model-client.d.ts +8 -5
- package/dist/src/{stepwise → builtin-loop}/scripted-model-client.js +8 -5
- package/dist/src/builtin-loop/scripted-model-client.js.map +1 -0
- package/dist/src/{stepwise → builtin-loop}/tool-source.d.ts +2 -2
- package/dist/src/builtin-loop/tool-source.js.map +1 -0
- package/dist/src/connectors/connector-input-schema.js +1 -1
- package/dist/src/connectors/connector-input-schema.js.map +1 -1
- package/dist/src/connectors/connector-step-context.d.ts +19 -2
- package/dist/src/connectors/connector-step-context.js +61 -5
- package/dist/src/connectors/connector-step-context.js.map +1 -1
- package/dist/src/connectors/connector-tool-source.d.ts +61 -13
- package/dist/src/connectors/connector-tool-source.js +111 -24
- package/dist/src/connectors/connector-tool-source.js.map +1 -1
- package/dist/src/index.d.ts +6 -4
- package/dist/src/index.js +3 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/index.d.ts +1 -0
- package/dist/src/mcp/index.js +1 -0
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/mcp/mcp-dex-conventions.d.ts +57 -0
- package/dist/src/mcp/mcp-dex-conventions.js +90 -0
- package/dist/src/mcp/mcp-dex-conventions.js.map +1 -0
- package/dist/src/mcp/mcp-image-content.d.ts +20 -0
- package/dist/src/mcp/mcp-image-content.js +82 -0
- package/dist/src/mcp/mcp-image-content.js.map +1 -0
- package/dist/src/mcp/mcp-tool-source.d.ts +178 -17
- package/dist/src/mcp/mcp-tool-source.js +237 -34
- package/dist/src/mcp/mcp-tool-source.js.map +1 -1
- package/dist/src/s3/index.d.ts +1 -0
- package/dist/src/s3/index.js +9 -0
- package/dist/src/s3/index.js.map +1 -0
- package/dist/src/s3/s3-media-store.d.ts +138 -0
- package/dist/src/s3/s3-media-store.js +255 -0
- package/dist/src/s3/s3-media-store.js.map +1 -0
- package/dist/src/stepwise/index.d.ts +41 -8
- package/dist/src/stepwise/index.js +35 -5
- package/dist/src/stepwise/index.js.map +1 -1
- package/dist/src/testing/agent-session-test-client.d.ts +6 -3
- package/dist/src/testing/agent-session-test-client.js +10 -3
- package/dist/src/testing/agent-session-test-client.js.map +1 -1
- package/dist/src/testing/scripted-model-client.d.ts +1 -1
- package/dist/src/testing/scripted-model-client.js +2 -2
- package/dist/src/testing/scripted-model-client.js.map +1 -1
- package/dist/src/tool-source-router.d.ts +3 -3
- package/dist/src/tool-source-router.js +2 -2
- package/dist/src/ui-stream/agent-event-json.d.ts +2 -1
- package/dist/src/ui-stream/agent-event-json.js +3 -1
- package/dist/src/ui-stream/agent-event-json.js.map +1 -1
- package/dist/src/ui-stream/agent-ui-messages.d.ts +11 -3
- package/dist/src/ui-stream/agent-ui-messages.js +29 -5
- package/dist/src/ui-stream/agent-ui-messages.js.map +1 -1
- package/package.json +16 -3
- package/dist/src/stepwise/agent-definition.js.map +0 -1
- package/dist/src/stepwise/function-tool.d.ts +0 -130
- package/dist/src/stepwise/function-tool.js.map +0 -1
- package/dist/src/stepwise/json-schema-validation.js.map +0 -1
- package/dist/src/stepwise/model-client.js.map +0 -1
- package/dist/src/stepwise/scripted-model-client.js.map +0 -1
- package/dist/src/stepwise/stepwise-agent-runner.js.map +0 -1
- package/dist/src/stepwise/stepwise-agent-session-flow.d.ts +0 -35
- package/dist/src/stepwise/stepwise-agent-session-flow.js.map +0 -1
- package/dist/src/stepwise/stepwise-input-items.js.map +0 -1
- package/dist/src/stepwise/tool-source.js.map +0 -1
- /package/dist/src/{stepwise → builtin-loop}/agent-definition.js +0 -0
- /package/dist/src/{stepwise → builtin-loop}/json-schema-validation.d.ts +0 -0
- /package/dist/src/{stepwise → builtin-loop}/json-schema-validation.js +0 -0
- /package/dist/src/{stepwise → builtin-loop}/model-client.js +0 -0
- /package/dist/src/{stepwise → builtin-loop}/tool-source.js +0 -0
|
@@ -4,8 +4,67 @@ import type { ModelSpendLimit } from "../agent-session-spend-limit.js";
|
|
|
4
4
|
import type { ToolPolicy } from "../agent-framework-runner.js";
|
|
5
5
|
import type { AgentPlan, InteractionMode, SessionSettings, ToolEffect } from "../agent-session-values.js";
|
|
6
6
|
import type { FunctionTool } from "./function-tool.js";
|
|
7
|
-
import type { ModelClient, ModelSettings } from "./model-client.js";
|
|
7
|
+
import type { ModelClient, ModelOutputItem, ModelSettings, ModelToolResultItem } from "./model-client.js";
|
|
8
8
|
import type { ToolSource } from "./tool-source.js";
|
|
9
|
+
/**
|
|
10
|
+
* The {@link TurnContinuation} that makes the model answer again within the same turn.
|
|
11
|
+
*
|
|
12
|
+
* {@link message} is the instruction for the next model call, such as what the previous answer lacked. The runner
|
|
13
|
+
* stores it in the turn as user text, so the next model request ends with a user message, which every provider
|
|
14
|
+
* accepts.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const continuation: ContinueTurn = { action: "continue", message: "Add the order number to your answer." };
|
|
19
|
+
* ```
|
|
20
|
+
* @since 0.5.0
|
|
21
|
+
*/
|
|
22
|
+
export interface ContinueTurn {
|
|
23
|
+
/** Discriminator. */
|
|
24
|
+
readonly action: "continue";
|
|
25
|
+
/** Text the model receives as the next user message of the turn. It must not be blank. */
|
|
26
|
+
readonly message: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* What {@link AgentDefinition.decideTurnContinuation} returns at the end of one loop iteration.
|
|
30
|
+
*
|
|
31
|
+
* - `"end"`: end the turn now. After tool calls, the runner makes no further model call.
|
|
32
|
+
* - {@link ContinueTurn}: store its message in the turn as user text, then call the model. After an answer
|
|
33
|
+
* without tool calls, this makes another model call instead of ending the turn. After tool calls, the message
|
|
34
|
+
* follows the tool results in the same model call.
|
|
35
|
+
* - `"default"`: do what the loop does without the hook: call the model again after tool calls, and end the turn
|
|
36
|
+
* after an answer.
|
|
37
|
+
*
|
|
38
|
+
* Later releases may add more forms, so handle only the values you return.
|
|
39
|
+
*
|
|
40
|
+
* @since 0.5.0
|
|
41
|
+
*/
|
|
42
|
+
export type TurnContinuation = "end" | "default" | ContinueTurn;
|
|
43
|
+
/**
|
|
44
|
+
* What {@link AgentDefinition.decideTurnContinuation} receives at the end of one loop iteration.
|
|
45
|
+
*
|
|
46
|
+
* An iteration is one model call and the tool calls it requested. The runner never stores this context.
|
|
47
|
+
*
|
|
48
|
+
* @since 0.5.0
|
|
49
|
+
*/
|
|
50
|
+
export interface TurnContinuationContext {
|
|
51
|
+
/** Flow ID, which is the session ID. */
|
|
52
|
+
readonly flowId: string;
|
|
53
|
+
/** Turn ID. */
|
|
54
|
+
readonly turnId: string;
|
|
55
|
+
/** The {@link SessionSettings} the turn started with. Empty when the session has none. */
|
|
56
|
+
readonly sessionSettings: SessionSettings;
|
|
57
|
+
/**
|
|
58
|
+
* The output items of this iteration's model response, in the order the model returned them. Read
|
|
59
|
+
* {@link ModelOutputItem.text} for the answer and {@link ModelOutputItem.toolCalls} for the calls.
|
|
60
|
+
*/
|
|
61
|
+
readonly modelOutput: readonly ModelOutputItem[];
|
|
62
|
+
/**
|
|
63
|
+
* The results of this iteration's tool calls, in the order the model requested them. Empty when the model
|
|
64
|
+
* answered without tool calls.
|
|
65
|
+
*/
|
|
66
|
+
readonly toolResults: readonly ModelToolResultItem[];
|
|
67
|
+
}
|
|
9
68
|
/**
|
|
10
69
|
* How the first model call of a planning turn without a draft uses `write_todos`, as
|
|
11
70
|
* {@link AgentDefinition.planningToolChoice}: `auto` lets the model choose, and `required` forces it.
|
|
@@ -33,9 +92,9 @@ export interface InstructionContext {
|
|
|
33
92
|
readonly sessionSettings?: SessionSettings;
|
|
34
93
|
}
|
|
35
94
|
/**
|
|
36
|
-
* An agent defined in Dex terms, run by the built-in
|
|
95
|
+
* An agent defined in Dex terms, run by the built-in agent loop.
|
|
37
96
|
*
|
|
38
|
-
* Pass it to {@link
|
|
97
|
+
* Pass it to {@link createBuiltinAgentSessionFlow}. The session Flow, its Steps, approvals, events,
|
|
39
98
|
* and RPCs are the ones every adapter uses: each model call is one `RunModel` Step, and each function
|
|
40
99
|
* tool call is its own Step. Nothing replays a loop, so no code follows a determinism rule, and a
|
|
41
100
|
* deployed change to the definition takes effect at the next model call.
|
|
@@ -44,9 +103,9 @@ export interface InstructionContext {
|
|
|
44
103
|
* ```ts
|
|
45
104
|
* import { openai } from "@ai-sdk/openai";
|
|
46
105
|
* import { createAiSdkModelClient } from "@superdurable/dex-agents/ai-sdk";
|
|
47
|
-
* import {
|
|
106
|
+
* import { createBuiltinAgentSessionFlow } from "@superdurable/dex-agents/builtin-loop";
|
|
48
107
|
*
|
|
49
|
-
* export const supportAgentFlow =
|
|
108
|
+
* export const supportAgentFlow = createBuiltinAgentSessionFlow(
|
|
50
109
|
* {
|
|
51
110
|
* name: "support",
|
|
52
111
|
* instructions: "You help customers with their orders.",
|
|
@@ -163,4 +222,60 @@ export interface AgentDefinition {
|
|
|
163
222
|
* @since 0.3.0
|
|
164
223
|
*/
|
|
165
224
|
readonly spendLimit?: ModelSpendLimit;
|
|
225
|
+
/**
|
|
226
|
+
* Decides, at the end of each loop iteration, whether the turn ends or continues.
|
|
227
|
+
*
|
|
228
|
+
* Use it to stop a turn once a tool call has done the work, or to make the model try again after an answer
|
|
229
|
+
* that the application rejects. Absent, the default, the loop calls the model again after tool calls and ends
|
|
230
|
+
* the turn after an answer.
|
|
231
|
+
*
|
|
232
|
+
* The runner calls it in two places:
|
|
233
|
+
*
|
|
234
|
+
* - After a batch of tool calls, in the next `RunModel` Step, before the model call. `"end"` completes the turn
|
|
235
|
+
* with no model call: the tool results become the turn's last messages, and the Step records zero model
|
|
236
|
+
* calls. A {@link ContinueTurn} adds its message after the tool results, and the model call receives both.
|
|
237
|
+
* `"default"` calls the model with the results.
|
|
238
|
+
* - After a model call that requested no tools, in the same `RunModel` Step. A {@link ContinueTurn} stores the
|
|
239
|
+
* answer and its message as user text, then makes another model call in a new `RunModel` Step. `"end"` and
|
|
240
|
+
* `"default"` complete the turn.
|
|
241
|
+
*
|
|
242
|
+
* The continuation message is part of the turn's transcript: the model sees it as user text, and snapshots hold
|
|
243
|
+
* it as a `user` message between the two answers. `convertAgentSnapshotToUIMessages` keeps such a message out of
|
|
244
|
+
* the chat and shows the next model call as a new step of the same assistant message, as the UI stream does.
|
|
245
|
+
*
|
|
246
|
+
* At most 8 continuations in a row may follow answers without tool calls; a tool call resets the count. The 9th
|
|
247
|
+
* ends the turn with that answer stored and the turn's `lastTurnError` set. Each continued model call counts
|
|
248
|
+
* toward {@link maxModelCallsPerTurn}.
|
|
249
|
+
*
|
|
250
|
+
* The function may be synchronous or return a Promise. It runs inside the `RunModel` attempt, so a thrown error
|
|
251
|
+
* or any other value, including a {@link ContinueTurn} with a blank message, fails that attempt, and the Step's
|
|
252
|
+
* retry policy runs it again. After an answer, that retry also repeats the model call. The function can run more
|
|
253
|
+
* than once for one iteration, so keep it free of side effects. `cancel_turn` and a steered message still end a
|
|
254
|
+
* continued turn, because the session checks them before every `RunModel` reaches the runner.
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```ts
|
|
258
|
+
* const definition: AgentDefinition = {
|
|
259
|
+
* name: "approvals",
|
|
260
|
+
* instructions: "Review the request, then call submit_decision.",
|
|
261
|
+
* model,
|
|
262
|
+
* tools: [submitDecision],
|
|
263
|
+
* decideTurnContinuation: ({ toolResults, modelOutput }) => {
|
|
264
|
+
* // Once submit_decision ran, the turn is done; skip the closing model call.
|
|
265
|
+
* if (toolResults.some((result) => result.toolName === "submit_decision")) {
|
|
266
|
+
* return "end";
|
|
267
|
+
* }
|
|
268
|
+
* const answer = modelOutput.map((item) => item.text ?? "").join("");
|
|
269
|
+
* if (toolResults.length === 0 && !answer.includes("DECISION:")) {
|
|
270
|
+
* return { action: "continue", message: "Finish with a line that starts with DECISION:." };
|
|
271
|
+
* }
|
|
272
|
+
* return "default";
|
|
273
|
+
* },
|
|
274
|
+
* };
|
|
275
|
+
* ```
|
|
276
|
+
* @param context - This iteration's model output and tool results.
|
|
277
|
+
* @returns `"end"`, `"default"`, or a {@link ContinueTurn}; see {@link TurnContinuation}.
|
|
278
|
+
* @since 0.5.0
|
|
279
|
+
*/
|
|
280
|
+
readonly decideTurnContinuation?: (context: TurnContinuationContext) => TurnContinuation | Promise<TurnContinuation>;
|
|
166
281
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-definition.js","sourceRoot":"","sources":["../../../src/builtin-loop/agent-definition.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,kDAAkD;AAClD,mEAAmE;AACnE,+CAA+C;AAC/C,EAAE;AACF,0DAA0D"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { MediaStore } from "../agent-media.js";
|
|
2
|
+
import { type AgentSessionFlow } from "../agent-session-flow.js";
|
|
3
|
+
import type { AgentDefinition } from "./agent-definition.js";
|
|
4
|
+
import { BuiltinLoopAgentRunner } from "./builtin-loop-agent-runner.js";
|
|
5
|
+
/**
|
|
6
|
+
* Options of {@link createBuiltinAgentSessionFlow} that are not part of the agent definition.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.5.0
|
|
9
|
+
*/
|
|
10
|
+
export interface BuiltinAgentSessionFlowOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The media store that holds the session's images, such as `S3MediaStore` from `@superdurable/dex-agents/s3`.
|
|
13
|
+
* Defaults to none.
|
|
14
|
+
*
|
|
15
|
+
* With a store, `send_user_message` accepts images, and the model sees each image of a user message or a tool
|
|
16
|
+
* result. Stored messages keep only references: the runner reads the bytes with `loadImages` right before each
|
|
17
|
+
* model call, so a store read failure fails that call and its `RunModel` Step retries. Use the same store, or one
|
|
18
|
+
* that reads the same objects, in every Worker process of the Flow type. Without a store, `send_user_message`
|
|
19
|
+
* refuses images and tool result images do not reach the model.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { S3MediaStore } from "@superdurable/dex-agents/s3";
|
|
24
|
+
*
|
|
25
|
+
* const mediaStore = S3MediaStore.fromStoreUri("s3://agent-media/sessions");
|
|
26
|
+
* const flow = createBuiltinAgentSessionFlow(supportAgent, "SupportAgent", { mediaStore });
|
|
27
|
+
* ```
|
|
28
|
+
* @since 0.5.0
|
|
29
|
+
*/
|
|
30
|
+
readonly mediaStore?: MediaStore;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates the agent session Flow for an agent defined in Dex terms, run by the built-in agent loop.
|
|
34
|
+
*
|
|
35
|
+
* It builds the session Flow with a {@link BuiltinLoopAgentRunner} and derives the session options from
|
|
36
|
+
* the definition, so tool policies, built-in tools, plan mode, the deadlines, and compaction are declared once. The Flow is the
|
|
37
|
+
* same session Flow every adapter uses, with the same Steps, RPCs, and events. Construct it once at
|
|
38
|
+
* application startup and register the same object in the Worker and Client Registry.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const supportAgentFlow = createBuiltinAgentSessionFlow(
|
|
43
|
+
* {
|
|
44
|
+
* name: "support",
|
|
45
|
+
* instructions: "You help customers with their orders.",
|
|
46
|
+
* model: createAiSdkModelClient(openai("gpt-5-mini")),
|
|
47
|
+
* tools: [lookupOrder, refundOrder],
|
|
48
|
+
* builtInTools: ["ask_user", "durable_wait"],
|
|
49
|
+
* interruptDeadlineMs: 24 * 60 * 60 * 1000,
|
|
50
|
+
* },
|
|
51
|
+
* "SupportAgent",
|
|
52
|
+
* );
|
|
53
|
+
* const registry = new Registry([supportAgentFlow]);
|
|
54
|
+
* await client.startFlow(supportAgentFlow, sessionId, { initialMessage: "Where is order 42?" });
|
|
55
|
+
* ```
|
|
56
|
+
* @param definition - The agent definition.
|
|
57
|
+
* @param flowType - Flow type, unique within the Registry. Keep it stable: running sessions resume by it.
|
|
58
|
+
* @param flowOptions - The media store; see {@link BuiltinAgentSessionFlowOptions}. Since 0.5.0.
|
|
59
|
+
* @returns A new Flow; its `runner` is the {@link BuiltinLoopAgentRunner}.
|
|
60
|
+
* @throws {TypeError} When the definition is invalid; see {@link BuiltinLoopAgentRunner} and
|
|
61
|
+
* `createAgentSessionFlow`.
|
|
62
|
+
* @throws {RangeError} When a limit or deadline in the definition is out of range.
|
|
63
|
+
*
|
|
64
|
+
* It replaces `createStepwiseAgentSessionFlow`, which `@superdurable/dex-agents/stepwise` keeps as a deprecated
|
|
65
|
+
* alias.
|
|
66
|
+
*
|
|
67
|
+
* @since 0.5.0
|
|
68
|
+
*/
|
|
69
|
+
export declare function createBuiltinAgentSessionFlow(definition: AgentDefinition, flowType: string, flowOptions?: BuiltinAgentSessionFlowOptions): AgentSessionFlow<BuiltinLoopAgentRunner>;
|
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
//
|
|
7
7
|
// SPDX-License-Identifier: LicenseRef-Sustainable-Use-1.0
|
|
8
8
|
import { createAgentSessionFlow } from "../agent-session-flow.js";
|
|
9
|
-
import {
|
|
9
|
+
import { BuiltinLoopAgentRunner } from "./builtin-loop-agent-runner.js";
|
|
10
10
|
/**
|
|
11
|
-
* Creates the agent session Flow for an agent defined in Dex terms, run by the built-in
|
|
11
|
+
* Creates the agent session Flow for an agent defined in Dex terms, run by the built-in agent loop.
|
|
12
12
|
*
|
|
13
|
-
* It builds the session Flow with a {@link
|
|
13
|
+
* It builds the session Flow with a {@link BuiltinLoopAgentRunner} and derives the session options from
|
|
14
14
|
* the definition, so tool policies, built-in tools, plan mode, the deadlines, and compaction are declared once. The Flow is the
|
|
15
15
|
* same session Flow every adapter uses, with the same Steps, RPCs, and events. Construct it once at
|
|
16
16
|
* application startup and register the same object in the Worker and Client Registry.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
19
|
* ```ts
|
|
20
|
-
* const supportAgentFlow =
|
|
20
|
+
* const supportAgentFlow = createBuiltinAgentSessionFlow(
|
|
21
21
|
* {
|
|
22
22
|
* name: "support",
|
|
23
23
|
* instructions: "You help customers with their orders.",
|
|
@@ -33,13 +33,19 @@ import { StepwiseAgentRunner } from "./stepwise-agent-runner.js";
|
|
|
33
33
|
* ```
|
|
34
34
|
* @param definition - The agent definition.
|
|
35
35
|
* @param flowType - Flow type, unique within the Registry. Keep it stable: running sessions resume by it.
|
|
36
|
-
* @
|
|
37
|
-
* @
|
|
36
|
+
* @param flowOptions - The media store; see {@link BuiltinAgentSessionFlowOptions}. Since 0.5.0.
|
|
37
|
+
* @returns A new Flow; its `runner` is the {@link BuiltinLoopAgentRunner}.
|
|
38
|
+
* @throws {TypeError} When the definition is invalid; see {@link BuiltinLoopAgentRunner} and
|
|
38
39
|
* `createAgentSessionFlow`.
|
|
39
40
|
* @throws {RangeError} When a limit or deadline in the definition is out of range.
|
|
41
|
+
*
|
|
42
|
+
* It replaces `createStepwiseAgentSessionFlow`, which `@superdurable/dex-agents/stepwise` keeps as a deprecated
|
|
43
|
+
* alias.
|
|
44
|
+
*
|
|
45
|
+
* @since 0.5.0
|
|
40
46
|
*/
|
|
41
|
-
export function
|
|
42
|
-
const runner = new
|
|
47
|
+
export function createBuiltinAgentSessionFlow(definition, flowType, flowOptions = {}) {
|
|
48
|
+
const runner = new BuiltinLoopAgentRunner(definition, flowOptions.mediaStore);
|
|
43
49
|
const options = {
|
|
44
50
|
...(definition.toolPolicies === undefined ? {} : { toolPolicies: definition.toolPolicies }),
|
|
45
51
|
...(definition.defaultToolEffect === undefined ? {} : { defaultToolEffect: definition.defaultToolEffect }),
|
|
@@ -54,4 +60,4 @@ export function createStepwiseAgentSessionFlow(definition, flowType) {
|
|
|
54
60
|
};
|
|
55
61
|
return createAgentSessionFlow(runner, flowType, options);
|
|
56
62
|
}
|
|
57
|
-
//# sourceMappingURL=
|
|
63
|
+
//# sourceMappingURL=builtin-agent-session-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-agent-session-flow.js","sourceRoot":"","sources":["../../../src/builtin-loop/builtin-agent-session-flow.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,kDAAkD;AAClD,mEAAmE;AACnE,+CAA+C;AAC/C,EAAE;AACF,0DAA0D;AAG1D,OAAO,EAAE,sBAAsB,EAAmD,MAAM,0BAA0B,CAAC;AAEnH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AA8BxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,6BAA6B,CAC3C,UAA2B,EAC3B,QAAgB,EAChB,cAA8C,EAAE;IAEhD,MAAM,MAAM,GAAG,IAAI,sBAAsB,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAwB;QACnC,GAAG,CAAC,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,YAAY,EAAE,CAAC;QAC3F,GAAG,CAAC,UAAU,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,UAAU,CAAC,iBAAiB,EAAE,CAAC;QAC1G,GAAG,CAAC,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,YAAY,EAAE,CAAC;QAC3F,GAAG,CAAC,UAAU,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC;QACpG,GAAG,CAAC,UAAU,CAAC,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,UAAU,CAAC,mBAAmB,EAAE,CAAC;QAChH,GAAG,CAAC,UAAU,CAAC,wBAAwB,KAAK,SAAS;YACnD,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,wBAAwB,EAAE,UAAU,CAAC,wBAAwB,EAAE,CAAC;QACtE,GAAG,CAAC,UAAU,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;QACrF,GAAG,CAAC,UAAU,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;KACtF,CAAC;IACF,OAAO,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/src/{stepwise/stepwise-agent-runner.d.ts → builtin-loop/builtin-loop-agent-runner.d.ts}
RENAMED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import { type ContextSummaryRequest, type ContextSummaryResult } from "../agent-context-compaction.js";
|
|
2
2
|
export { buildContextSummaryNote, buildContextSummaryOmissionNote, contextSummaryInstructions, contextSummaryNoteHeader, contextSummaryRequest, } from "../agent-context-compaction.js";
|
|
3
3
|
import { type AgentFrameworkRunner, type AgentTurnContext, type AgentTurnOutcome, type DeferredToolExecution, type DeferredToolOutcome, type ToolCallStepOptions, type ToolTaskCancellation, type ToolTaskPoll, type ToolTaskPollOutcome } from "../agent-framework-runner.js";
|
|
4
|
+
import { type MediaStore } from "../agent-media.js";
|
|
4
5
|
import { type AgentToolCall, type FrameworkMessage } from "../agent-session-values.js";
|
|
5
6
|
import type { AgentDefinition } from "./agent-definition.js";
|
|
6
7
|
export { defaultToolSourceListingTimeoutMs } from "../tool-source-router.js";
|
|
7
8
|
export declare const defaultMaxModelCallsPerTurn = 100;
|
|
9
|
+
/**
|
|
10
|
+
* How many {@link ContinueTurn} results of {@link AgentDefinition.decideTurnContinuation} may follow answers without
|
|
11
|
+
* tool calls in a row. A model response with tool calls resets the count.
|
|
12
|
+
* @since 0.5.0
|
|
13
|
+
*/
|
|
14
|
+
export declare const maxConsecutiveTurnContinuations = 8;
|
|
8
15
|
/** Result of a tool call the model made after the turn's model call limit; the same text as the Python core. */
|
|
9
16
|
export declare function buildToolCallLimitReachedResult(maxModelCallsPerTurn: number): string;
|
|
10
17
|
/**
|
|
11
|
-
* The {@link
|
|
18
|
+
* The `lastTurnError` of a turn whose `decideTurnContinuation` returned a {@link ContinueTurn} once too often in a
|
|
19
|
+
* row; the same text as the Python core.
|
|
20
|
+
* @param limit - {@link maxConsecutiveTurnContinuations}.
|
|
21
|
+
* @returns The error text.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildTurnContinuationLimitError(limit: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* The {@link AgentFrameworkRunner} of the built-in agent loop.
|
|
12
26
|
*
|
|
13
|
-
* {@link
|
|
27
|
+
* {@link createBuiltinAgentSessionFlow} creates one; construct it directly only to pass it to
|
|
14
28
|
* `createAgentSessionFlow` with options of your own. Each `RunModel` makes at most one model call
|
|
15
29
|
* through {@link AgentDefinition.model}, from committed state only: the stored messages, the results
|
|
16
30
|
* of the previous model response from the turn's final records, and the instructions. The runner
|
|
@@ -22,13 +36,28 @@ export declare function buildToolCallLimitReachedResult(maxModelCallsPerTurn: nu
|
|
|
22
36
|
* tasks. Its {@link cancelToolTask} passes a task that `cancel_turn` abandoned to that source's optional
|
|
23
37
|
* `cancelToolTask`.
|
|
24
38
|
*
|
|
39
|
+
* With a media store, the runner shows images to the model. It then has `buildUserMessageWithImages` of
|
|
40
|
+
* {@link AgentFrameworkRunner}, as an own property, so `send_user_message` accepts images: the stored `user_text` item keeps their references after the text. A tool
|
|
41
|
+
* result item keeps the references of `AgentToolCall.images`. Before each model call, the runner reads the bytes of
|
|
42
|
+
* every image in the request with `loadImages` and passes them in `ModelRequest.imageBytes`; the model client
|
|
43
|
+
* converts each image to the provider's image part. A failed read fails that `RunModel` attempt, which retries. The
|
|
44
|
+
* model call that writes a context summary sees the text of the items only. Without a store the session refuses
|
|
45
|
+
* user images, and a tool source result's images are stored but not shown to the model. A function tool's images fail
|
|
46
|
+
* the call instead, without a retry. The class declares neither member, so a subclass may still define its own
|
|
47
|
+
* `buildUserMessageWithImages` or `mediaStore`; a subclass method stays in use with a store.
|
|
48
|
+
*
|
|
25
49
|
* @example
|
|
26
50
|
* ```ts
|
|
27
|
-
* const runner = new
|
|
51
|
+
* const runner = new BuiltinLoopAgentRunner(definition);
|
|
28
52
|
* const flow = createAgentSessionFlow(runner, "SupportAgent", { builtInTools: ["ask_user"] });
|
|
29
53
|
* ```
|
|
54
|
+
*
|
|
55
|
+
* It replaces `StepwiseAgentRunner`, which `@superdurable/dex-agents/stepwise` keeps as a deprecated alias.
|
|
56
|
+
*
|
|
57
|
+
* @since 0.5.0
|
|
30
58
|
*/
|
|
31
|
-
export declare class
|
|
59
|
+
export declare class BuiltinLoopAgentRunner implements AgentFrameworkRunner<DeferredToolOutcome> {
|
|
60
|
+
#private;
|
|
32
61
|
/** The agent definition, frozen at construction. */
|
|
33
62
|
readonly definition: AgentDefinition;
|
|
34
63
|
/** The runner honors {@link AgentTurnContext.interactionMode}, so plan mode can be enabled. */
|
|
@@ -39,13 +68,22 @@ export declare class StepwiseAgentRunner implements AgentFrameworkRunner<Deferre
|
|
|
39
68
|
/**
|
|
40
69
|
* Creates the runner and checks the definition.
|
|
41
70
|
* @param definition - The agent definition.
|
|
42
|
-
* @
|
|
43
|
-
*
|
|
71
|
+
* @param mediaStore - The store that holds the session's images, such as `S3MediaStore`. With it, the runner
|
|
72
|
+
* accepts user messages with images and shows them and tool result images to the model, reading the bytes for
|
|
73
|
+
* each model call; stored messages hold only references. It also gets an own `buildUserMessageWithImages`, which
|
|
74
|
+
* stores user text and its images as one `user_text` item that holds the references, not the bytes, unless a
|
|
75
|
+
* subclass defines its own `buildUserMessageWithImages`, which then stays in use. Use the store
|
|
76
|
+
* the clients and tools upload to. Omit it to refuse user images and show tool result images to the model as text
|
|
77
|
+
* only. Since 0.5.0.
|
|
78
|
+
*
|
|
79
|
+
* Changed in 0.5.0: takes `mediaStore`.
|
|
80
|
+
* @throws {TypeError} When the name, instructions, model, tools, or `decideTurnContinuation` are invalid, two tools
|
|
81
|
+
* share a name, a function tool uses the name of an enabled built-in tool, `planModeEnabled` is set without
|
|
44
82
|
* `write_todos`, `planningToolChoice` is neither `auto` nor `required`, or a tool source lacks a
|
|
45
83
|
* {@link ToolSource} method.
|
|
46
84
|
* @throws {RangeError} When `maxModelCallsPerTurn` is not a positive integer.
|
|
47
85
|
*/
|
|
48
|
-
constructor(definition: AgentDefinition);
|
|
86
|
+
constructor(definition: AgentDefinition, mediaStore?: MediaStore | undefined);
|
|
49
87
|
/**
|
|
50
88
|
* Converts user text into a stored `user_text` item.
|
|
51
89
|
* @param text - User message text.
|
|
@@ -56,27 +94,42 @@ export declare class StepwiseAgentRunner implements AgentFrameworkRunner<Deferre
|
|
|
56
94
|
* Makes the turn's next model call.
|
|
57
95
|
* @param turn - The turn context.
|
|
58
96
|
* @returns {@link TurnCompleted} with the results and final answer not stored yet, or
|
|
59
|
-
* {@link ToolCallsRequested} with the previous results, this response, and its tool calls.
|
|
97
|
+
* {@link ToolCallsRequested} with the previous results, this response, and its tool calls. When
|
|
98
|
+
* {@link AgentDefinition.decideTurnContinuation} returns `"end"` after tool calls, a {@link TurnCompleted} with only
|
|
99
|
+
* the results and zero usage, without a model call. When it continues after tool calls, its message follows the
|
|
100
|
+
* results in the request and in the stored messages. When it continues after an answer, a {@link TurnContinued}
|
|
101
|
+
* with the previous results, this response, and the message as user text, or a {@link TurnCompleted} with
|
|
102
|
+
* {@link TurnCompleted.turnError} once {@link maxConsecutiveTurnContinuations} is exceeded.
|
|
60
103
|
* @throws {TypeError} When a function tool uses the name of an enabled built-in tool, or a tool source lists a
|
|
61
104
|
* name that repeats a function tool, an enabled built-in tool, or another source's tool. No model request is
|
|
62
|
-
* made.
|
|
63
|
-
* @throws Any error of the model call
|
|
105
|
+
* made. Also when `decideTurnContinuation` returns another value.
|
|
106
|
+
* @throws Any error of the model call, of the media store, of a tool source's `listTools`, or of
|
|
107
|
+
* `decideTurnContinuation`, which retries the `RunModel` attempt.
|
|
64
108
|
*/
|
|
65
109
|
runModelStep(turn: AgentTurnContext): Promise<AgentTurnOutcome>;
|
|
66
110
|
/**
|
|
67
|
-
* Runs one function tool call after
|
|
111
|
+
* Runs one function tool call after converting its arguments with the tool's `prepareArguments`, when it has
|
|
112
|
+
* one, and checking them against the tool's schema, or passes a call that a
|
|
68
113
|
* tool source built in `runModelStep` to that source, with the source's own `toolSourceReference` and without a
|
|
69
114
|
* listing. Any other name is an unknown tool and never reaches a source.
|
|
115
|
+
* A function tool's {@link ToolCallContext.mediaStore} is this runner's store.
|
|
116
|
+
*
|
|
117
|
+
* Changed in 0.5.0: a function tool receives the media store and may return a {@link FunctionToolResult} with
|
|
118
|
+
* images.
|
|
70
119
|
* @param call - The deferred call.
|
|
71
|
-
* @returns The output: a `string` result unchanged,
|
|
72
|
-
* {@link ToolInputRequested}; or a source's outcome, such as
|
|
120
|
+
* @returns The output: a `string` result unchanged, a {@link FunctionToolResult} as its output and images, any
|
|
121
|
+
* other result as JSON; the tool's {@link ToolInputRequested}; or a source's outcome, such as
|
|
122
|
+
* {@link ToolTaskStarted}.
|
|
73
123
|
* @throws {ToolExecutionError} For an unknown tool, arguments that are not a JSON object or break the
|
|
74
|
-
* schema, or a
|
|
124
|
+
* schema, a non-cancellation error or a thenable result of the tool's `prepareArguments`, a
|
|
125
|
+
* `ToolExecutionError` from the tool or its source, or a function tool that returned images while this runner has
|
|
126
|
+
* no media store.
|
|
75
127
|
* @throws {RangeError} When a source built the call but the definition no longer has it, so the effect decides
|
|
76
128
|
* the outcome.
|
|
77
129
|
* @throws Any other error of the tool source.
|
|
78
130
|
*/
|
|
79
131
|
executeDeferredToolCall(call: DeferredToolExecution): Promise<DeferredToolOutcome>;
|
|
132
|
+
private toToolExecutionResult;
|
|
80
133
|
/**
|
|
81
134
|
* Polls a tool source's task once, through the source that built the call.
|
|
82
135
|
* @param poll - The call's record from `PollToolTask`.
|
|
@@ -154,6 +207,9 @@ export declare class StepwiseAgentRunner implements AgentFrameworkRunner<Deferre
|
|
|
154
207
|
private buildSummaryRequest;
|
|
155
208
|
private buildModelRequest;
|
|
156
209
|
private estimateItems;
|
|
210
|
+
/** Returns the request with the bytes of its images, read from the store right now. */
|
|
211
|
+
private addImageBytes;
|
|
212
|
+
private keepShownImagesOnly;
|
|
157
213
|
/** A built-in enabled only in the session options must not share a function tool's name. */
|
|
158
214
|
private requireNoBuiltInToolNameClash;
|
|
159
215
|
private listOfferedTools;
|
|
@@ -161,6 +217,8 @@ export declare class StepwiseAgentRunner implements AgentFrameworkRunner<Deferre
|
|
|
161
217
|
private resolveModelToolPolicy;
|
|
162
218
|
private resolveModel;
|
|
163
219
|
private resolveInstructions;
|
|
220
|
+
/** Returns the hook's decision for one iteration, or `"default"` without a hook. */
|
|
221
|
+
private decideTurnContinuation;
|
|
164
222
|
}
|
|
165
223
|
/** Error of a call to a tool that no function tool or source listing offers; the same text as the Python core. */
|
|
166
224
|
export declare function buildUnknownToolError(toolName: string): string;
|