@downcity/agent 1.1.79 → 1.1.81
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 +1 -1
- package/bin/agent/local/Agent.d.ts +8 -121
- package/bin/agent/local/Agent.d.ts.map +1 -1
- package/bin/agent/local/Agent.js +63 -381
- package/bin/agent/local/Agent.js.map +1 -1
- package/bin/agent/local/AgentRuntimeFactory.d.ts +2 -2
- package/bin/agent/local/AgentRuntimeFactory.d.ts.map +1 -1
- package/bin/agent/local/AgentRuntimeFactory.js +2 -23
- package/bin/agent/local/AgentRuntimeFactory.js.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.d.ts +112 -0
- package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -0
- package/bin/agent/local/services/AgentAssemblyService.js +135 -0
- package/bin/agent/local/services/AgentAssemblyService.js.map +1 -0
- package/bin/agent/local/services/AgentLifecycleService.d.ts +59 -0
- package/bin/agent/local/services/AgentLifecycleService.d.ts.map +1 -0
- package/bin/agent/local/services/AgentLifecycleService.js +136 -0
- package/bin/agent/local/services/AgentLifecycleService.js.map +1 -0
- package/bin/agent/local/services/AgentSessionManager.d.ts +106 -0
- package/bin/agent/local/services/AgentSessionManager.d.ts.map +1 -0
- package/bin/agent/local/services/AgentSessionManager.js +182 -0
- package/bin/agent/local/services/AgentSessionManager.js.map +1 -0
- package/bin/executor/Executor.d.ts +7 -24
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +73 -361
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/SessionRunScope.d.ts +18 -34
- package/bin/executor/SessionRunScope.d.ts.map +1 -1
- package/bin/executor/SessionRunScope.js +42 -28
- package/bin/executor/SessionRunScope.js.map +1 -1
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +5 -3
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +1 -1
- package/bin/executor/composer/context/LocalSessionContextComposer.js +11 -18
- package/bin/executor/composer/context/LocalSessionContextComposer.js.map +1 -1
- package/bin/executor/composer/context/SessionContextComposer.d.ts +8 -3
- package/bin/executor/composer/context/SessionContextComposer.d.ts.map +1 -1
- package/bin/executor/composer/system/SessionSystemComposer.d.ts +2 -1
- package/bin/executor/composer/system/SessionSystemComposer.d.ts.map +1 -1
- package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts +2 -1
- package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts.map +1 -1
- package/bin/executor/composer/system/default/DefaultSessionSystemComposer.js +2 -4
- package/bin/executor/composer/system/default/DefaultSessionSystemComposer.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.d.ts +62 -0
- package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -0
- package/bin/executor/core-engine/CoreEngineRunner.js +309 -0
- package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -0
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts +5 -0
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.js +2 -4
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.js.map +1 -1
- package/bin/executor/services/ExecutorInflightService.d.ts +39 -0
- package/bin/executor/services/ExecutorInflightService.d.ts.map +1 -0
- package/bin/executor/services/ExecutorInflightService.js +75 -0
- package/bin/executor/services/ExecutorInflightService.js.map +1 -0
- package/bin/executor/services/ExecutorRecoveryPolicy.d.ts +103 -0
- package/bin/executor/services/ExecutorRecoveryPolicy.d.ts.map +1 -0
- package/bin/executor/services/ExecutorRecoveryPolicy.js +87 -0
- package/bin/executor/services/ExecutorRecoveryPolicy.js.map +1 -0
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts +19 -0
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -0
- package/bin/executor/tools/plugin/PluginToolBridge.js +143 -0
- package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -0
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts +32 -0
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -0
- package/bin/executor/tools/plugin/PluginToolDefinition.js +27 -0
- package/bin/executor/tools/plugin/PluginToolDefinition.js.map +1 -0
- package/bin/executor/tools/plugin/PluginToolSchemas.d.ts +14 -0
- package/bin/executor/tools/plugin/PluginToolSchemas.d.ts.map +1 -0
- package/bin/executor/tools/plugin/PluginToolSchemas.js +19 -0
- package/bin/executor/tools/plugin/PluginToolSchemas.js.map +1 -0
- package/bin/executor/tools/plugin/types/PluginTool.d.ts +39 -0
- package/bin/executor/tools/plugin/types/PluginTool.d.ts.map +1 -0
- package/bin/executor/tools/plugin/types/PluginTool.js +9 -0
- package/bin/executor/tools/plugin/types/PluginTool.js.map +1 -0
- package/bin/executor/tools/shell/ShellToolBridge.js +3 -3
- package/bin/executor/tools/shell/ShellToolBridge.js.map +1 -1
- package/bin/executor/types/SessionRun.d.ts +18 -0
- package/bin/executor/types/SessionRun.d.ts.map +1 -1
- package/bin/index.d.ts +10 -1
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +3 -0
- package/bin/index.js.map +1 -1
- package/bin/plugin/core/BasePlugin.d.ts +2 -2
- package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
- package/bin/plugin/core/BasePlugin.js.map +1 -1
- package/bin/plugin/core/ImagePlugin.d.ts +56 -0
- package/bin/plugin/core/ImagePlugin.d.ts.map +1 -0
- package/bin/plugin/core/ImagePlugin.js +109 -0
- package/bin/plugin/core/ImagePlugin.js.map +1 -0
- package/bin/session/Session.d.ts +14 -83
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +139 -362
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionSystemBuilder.d.ts +2 -1
- package/bin/session/SessionSystemBuilder.d.ts.map +1 -1
- package/bin/session/SessionSystemBuilder.js +2 -3
- package/bin/session/SessionSystemBuilder.js.map +1 -1
- package/bin/session/services/SessionStateService.d.ts +132 -0
- package/bin/session/services/SessionStateService.d.ts.map +1 -0
- package/bin/session/services/SessionStateService.js +242 -0
- package/bin/session/services/SessionStateService.js.map +1 -0
- package/bin/session/services/SessionTurnService.d.ts +66 -0
- package/bin/session/services/SessionTurnService.d.ts.map +1 -0
- package/bin/session/services/SessionTurnService.js +137 -0
- package/bin/session/services/SessionTurnService.js.map +1 -0
- package/bin/session/services/SessionViewService.d.ts +105 -0
- package/bin/session/services/SessionViewService.d.ts.map +1 -0
- package/bin/session/services/SessionViewService.js +184 -0
- package/bin/session/services/SessionViewService.js.map +1 -0
- package/bin/types/agent/AgentOptions.d.ts +18 -0
- package/bin/types/agent/AgentOptions.d.ts.map +1 -1
- package/bin/types/agent/AgentTypes.d.ts +3 -1
- package/bin/types/agent/AgentTypes.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +66 -0
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -0
- package/bin/types/executor/SessionRunContext.js +10 -0
- package/bin/types/executor/SessionRunContext.js.map +1 -0
- package/bin/types/plugin/ImagePlugin.d.ts +94 -0
- package/bin/types/plugin/ImagePlugin.d.ts.map +1 -0
- package/bin/types/plugin/ImagePlugin.js +10 -0
- package/bin/types/plugin/ImagePlugin.js.map +1 -0
- package/bin/types/session/SessionComposerOptions.d.ts +90 -0
- package/bin/types/session/SessionComposerOptions.d.ts.map +1 -0
- package/bin/types/session/SessionComposerOptions.js +10 -0
- package/bin/types/session/SessionComposerOptions.js.map +1 -0
- package/bin/types/session/SessionLocalState.d.ts +35 -0
- package/bin/types/session/SessionLocalState.d.ts.map +1 -0
- package/bin/types/session/SessionLocalState.js +10 -0
- package/bin/types/session/SessionLocalState.js.map +1 -0
- package/bin/types/session/SessionOptions.d.ts +85 -0
- package/bin/types/session/SessionOptions.d.ts.map +1 -0
- package/bin/types/session/SessionOptions.js +10 -0
- package/bin/types/session/SessionOptions.js.map +1 -0
- package/package.json +1 -1
- package/src/agent/local/Agent.ts +74 -433
- package/src/agent/local/AgentRuntimeFactory.ts +4 -25
- package/src/agent/local/services/AgentAssemblyService.ts +268 -0
- package/src/agent/local/services/AgentLifecycleService.ts +187 -0
- package/src/agent/local/services/AgentSessionManager.ts +291 -0
- package/src/executor/Executor.ts +103 -441
- package/src/executor/README.md +4 -4
- package/src/executor/SessionRunScope.ts +47 -71
- package/src/executor/composer/context/LocalSessionContextComposer.ts +24 -20
- package/src/executor/composer/context/SessionContextComposer.ts +13 -3
- package/src/executor/composer/system/SessionSystemComposer.ts +2 -1
- package/src/executor/composer/system/default/DefaultSessionSystemComposer.ts +3 -4
- package/src/executor/core-engine/CoreEngineRunner.ts +433 -0
- package/src/executor/core-engine/CoreEngineUiStreamCollector.ts +7 -5
- package/src/executor/services/ExecutorInflightService.ts +101 -0
- package/src/executor/services/ExecutorRecoveryPolicy.ts +213 -0
- package/src/executor/tools/plugin/PluginToolBridge.ts +161 -0
- package/src/executor/tools/plugin/PluginToolDefinition.ts +32 -0
- package/src/executor/tools/plugin/PluginToolSchemas.ts +20 -0
- package/src/executor/tools/plugin/types/PluginTool.ts +41 -0
- package/src/executor/tools/shell/ShellToolBridge.ts +3 -3
- package/src/executor/types/SessionRun.ts +20 -0
- package/src/index.ts +33 -0
- package/src/plugin/core/BasePlugin.ts +2 -2
- package/src/plugin/core/ImagePlugin.ts +128 -0
- package/src/session/Session.ts +178 -485
- package/src/session/SessionSystemBuilder.ts +3 -3
- package/src/session/services/SessionStateService.ts +341 -0
- package/src/session/services/SessionTurnService.ts +202 -0
- package/src/session/services/SessionViewService.ts +301 -0
- package/src/types/agent/AgentOptions.ts +25 -0
- package/src/types/agent/AgentTypes.ts +10 -0
- package/src/types/agent/SessionTypes.ts +1 -0
- package/src/types/executor/SessionRunContext.ts +76 -0
- package/src/types/plugin/ImagePlugin.ts +103 -0
- package/src/types/session/SessionComposerOptions.ts +107 -0
- package/src/types/session/SessionLocalState.ts +40 -0
- package/src/types/session/SessionOptions.ts +99 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/executor/Executor.ts
CHANGED
|
@@ -12,55 +12,24 @@ import { SessionHistoryWriter } from "@executor/composer/history/SessionHistoryW
|
|
|
12
12
|
import type { SessionHistoryComposer } from "@executor/composer/history/SessionHistoryComposer.js";
|
|
13
13
|
import type { SessionHistoryStore } from "@/executor/store/history/SessionHistoryStore.js";
|
|
14
14
|
import { withSessionRunScope } from "@executor/SessionRunScope.js";
|
|
15
|
-
import type { SessionRunScope } from "@executor/SessionRunScope.js";
|
|
16
15
|
import { buildSessionStepParts } from "@executor/messages/SessionStepEventMapper.js";
|
|
17
16
|
import { JsonlSessionCompactionComposer } from "@executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js";
|
|
18
17
|
import { LocalSessionContextComposer } from "@executor/composer/context/LocalSessionContextComposer.js";
|
|
18
|
+
import { CoreEngineRunner } from "@executor/core-engine/CoreEngineRunner.js";
|
|
19
19
|
import type { SessionCompactionComposer } from "@executor/composer/compaction/SessionCompactionComposer.js";
|
|
20
20
|
import type { SessionContextComposer } from "@executor/composer/context/SessionContextComposer.js";
|
|
21
21
|
import type { SessionSystemComposer } from "@executor/composer/system/SessionSystemComposer.js";
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
MAX_TEXT_ONLY_CONTINUATIONS,
|
|
25
|
-
MAX_TOOL_LOOP_STEPS,
|
|
26
|
-
buildIncompleteResponseRecoveryNudge,
|
|
27
|
-
buildTextOnlyContinuationNudge,
|
|
28
|
-
detectIncompleteResponse,
|
|
29
|
-
detectTextOnlyContinuationReason,
|
|
30
|
-
mergeAssistantUiMessages,
|
|
31
|
-
summarizeStepForDebug,
|
|
32
|
-
summarizeUiMessageForDebug,
|
|
33
|
-
toInlinePreview,
|
|
34
|
-
} from "@executor/core-engine/CoreEngineSignals.js";
|
|
35
|
-
import {
|
|
36
|
-
evaluateCoreEngineLoopDecision,
|
|
37
|
-
shouldContinueForTailMergedUserMessages,
|
|
38
|
-
} from "@executor/core-engine/CoreEngineLoopDecision.js";
|
|
39
|
-
import {
|
|
40
|
-
resolveEffectiveCoreEngineError,
|
|
41
|
-
summarizeStreamError,
|
|
42
|
-
} from "@executor/core-engine/CoreEngineError.js";
|
|
43
|
-
import { collectFinalAssistantMessageFromUiStream } from "@executor/core-engine/CoreEngineUiStreamCollector.js";
|
|
44
|
-
import { CoreEngineMessageState } from "@executor/core-engine/CoreEngineMessageState.js";
|
|
45
|
-
import {
|
|
46
|
-
buildOpenAIResponsesProviderOptions,
|
|
47
|
-
} from "@executor/messages/SessionMessageCodec.js";
|
|
48
|
-
import { logAssistantMessageNow } from "@executor/messages/SessionMessageLog.js";
|
|
22
|
+
import { ExecutorInflightService } from "@executor/services/ExecutorInflightService.js";
|
|
23
|
+
import { ExecutorRecoveryPolicy } from "@executor/services/ExecutorRecoveryPolicy.js";
|
|
49
24
|
import type { Logger } from "@/utils/logger/Logger.js";
|
|
50
25
|
import type { JsonObject } from "@/types/common/Json.js";
|
|
51
26
|
import type { SessionMessageV1 } from "@/executor/types/SessionMessages.js";
|
|
52
27
|
import type { SessionExecutor } from "@/executor/types/SessionExecutor.js";
|
|
28
|
+
import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
|
|
53
29
|
import type {
|
|
54
30
|
SessionExecuteInput,
|
|
55
|
-
SessionRunInput,
|
|
56
31
|
SessionRunResult,
|
|
57
32
|
} from "@/executor/types/SessionRun.js";
|
|
58
|
-
import { generateId } from "@/utils/Id.js";
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* 可压缩错误的最大重试次数。
|
|
62
|
-
*/
|
|
63
|
-
const MAX_COMPACTION_RETRY_ATTEMPTS = 3;
|
|
64
33
|
|
|
65
34
|
type ExecutorOptions = {
|
|
66
35
|
/**
|
|
@@ -134,9 +103,11 @@ export class Executor implements SessionExecutor {
|
|
|
134
103
|
private readonly systemComposer: SessionSystemComposer;
|
|
135
104
|
protected readonly contextComposer: SessionContextComposer;
|
|
136
105
|
private readonly historyWriter: SessionHistoryWriter;
|
|
106
|
+
private readonly inflight_service: ExecutorInflightService;
|
|
107
|
+
private readonly recovery_policy: ExecutorRecoveryPolicy;
|
|
108
|
+
private readonly core_engine_runner: CoreEngineRunner;
|
|
137
109
|
|
|
138
110
|
private executing = false;
|
|
139
|
-
private retryCount = 0;
|
|
140
111
|
|
|
141
112
|
constructor(options: ExecutorOptions) {
|
|
142
113
|
const sessionId = String(options.sessionId || "").trim();
|
|
@@ -163,6 +134,24 @@ export class Executor implements SessionExecutor {
|
|
|
163
134
|
getHistoryStore: () => this.getHistoryStore(),
|
|
164
135
|
runAfterSessionUpdated: options.runAfterSessionUpdated,
|
|
165
136
|
});
|
|
137
|
+
this.inflight_service = new ExecutorInflightService({
|
|
138
|
+
session_id: this.sessionId,
|
|
139
|
+
history_store: this.historyStore,
|
|
140
|
+
run_after_session_updated_async: async () =>
|
|
141
|
+
await this.afterSessionUpdatedAsync(),
|
|
142
|
+
});
|
|
143
|
+
this.recovery_policy = new ExecutorRecoveryPolicy({
|
|
144
|
+
compaction_composer: this.compactionComposer,
|
|
145
|
+
context_composer: this.contextComposer,
|
|
146
|
+
logger: this.logger,
|
|
147
|
+
});
|
|
148
|
+
this.core_engine_runner = new CoreEngineRunner({
|
|
149
|
+
history_store: this.historyStore,
|
|
150
|
+
context_composer: this.contextComposer,
|
|
151
|
+
logger: this.logger,
|
|
152
|
+
should_compact_on_error: (error) =>
|
|
153
|
+
this.compactionComposer.shouldCompactOnError(error),
|
|
154
|
+
});
|
|
166
155
|
}
|
|
167
156
|
|
|
168
157
|
/**
|
|
@@ -227,56 +216,6 @@ export class Executor implements SessionExecutor {
|
|
|
227
216
|
await this.historyWriter.appendAssistantMessage(params);
|
|
228
217
|
}
|
|
229
218
|
|
|
230
|
-
/**
|
|
231
|
-
* 把 step/tool 过程增量写入当前运行中的 assistant 快照。
|
|
232
|
-
*/
|
|
233
|
-
private async appendAssistantStepPartsToInflight(
|
|
234
|
-
parts: SessionMessageV1["parts"],
|
|
235
|
-
): Promise<void> {
|
|
236
|
-
const normalized_parts = Array.isArray(parts)
|
|
237
|
-
? parts.filter((part) => part && typeof part === "object")
|
|
238
|
-
: [];
|
|
239
|
-
if (normalized_parts.length === 0) return;
|
|
240
|
-
|
|
241
|
-
const current_inflight = await this.historyStore.readInflight();
|
|
242
|
-
const next_message: SessionMessageV1 = current_inflight
|
|
243
|
-
? {
|
|
244
|
-
...current_inflight,
|
|
245
|
-
metadata: {
|
|
246
|
-
...(current_inflight.metadata || {
|
|
247
|
-
v: 1 as const,
|
|
248
|
-
ts: Date.now(),
|
|
249
|
-
sessionId: this.sessionId,
|
|
250
|
-
}),
|
|
251
|
-
ts: Date.now(),
|
|
252
|
-
sessionId: this.sessionId,
|
|
253
|
-
source: "egress",
|
|
254
|
-
kind: "normal",
|
|
255
|
-
},
|
|
256
|
-
parts: [
|
|
257
|
-
...(Array.isArray(current_inflight.parts)
|
|
258
|
-
? current_inflight.parts
|
|
259
|
-
: []),
|
|
260
|
-
...normalized_parts,
|
|
261
|
-
],
|
|
262
|
-
}
|
|
263
|
-
: {
|
|
264
|
-
id: `a:${this.sessionId}:${generateId()}`,
|
|
265
|
-
role: "assistant",
|
|
266
|
-
metadata: {
|
|
267
|
-
v: 1,
|
|
268
|
-
ts: Date.now(),
|
|
269
|
-
sessionId: this.sessionId,
|
|
270
|
-
source: "egress",
|
|
271
|
-
kind: "normal",
|
|
272
|
-
},
|
|
273
|
-
parts: normalized_parts,
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
await this.historyStore.writeInflight(next_message);
|
|
277
|
-
await this.afterSessionUpdatedAsync();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
219
|
/**
|
|
281
220
|
* 运行当前 session 的一次请求。
|
|
282
221
|
*
|
|
@@ -286,9 +225,7 @@ export class Executor implements SessionExecutor {
|
|
|
286
225
|
*/
|
|
287
226
|
async run(params: {
|
|
288
227
|
query: string;
|
|
289
|
-
|
|
290
|
-
onAssistantStepCallback?: SessionRunScope["onAssistantStepCallback"];
|
|
291
|
-
onUiMessageChunkCallback?: SessionRunScope["onUiMessageChunkCallback"];
|
|
228
|
+
runContext?: SessionRunContext;
|
|
292
229
|
}): Promise<SessionRunResult> {
|
|
293
230
|
if (this.executing) {
|
|
294
231
|
// 关键点(中文):同一个 Session 实例只允许一个活跃 run,
|
|
@@ -296,19 +233,9 @@ export class Executor implements SessionExecutor {
|
|
|
296
233
|
throw new Error("Executor.run does not support concurrent execution");
|
|
297
234
|
}
|
|
298
235
|
const query = String(params.query || "").trim();
|
|
299
|
-
const
|
|
300
|
-
...(typeof params.onStepCallback === "function"
|
|
301
|
-
? { onStepCallback: params.onStepCallback }
|
|
302
|
-
: {}),
|
|
303
|
-
...(typeof params.onAssistantStepCallback === "function"
|
|
304
|
-
? { onAssistantStepCallback: params.onAssistantStepCallback }
|
|
305
|
-
: {}),
|
|
306
|
-
...(typeof params.onUiMessageChunkCallback === "function"
|
|
307
|
-
? { onUiMessageChunkCallback: params.onUiMessageChunkCallback }
|
|
308
|
-
: {}),
|
|
309
|
-
};
|
|
236
|
+
const run_context = this.createRunContext(params.runContext);
|
|
310
237
|
const providedOnAssistantStepCallback =
|
|
311
|
-
|
|
238
|
+
run_context.onAssistantStepCallback;
|
|
312
239
|
|
|
313
240
|
const wrappedOnAssistantStepCallback = async (step: {
|
|
314
241
|
text: string;
|
|
@@ -323,95 +250,79 @@ export class Executor implements SessionExecutor {
|
|
|
323
250
|
visibility: step.visibility,
|
|
324
251
|
});
|
|
325
252
|
if (step_parts.length > 0) {
|
|
326
|
-
await this.
|
|
253
|
+
await this.inflight_service.append_assistant_step_parts(step_parts);
|
|
327
254
|
}
|
|
328
255
|
|
|
329
256
|
if (typeof providedOnAssistantStepCallback === "function") {
|
|
330
257
|
await providedOnAssistantStepCallback(step);
|
|
331
258
|
}
|
|
332
259
|
};
|
|
260
|
+
run_context.onAssistantStepCallback = wrappedOnAssistantStepCallback;
|
|
333
261
|
|
|
334
262
|
this.executing = true;
|
|
335
|
-
this.
|
|
263
|
+
this.recovery_policy.reset_run_state();
|
|
336
264
|
try {
|
|
337
265
|
const result = await withSessionRunScope(
|
|
338
266
|
{
|
|
339
|
-
|
|
340
|
-
...sessionRunScope,
|
|
341
|
-
onAssistantStepCallback: wrappedOnAssistantStepCallback,
|
|
267
|
+
runContext: run_context,
|
|
342
268
|
},
|
|
343
|
-
() =>
|
|
269
|
+
async () =>
|
|
270
|
+
await this.recovery_policy.run_with_retry({
|
|
271
|
+
query,
|
|
272
|
+
model: this.resolveModelOrThrow(),
|
|
273
|
+
run_context,
|
|
274
|
+
prepare_execute_input: async ({
|
|
275
|
+
query: next_query,
|
|
276
|
+
model,
|
|
277
|
+
run_context: next_run_context,
|
|
278
|
+
retry_count,
|
|
279
|
+
}) =>
|
|
280
|
+
await this.prepareExecuteInput(
|
|
281
|
+
next_query,
|
|
282
|
+
model,
|
|
283
|
+
next_run_context,
|
|
284
|
+
retry_count,
|
|
285
|
+
),
|
|
286
|
+
execute_prepared_run: async ({
|
|
287
|
+
execute_input,
|
|
288
|
+
model,
|
|
289
|
+
run_context: next_run_context,
|
|
290
|
+
}) =>
|
|
291
|
+
await this.executePreparedRun(
|
|
292
|
+
execute_input,
|
|
293
|
+
model,
|
|
294
|
+
next_run_context,
|
|
295
|
+
),
|
|
296
|
+
}),
|
|
344
297
|
);
|
|
345
298
|
return result;
|
|
346
299
|
} finally {
|
|
347
|
-
this.
|
|
300
|
+
this.recovery_policy.reset_run_state();
|
|
348
301
|
this.executing = false;
|
|
349
302
|
}
|
|
350
303
|
}
|
|
351
304
|
|
|
352
|
-
/**
|
|
353
|
-
* 执行一次 session run(带可压缩错误重试)。
|
|
354
|
-
*/
|
|
355
|
-
private async runWithRetry(input: SessionRunInput): Promise<SessionRunResult> {
|
|
356
|
-
const model = this.resolveModelOrThrow();
|
|
357
|
-
try {
|
|
358
|
-
const query = String(input.query || "").trim();
|
|
359
|
-
const prepared = await this.prepareExecuteInput(query, model);
|
|
360
|
-
return await this.executePreparedRun(prepared, model);
|
|
361
|
-
} catch (error) {
|
|
362
|
-
if (this.compactionComposer.shouldCompactOnError(error)) {
|
|
363
|
-
await this.logger.log("info", "[agent] compacting", {
|
|
364
|
-
retryCount: this.retryCount,
|
|
365
|
-
error: String(error),
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
if (this.retryCount < MAX_COMPACTION_RETRY_ATTEMPTS) {
|
|
369
|
-
this.retryCount += 1;
|
|
370
|
-
return this.runWithRetry(input);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return {
|
|
374
|
-
success: false,
|
|
375
|
-
error: "Context length exceeded and retries failed. Please resend your question.",
|
|
376
|
-
assistantMessage: this.contextComposer.buildFallbackAssistantMessage(
|
|
377
|
-
"Context length exceeded and retries failed. Please resend your question.",
|
|
378
|
-
),
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const errorMsg = String(error);
|
|
383
|
-
await this.logger.log("error", "Executor execution failed", {
|
|
384
|
-
error: errorMsg,
|
|
385
|
-
});
|
|
386
|
-
return {
|
|
387
|
-
success: false,
|
|
388
|
-
error: errorMsg,
|
|
389
|
-
assistantMessage: this.contextComposer.buildFallbackAssistantMessage(
|
|
390
|
-
`Execution failed: ${errorMsg}`,
|
|
391
|
-
),
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
305
|
/**
|
|
397
306
|
* 调用 Composer 组装当前轮执行输入。
|
|
398
307
|
*/
|
|
399
308
|
private async prepareExecuteInput(
|
|
400
309
|
query: string,
|
|
401
310
|
model: LanguageModel,
|
|
311
|
+
run_context: SessionRunContext,
|
|
312
|
+
retry_count: number,
|
|
402
313
|
): Promise<SessionExecuteInput> {
|
|
403
314
|
if (!String(this.historyComposer.sessionId || "").trim()) {
|
|
404
315
|
throw new Error("Executor.run requires historyComposer.sessionId");
|
|
405
316
|
}
|
|
406
317
|
|
|
407
|
-
const
|
|
408
|
-
const tools =
|
|
409
|
-
const system = await this.systemComposer.resolve();
|
|
318
|
+
const composed_context = await this.contextComposer.compose(run_context);
|
|
319
|
+
const tools = composed_context.tools;
|
|
320
|
+
const system = await this.systemComposer.resolve(run_context);
|
|
410
321
|
|
|
411
322
|
try {
|
|
412
|
-
if (
|
|
323
|
+
if (retry_count > 0) {
|
|
413
324
|
await this.logger.log("info", "[agent] compacting", {
|
|
414
|
-
retryCount:
|
|
325
|
+
retryCount: retry_count,
|
|
415
326
|
});
|
|
416
327
|
}
|
|
417
328
|
|
|
@@ -419,7 +330,7 @@ export class Executor implements SessionExecutor {
|
|
|
419
330
|
historyStore: this.historyStore,
|
|
420
331
|
model,
|
|
421
332
|
system,
|
|
422
|
-
retryCount:
|
|
333
|
+
retryCount: retry_count,
|
|
423
334
|
});
|
|
424
335
|
} catch {
|
|
425
336
|
// 压缩失败不阻断主流程,继续使用当前历史消息执行。
|
|
@@ -430,7 +341,7 @@ export class Executor implements SessionExecutor {
|
|
|
430
341
|
tools,
|
|
431
342
|
system,
|
|
432
343
|
model,
|
|
433
|
-
retryCount:
|
|
344
|
+
retryCount: retry_count,
|
|
434
345
|
});
|
|
435
346
|
|
|
436
347
|
return {
|
|
@@ -447,286 +358,44 @@ export class Executor implements SessionExecutor {
|
|
|
447
358
|
private async executePreparedRun(
|
|
448
359
|
input: SessionExecuteInput,
|
|
449
360
|
model: LanguageModel,
|
|
361
|
+
run_context: SessionRunContext,
|
|
450
362
|
): Promise<SessionRunResult> {
|
|
451
|
-
return await this.
|
|
363
|
+
return await this.core_engine_runner.run({
|
|
364
|
+
execute_input: input,
|
|
365
|
+
model,
|
|
366
|
+
run_context,
|
|
367
|
+
});
|
|
452
368
|
}
|
|
453
369
|
|
|
454
370
|
/**
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
* 关键点(中文)
|
|
458
|
-
* - CoreEngine 是 Executor 内部机制,不是第二个 Executor 实例。
|
|
459
|
-
* - 这里只返回最终 assistant message;是否写入长期 history 由外层 Session/Service 决定。
|
|
460
|
-
* - 运行中生成的内部续写 user message 只进入本轮内存态,不直接落盘。
|
|
371
|
+
* 归一化本轮显式运行上下文。
|
|
461
372
|
*/
|
|
462
|
-
private
|
|
463
|
-
input
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
const summary = summarizeStepForDebug(stepResult);
|
|
489
|
-
totalToolCallCount +=
|
|
490
|
-
typeof summary.toolCallCount === "number" ? summary.toolCallCount : 0;
|
|
491
|
-
totalToolResultCount +=
|
|
492
|
-
typeof summary.toolResultCount === "number"
|
|
493
|
-
? summary.toolResultCount
|
|
494
|
-
: 0;
|
|
495
|
-
await this.logger.log("info", "[agent] step.finish", {
|
|
496
|
-
sessionId,
|
|
497
|
-
stepIndex: stepCount,
|
|
498
|
-
...summary,
|
|
499
|
-
});
|
|
500
|
-
await contextComposerOnStepFinish(stepResult);
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
const prepareStep = this.contextComposer.createPrepareStepHandler({
|
|
504
|
-
system,
|
|
505
|
-
appendMergedUserMessages,
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
let finalAssistantUiMessage: SessionMessageV1 | null = null;
|
|
509
|
-
let textOnlyContinuationCount = 0;
|
|
510
|
-
let incompleteResponseRecoveryCount = 0;
|
|
511
|
-
|
|
512
|
-
while (stepCount < MAX_TOOL_LOOP_STEPS) {
|
|
513
|
-
const result = streamText({
|
|
514
|
-
model,
|
|
515
|
-
system,
|
|
516
|
-
onStepFinish,
|
|
517
|
-
prepareStep,
|
|
518
|
-
messages: messageState.modelMessages,
|
|
519
|
-
tools,
|
|
520
|
-
providerOptions: buildOpenAIResponsesProviderOptions(),
|
|
521
|
-
onError: async ({ error }) => {
|
|
522
|
-
lastObservedStreamError = error;
|
|
523
|
-
await this.logger.log("error", "[agent] stream.error", {
|
|
524
|
-
sessionId,
|
|
525
|
-
...summarizeStreamError(error),
|
|
526
|
-
});
|
|
527
|
-
},
|
|
528
|
-
});
|
|
529
|
-
|
|
530
|
-
const stepAssistantUiMessage = await collectFinalAssistantMessageFromUiStream({
|
|
531
|
-
result,
|
|
532
|
-
sessionId,
|
|
533
|
-
logger: this.logger,
|
|
534
|
-
buildFallbackAssistantMessage: (text) =>
|
|
535
|
-
this.contextComposer.buildFallbackAssistantMessage(text),
|
|
536
|
-
});
|
|
537
|
-
|
|
538
|
-
const executedSteps = await result.steps;
|
|
539
|
-
const lastStep = executedSteps[executedSteps.length - 1];
|
|
540
|
-
if (!lastStep) break;
|
|
541
|
-
|
|
542
|
-
const incompleteResponse = detectIncompleteResponse({
|
|
543
|
-
stepResult: lastStep,
|
|
544
|
-
assistantMessage: stepAssistantUiMessage,
|
|
545
|
-
});
|
|
546
|
-
const textOnlyContinuationReason =
|
|
547
|
-
detectTextOnlyContinuationReason(lastStep);
|
|
548
|
-
const loopDecision = evaluateCoreEngineLoopDecision({
|
|
549
|
-
hasIncompleteResponse: incompleteResponse !== null,
|
|
550
|
-
incompleteRecoveryCount: incompleteResponseRecoveryCount,
|
|
551
|
-
maxIncompleteRecoveries: MAX_INCOMPLETE_RESPONSE_RECOVERIES,
|
|
552
|
-
textOnlyContinuationReason,
|
|
553
|
-
textOnlyContinuationCount,
|
|
554
|
-
maxTextOnlyContinuations: MAX_TEXT_ONLY_CONTINUATIONS,
|
|
555
|
-
hasTools: Object.keys(tools).length > 0,
|
|
556
|
-
toolCallCount: lastStep.toolCalls.length,
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
await this.logger.log("info", "[agent] loop.decision", {
|
|
560
|
-
sessionId,
|
|
561
|
-
stepIndex: stepCount,
|
|
562
|
-
continueForToolCalls: loopDecision.continueForToolCalls,
|
|
563
|
-
continueForTextOnly: loopDecision.continueForTextOnly,
|
|
564
|
-
continueForIncompleteRecovery:
|
|
565
|
-
loopDecision.continueForIncompleteRecovery,
|
|
566
|
-
decisionKind: loopDecision.kind,
|
|
567
|
-
textOnlyContinuationReason,
|
|
568
|
-
textOnlyContinuationCount,
|
|
569
|
-
incompleteResponseReason: incompleteResponse?.reason ?? null,
|
|
570
|
-
incompleteResponseRecoveryCount,
|
|
571
|
-
toolCallCount: lastStep.toolCalls.length,
|
|
572
|
-
toolResultCount: lastStep.toolResults.length,
|
|
573
|
-
finishReason: lastStep.finishReason,
|
|
574
|
-
textPreview: toInlinePreview(lastStep.text),
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
if (loopDecision.continueForIncompleteRecovery && incompleteResponse) {
|
|
578
|
-
incompleteResponseRecoveryCount += 1;
|
|
579
|
-
await this.logger.log("warn", "[agent] incomplete_response.recover", {
|
|
580
|
-
sessionId,
|
|
581
|
-
stepIndex: stepCount,
|
|
582
|
-
recoveryCount: incompleteResponseRecoveryCount,
|
|
583
|
-
reason: incompleteResponse.reason,
|
|
584
|
-
...incompleteResponse.details,
|
|
585
|
-
});
|
|
586
|
-
const recoveryMessage = this.historyStore.userText({
|
|
587
|
-
text: buildIncompleteResponseRecoveryNudge(
|
|
588
|
-
incompleteResponseRecoveryCount,
|
|
589
|
-
),
|
|
590
|
-
metadata: {
|
|
591
|
-
sessionId,
|
|
592
|
-
extra: {
|
|
593
|
-
internal: "agent_incomplete_response_recover",
|
|
594
|
-
reason: incompleteResponse.reason,
|
|
595
|
-
stepIndex: stepCount,
|
|
596
|
-
},
|
|
597
|
-
},
|
|
598
|
-
});
|
|
599
|
-
await messageState.appendUserTextMessage(recoveryMessage);
|
|
600
|
-
continue;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
if (incompleteResponse) {
|
|
604
|
-
await this.logger.log("error", "[agent] incomplete_response", {
|
|
605
|
-
sessionId,
|
|
606
|
-
stepIndex: stepCount,
|
|
607
|
-
reason: incompleteResponse.reason,
|
|
608
|
-
recoveryCount: incompleteResponseRecoveryCount,
|
|
609
|
-
...incompleteResponse.details,
|
|
610
|
-
});
|
|
611
|
-
throw new Error(
|
|
612
|
-
`Agent received incomplete response (${incompleteResponse.reason})`,
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
const responseMessages = Array.isArray(lastStep.response?.messages)
|
|
617
|
-
? lastStep.response.messages
|
|
618
|
-
: [];
|
|
619
|
-
messageState.appendModelMessages(responseMessages);
|
|
620
|
-
|
|
621
|
-
finalAssistantUiMessage = mergeAssistantUiMessages(
|
|
622
|
-
finalAssistantUiMessage,
|
|
623
|
-
stepAssistantUiMessage,
|
|
624
|
-
);
|
|
625
|
-
|
|
626
|
-
// 关键点(中文):把本 step 的 assistant UI 消息并入运行时上下文,保证后续全量重算不丢历史。
|
|
627
|
-
messageState.appendRuntimeSessionMessage(stepAssistantUiMessage);
|
|
628
|
-
|
|
629
|
-
if (loopDecision.continueForToolCalls) {
|
|
630
|
-
textOnlyContinuationCount = 0;
|
|
631
|
-
incompleteResponseRecoveryCount = 0;
|
|
632
|
-
continue;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
if (loopDecision.continueForTextOnly) {
|
|
636
|
-
textOnlyContinuationCount += 1;
|
|
637
|
-
incompleteResponseRecoveryCount = 0;
|
|
638
|
-
const continuationMessage = this.historyStore.userText({
|
|
639
|
-
text: buildTextOnlyContinuationNudge(textOnlyContinuationCount),
|
|
640
|
-
metadata: {
|
|
641
|
-
sessionId,
|
|
642
|
-
extra: {
|
|
643
|
-
internal: "agent_loop_auto_continue",
|
|
644
|
-
reason: textOnlyContinuationReason,
|
|
645
|
-
stepIndex: stepCount,
|
|
646
|
-
},
|
|
647
|
-
},
|
|
648
|
-
});
|
|
649
|
-
await messageState.appendUserTextMessage(continuationMessage);
|
|
650
|
-
continue;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// 关键点(中文):stop 前做 tail merge,覆盖最后一个 step 后才入队的新 user 消息。
|
|
654
|
-
const tailPrepared = await prepareStep({ messages: [] });
|
|
655
|
-
const tailMergedMessageCount = Array.isArray(tailPrepared.messages)
|
|
656
|
-
? tailPrepared.messages.length
|
|
657
|
-
: 0;
|
|
658
|
-
if (
|
|
659
|
-
shouldContinueForTailMergedUserMessages({
|
|
660
|
-
mergedUserMessageCount: tailMergedMessageCount,
|
|
661
|
-
})
|
|
662
|
-
) {
|
|
663
|
-
textOnlyContinuationCount = 0;
|
|
664
|
-
incompleteResponseRecoveryCount = 0;
|
|
665
|
-
await this.logger.log("info", "[agent] loop.tail_merge_continue", {
|
|
666
|
-
sessionId,
|
|
667
|
-
stepIndex: stepCount,
|
|
668
|
-
mergedUserMessageCount: tailMergedMessageCount,
|
|
669
|
-
});
|
|
670
|
-
continue;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
break;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
if (stepCount >= MAX_TOOL_LOOP_STEPS) {
|
|
677
|
-
await this.logger.log("warn", "[agent] loop.max_steps_reached", {
|
|
678
|
-
sessionId,
|
|
679
|
-
stepCount,
|
|
680
|
-
totalToolCallCount,
|
|
681
|
-
totalToolResultCount,
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
const finalMessage =
|
|
686
|
-
finalAssistantUiMessage ||
|
|
687
|
-
this.contextComposer.buildFallbackAssistantMessage("Execution completed");
|
|
688
|
-
|
|
689
|
-
await this.logger.log("info", "[agent] final.message", {
|
|
690
|
-
sessionId,
|
|
691
|
-
...summarizeUiMessageForDebug(finalMessage),
|
|
692
|
-
});
|
|
693
|
-
await logAssistantMessageNow(this.logger, finalMessage);
|
|
694
|
-
|
|
695
|
-
const duration = Date.now() - startTime;
|
|
696
|
-
await this.logger.log("info", "[agent] finish", {
|
|
697
|
-
sessionId,
|
|
698
|
-
duration,
|
|
699
|
-
stepCount,
|
|
700
|
-
totalToolCallCount,
|
|
701
|
-
totalToolResultCount,
|
|
702
|
-
});
|
|
703
|
-
|
|
704
|
-
return {
|
|
705
|
-
success: true,
|
|
706
|
-
assistantMessage: finalMessage,
|
|
707
|
-
};
|
|
708
|
-
} catch (error) {
|
|
709
|
-
if (this.compactionComposer.shouldCompactOnError(error)) {
|
|
710
|
-
throw error;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
const errorMsg = resolveEffectiveCoreEngineError({
|
|
714
|
-
error,
|
|
715
|
-
streamError: lastObservedStreamError,
|
|
716
|
-
});
|
|
717
|
-
|
|
718
|
-
await this.logger.log("error", "CoreEngine execution failed", {
|
|
719
|
-
error: errorMsg,
|
|
720
|
-
});
|
|
721
|
-
|
|
722
|
-
return {
|
|
723
|
-
success: false,
|
|
724
|
-
error: errorMsg,
|
|
725
|
-
assistantMessage: this.contextComposer.buildFallbackAssistantMessage(
|
|
726
|
-
`Execution failed: ${errorMsg}`,
|
|
727
|
-
),
|
|
728
|
-
};
|
|
729
|
-
}
|
|
373
|
+
private createRunContext(
|
|
374
|
+
input?: SessionRunContext,
|
|
375
|
+
): SessionRunContext {
|
|
376
|
+
return {
|
|
377
|
+
sessionId: String(input?.sessionId || this.sessionId).trim(),
|
|
378
|
+
...(typeof input?.onStepCallback === "function"
|
|
379
|
+
? { onStepCallback: input.onStepCallback }
|
|
380
|
+
: {}),
|
|
381
|
+
...(typeof input?.onAssistantStepCallback === "function"
|
|
382
|
+
? { onAssistantStepCallback: input.onAssistantStepCallback }
|
|
383
|
+
: {}),
|
|
384
|
+
...(typeof input?.onUiMessageChunkCallback === "function"
|
|
385
|
+
? { onUiMessageChunkCallback: input.onUiMessageChunkCallback }
|
|
386
|
+
: {}),
|
|
387
|
+
injectedUserMessages: Array.isArray(input?.injectedUserMessages)
|
|
388
|
+
? [...input.injectedUserMessages]
|
|
389
|
+
: [],
|
|
390
|
+
deferredPersistedUserMessages: Array.isArray(
|
|
391
|
+
input?.deferredPersistedUserMessages,
|
|
392
|
+
)
|
|
393
|
+
? [...input.deferredPersistedUserMessages]
|
|
394
|
+
: [],
|
|
395
|
+
pendingAssistantFileParts: Array.isArray(input?.pendingAssistantFileParts)
|
|
396
|
+
? [...input.pendingAssistantFileParts]
|
|
397
|
+
: [],
|
|
398
|
+
};
|
|
730
399
|
}
|
|
731
400
|
|
|
732
401
|
/**
|
|
@@ -741,11 +410,4 @@ export class Executor implements SessionExecutor {
|
|
|
741
410
|
}
|
|
742
411
|
return model;
|
|
743
412
|
}
|
|
744
|
-
|
|
745
|
-
/**
|
|
746
|
-
* 重置当前 run 级状态。
|
|
747
|
-
*/
|
|
748
|
-
private resetRunState(): void {
|
|
749
|
-
this.retryCount = 0;
|
|
750
|
-
}
|
|
751
413
|
}
|