@downcity/agent 1.1.199 → 1.1.202
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/bin/agent/local/Agent.d.ts +3 -7
- package/bin/agent/local/Agent.d.ts.map +1 -1
- package/bin/agent/local/Agent.js +14 -19
- package/bin/agent/local/Agent.js.map +1 -1
- package/bin/agent/local/services/{AgentSessionManager.d.ts → AgentSessions.d.ts} +12 -17
- package/bin/agent/local/services/AgentSessions.d.ts.map +1 -0
- package/bin/agent/local/services/{AgentSessionManager.js → AgentSessions.js} +11 -26
- package/bin/agent/local/services/AgentSessions.js.map +1 -0
- package/bin/agent/remote/RemoteAgent.d.ts +2 -9
- package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
- package/bin/agent/remote/RemoteAgent.js +40 -22
- package/bin/agent/remote/RemoteAgent.js.map +1 -1
- package/bin/agent/remote/RemoteSession.d.ts +5 -5
- package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
- package/bin/agent/remote/RemoteSession.js +5 -3
- package/bin/agent/remote/RemoteSession.js.map +1 -1
- package/bin/agent/remote/RemoteTransport.d.ts +2 -2
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +2 -2
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +5 -5
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +2 -2
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +2 -2
- package/bin/executor/Executor.d.ts +7 -7
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +41 -33
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/SessionRunScope.d.ts +1 -1
- package/bin/executor/SessionRunScope.d.ts.map +1 -1
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +5 -5
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +4 -5
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +73 -40
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts +27 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts.map +1 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js +181 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js.map +1 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts +45 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.d.ts.map +1 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js +144 -0
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js.map +1 -0
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +3 -3
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +1 -1
- package/bin/executor/composer/context/SessionContextComposer.d.ts +3 -3
- package/bin/executor/composer/context/SessionContextComposer.d.ts.map +1 -1
- package/bin/executor/composer/history/SessionHistoryComposer.d.ts +2 -2
- package/bin/executor/composer/history/SessionHistoryComposer.d.ts.map +1 -1
- package/bin/executor/composer/history/SessionHistoryWriter.d.ts +5 -5
- package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +1 -1
- package/bin/executor/composer/history/SessionHistoryWriter.js +6 -6
- package/bin/executor/composer/history/SessionHistoryWriter.js.map +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts +2 -2
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +5 -4
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineMessageState.d.ts +5 -5
- package/bin/executor/core-engine/CoreEngineMessageState.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineMessageState.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineSignals.d.ts +4 -4
- package/bin/executor/core-engine/CoreEngineSignals.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineSignals.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts +3 -3
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineUiStreamCollector.js.map +1 -1
- package/bin/executor/messages/AssistantResultPersistence.d.ts +5 -5
- package/bin/executor/messages/AssistantResultPersistence.d.ts.map +1 -1
- package/bin/executor/messages/AssistantResultPersistence.js +1 -1
- package/bin/executor/messages/AssistantResultPersistence.js.map +1 -1
- package/bin/executor/messages/SessionAttachmentMapper.d.ts +3 -3
- package/bin/executor/messages/SessionAttachmentMapper.d.ts.map +1 -1
- package/bin/executor/messages/SessionAttachmentMapper.js.map +1 -1
- package/bin/executor/messages/SessionMessageCodec.d.ts +4 -4
- package/bin/executor/messages/SessionMessageCodec.d.ts.map +1 -1
- package/bin/executor/messages/SessionMessageCodec.js +5 -5
- package/bin/executor/messages/SessionMessageCodec.js.map +1 -1
- package/bin/executor/messages/SessionMessageLog.d.ts +3 -3
- package/bin/executor/messages/SessionMessageLog.d.ts.map +1 -1
- package/bin/executor/messages/SessionMessageLog.js.map +1 -1
- package/bin/executor/messages/SessionStepEventMapper.d.ts +2 -2
- package/bin/executor/messages/SessionStepEventMapper.d.ts.map +1 -1
- package/bin/executor/messages/SessionStepEventMapper.js.map +1 -1
- package/bin/executor/messages/UserVisibleText.d.ts +3 -3
- package/bin/executor/messages/UserVisibleText.d.ts.map +1 -1
- package/bin/executor/messages/UserVisibleText.js +3 -3
- package/bin/executor/messages/UserVisibleText.js.map +1 -1
- package/bin/executor/services/ExecutorInflightService.d.ts +2 -2
- package/bin/executor/services/ExecutorInflightService.d.ts.map +1 -1
- package/bin/executor/services/ExecutorInflightService.js +11 -7
- package/bin/executor/services/ExecutorInflightService.js.map +1 -1
- package/bin/executor/store/history/SessionHistoryStore.d.ts +30 -27
- package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/SessionHistoryStore.js +3 -3
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +21 -20
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +114 -72
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts +1 -7
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolSchemas.d.ts +4 -6
- package/bin/executor/tools/plugin/PluginToolSchemas.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolSchemas.js +24 -10
- package/bin/executor/tools/plugin/PluginToolSchemas.js.map +1 -1
- package/bin/executor/types/SessionRecords.d.ts +162 -0
- package/bin/executor/types/SessionRecords.d.ts.map +1 -0
- package/bin/executor/types/SessionRecords.js +52 -0
- package/bin/executor/types/SessionRecords.js.map +1 -0
- package/bin/executor/types/SessionRun.d.ts +3 -3
- package/bin/executor/types/SessionRun.d.ts.map +1 -1
- package/bin/index.d.ts +2 -2
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js.map +1 -1
- package/bin/rpc/Client.d.ts +5 -5
- package/bin/rpc/Client.js +4 -4
- package/bin/session/Session.d.ts +6 -6
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +8 -8
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionTitle.d.ts +2 -2
- package/bin/session/SessionTitle.d.ts.map +1 -1
- package/bin/session/SessionTitle.js +5 -0
- package/bin/session/SessionTitle.js.map +1 -1
- package/bin/session/browse/Browse.d.ts +12 -12
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +37 -34
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/index.d.ts +1 -1
- package/bin/session/index.js +1 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts +3 -3
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.d.ts +11 -12
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +43 -69
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/session/services/SessionTurnService.js +3 -3
- package/bin/session/services/SessionTurnService.js.map +1 -1
- package/bin/session/services/SessionViewService.d.ts +4 -4
- package/bin/session/services/SessionViewService.d.ts.map +1 -1
- package/bin/session/services/SessionViewService.js +26 -36
- package/bin/session/services/SessionViewService.js.map +1 -1
- package/bin/session/storage/Persistence.d.ts +4 -4
- package/bin/session/storage/Persistence.d.ts.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.d.ts +2 -2
- package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.js +4 -4
- package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
- package/bin/types/agent/AgentTypes.d.ts +2 -2
- package/bin/types/agent/AgentTypes.d.ts.map +1 -1
- package/bin/types/agent/SessionActor.d.ts +11 -11
- package/bin/types/agent/SessionActor.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +22 -22
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +7 -7
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/rpc/RpcProtocol.d.ts +6 -6
- package/bin/types/runtime/agent/AgentContext.d.ts +7 -7
- package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
- package/bin/types/sdk/AgentSessionAction.d.ts +26 -0
- package/bin/types/sdk/AgentSessionAction.d.ts.map +1 -0
- package/bin/types/sdk/AgentSessionAction.js +10 -0
- package/bin/types/sdk/AgentSessionAction.js.map +1 -0
- package/bin/types/sdk/AgentSessionEvent.d.ts +2 -2
- package/bin/types/sdk/AgentSessionEvent.d.ts.map +1 -1
- package/bin/types/sdk/AgentSessionTurn.d.ts +2 -2
- package/bin/types/sdk/AgentSessionTurn.d.ts.map +1 -1
- package/package.json +3 -3
- package/scripts/agent-ready.test.mjs +1 -1
- package/scripts/city-model-tool-loop.test.mjs +36 -4
- package/scripts/plugin-tool-bridge.test.mjs +13 -0
- package/scripts/session-action-message.test.mjs +199 -0
- package/scripts/session-compaction-prompts.test.mjs +97 -0
- package/scripts/session-history-archive.test.mjs +8 -8
- package/scripts/session-history-inflight.test.mjs +10 -10
- package/scripts/session-list-title.test.mjs +9 -9
- package/scripts/session-title-event.test.mjs +12 -10
- package/src/agent/local/Agent.ts +16 -22
- package/src/agent/local/services/{AgentSessionManager.ts → AgentSessions.ts} +16 -32
- package/src/agent/remote/RemoteAgent.ts +58 -23
- package/src/agent/remote/RemoteSession.ts +10 -8
- package/src/agent/remote/RemoteTransport.ts +5 -5
- package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +10 -10
- package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +6 -6
- package/src/executor/Executor.ts +51 -41
- package/src/executor/SessionRunScope.ts +1 -1
- package/src/executor/composer/compaction/SessionCompactionComposer.ts +5 -5
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +1 -1
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +91 -52
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.ts +197 -0
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.ts +162 -0
- package/src/executor/composer/context/LocalSessionContextComposer.ts +5 -5
- package/src/executor/composer/context/SessionContextComposer.ts +5 -5
- package/src/executor/composer/history/SessionHistoryComposer.ts +2 -2
- package/src/executor/composer/history/SessionHistoryWriter.ts +10 -10
- package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +13 -10
- package/src/executor/core-engine/CoreEngineMessageState.ts +8 -8
- package/src/executor/core-engine/CoreEngineRunner.ts +7 -7
- package/src/executor/core-engine/CoreEngineSignals.ts +7 -7
- package/src/executor/core-engine/CoreEngineUiStreamCollector.ts +5 -5
- package/src/executor/messages/AssistantResultPersistence.ts +8 -8
- package/src/executor/messages/SessionAttachmentMapper.ts +11 -11
- package/src/executor/messages/SessionMessageCodec.ts +10 -10
- package/src/executor/messages/SessionMessageLog.ts +3 -3
- package/src/executor/messages/SessionStepEventMapper.ts +5 -5
- package/src/executor/messages/UserVisibleText.ts +9 -9
- package/src/executor/services/ExecutorInflightService.ts +13 -9
- package/src/executor/store/history/SessionHistoryStore.ts +32 -28
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +146 -95
- package/src/executor/tools/plugin/PluginToolSchemas.ts +24 -10
- package/src/executor/types/SessionRecords.ts +217 -0
- package/src/executor/types/SessionRun.ts +5 -5
- package/src/index.ts +9 -10
- package/src/rpc/Client.ts +9 -9
- package/src/session/Session.ts +10 -10
- package/src/session/SessionTitle.ts +7 -4
- package/src/session/browse/Browse.ts +66 -58
- package/src/session/index.ts +1 -1
- package/src/session/runtime/SessionPromptRuntime.ts +6 -6
- package/src/session/services/SessionStateService.ts +61 -86
- package/src/session/services/SessionTurnService.ts +7 -7
- package/src/session/services/SessionViewService.ts +35 -45
- package/src/session/storage/Persistence.ts +6 -6
- package/src/session/storage/RuntimeSessionPort.ts +6 -6
- package/src/types/agent/AgentTypes.ts +4 -4
- package/src/types/agent/SessionActor.ts +12 -12
- package/src/types/agent/SessionTypes.ts +22 -22
- package/src/types/executor/SessionRunContext.ts +12 -12
- package/src/types/rpc/RpcProtocol.ts +6 -6
- package/src/types/runtime/agent/AgentContext.ts +8 -8
- package/src/types/sdk/AgentSessionAction.ts +35 -0
- package/src/types/sdk/AgentSessionEvent.ts +2 -2
- package/src/types/sdk/AgentSessionTurn.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/agent/local/services/AgentSessionManager.d.ts.map +0 -1
- package/bin/agent/local/services/AgentSessionManager.js.map +0 -1
- package/bin/executor/types/SessionMessages.d.ts +0 -118
- package/bin/executor/types/SessionMessages.d.ts.map +0 -1
- package/bin/executor/types/SessionMessages.js +0 -28
- package/bin/executor/types/SessionMessages.js.map +0 -1
- package/bin/types/sdk/AgentSessionOperation.d.ts +0 -99
- package/bin/types/sdk/AgentSessionOperation.d.ts.map +0 -1
- package/bin/types/sdk/AgentSessionOperation.js +0 -10
- package/bin/types/sdk/AgentSessionOperation.js.map +0 -1
- package/scripts/session-operation-message.test.mjs +0 -197
- package/src/executor/types/SessionMessages.ts +0 -148
- package/src/types/sdk/AgentSessionOperation.ts +0 -125
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import type { JsonObject } from "@/types/common/Json.js";
|
|
11
11
|
import type {
|
|
12
|
-
|
|
12
|
+
SessionRecordV1,
|
|
13
13
|
SessionMetadataV1,
|
|
14
|
-
} from "@/executor/types/
|
|
14
|
+
} from "@/executor/types/SessionRecords.js";
|
|
15
15
|
import type { SessionHistoryStore } from "@/executor/store/history/SessionHistoryStore.js";
|
|
16
16
|
|
|
17
17
|
type SessionHistoryWriterOptions = {
|
|
@@ -63,15 +63,15 @@ export class SessionHistoryWriter {
|
|
|
63
63
|
/**
|
|
64
64
|
* 追加一条 user 消息。
|
|
65
65
|
*/
|
|
66
|
-
async
|
|
67
|
-
message?:
|
|
66
|
+
async append_user_message(params: {
|
|
67
|
+
message?: SessionRecordV1 | null;
|
|
68
68
|
text?: string;
|
|
69
69
|
extra?: JsonObject;
|
|
70
70
|
}): Promise<void> {
|
|
71
71
|
try {
|
|
72
72
|
const historyStore = this.getHistoryStore();
|
|
73
73
|
if (params.message && typeof params.message === "object") {
|
|
74
|
-
await historyStore.
|
|
74
|
+
await historyStore.write_record(params.message);
|
|
75
75
|
void this.afterSessionUpdatedAsync();
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
@@ -86,7 +86,7 @@ export class SessionHistoryWriter {
|
|
|
86
86
|
extra: params.extra,
|
|
87
87
|
} as Omit<SessionMetadataV1, "v" | "ts">,
|
|
88
88
|
});
|
|
89
|
-
await historyStore.
|
|
89
|
+
await historyStore.write_record(message);
|
|
90
90
|
void this.afterSessionUpdatedAsync();
|
|
91
91
|
} catch {
|
|
92
92
|
// ignore
|
|
@@ -96,15 +96,15 @@ export class SessionHistoryWriter {
|
|
|
96
96
|
/**
|
|
97
97
|
* 追加一条 assistant 消息。
|
|
98
98
|
*/
|
|
99
|
-
async
|
|
100
|
-
message?:
|
|
99
|
+
async append_assistant_message(params: {
|
|
100
|
+
message?: SessionRecordV1 | null;
|
|
101
101
|
fallbackText?: string;
|
|
102
102
|
extra?: JsonObject;
|
|
103
103
|
}): Promise<void> {
|
|
104
104
|
try {
|
|
105
105
|
const historyStore = this.getHistoryStore();
|
|
106
106
|
if (params.message && typeof params.message === "object") {
|
|
107
|
-
await historyStore.
|
|
107
|
+
await historyStore.finalize_inflight(params.message);
|
|
108
108
|
void this.afterSessionUpdatedAsync();
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
@@ -112,7 +112,7 @@ export class SessionHistoryWriter {
|
|
|
112
112
|
const fallbackText = String(params.fallbackText || "").trim();
|
|
113
113
|
if (!fallbackText) return;
|
|
114
114
|
|
|
115
|
-
await historyStore.
|
|
115
|
+
await historyStore.finalize_inflight(
|
|
116
116
|
historyStore.assistantText({
|
|
117
117
|
text: fallbackText,
|
|
118
118
|
metadata: {
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Tool } from "ai";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
is_session_action_record,
|
|
13
|
+
is_session_message_record,
|
|
14
|
+
type SessionRecordV1,
|
|
15
|
+
type SessionMessageRecordV1,
|
|
16
|
+
} from "@/executor/types/SessionRecords.js";
|
|
15
17
|
import type { SessionHistoryStore } from "@/executor/store/history/SessionHistoryStore.js";
|
|
16
18
|
import type {
|
|
17
19
|
SessionHistoryComposer,
|
|
@@ -49,7 +51,7 @@ export class JsonlSessionHistoryComposer implements SessionHistoryComposer {
|
|
|
49
51
|
return tools && typeof tools === "object" ? { ...tools } : {};
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
private readUserSessionMessageText(message:
|
|
54
|
+
private readUserSessionMessageText(message: SessionMessageRecordV1): string {
|
|
53
55
|
if (!message || typeof message !== "object" || message.role !== "user") {
|
|
54
56
|
return "";
|
|
55
57
|
}
|
|
@@ -68,7 +70,7 @@ export class JsonlSessionHistoryComposer implements SessionHistoryComposer {
|
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
private hasTrailingUserQuery(
|
|
71
|
-
messages:
|
|
73
|
+
messages: SessionRecordV1[],
|
|
72
74
|
query: string,
|
|
73
75
|
): boolean {
|
|
74
76
|
const target = String(query || "").trim();
|
|
@@ -76,15 +78,17 @@ export class JsonlSessionHistoryComposer implements SessionHistoryComposer {
|
|
|
76
78
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
77
79
|
const item = messages[index];
|
|
78
80
|
if (!item || typeof item !== "object") continue;
|
|
79
|
-
if (item.role !== "user") continue;
|
|
81
|
+
if (!is_session_message_record(item) || item.role !== "user") continue;
|
|
80
82
|
return this.readUserSessionMessageText(item) === target;
|
|
81
83
|
}
|
|
82
84
|
return false;
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
private sanitizeMessages(messages:
|
|
87
|
+
private sanitizeMessages(messages: SessionRecordV1[]): SessionRecordV1[] {
|
|
86
88
|
if (!Array.isArray(messages)) return [];
|
|
87
89
|
return messages
|
|
90
|
+
.filter((message) => !is_session_action_record(message))
|
|
91
|
+
.filter(is_session_message_record)
|
|
88
92
|
.map((message) => {
|
|
89
93
|
const parts = Array.isArray(message.parts)
|
|
90
94
|
? message.parts.filter((part) => part && typeof part === "object")
|
|
@@ -94,16 +98,15 @@ export class JsonlSessionHistoryComposer implements SessionHistoryComposer {
|
|
|
94
98
|
parts,
|
|
95
99
|
};
|
|
96
100
|
})
|
|
97
|
-
.filter((message) => !isSessionOperationMessage(message))
|
|
98
101
|
.filter((message) => Array.isArray(message.parts) && message.parts.length > 0);
|
|
99
102
|
}
|
|
100
103
|
|
|
101
|
-
async prepare(input: SessionHistoryPrepareInput): Promise<
|
|
104
|
+
async prepare(input: SessionHistoryPrepareInput): Promise<SessionRecordV1[]> {
|
|
102
105
|
const query = String(input.query || "").trim();
|
|
103
106
|
const tools = this.normalizeTools(input.tools);
|
|
104
107
|
void tools;
|
|
105
108
|
|
|
106
|
-
let baseMessages = this.sanitizeMessages(await this.store.
|
|
109
|
+
let baseMessages = this.sanitizeMessages(await this.store.list_records());
|
|
107
110
|
if ((!Array.isArray(baseMessages) || baseMessages.length === 0) && query) {
|
|
108
111
|
baseMessages = [
|
|
109
112
|
this.store.userText({
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { ModelMessage, Tool } from "ai";
|
|
11
|
-
import type {
|
|
11
|
+
import type { SessionRecordV1 } from "@/executor/types/SessionRecords.js";
|
|
12
12
|
import {
|
|
13
13
|
pickMergedUserMessages,
|
|
14
14
|
toModelMessages,
|
|
@@ -21,7 +21,7 @@ export class CoreEngineMessageState {
|
|
|
21
21
|
/**
|
|
22
22
|
* 当前运行时 session 语义消息。
|
|
23
23
|
*/
|
|
24
|
-
private sessionMessages:
|
|
24
|
+
private sessionMessages: SessionRecordV1[];
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* 当前模型侧消息基线。
|
|
@@ -42,7 +42,7 @@ export class CoreEngineMessageState {
|
|
|
42
42
|
/**
|
|
43
43
|
* 当前运行时 session 语义消息。
|
|
44
44
|
*/
|
|
45
|
-
sessionMessages:
|
|
45
|
+
sessionMessages: SessionRecordV1[];
|
|
46
46
|
/**
|
|
47
47
|
* 当前模型侧消息基线。
|
|
48
48
|
*/
|
|
@@ -69,7 +69,7 @@ export class CoreEngineMessageState {
|
|
|
69
69
|
/**
|
|
70
70
|
* 初始 session 语义消息。
|
|
71
71
|
*/
|
|
72
|
-
messages:
|
|
72
|
+
messages: SessionRecordV1[];
|
|
73
73
|
/**
|
|
74
74
|
* 当前轮可用工具集合。
|
|
75
75
|
*/
|
|
@@ -105,7 +105,7 @@ export class CoreEngineMessageState {
|
|
|
105
105
|
* 把 step 间新增的 user 消息并入两份基线。
|
|
106
106
|
*/
|
|
107
107
|
async appendMergedUserMessages(
|
|
108
|
-
messages:
|
|
108
|
+
messages: SessionRecordV1[],
|
|
109
109
|
): Promise<ModelMessage[]> {
|
|
110
110
|
const mergedMessages = pickMergedUserMessages(messages);
|
|
111
111
|
if (mergedMessages.length === 0) return [];
|
|
@@ -115,14 +115,14 @@ export class CoreEngineMessageState {
|
|
|
115
115
|
/**
|
|
116
116
|
* 追加内部生成的 user nudge 消息。
|
|
117
117
|
*/
|
|
118
|
-
async appendUserTextMessage(message:
|
|
118
|
+
async appendUserTextMessage(message: SessionRecordV1): Promise<void> {
|
|
119
119
|
await this.appendSessionMessagesAsModelMessages([message]);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
123
|
* 追加 assistant UI 消息到 session 语义基线。
|
|
124
124
|
*/
|
|
125
|
-
appendRuntimeSessionMessage(message:
|
|
125
|
+
appendRuntimeSessionMessage(message: SessionRecordV1): void {
|
|
126
126
|
this.sessionMessages = [...this.sessionMessages, message];
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -135,7 +135,7 @@ export class CoreEngineMessageState {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
private async appendSessionMessagesAsModelMessages(
|
|
138
|
-
messages:
|
|
138
|
+
messages: SessionRecordV1[],
|
|
139
139
|
): Promise<ModelMessage[]> {
|
|
140
140
|
this.sessionMessages = [...this.sessionMessages, ...messages];
|
|
141
141
|
const modelMessages = await toModelMessages(
|
|
@@ -42,9 +42,9 @@ import type {
|
|
|
42
42
|
SessionRunResult,
|
|
43
43
|
} from "@/executor/types/SessionRun.js";
|
|
44
44
|
import type {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
} from "@/executor/types/
|
|
45
|
+
SessionRecordV1,
|
|
46
|
+
SessionMessageRecordV1,
|
|
47
|
+
} from "@/executor/types/SessionRecords.js";
|
|
48
48
|
|
|
49
49
|
const TURN_STOPPED_MESSAGE = "Turn stopped";
|
|
50
50
|
|
|
@@ -64,9 +64,9 @@ function build_file_part_key(part: FileUIPart): string {
|
|
|
64
64
|
* 把 tool/plugin 运行期产生的 file parts 并入最终 assistant UIMessage。
|
|
65
65
|
*/
|
|
66
66
|
function mergePendingAssistantFileParts(
|
|
67
|
-
message:
|
|
67
|
+
message: SessionMessageRecordV1,
|
|
68
68
|
parts: FileUIPart[],
|
|
69
|
-
):
|
|
69
|
+
): SessionMessageRecordV1 {
|
|
70
70
|
if (!Array.isArray(parts) || parts.length === 0) return message;
|
|
71
71
|
const current_parts = Array.isArray(message.parts) ? message.parts : [];
|
|
72
72
|
const seen = new Set<string>();
|
|
@@ -154,7 +154,7 @@ export class CoreEngineRunner {
|
|
|
154
154
|
: [];
|
|
155
155
|
const tools = input.execute_input.tools;
|
|
156
156
|
let last_observed_stream_error: unknown = undefined;
|
|
157
|
-
let final_assistant_ui_message:
|
|
157
|
+
let final_assistant_ui_message: SessionMessageRecordV1 | null = null;
|
|
158
158
|
|
|
159
159
|
try {
|
|
160
160
|
const message_state = await CoreEngineMessageState.create({
|
|
@@ -163,7 +163,7 @@ export class CoreEngineRunner {
|
|
|
163
163
|
projectRoot: input.run_context.projectRoot,
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
-
const append_merged_user_messages = (messages:
|
|
166
|
+
const append_merged_user_messages = (messages: SessionRecordV1[]) =>
|
|
167
167
|
message_state.appendMergedUserMessages(messages);
|
|
168
168
|
|
|
169
169
|
const context_composer_on_step_finish =
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isTextUIPart,
|
|
13
13
|
isToolUIPart,
|
|
14
14
|
} from "ai";
|
|
15
|
-
import type {
|
|
15
|
+
import type { SessionMessageRecordV1 } from "@/executor/types/SessionRecords.js";
|
|
16
16
|
import type { JsonObject } from "@/types/common/Json.js";
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -192,7 +192,7 @@ export function summarizeStepForDebug(stepResult: unknown): JsonObject {
|
|
|
192
192
|
* 汇总最终 assistant UI 消息的调试摘要。
|
|
193
193
|
*/
|
|
194
194
|
export function summarizeUiMessageForDebug(
|
|
195
|
-
message:
|
|
195
|
+
message: SessionMessageRecordV1 | null | undefined,
|
|
196
196
|
): JsonObject {
|
|
197
197
|
const parts = Array.isArray(message?.parts) ? message.parts : [];
|
|
198
198
|
const text = parts
|
|
@@ -230,9 +230,9 @@ export function summarizeUiMessageForDebug(
|
|
|
230
230
|
* - 多 step 场景下,最终 assistant message 需要把各 step 的 UI part 串起来。
|
|
231
231
|
*/
|
|
232
232
|
export function mergeAssistantUiMessages(
|
|
233
|
-
base:
|
|
234
|
-
incoming:
|
|
235
|
-
):
|
|
233
|
+
base: SessionMessageRecordV1 | null,
|
|
234
|
+
incoming: SessionMessageRecordV1,
|
|
235
|
+
): SessionMessageRecordV1 {
|
|
236
236
|
if (!base) return incoming;
|
|
237
237
|
const baseMetadata = base.metadata;
|
|
238
238
|
const incomingMetadata = incoming.metadata;
|
|
@@ -254,7 +254,7 @@ export function mergeAssistantUiMessages(
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
function pickIncompleteToolParts(
|
|
257
|
-
message:
|
|
257
|
+
message: SessionMessageRecordV1 | null | undefined,
|
|
258
258
|
): Array<{
|
|
259
259
|
toolName: string;
|
|
260
260
|
state: string;
|
|
@@ -304,7 +304,7 @@ export function buildIncompleteResponseRecoveryNudge(
|
|
|
304
304
|
*/
|
|
305
305
|
export function detectIncompleteResponse(params: {
|
|
306
306
|
stepResult: unknown;
|
|
307
|
-
assistantMessage:
|
|
307
|
+
assistantMessage: SessionMessageRecordV1 | null | undefined;
|
|
308
308
|
}): {
|
|
309
309
|
reason: string;
|
|
310
310
|
details: JsonObject;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import type { streamText } from "ai";
|
|
11
11
|
import type { Logger } from "@/utils/logger/Logger.js";
|
|
12
12
|
import type { JsonObject } from "@/types/common/Json.js";
|
|
13
|
-
import type {
|
|
13
|
+
import type { SessionMessageRecordV1 } from "@/executor/types/SessionRecords.js";
|
|
14
14
|
import type { SessionUiMessageChunkCallback } from "@/executor/types/SessionRun.js";
|
|
15
15
|
import { generateId } from "@/utils/Id.js";
|
|
16
16
|
import {
|
|
@@ -37,7 +37,7 @@ export async function collectFinalAssistantMessageFromUiStream(params: {
|
|
|
37
37
|
/**
|
|
38
38
|
* 构造 fallback assistant 消息的工厂函数。
|
|
39
39
|
*/
|
|
40
|
-
buildFallbackAssistantMessage: (text: string) =>
|
|
40
|
+
buildFallbackAssistantMessage: (text: string) => SessionMessageRecordV1;
|
|
41
41
|
/**
|
|
42
42
|
* UI stream chunk 回调。
|
|
43
43
|
*/
|
|
@@ -50,12 +50,12 @@ export async function collectFinalAssistantMessageFromUiStream(params: {
|
|
|
50
50
|
* - 此时仍应尽量用已经收到的 text delta 构造可持久化 assistant 消息。
|
|
51
51
|
*/
|
|
52
52
|
abortSignal?: AbortSignal;
|
|
53
|
-
}): Promise<
|
|
54
|
-
let streamedAssistantMessage:
|
|
53
|
+
}): Promise<SessionMessageRecordV1> {
|
|
54
|
+
let streamedAssistantMessage: SessionMessageRecordV1 | null = null;
|
|
55
55
|
let uiFinishSummary: JsonObject | null = null;
|
|
56
56
|
let streamed_text = "";
|
|
57
57
|
|
|
58
|
-
const uiStream = params.result.toUIMessageStream<
|
|
58
|
+
const uiStream = params.result.toUIMessageStream<SessionMessageRecordV1>({
|
|
59
59
|
// 关键点(中文):SDK stream 需要 reasoning 旁路事件时可直接消费;最终落盘仍由 responseMessage 收敛。
|
|
60
60
|
originalMessages: [],
|
|
61
61
|
generateMessageId: () => `a:${params.sessionId}:${generateId()}`,
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "@/executor/types/
|
|
11
|
+
SessionRecordV1,
|
|
12
|
+
SessionMessageRecordV1,
|
|
13
|
+
} from "@/executor/types/SessionRecords.js";
|
|
14
14
|
import { resolveAssistantMessageForPersistence } from "@/executor/messages/UserVisibleText.js";
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -20,11 +20,11 @@ export interface AssistantResultPersistenceWriter {
|
|
|
20
20
|
/**
|
|
21
21
|
* 追加 assistant 消息。
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
append_assistant_message(params: {
|
|
24
24
|
/**
|
|
25
25
|
* 已构造好的完整 assistant 消息。
|
|
26
26
|
*/
|
|
27
|
-
message?:
|
|
27
|
+
message?: SessionRecordV1 | null;
|
|
28
28
|
/**
|
|
29
29
|
* 在没有完整 message 可写时的兜底文本。
|
|
30
30
|
*/
|
|
@@ -43,7 +43,7 @@ export interface PersistAssistantResultParams {
|
|
|
43
43
|
/**
|
|
44
44
|
* 本轮执行得到的 assistant message。
|
|
45
45
|
*/
|
|
46
|
-
assistantMessage:
|
|
46
|
+
assistantMessage: SessionMessageRecordV1 | null | undefined;
|
|
47
47
|
/**
|
|
48
48
|
* 可选兜底文本。
|
|
49
49
|
*
|
|
@@ -68,7 +68,7 @@ export function buildAssistantResultPersistencePayload(
|
|
|
68
68
|
/**
|
|
69
69
|
* 已构造好的完整 assistant message。
|
|
70
70
|
*/
|
|
71
|
-
message?:
|
|
71
|
+
message?: SessionMessageRecordV1 | null;
|
|
72
72
|
/**
|
|
73
73
|
* 允许写入的兜底文本。
|
|
74
74
|
*/
|
|
@@ -101,6 +101,6 @@ export async function persistAssistantResult(
|
|
|
101
101
|
fallbackText: params.fallbackText,
|
|
102
102
|
});
|
|
103
103
|
if (!payload) return false;
|
|
104
|
-
await params.writer.
|
|
104
|
+
await params.writer.append_assistant_message(payload);
|
|
105
105
|
return true;
|
|
106
106
|
}
|
|
@@ -18,9 +18,9 @@ import {
|
|
|
18
18
|
} from "ai";
|
|
19
19
|
import type { SessionUserMessagePart } from "@/types/sdk/AgentSessionPrompt.js";
|
|
20
20
|
import type {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
} from "@/executor/types/
|
|
21
|
+
SessionRecordV1,
|
|
22
|
+
SessionMessageRecordV1,
|
|
23
|
+
} from "@/executor/types/SessionRecords.js";
|
|
24
24
|
import { parseChatMessageMarkup } from "@/executor/messages/ChatMessageMarkup.js";
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -174,12 +174,12 @@ export async function hydrateUserPromptFileParts(
|
|
|
174
174
|
* - 新历史保留 Agent 根目录相对路径,旧历史的 `file://` 仍继续兼容。
|
|
175
175
|
*/
|
|
176
176
|
export async function hydrateFileUrlPartsForModel(
|
|
177
|
-
messages:
|
|
177
|
+
messages: SessionMessageRecordV1[],
|
|
178
178
|
projectRoot?: string,
|
|
179
|
-
): Promise<
|
|
179
|
+
): Promise<SessionMessageRecordV1[]> {
|
|
180
180
|
if (!Array.isArray(messages) || messages.length === 0) return messages;
|
|
181
181
|
|
|
182
|
-
const out:
|
|
182
|
+
const out: SessionMessageRecordV1[] = [];
|
|
183
183
|
for (const message of messages) {
|
|
184
184
|
const parts = Array.isArray(message?.parts) ? message.parts : [];
|
|
185
185
|
if (!parts.some((part) => isFileUIPart(part as FileUIPart))) {
|
|
@@ -187,7 +187,7 @@ export async function hydrateFileUrlPartsForModel(
|
|
|
187
187
|
continue;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
const nextParts:
|
|
190
|
+
const nextParts: SessionMessageRecordV1["parts"] = [];
|
|
191
191
|
let changed = false;
|
|
192
192
|
for (const part of parts) {
|
|
193
193
|
if (!isFileUIPart(part as FileUIPart)) {
|
|
@@ -196,7 +196,7 @@ export async function hydrateFileUrlPartsForModel(
|
|
|
196
196
|
}
|
|
197
197
|
const nextPart = await hydrateFileUrlPart(part as FileUIPart, projectRoot);
|
|
198
198
|
if (nextPart !== part) changed = true;
|
|
199
|
-
nextParts.push(nextPart as
|
|
199
|
+
nextParts.push(nextPart as SessionMessageRecordV1["parts"][number]);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
out.push(changed ? { ...message, parts: nextParts } : message);
|
|
@@ -209,13 +209,13 @@ export async function hydrateFileUrlPartsForModel(
|
|
|
209
209
|
* 在 user 消息上注入 FileUIPart,以便多模态模型直接消费本地附件。
|
|
210
210
|
*/
|
|
211
211
|
export async function injectFilePartsFromAttachments(
|
|
212
|
-
messages:
|
|
212
|
+
messages: SessionMessageRecordV1[],
|
|
213
213
|
projectRoot?: string,
|
|
214
|
-
): Promise<
|
|
214
|
+
): Promise<SessionMessageRecordV1[]> {
|
|
215
215
|
if (!Array.isArray(messages) || messages.length === 0) return messages;
|
|
216
216
|
|
|
217
217
|
const root = path.resolve(String(projectRoot || "").trim() || process.cwd());
|
|
218
|
-
const out:
|
|
218
|
+
const out: SessionMessageRecordV1[] = [];
|
|
219
219
|
|
|
220
220
|
for (const message of messages) {
|
|
221
221
|
if (!message || typeof message !== "object" || message.role !== "user") {
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
type ToolSet,
|
|
16
16
|
} from "ai";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
type
|
|
20
|
-
} from "@/executor/types/
|
|
18
|
+
is_session_message_record,
|
|
19
|
+
type SessionRecordV1,
|
|
20
|
+
} from "@/executor/types/SessionRecords.js";
|
|
21
21
|
import {
|
|
22
22
|
hydrateFileUrlPartsForModel,
|
|
23
23
|
injectFilePartsFromAttachments,
|
|
@@ -28,19 +28,19 @@ import {
|
|
|
28
28
|
*
|
|
29
29
|
* 关键点(中文)
|
|
30
30
|
* - 用途:从 onStepCallback 返回的消息里挑出可并入推理上下文的 user 文本。
|
|
31
|
-
* - 输入:任意
|
|
31
|
+
* - 输入:任意 SessionRecordV1[](可能混有 assistant/tool/action/空消息)。
|
|
32
32
|
* - 输出:只包含“非空 user 文本”的消息数组。
|
|
33
33
|
*/
|
|
34
34
|
export function pickMergedUserMessages(
|
|
35
|
-
messages:
|
|
36
|
-
):
|
|
35
|
+
messages: SessionRecordV1[],
|
|
36
|
+
): SessionRecordV1[] {
|
|
37
37
|
// 如果不是数组,直接返回空数组,避免后续 filter 报错。
|
|
38
38
|
if (!Array.isArray(messages)) return [];
|
|
39
39
|
|
|
40
40
|
// 逐条过滤消息。
|
|
41
41
|
return messages.filter((message) => {
|
|
42
42
|
// 防御 1:消息必须是对象。
|
|
43
|
-
if (!message
|
|
43
|
+
if (!is_session_message_record(message)) return false;
|
|
44
44
|
|
|
45
45
|
// 防御 2:只接受 user 角色。
|
|
46
46
|
if (message.role !== "user") return false;
|
|
@@ -73,15 +73,15 @@ export function pickMergedUserMessages(
|
|
|
73
73
|
* - 输出:可直接喂给 streamText 的 messages。
|
|
74
74
|
*/
|
|
75
75
|
export async function toModelMessages(
|
|
76
|
-
messages:
|
|
76
|
+
messages: SessionRecordV1[],
|
|
77
77
|
tools: Record<string, Tool>,
|
|
78
78
|
projectRoot?: string,
|
|
79
79
|
): Promise<ModelMessage[]> {
|
|
80
80
|
// 空输入快速返回,避免调用转换器的额外开销。
|
|
81
81
|
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
82
82
|
|
|
83
|
-
//
|
|
84
|
-
const model_messages = messages.filter(
|
|
83
|
+
// action record 只服务前端时间线,不能传入模型。
|
|
84
|
+
const model_messages = messages.filter(is_session_message_record);
|
|
85
85
|
if (model_messages.length === 0) return [];
|
|
86
86
|
|
|
87
87
|
// 第一步(中文):在 user 消息上注入 file parts(多模态附件)。
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
import { isTextUIPart } from "ai";
|
|
11
11
|
import type { Logger } from "@/utils/logger/Logger.js";
|
|
12
|
-
import type {
|
|
12
|
+
import type { SessionMessageRecordV1 } from "@/executor/types/SessionRecords.js";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* 从 UI message 中提取 assistant 文本部分。
|
|
16
16
|
*/
|
|
17
17
|
export function extractAssistantTextForLog(
|
|
18
|
-
message:
|
|
18
|
+
message: SessionMessageRecordV1,
|
|
19
19
|
): string {
|
|
20
20
|
if (!Array.isArray(message.parts)) return "";
|
|
21
21
|
return message.parts
|
|
@@ -30,7 +30,7 @@ export function extractAssistantTextForLog(
|
|
|
30
30
|
*/
|
|
31
31
|
export async function logAssistantMessageNow(
|
|
32
32
|
logger: Logger,
|
|
33
|
-
message:
|
|
33
|
+
message: SessionMessageRecordV1,
|
|
34
34
|
): Promise<void> {
|
|
35
35
|
const text = extractAssistantTextForLog(message) || "-";
|
|
36
36
|
const normalized = text.replace(/\r\n/g, "\n");
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - 每个 step 前插入 `step-start`,便于在 UI 中保留多 step 边界。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { SessionMessageRecordV1 } from "@/executor/types/SessionRecords.js";
|
|
11
11
|
|
|
12
12
|
type UnknownRecord = Record<string, unknown>;
|
|
13
13
|
|
|
@@ -112,8 +112,8 @@ export function buildSessionStepParts(params: {
|
|
|
112
112
|
stepResult?: unknown;
|
|
113
113
|
text: string;
|
|
114
114
|
visibility?: "visible" | "internal";
|
|
115
|
-
}):
|
|
116
|
-
const out:
|
|
115
|
+
}): SessionMessageRecordV1["parts"] {
|
|
116
|
+
const out: SessionMessageRecordV1["parts"] = [];
|
|
117
117
|
const stepRecord = toRecord(params.stepResult) || {};
|
|
118
118
|
const toolCalls = Array.isArray(stepRecord.toolCalls) ? stepRecord.toolCalls : [];
|
|
119
119
|
const toolResults = Array.isArray(stepRecord.toolResults)
|
|
@@ -171,7 +171,7 @@ export function buildSessionStepParts(params: {
|
|
|
171
171
|
state: "output-available",
|
|
172
172
|
output,
|
|
173
173
|
}),
|
|
174
|
-
} as
|
|
174
|
+
} as SessionMessageRecordV1["parts"][number],
|
|
175
175
|
);
|
|
176
176
|
}
|
|
177
177
|
|
|
@@ -183,7 +183,7 @@ export function buildSessionStepParts(params: {
|
|
|
183
183
|
{
|
|
184
184
|
type: toDataPartType(type),
|
|
185
185
|
data: resolveAcpEventData(acpEvent),
|
|
186
|
-
} as
|
|
186
|
+
} as SessionMessageRecordV1["parts"][number],
|
|
187
187
|
);
|
|
188
188
|
}
|
|
189
189
|
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
type
|
|
13
|
-
type
|
|
14
|
-
} from "@/executor/types/
|
|
11
|
+
is_session_message_record,
|
|
12
|
+
type SessionRecordV1,
|
|
13
|
+
type SessionMessageRecordV1,
|
|
14
|
+
} from "@/executor/types/SessionRecords.js";
|
|
15
15
|
import {
|
|
16
16
|
extractTextFromUiMessage,
|
|
17
17
|
extractToolCallsFromUiMessage,
|
|
@@ -25,10 +25,10 @@ import {
|
|
|
25
25
|
* - 运行中 step/tool 的中断恢复由 inflight 快照承担,不再通过跳过最终 message 收口。
|
|
26
26
|
*/
|
|
27
27
|
export function resolveAssistantMessageForPersistence(
|
|
28
|
-
message:
|
|
29
|
-
):
|
|
28
|
+
message: SessionRecordV1 | null | undefined,
|
|
29
|
+
): SessionMessageRecordV1 | null {
|
|
30
30
|
if (!message || typeof message !== "object") return null;
|
|
31
|
-
if (!
|
|
31
|
+
if (!is_session_message_record(message)) return null;
|
|
32
32
|
return message;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -40,9 +40,9 @@ export function resolveAssistantMessageForPersistence(
|
|
|
40
40
|
* - 若无 tool call,则回退到 message 文本内容。
|
|
41
41
|
*/
|
|
42
42
|
export function pickLastSuccessfulChatSendText(
|
|
43
|
-
message:
|
|
43
|
+
message: SessionRecordV1 | null | undefined,
|
|
44
44
|
): string {
|
|
45
|
-
if (!
|
|
45
|
+
if (!is_session_message_record(message)) return "";
|
|
46
46
|
const toolCalls = extractToolCallsFromUiMessage(message);
|
|
47
47
|
// 关键点(中文):优先从 chat_send 的 input.text 还原"用户可见回复"。
|
|
48
48
|
for (let i = toolCalls.length - 1; i >= 0; i -= 1) {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import { generateId } from "@/utils/Id.js";
|
|
11
11
|
import type { SessionHistoryStore } from "@/executor/store/history/SessionHistoryStore.js";
|
|
12
|
-
import type {
|
|
12
|
+
import type { SessionMessageRecordV1 } from "@/executor/types/SessionRecords.js";
|
|
13
|
+
import { is_session_message_record } from "@/executor/types/SessionRecords.js";
|
|
13
14
|
|
|
14
15
|
interface ExecutorInflightServiceOptions {
|
|
15
16
|
/**
|
|
@@ -51,19 +52,22 @@ export class ExecutorInflightService {
|
|
|
51
52
|
* 把 step/tool 过程增量写入当前运行中的 assistant 快照。
|
|
52
53
|
*/
|
|
53
54
|
async append_assistant_step_parts(
|
|
54
|
-
parts:
|
|
55
|
+
parts: SessionMessageRecordV1["parts"],
|
|
55
56
|
): Promise<void> {
|
|
56
57
|
const normalized_parts = Array.isArray(parts)
|
|
57
58
|
? parts.filter((part) => part && typeof part === "object")
|
|
58
59
|
: [];
|
|
59
60
|
if (normalized_parts.length === 0) return;
|
|
60
61
|
|
|
61
|
-
const current_inflight = await this.history_store.
|
|
62
|
-
const
|
|
62
|
+
const current_inflight = await this.history_store.read_inflight();
|
|
63
|
+
const normalized_inflight = is_session_message_record(current_inflight)
|
|
64
|
+
? current_inflight
|
|
65
|
+
: null;
|
|
66
|
+
const next_message: SessionMessageRecordV1 = normalized_inflight
|
|
63
67
|
? {
|
|
64
|
-
...
|
|
68
|
+
...normalized_inflight,
|
|
65
69
|
metadata: {
|
|
66
|
-
...(
|
|
70
|
+
...(normalized_inflight.metadata || {
|
|
67
71
|
v: 1 as const,
|
|
68
72
|
ts: Date.now(),
|
|
69
73
|
sessionId: this.session_id,
|
|
@@ -74,8 +78,8 @@ export class ExecutorInflightService {
|
|
|
74
78
|
kind: "normal",
|
|
75
79
|
},
|
|
76
80
|
parts: [
|
|
77
|
-
...(Array.isArray(
|
|
78
|
-
?
|
|
81
|
+
...(Array.isArray(normalized_inflight.parts)
|
|
82
|
+
? normalized_inflight.parts
|
|
79
83
|
: []),
|
|
80
84
|
...normalized_parts,
|
|
81
85
|
],
|
|
@@ -93,7 +97,7 @@ export class ExecutorInflightService {
|
|
|
93
97
|
parts: normalized_parts,
|
|
94
98
|
};
|
|
95
99
|
|
|
96
|
-
await this.history_store.
|
|
100
|
+
await this.history_store.write_inflight(next_message);
|
|
97
101
|
if (this.run_after_session_updated_async) {
|
|
98
102
|
await this.run_after_session_updated_async();
|
|
99
103
|
}
|