@botbotgo/agent-harness 0.0.298 → 0.0.300
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 +78 -38
- package/README.zh.md +80 -31
- package/dist/acp.d.ts +3 -0
- package/dist/acp.js +10 -2
- package/dist/api.d.ts +14 -2
- package/dist/api.js +19 -3
- package/dist/cli.d.ts +18 -1
- package/dist/cli.js +1408 -319
- package/dist/client/acp.d.ts +9 -3
- package/dist/client/acp.js +55 -1
- package/dist/client/in-process.d.ts +5 -2
- package/dist/client/in-process.js +4 -6
- package/dist/client/index.d.ts +1 -1
- package/dist/client/types.d.ts +6 -5
- package/dist/config/agents/direct.yaml +7 -17
- package/dist/config/agents/orchestra.yaml +9 -65
- package/dist/config/catalogs/embedding-models.yaml +1 -1
- package/dist/config/catalogs/stores.yaml +1 -1
- package/dist/config/knowledge/knowledge-runtime.yaml +36 -2
- package/dist/config/knowledge/procedural-memory-runtime.yaml +78 -0
- package/dist/config/{catalogs/models.yaml → models.yaml} +2 -2
- package/dist/config/prompts/direct-system.md +16 -0
- package/dist/config/prompts/orchestra-system.md +62 -0
- package/dist/config/prompts/routing-system.md +14 -0
- package/dist/config/runtime/runtime-memory.yaml +39 -5
- package/dist/config/runtime/workspace.yaml +7 -16
- package/dist/contracts/runtime.d.ts +242 -1
- package/dist/contracts/workspace.d.ts +2 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +2 -1
- package/dist/init-project.js +178 -33
- package/dist/knowledge/contracts.d.ts +5 -0
- package/dist/knowledge/module.d.ts +5 -0
- package/dist/knowledge/module.js +340 -18
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.d.ts +5 -1
- package/dist/persistence/file-store.js +16 -0
- package/dist/persistence/sqlite-store.d.ts +4 -1
- package/dist/persistence/sqlite-store.js +88 -14
- package/dist/persistence/types.d.ts +4 -1
- package/dist/procedural/config.d.ts +63 -0
- package/dist/procedural/config.js +125 -0
- package/dist/procedural/index.d.ts +2 -0
- package/dist/procedural/index.js +1 -0
- package/dist/protocol/ag-ui/http.d.ts +3 -0
- package/dist/protocol/ag-ui/http.js +10 -0
- package/dist/request-events.d.ts +63 -0
- package/dist/request-events.js +400 -0
- package/dist/resource/isolation.js +11 -0
- package/dist/resource/resource-impl.d.ts +1 -0
- package/dist/resource/resource-impl.js +103 -12
- package/dist/resources/init-templates/agent-context/deep-research.md +5 -0
- package/dist/resources/init-templates/prompts/research-analyst-basic.md +1 -0
- package/dist/resources/init-templates/prompts/research-analyst-web-search.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-deep-research-basic.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-deep-research-web-search.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-single-agent-basic.md +1 -0
- package/dist/resources/init-templates/prompts/research-host-single-agent-web-search.md +1 -0
- package/dist/resources/prompts/runtime/browser-capability-disclaimer-recovery.md +1 -0
- package/dist/resources/prompts/runtime/default-subagent.md +2 -0
- package/dist/resources/prompts/runtime/durable-memory-context.md +7 -0
- package/dist/resources/prompts/runtime/execution-with-tool-evidence-retry.md +1 -0
- package/dist/resources/prompts/runtime/execution-with-tool-evidence.md +1 -0
- package/dist/resources/prompts/runtime/invalid-tool-selection-recovery.md +1 -0
- package/dist/resources/prompts/runtime/memory-manager.md +31 -0
- package/dist/resources/prompts/runtime/memory-mutation-reconciliation.md +22 -0
- package/dist/resources/prompts/runtime/slash-command-skill.md +6 -0
- package/dist/resources/prompts/runtime/strict-tool-json.md +1 -0
- package/dist/resources/prompts/runtime/workspace-boundary-guidance.md +3 -0
- package/dist/resources/prompts/runtime/workspace-relative-path.md +1 -0
- package/dist/resources/prompts/runtime/write-todos-descriptive-content.md +1 -0
- package/dist/resources/prompts/runtime/write-todos-full-entry.md +1 -0
- package/dist/resources/prompts/runtime/write-todos-non-empty-initial-list.md +1 -0
- package/dist/resources/tools/_runtime_tool_helpers.mjs +152 -0
- package/dist/resources/tools/cancel_request.mjs +21 -0
- package/dist/resources/tools/fetch_url.mjs +23 -0
- package/dist/resources/tools/http_request.mjs +30 -0
- package/dist/resources/tools/inspect_approvals.mjs +27 -0
- package/dist/resources/tools/inspect_artifacts.mjs +21 -0
- package/dist/resources/tools/inspect_events.mjs +21 -0
- package/dist/resources/tools/inspect_requests.mjs +27 -0
- package/dist/resources/tools/inspect_sessions.mjs +21 -0
- package/dist/resources/tools/list_files.mjs +27 -0
- package/dist/resources/tools/read_artifact.mjs +22 -0
- package/dist/resources/tools/request_approval.mjs +27 -0
- package/dist/resources/tools/run_command.mjs +21 -0
- package/dist/resources/tools/schedule_task.mjs +76 -0
- package/dist/resources/tools/search_files.mjs +47 -0
- package/dist/resources/tools/send_message.mjs +23 -0
- package/dist/runtime/adapter/direct-builtin-utility.d.ts +1 -0
- package/dist/runtime/adapter/direct-builtin-utility.js +90 -0
- package/dist/runtime/adapter/flow/execution-context.d.ts +1 -1
- package/dist/runtime/adapter/flow/execution-context.js +1 -1
- package/dist/runtime/adapter/flow/invocation-flow.d.ts +1 -0
- package/dist/runtime/adapter/flow/invocation-flow.js +9 -1
- package/dist/runtime/adapter/flow/invoke-runtime.d.ts +1 -1
- package/dist/runtime/adapter/flow/stream-runtime.d.ts +5 -1
- package/dist/runtime/adapter/flow/stream-runtime.js +556 -35
- package/dist/runtime/adapter/invocation-result.js +3 -2
- package/dist/runtime/adapter/local-tool-invocation.d.ts +1 -1
- package/dist/runtime/adapter/local-tool-invocation.js +28 -4
- package/dist/runtime/adapter/middleware-assembly.js +3 -1
- package/dist/runtime/adapter/model/invocation-request.d.ts +4 -1
- package/dist/runtime/adapter/model/invocation-request.js +138 -16
- package/dist/runtime/adapter/model/message-assembly.js +2 -6
- package/dist/runtime/adapter/model/model-providers.js +103 -5
- package/dist/runtime/adapter/resilience.js +17 -2
- package/dist/runtime/adapter/runtime-adapter-support.d.ts +11 -7
- package/dist/runtime/adapter/runtime-adapter-support.js +39 -5
- package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +63 -1
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +193 -21
- package/dist/runtime/adapter/tool/tool-arguments.d.ts +3 -1
- package/dist/runtime/adapter/tool/tool-arguments.js +52 -17
- package/dist/runtime/adapter/tool-resolution.d.ts +1 -0
- package/dist/runtime/adapter/tool-resolution.js +4 -2
- package/dist/runtime/agent-runtime-adapter.d.ts +27 -0
- package/dist/runtime/agent-runtime-adapter.js +163 -11
- package/dist/runtime/harness/events/event-bus.d.ts +1 -0
- package/dist/runtime/harness/events/event-bus.js +3 -0
- package/dist/runtime/harness/events/event-sink.d.ts +3 -0
- package/dist/runtime/harness/events/event-sink.js +16 -7
- package/dist/runtime/harness/events/streaming.d.ts +18 -1
- package/dist/runtime/harness/events/streaming.js +23 -10
- package/dist/runtime/harness/run/inspection.js +26 -5
- package/dist/runtime/harness/run/stream-run.d.ts +13 -4
- package/dist/runtime/harness/run/stream-run.js +448 -4
- package/dist/runtime/harness/run/surface-semantics.js +7 -34
- package/dist/runtime/harness/system/runtime-memory-manager.d.ts +3 -0
- package/dist/runtime/harness/system/runtime-memory-manager.js +384 -69
- package/dist/runtime/harness/system/runtime-memory-policy.d.ts +20 -1
- package/dist/runtime/harness/system/runtime-memory-policy.js +65 -17
- package/dist/runtime/harness/system/runtime-memory-records.js +100 -0
- package/dist/runtime/harness/system/runtime-memory-sync.js +2 -2
- package/dist/runtime/harness/system/store.d.ts +4 -0
- package/dist/runtime/harness/system/store.js +153 -0
- package/dist/runtime/harness.d.ts +9 -1
- package/dist/runtime/harness.js +141 -7
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.d.ts +8 -3
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +152 -53
- package/dist/runtime/parsing/output-parsing.d.ts +10 -2
- package/dist/runtime/parsing/output-parsing.js +223 -16
- package/dist/runtime/parsing/stream-event-parsing.d.ts +7 -0
- package/dist/runtime/parsing/stream-event-parsing.js +51 -1
- package/dist/runtime/scheduling/system-schedule-manager.d.ts +41 -0
- package/dist/runtime/scheduling/system-schedule-manager.js +532 -0
- package/dist/runtime/support/embedding-models.d.ts +1 -1
- package/dist/runtime/support/embedding-models.js +5 -2
- package/dist/runtime/support/runtime-factories.js +1 -1
- package/dist/runtime/support/runtime-layout.d.ts +3 -0
- package/dist/runtime/support/runtime-layout.js +10 -1
- package/dist/runtime/support/runtime-prompts.d.ts +30 -0
- package/dist/runtime/support/runtime-prompts.js +55 -0
- package/dist/runtime/support/vector-stores.d.ts +1 -1
- package/dist/runtime/support/vector-stores.js +5 -2
- package/dist/upstream-events.js +8 -7
- package/dist/utils/bundled-text.d.ts +3 -0
- package/dist/utils/bundled-text.js +25 -0
- package/dist/utils/id.js +3 -2
- package/dist/workspace/agent-binding-compiler.js +53 -13
- package/dist/workspace/object-loader.js +64 -2
- package/dist/workspace/support/workspace-ref-utils.d.ts +2 -1
- package/dist/workspace/support/workspace-ref-utils.js +24 -5
- package/dist/workspace/yaml-object-reader.d.ts +1 -0
- package/dist/workspace/yaml-object-reader.js +95 -17
- package/package.json +11 -5
|
@@ -1,67 +1,477 @@
|
|
|
1
|
-
import { isToolCallRecoveryFailure, resolveToolCallRecoveryInstruction, sanitizeVisibleText, } from "../../parsing/output-parsing.js";
|
|
1
|
+
import { extractVisibleOutput, isToolCallRecoveryFailure, isRetrySafeInvalidToolSelectionError, shouldValidateExecutionWithoutToolEvidence, resolveExecutionWithoutToolEvidenceTextInstruction, resolveToolCallRecoveryInstruction, sanitizeVisibleText, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, } from "../../parsing/output-parsing.js";
|
|
2
2
|
import { buildInvocationRequest } from "../model/invocation-request.js";
|
|
3
3
|
import { buildRawModelMessages } from "../model/message-assembly.js";
|
|
4
4
|
import { projectRuntimeStreamEvent, createStreamEventProjectionState } from "../stream-event-projection.js";
|
|
5
5
|
import { projectTextStreamChunks } from "../stream-text-consumption.js";
|
|
6
6
|
import { computeRemainingTimeoutMs } from "../resilience.js";
|
|
7
7
|
import { UPSTREAM_REQUEST_CONFIG_KEY, UPSTREAM_SESSION_CONFIG_KEY } from "../upstream-configurable-keys.js";
|
|
8
|
+
function toVisibleContent(value) {
|
|
9
|
+
const extracted = extractVisibleOutput(value);
|
|
10
|
+
return extracted ? sanitizeVisibleText(extracted) : "";
|
|
11
|
+
}
|
|
12
|
+
function createProfileStep(id, kind, name, action, status, detail) {
|
|
13
|
+
return {
|
|
14
|
+
kind: "profile",
|
|
15
|
+
step: {
|
|
16
|
+
id,
|
|
17
|
+
kind,
|
|
18
|
+
name,
|
|
19
|
+
action,
|
|
20
|
+
status,
|
|
21
|
+
...(detail ? { detail } : {}),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function startProfileStep(input) {
|
|
26
|
+
const startedAt = new Date().toISOString();
|
|
27
|
+
return {
|
|
28
|
+
startedAt,
|
|
29
|
+
chunk: createProfileStep(input.id, input.kind, input.name, input.action, "started", {
|
|
30
|
+
...(input.detail ?? {}),
|
|
31
|
+
startedAt,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function finishProfileStep(input) {
|
|
36
|
+
const endedAt = new Date().toISOString();
|
|
37
|
+
return createProfileStep(input.id, input.kind, input.name, input.action, input.status, {
|
|
38
|
+
...(input.detail ?? {}),
|
|
39
|
+
startedAt: input.startedAt,
|
|
40
|
+
endedAt,
|
|
41
|
+
durationMs: Math.max(0, new Date(endedAt).getTime() - new Date(input.startedAt).getTime()),
|
|
42
|
+
...(input.error !== undefined ? { error: input.error instanceof Error ? input.error.message : String(input.error) } : {}),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
8
45
|
export async function* streamRuntimeExecution(options) {
|
|
9
46
|
const request = buildInvocationRequest(options.binding, options.history, options.input, options.runtimeOptions);
|
|
47
|
+
let emittedUnsafeStreamSideEffects = false;
|
|
48
|
+
const shouldProfile = options.runtimeOptions.profiling === true;
|
|
49
|
+
const shouldValidateStreamOutput = shouldValidateExecutionWithoutToolEvidence(request);
|
|
50
|
+
const deferredStreamContent = [];
|
|
51
|
+
let sawRetrySafeInvalidToolSelectionError = false;
|
|
52
|
+
let sawNonRetrySafeToolSideEffects = false;
|
|
53
|
+
const shouldDeferStreamContent = () => shouldValidateStreamOutput && !emittedUnsafeStreamSideEffects;
|
|
54
|
+
const flushDeferredStreamContent = async function* () {
|
|
55
|
+
while (deferredStreamContent.length > 0) {
|
|
56
|
+
yield deferredStreamContent.shift();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
10
59
|
try {
|
|
11
60
|
if (options.isLangChainBinding(options.binding) && options.canUseDirectModelStream && options.langChainStreamModel?.stream) {
|
|
12
|
-
const
|
|
61
|
+
const modelStreamStart = startProfileStep({
|
|
62
|
+
id: "profile:agent:model-stream-start",
|
|
63
|
+
kind: "agent",
|
|
64
|
+
name: "model stream",
|
|
65
|
+
action: "start",
|
|
66
|
+
});
|
|
67
|
+
if (shouldProfile)
|
|
68
|
+
yield modelStreamStart.chunk;
|
|
69
|
+
let stream;
|
|
70
|
+
try {
|
|
71
|
+
stream = await options.withTimeout(() => options.langChainStreamModel.stream(buildRawModelMessages(options.binding, options.getSystemPrompt(options.binding), options.history, options.input, options.runtimeOptions.memoryContext)), computeRemainingTimeoutMs(options.streamDeadlineAt, options.invokeTimeoutMs), "model stream start", "stream");
|
|
72
|
+
if (shouldProfile)
|
|
73
|
+
yield finishProfileStep({
|
|
74
|
+
id: "profile:agent:model-stream-start",
|
|
75
|
+
kind: "agent",
|
|
76
|
+
name: "model stream",
|
|
77
|
+
action: "start",
|
|
78
|
+
startedAt: modelStreamStart.startedAt,
|
|
79
|
+
status: "completed",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (shouldProfile)
|
|
84
|
+
yield finishProfileStep({
|
|
85
|
+
id: "profile:agent:model-stream-start",
|
|
86
|
+
kind: "agent",
|
|
87
|
+
name: "model stream",
|
|
88
|
+
action: "start",
|
|
89
|
+
startedAt: modelStreamStart.startedAt,
|
|
90
|
+
status: "failed",
|
|
91
|
+
error,
|
|
92
|
+
});
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
13
95
|
let emitted = false;
|
|
14
96
|
const projected = projectTextStreamChunks(options.iterateWithTimeout(stream, options.streamIdleTimeoutMs, "model stream", options.streamDeadlineAt, options.invokeTimeoutMs));
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
97
|
+
const modelStreamConsume = startProfileStep({
|
|
98
|
+
id: "profile:agent:model-stream-consume",
|
|
99
|
+
kind: "agent",
|
|
100
|
+
name: "model stream",
|
|
101
|
+
action: "consume",
|
|
102
|
+
});
|
|
103
|
+
if (shouldProfile)
|
|
104
|
+
yield modelStreamConsume.chunk;
|
|
105
|
+
try {
|
|
106
|
+
let currentChunk = await projected.next();
|
|
107
|
+
while (!currentChunk.done) {
|
|
108
|
+
if (currentChunk.value.kind === "content") {
|
|
109
|
+
emitted = true;
|
|
110
|
+
emittedUnsafeStreamSideEffects = true;
|
|
111
|
+
}
|
|
112
|
+
yield currentChunk.value;
|
|
113
|
+
currentChunk = await projected.next();
|
|
114
|
+
}
|
|
115
|
+
if (shouldProfile)
|
|
116
|
+
yield finishProfileStep({
|
|
117
|
+
id: "profile:agent:model-stream-consume",
|
|
118
|
+
kind: "agent",
|
|
119
|
+
name: "model stream",
|
|
120
|
+
action: "consume",
|
|
121
|
+
startedAt: modelStreamConsume.startedAt,
|
|
122
|
+
status: "completed",
|
|
123
|
+
});
|
|
124
|
+
if (currentChunk.value.emittedContent || emitted) {
|
|
125
|
+
return;
|
|
19
126
|
}
|
|
20
|
-
yield nextChunk.value;
|
|
21
|
-
nextChunk = await projected.next();
|
|
22
127
|
}
|
|
23
|
-
|
|
24
|
-
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (shouldProfile)
|
|
130
|
+
yield finishProfileStep({
|
|
131
|
+
id: "profile:agent:model-stream-consume",
|
|
132
|
+
kind: "agent",
|
|
133
|
+
name: "model stream",
|
|
134
|
+
action: "consume",
|
|
135
|
+
startedAt: modelStreamConsume.startedAt,
|
|
136
|
+
status: "failed",
|
|
137
|
+
error,
|
|
138
|
+
});
|
|
139
|
+
throw error;
|
|
25
140
|
}
|
|
26
141
|
}
|
|
27
|
-
const
|
|
142
|
+
const createRunnableStep = startProfileStep({
|
|
143
|
+
id: "profile:agent:create-runnable",
|
|
144
|
+
kind: "agent",
|
|
145
|
+
name: "create runnable",
|
|
146
|
+
action: "startup",
|
|
147
|
+
});
|
|
148
|
+
if (shouldProfile)
|
|
149
|
+
yield createRunnableStep.chunk;
|
|
150
|
+
let runnable;
|
|
151
|
+
try {
|
|
152
|
+
runnable = await options.createRunnable();
|
|
153
|
+
if (shouldProfile)
|
|
154
|
+
yield finishProfileStep({
|
|
155
|
+
id: "profile:agent:create-runnable",
|
|
156
|
+
kind: "agent",
|
|
157
|
+
name: "create runnable",
|
|
158
|
+
action: "startup",
|
|
159
|
+
startedAt: createRunnableStep.startedAt,
|
|
160
|
+
status: "completed",
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (shouldProfile)
|
|
165
|
+
yield finishProfileStep({
|
|
166
|
+
id: "profile:agent:create-runnable",
|
|
167
|
+
kind: "agent",
|
|
168
|
+
name: "create runnable",
|
|
169
|
+
action: "startup",
|
|
170
|
+
startedAt: createRunnableStep.startedAt,
|
|
171
|
+
status: "failed",
|
|
172
|
+
error,
|
|
173
|
+
});
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
28
176
|
if (!options.forceInvokeFallback && typeof runnable.streamEvents === "function") {
|
|
29
|
-
const
|
|
177
|
+
const streamEventsStart = startProfileStep({
|
|
178
|
+
id: "profile:agent:stream-events-start",
|
|
179
|
+
kind: "agent",
|
|
180
|
+
name: "streamEvents",
|
|
181
|
+
action: "start",
|
|
182
|
+
});
|
|
183
|
+
if (shouldProfile)
|
|
184
|
+
yield streamEventsStart.chunk;
|
|
185
|
+
let events;
|
|
186
|
+
try {
|
|
187
|
+
events = await options.withTimeout(() => runnable.streamEvents(request, {
|
|
188
|
+
configurable: { [UPSTREAM_SESSION_CONFIG_KEY]: options.sessionId, [UPSTREAM_REQUEST_CONFIG_KEY]: options.runtimeOptions.requestId },
|
|
189
|
+
version: "v2",
|
|
190
|
+
...(options.runtimeOptions.context ? { context: options.runtimeOptions.context } : {}),
|
|
191
|
+
...(options.runtimeOptions.toolRuntimeContext ? { toolRuntimeContext: options.runtimeOptions.toolRuntimeContext } : {}),
|
|
192
|
+
}), computeRemainingTimeoutMs(options.streamDeadlineAt, options.invokeTimeoutMs), "agent streamEvents start", "stream");
|
|
193
|
+
if (shouldProfile)
|
|
194
|
+
yield finishProfileStep({
|
|
195
|
+
id: "profile:agent:stream-events-start",
|
|
196
|
+
kind: "agent",
|
|
197
|
+
name: "streamEvents",
|
|
198
|
+
action: "start",
|
|
199
|
+
startedAt: streamEventsStart.startedAt,
|
|
200
|
+
status: "completed",
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
if (shouldProfile)
|
|
205
|
+
yield finishProfileStep({
|
|
206
|
+
id: "profile:agent:stream-events-start",
|
|
207
|
+
kind: "agent",
|
|
208
|
+
name: "streamEvents",
|
|
209
|
+
action: "start",
|
|
210
|
+
startedAt: streamEventsStart.startedAt,
|
|
211
|
+
status: "failed",
|
|
212
|
+
error,
|
|
213
|
+
});
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
30
216
|
const projectionState = createStreamEventProjectionState();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
217
|
+
const streamEventsConsume = startProfileStep({
|
|
218
|
+
id: "profile:agent:stream-events-consume",
|
|
219
|
+
kind: "agent",
|
|
220
|
+
name: "streamEvents",
|
|
221
|
+
action: "consume",
|
|
222
|
+
});
|
|
223
|
+
if (shouldProfile)
|
|
224
|
+
yield streamEventsConsume.chunk;
|
|
225
|
+
try {
|
|
226
|
+
for await (const event of options.iterateWithTimeout(events, options.streamIdleTimeoutMs, "agent streamEvents", options.streamDeadlineAt, options.invokeTimeoutMs)) {
|
|
227
|
+
const projectedChunks = projectRuntimeStreamEvent({
|
|
228
|
+
event,
|
|
229
|
+
allowVisibleStreamDeltas: options.isLangChainBinding(options.binding),
|
|
230
|
+
includeStateStreamOutput: options.isDeepAgentBinding(options.binding),
|
|
231
|
+
toolNameMapping: options.toolNameMapping,
|
|
232
|
+
primaryTools: options.primaryTools,
|
|
233
|
+
state: projectionState,
|
|
234
|
+
});
|
|
235
|
+
const eventContainsNonTodoToolResult = projectedChunks.some((chunk) => chunk.kind === "tool-result"
|
|
236
|
+
&& chunk.toolName !== "write_todos"
|
|
237
|
+
&& !(chunk.isError === true && isRetrySafeInvalidToolSelectionError(chunk.output)));
|
|
238
|
+
const eventContainsNonRetrySafeChunk = projectedChunks.some((chunk) => chunk.kind !== "upstream-event"
|
|
239
|
+
&& chunk.kind !== "content"
|
|
240
|
+
&& !(chunk.kind === "tool-result" && chunk.toolName === "write_todos")
|
|
241
|
+
&& !(chunk.kind === "tool-result" && chunk.isError === true && isRetrySafeInvalidToolSelectionError(chunk.output)));
|
|
242
|
+
for (const chunk of projectedChunks) {
|
|
243
|
+
if (chunk.kind === "tool-result" && chunk.isError === true && isRetrySafeInvalidToolSelectionError(chunk.output)) {
|
|
244
|
+
sawRetrySafeInvalidToolSelectionError = true;
|
|
245
|
+
}
|
|
246
|
+
if ((eventContainsNonTodoToolResult || eventContainsNonRetrySafeChunk) && deferredStreamContent.length > 0) {
|
|
247
|
+
yield* flushDeferredStreamContent();
|
|
248
|
+
}
|
|
249
|
+
if (eventContainsNonTodoToolResult || eventContainsNonRetrySafeChunk) {
|
|
250
|
+
emittedUnsafeStreamSideEffects = true;
|
|
251
|
+
sawNonRetrySafeToolSideEffects = true;
|
|
252
|
+
}
|
|
253
|
+
if (chunk.kind === "content" && shouldDeferStreamContent()) {
|
|
254
|
+
deferredStreamContent.push(chunk);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
yield chunk;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (shouldProfile)
|
|
261
|
+
yield finishProfileStep({
|
|
262
|
+
id: "profile:agent:stream-events-consume",
|
|
263
|
+
kind: "agent",
|
|
264
|
+
name: "streamEvents",
|
|
265
|
+
action: "consume",
|
|
266
|
+
startedAt: streamEventsConsume.startedAt,
|
|
267
|
+
status: "completed",
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
if (shouldProfile)
|
|
272
|
+
yield finishProfileStep({
|
|
273
|
+
id: "profile:agent:stream-events-consume",
|
|
274
|
+
kind: "agent",
|
|
275
|
+
name: "streamEvents",
|
|
276
|
+
action: "consume",
|
|
277
|
+
startedAt: streamEventsConsume.startedAt,
|
|
278
|
+
status: "failed",
|
|
279
|
+
error,
|
|
280
|
+
});
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
const streamRecoveryInstruction = resolveExecutionWithoutToolEvidenceTextInstruction(request, projectionState.emittedOutput, projectionState.emittedToolResult || (projectionState.emittedToolError && (sawNonRetrySafeToolSideEffects || !sawRetrySafeInvalidToolSelectionError)));
|
|
284
|
+
const terminalRecoveryInstruction = streamRecoveryInstruction
|
|
285
|
+
?? (!emittedUnsafeStreamSideEffects && sawRetrySafeInvalidToolSelectionError ? INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION : null);
|
|
286
|
+
if (!emittedUnsafeStreamSideEffects && terminalRecoveryInstruction) {
|
|
287
|
+
const toolRecovery = startProfileStep({
|
|
288
|
+
id: "profile:agent:stream-output-recovery-fallback",
|
|
289
|
+
kind: "agent",
|
|
290
|
+
name: "stream output recovery fallback",
|
|
291
|
+
action: "invoke",
|
|
292
|
+
detail: {
|
|
293
|
+
recoveryInstruction: terminalRecoveryInstruction,
|
|
294
|
+
},
|
|
39
295
|
});
|
|
40
|
-
|
|
41
|
-
yield chunk;
|
|
296
|
+
if (shouldProfile)
|
|
297
|
+
yield toolRecovery.chunk;
|
|
298
|
+
let retried;
|
|
299
|
+
try {
|
|
300
|
+
retried = await options.invoke(options.applyToolRecoveryInstruction(options.binding, terminalRecoveryInstruction), options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
|
|
301
|
+
if (shouldProfile)
|
|
302
|
+
yield finishProfileStep({
|
|
303
|
+
id: "profile:agent:stream-output-recovery-fallback",
|
|
304
|
+
kind: "agent",
|
|
305
|
+
name: "stream output recovery fallback",
|
|
306
|
+
action: "invoke",
|
|
307
|
+
startedAt: toolRecovery.startedAt,
|
|
308
|
+
status: "completed",
|
|
309
|
+
detail: {
|
|
310
|
+
recoveryInstruction: terminalRecoveryInstruction,
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
catch (retryError) {
|
|
315
|
+
if (shouldProfile)
|
|
316
|
+
yield finishProfileStep({
|
|
317
|
+
id: "profile:agent:stream-output-recovery-fallback",
|
|
318
|
+
kind: "agent",
|
|
319
|
+
name: "stream output recovery fallback",
|
|
320
|
+
action: "invoke",
|
|
321
|
+
startedAt: toolRecovery.startedAt,
|
|
322
|
+
status: "failed",
|
|
323
|
+
detail: {
|
|
324
|
+
recoveryInstruction: terminalRecoveryInstruction,
|
|
325
|
+
},
|
|
326
|
+
error: retryError,
|
|
327
|
+
});
|
|
328
|
+
throw retryError;
|
|
329
|
+
}
|
|
330
|
+
const executedToolResults = Array.isArray(retried.metadata?.executedToolResults)
|
|
331
|
+
? retried.metadata.executedToolResults
|
|
332
|
+
: [];
|
|
333
|
+
for (const toolResult of executedToolResults) {
|
|
334
|
+
yield {
|
|
335
|
+
kind: "tool-result",
|
|
336
|
+
toolName: toolResult.toolName,
|
|
337
|
+
output: toolResult.output,
|
|
338
|
+
isError: toolResult.isError,
|
|
339
|
+
};
|
|
42
340
|
}
|
|
341
|
+
if (retried.output) {
|
|
342
|
+
const visible = toVisibleContent(retried.output);
|
|
343
|
+
if (visible) {
|
|
344
|
+
yield { kind: "content", content: visible };
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (deferredStreamContent.length > 0) {
|
|
350
|
+
yield* flushDeferredStreamContent();
|
|
43
351
|
}
|
|
44
352
|
if (projectionState.emittedOutput || projectionState.emittedToolResult || projectionState.emittedToolError) {
|
|
45
353
|
return;
|
|
46
354
|
}
|
|
47
355
|
}
|
|
48
356
|
if (!options.forceInvokeFallback && options.isLangChainBinding(options.binding) && typeof runnable.stream === "function") {
|
|
49
|
-
const
|
|
357
|
+
const streamStart = startProfileStep({
|
|
358
|
+
id: "profile:agent:stream-start",
|
|
359
|
+
kind: "agent",
|
|
360
|
+
name: "stream",
|
|
361
|
+
action: "start",
|
|
362
|
+
});
|
|
363
|
+
if (shouldProfile)
|
|
364
|
+
yield streamStart.chunk;
|
|
365
|
+
let stream;
|
|
366
|
+
try {
|
|
367
|
+
stream = await options.withTimeout(() => runnable.stream(request, {
|
|
368
|
+
configurable: { [UPSTREAM_SESSION_CONFIG_KEY]: options.sessionId, [UPSTREAM_REQUEST_CONFIG_KEY]: options.runtimeOptions.requestId },
|
|
369
|
+
...(options.runtimeOptions.toolRuntimeContext ? { toolRuntimeContext: options.runtimeOptions.toolRuntimeContext } : {}),
|
|
370
|
+
}), computeRemainingTimeoutMs(options.streamDeadlineAt, options.invokeTimeoutMs), "agent stream start", "stream");
|
|
371
|
+
if (shouldProfile)
|
|
372
|
+
yield finishProfileStep({
|
|
373
|
+
id: "profile:agent:stream-start",
|
|
374
|
+
kind: "agent",
|
|
375
|
+
name: "stream",
|
|
376
|
+
action: "start",
|
|
377
|
+
startedAt: streamStart.startedAt,
|
|
378
|
+
status: "completed",
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
if (shouldProfile)
|
|
383
|
+
yield finishProfileStep({
|
|
384
|
+
id: "profile:agent:stream-start",
|
|
385
|
+
kind: "agent",
|
|
386
|
+
name: "stream",
|
|
387
|
+
action: "start",
|
|
388
|
+
startedAt: streamStart.startedAt,
|
|
389
|
+
status: "failed",
|
|
390
|
+
error,
|
|
391
|
+
});
|
|
392
|
+
throw error;
|
|
393
|
+
}
|
|
50
394
|
let emitted = false;
|
|
51
395
|
const projected = projectTextStreamChunks(options.iterateWithTimeout(stream, options.streamIdleTimeoutMs, "agent stream", options.streamDeadlineAt, options.invokeTimeoutMs));
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
396
|
+
const streamConsume = startProfileStep({
|
|
397
|
+
id: "profile:agent:stream-consume",
|
|
398
|
+
kind: "agent",
|
|
399
|
+
name: "stream",
|
|
400
|
+
action: "consume",
|
|
401
|
+
});
|
|
402
|
+
if (shouldProfile)
|
|
403
|
+
yield streamConsume.chunk;
|
|
404
|
+
try {
|
|
405
|
+
let nextChunk = await projected.next();
|
|
406
|
+
while (!nextChunk.done) {
|
|
407
|
+
if (nextChunk.value.kind === "content") {
|
|
408
|
+
emitted = true;
|
|
409
|
+
emittedUnsafeStreamSideEffects = true;
|
|
410
|
+
}
|
|
411
|
+
yield nextChunk.value;
|
|
412
|
+
nextChunk = await projected.next();
|
|
413
|
+
}
|
|
414
|
+
if (shouldProfile)
|
|
415
|
+
yield finishProfileStep({
|
|
416
|
+
id: "profile:agent:stream-consume",
|
|
417
|
+
kind: "agent",
|
|
418
|
+
name: "stream",
|
|
419
|
+
action: "consume",
|
|
420
|
+
startedAt: streamConsume.startedAt,
|
|
421
|
+
status: "completed",
|
|
422
|
+
});
|
|
423
|
+
if (nextChunk.value.emittedContent || emitted) {
|
|
424
|
+
return;
|
|
56
425
|
}
|
|
57
|
-
yield nextChunk.value;
|
|
58
|
-
nextChunk = await projected.next();
|
|
59
426
|
}
|
|
60
|
-
|
|
61
|
-
|
|
427
|
+
catch (error) {
|
|
428
|
+
if (shouldProfile)
|
|
429
|
+
yield finishProfileStep({
|
|
430
|
+
id: "profile:agent:stream-consume",
|
|
431
|
+
kind: "agent",
|
|
432
|
+
name: "stream",
|
|
433
|
+
action: "consume",
|
|
434
|
+
startedAt: streamConsume.startedAt,
|
|
435
|
+
status: "failed",
|
|
436
|
+
error,
|
|
437
|
+
});
|
|
438
|
+
throw error;
|
|
62
439
|
}
|
|
63
440
|
}
|
|
64
|
-
const
|
|
441
|
+
const invokeFallback = startProfileStep({
|
|
442
|
+
id: "profile:agent:invoke-fallback",
|
|
443
|
+
kind: "agent",
|
|
444
|
+
name: "invoke fallback",
|
|
445
|
+
action: "invoke",
|
|
446
|
+
});
|
|
447
|
+
if (shouldProfile)
|
|
448
|
+
yield invokeFallback.chunk;
|
|
449
|
+
let result;
|
|
450
|
+
try {
|
|
451
|
+
result = await options.invoke(options.binding, options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
|
|
452
|
+
if (shouldProfile)
|
|
453
|
+
yield finishProfileStep({
|
|
454
|
+
id: "profile:agent:invoke-fallback",
|
|
455
|
+
kind: "agent",
|
|
456
|
+
name: "invoke fallback",
|
|
457
|
+
action: "invoke",
|
|
458
|
+
startedAt: invokeFallback.startedAt,
|
|
459
|
+
status: "completed",
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
catch (error) {
|
|
463
|
+
if (shouldProfile)
|
|
464
|
+
yield finishProfileStep({
|
|
465
|
+
id: "profile:agent:invoke-fallback",
|
|
466
|
+
kind: "agent",
|
|
467
|
+
name: "invoke fallback",
|
|
468
|
+
action: "invoke",
|
|
469
|
+
startedAt: invokeFallback.startedAt,
|
|
470
|
+
status: "failed",
|
|
471
|
+
error,
|
|
472
|
+
});
|
|
473
|
+
throw error;
|
|
474
|
+
}
|
|
65
475
|
const executedToolResults = Array.isArray(result.metadata?.executedToolResults)
|
|
66
476
|
? result.metadata.executedToolResults
|
|
67
477
|
: [];
|
|
@@ -74,10 +484,76 @@ export async function* streamRuntimeExecution(options) {
|
|
|
74
484
|
};
|
|
75
485
|
}
|
|
76
486
|
if (result.output) {
|
|
77
|
-
|
|
487
|
+
const visible = toVisibleContent(result.output);
|
|
488
|
+
if (visible) {
|
|
489
|
+
yield { kind: "content", content: visible };
|
|
490
|
+
}
|
|
78
491
|
}
|
|
79
492
|
}
|
|
80
493
|
catch (error) {
|
|
494
|
+
if (!emittedUnsafeStreamSideEffects && options.isRetryableProviderError?.(options.binding, error)) {
|
|
495
|
+
const providerRetry = startProfileStep({
|
|
496
|
+
id: "profile:agent:provider-retry-fallback",
|
|
497
|
+
kind: "agent",
|
|
498
|
+
name: "provider retry fallback",
|
|
499
|
+
action: "invoke",
|
|
500
|
+
detail: {
|
|
501
|
+
error: error instanceof Error ? error.message : String(error),
|
|
502
|
+
},
|
|
503
|
+
});
|
|
504
|
+
if (shouldProfile)
|
|
505
|
+
yield providerRetry.chunk;
|
|
506
|
+
let recovered;
|
|
507
|
+
try {
|
|
508
|
+
recovered = await options.invoke(options.binding, options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
|
|
509
|
+
if (shouldProfile)
|
|
510
|
+
yield finishProfileStep({
|
|
511
|
+
id: "profile:agent:provider-retry-fallback",
|
|
512
|
+
kind: "agent",
|
|
513
|
+
name: "provider retry fallback",
|
|
514
|
+
action: "invoke",
|
|
515
|
+
startedAt: providerRetry.startedAt,
|
|
516
|
+
status: "completed",
|
|
517
|
+
detail: {
|
|
518
|
+
error: error instanceof Error ? error.message : String(error),
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
catch (retryError) {
|
|
523
|
+
if (shouldProfile)
|
|
524
|
+
yield finishProfileStep({
|
|
525
|
+
id: "profile:agent:provider-retry-fallback",
|
|
526
|
+
kind: "agent",
|
|
527
|
+
name: "provider retry fallback",
|
|
528
|
+
action: "invoke",
|
|
529
|
+
startedAt: providerRetry.startedAt,
|
|
530
|
+
status: "failed",
|
|
531
|
+
detail: {
|
|
532
|
+
error: error instanceof Error ? error.message : String(error),
|
|
533
|
+
},
|
|
534
|
+
error: retryError,
|
|
535
|
+
});
|
|
536
|
+
throw retryError;
|
|
537
|
+
}
|
|
538
|
+
const executedToolResults = Array.isArray(recovered.metadata?.executedToolResults)
|
|
539
|
+
? recovered.metadata.executedToolResults
|
|
540
|
+
: [];
|
|
541
|
+
for (const toolResult of executedToolResults) {
|
|
542
|
+
yield {
|
|
543
|
+
kind: "tool-result",
|
|
544
|
+
toolName: toolResult.toolName,
|
|
545
|
+
output: toolResult.output,
|
|
546
|
+
isError: toolResult.isError,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
if (recovered.output) {
|
|
550
|
+
const visible = toVisibleContent(recovered.output);
|
|
551
|
+
if (visible) {
|
|
552
|
+
yield { kind: "content", content: visible };
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
81
557
|
if (options.countConfiguredTools(options.binding) > 0 &&
|
|
82
558
|
error instanceof Error &&
|
|
83
559
|
error.message.includes("does not support tool binding")) {
|
|
@@ -90,9 +566,54 @@ export async function* streamRuntimeExecution(options) {
|
|
|
90
566
|
if (!recoveryInstruction) {
|
|
91
567
|
throw error;
|
|
92
568
|
}
|
|
93
|
-
const
|
|
569
|
+
const toolRecovery = startProfileStep({
|
|
570
|
+
id: "profile:agent:tool-recovery-fallback",
|
|
571
|
+
kind: "agent",
|
|
572
|
+
name: "tool recovery fallback",
|
|
573
|
+
action: "invoke",
|
|
574
|
+
detail: {
|
|
575
|
+
recoveryInstruction,
|
|
576
|
+
},
|
|
577
|
+
});
|
|
578
|
+
if (shouldProfile)
|
|
579
|
+
yield toolRecovery.chunk;
|
|
580
|
+
let retried;
|
|
581
|
+
try {
|
|
582
|
+
retried = await options.invoke(options.applyToolRecoveryInstruction(options.binding, recoveryInstruction), options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
|
|
583
|
+
if (shouldProfile)
|
|
584
|
+
yield finishProfileStep({
|
|
585
|
+
id: "profile:agent:tool-recovery-fallback",
|
|
586
|
+
kind: "agent",
|
|
587
|
+
name: "tool recovery fallback",
|
|
588
|
+
action: "invoke",
|
|
589
|
+
startedAt: toolRecovery.startedAt,
|
|
590
|
+
status: "completed",
|
|
591
|
+
detail: {
|
|
592
|
+
recoveryInstruction,
|
|
593
|
+
},
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
catch (retryError) {
|
|
597
|
+
if (shouldProfile)
|
|
598
|
+
yield finishProfileStep({
|
|
599
|
+
id: "profile:agent:tool-recovery-fallback",
|
|
600
|
+
kind: "agent",
|
|
601
|
+
name: "tool recovery fallback",
|
|
602
|
+
action: "invoke",
|
|
603
|
+
startedAt: toolRecovery.startedAt,
|
|
604
|
+
status: "failed",
|
|
605
|
+
detail: {
|
|
606
|
+
recoveryInstruction,
|
|
607
|
+
},
|
|
608
|
+
error: retryError,
|
|
609
|
+
});
|
|
610
|
+
throw retryError;
|
|
611
|
+
}
|
|
94
612
|
if (retried.output) {
|
|
95
|
-
|
|
613
|
+
const visible = toVisibleContent(retried.output);
|
|
614
|
+
if (visible) {
|
|
615
|
+
yield { kind: "content", content: visible };
|
|
616
|
+
}
|
|
96
617
|
}
|
|
97
618
|
}
|
|
98
619
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extractContentBlocks, extractEmptyAssistantMessageFailure, extractOutputContent, extractToolFallbackContext, extractVisibleOutput, isLikelyToolArgsObject, sanitizeVisibleText, tryParseJson, } from "../parsing/output-parsing.js";
|
|
1
|
+
import { containsLikelySkillDocument, extractContentBlocks, extractEmptyAssistantMessageFailure, extractOutputContent, extractToolFallbackContext, extractVisibleOutput, isLikelyToolArgsObject, sanitizeVisibleText, tryParseJson, } from "../parsing/output-parsing.js";
|
|
2
2
|
import { buildStateSnapshot } from "./model/message-assembly.js";
|
|
3
3
|
import { asRecord } from "./tool/resolved-tool.js";
|
|
4
4
|
export function finalizeRequestResult(params) {
|
|
@@ -11,7 +11,8 @@ export function finalizeRequestResult(params) {
|
|
|
11
11
|
if (!visibleOutput && !toolFallback && emptyAssistantMessageFailure) {
|
|
12
12
|
throw new Error(emptyAssistantMessageFailure);
|
|
13
13
|
}
|
|
14
|
-
const
|
|
14
|
+
const serializedResult = JSON.stringify(result, null, 2);
|
|
15
|
+
const output = visibleOutput || toolFallback || (containsLikelySkillDocument(result) ? "" : serializedResult);
|
|
15
16
|
const finalMessageText = sanitizeVisibleText(output);
|
|
16
17
|
const outputContent = extractOutputContent(result);
|
|
17
18
|
const contentBlocks = extractContentBlocks(result);
|
|
@@ -4,7 +4,7 @@ import type { ExecutedToolResult } from "./invocation-result.js";
|
|
|
4
4
|
type ExecutableTool = {
|
|
5
5
|
name: string;
|
|
6
6
|
schema: unknown;
|
|
7
|
-
invoke: (input: unknown) => Promise<unknown>;
|
|
7
|
+
invoke: (input: unknown, config?: Record<string, unknown>) => Promise<unknown>;
|
|
8
8
|
};
|
|
9
9
|
type LocalToolInvocationParams = {
|
|
10
10
|
binding: CompiledAgentBinding;
|