@downcity/agent 1.1.198 → 1.1.200
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/executor/Executor.d.ts +2 -2
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +23 -24
- package/bin/executor/Executor.js.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 +2 -2
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +23 -30
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +2 -2
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +1 -1
- package/bin/executor/composer/context/LocalSessionContextComposer.js.map +1 -1
- package/bin/executor/composer/context/SessionContextComposer.d.ts +2 -2
- package/bin/executor/composer/context/SessionContextComposer.d.ts.map +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +1 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +4 -3
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.d.ts.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 +3 -3
- package/bin/executor/messages/AssistantResultPersistence.d.ts.map +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 +1 -1
- 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 +2 -2
- package/bin/executor/messages/UserVisibleText.d.ts.map +1 -1
- package/bin/executor/messages/UserVisibleText.js +5 -0
- 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 +9 -5
- package/bin/executor/services/ExecutorInflightService.js.map +1 -1
- package/bin/executor/store/history/SessionHistoryStore.d.ts +11 -11
- package/bin/executor/store/history/SessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +9 -7
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +98 -52
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/types/SessionMessages.d.ts +57 -18
- package/bin/executor/types/SessionMessages.d.ts.map +1 -1
- package/bin/executor/types/SessionMessages.js +33 -5
- package/bin/executor/types/SessionMessages.js.map +1 -1
- package/bin/executor/types/SessionRun.d.ts +2 -3
- package/bin/executor/types/SessionRun.d.ts.map +1 -1
- package/bin/index.d.ts +1 -1
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js.map +1 -1
- 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.map +1 -1
- package/bin/session/browse/Browse.js +36 -26
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts +2 -2
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +1 -1
- package/bin/session/runtime/SessionPromptRuntime.js.map +1 -1
- package/bin/session/services/SessionStateService.d.ts +10 -10
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +44 -53
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/session/services/SessionTurnService.d.ts.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.map +1 -1
- package/bin/session/services/SessionViewService.js +17 -27
- package/bin/session/services/SessionViewService.js.map +1 -1
- package/bin/session/storage/Persistence.d.ts +2 -2
- package/bin/session/storage/Persistence.d.ts.map +1 -1
- package/bin/session/storage/Persistence.js.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +10 -10
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +6 -6
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/sdk/AgentSessionAction.d.ts +67 -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/{session-operation-message.test.mjs → session-action-message.test.mjs} +58 -41
- package/src/executor/Executor.ts +28 -29
- 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 +32 -37
- package/src/executor/composer/context/LocalSessionContextComposer.ts +5 -2
- package/src/executor/composer/context/SessionContextComposer.ts +5 -2
- package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +7 -4
- package/src/executor/core-engine/CoreEngineRunner.ts +7 -4
- package/src/executor/core-engine/CoreEngineSignals.ts +7 -7
- package/src/executor/core-engine/CoreEngineUiStreamCollector.ts +5 -5
- package/src/executor/messages/AssistantResultPersistence.ts +6 -3
- package/src/executor/messages/SessionAttachmentMapper.ts +12 -9
- package/src/executor/messages/SessionMessageCodec.ts +5 -7
- package/src/executor/messages/SessionMessageLog.ts +5 -3
- package/src/executor/messages/SessionStepEventMapper.ts +5 -5
- package/src/executor/messages/UserVisibleText.ts +8 -2
- package/src/executor/services/ExecutorInflightService.ts +11 -7
- package/src/executor/store/history/SessionHistoryStore.ts +11 -10
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +120 -63
- package/src/executor/types/SessionMessages.ts +92 -22
- package/src/executor/types/SessionRun.ts +6 -3
- package/src/index.ts +5 -6
- package/src/session/SessionTitle.ts +3 -0
- package/src/session/browse/Browse.ts +49 -30
- package/src/session/runtime/SessionPromptRuntime.ts +6 -3
- package/src/session/services/SessionStateService.ts +56 -65
- package/src/session/services/SessionTurnService.ts +5 -4
- package/src/session/services/SessionViewService.ts +17 -27
- package/src/session/storage/Persistence.ts +5 -2
- package/src/types/agent/SessionTypes.ts +10 -10
- package/src/types/executor/SessionRunContext.ts +11 -11
- package/src/types/sdk/AgentSessionAction.ts +79 -0
- package/src/types/sdk/AgentSessionEvent.ts +2 -2
- package/src/types/sdk/AgentSessionTurn.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -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/src/types/sdk/AgentSessionOperation.ts +0 -125
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSessionEvent.d.ts","sourceRoot":"","sources":["../../../src/types/sdk/AgentSessionEvent.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"AgentSessionEvent.d.ts","sourceRoot":"","sources":["../../../src/types/sdk/AgentSessionEvent.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - 同一个 turn 可以吸收多条 prompt,因此多个 prompt 可能返回相同 `id` 的 turn handle。
|
|
7
7
|
* - 增量过程继续通过 `session.subscribe()` 观察;turn handle 只负责等待最终完成结果。
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
9
|
+
import type { SessionModelMessageV1 } from "../../executor/types/SessionMessages.js";
|
|
10
10
|
/**
|
|
11
11
|
* 单个 Session turn 的最终结果。
|
|
12
12
|
*/
|
|
@@ -30,7 +30,7 @@ export interface AgentSessionTurnResult {
|
|
|
30
30
|
* - `turn.finished` 返回的结果以这条消息作为最终事实源。
|
|
31
31
|
* - transport / runtime service 若需要读取最终结构化输出,应优先消费这里。
|
|
32
32
|
*/
|
|
33
|
-
assistantMessage?:
|
|
33
|
+
assistantMessage?: SessionModelMessageV1;
|
|
34
34
|
/**
|
|
35
35
|
* 当前 turn 失败时的错误文本。
|
|
36
36
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentSessionTurn.d.ts","sourceRoot":"","sources":["../../../src/types/sdk/AgentSessionTurn.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"AgentSessionTurn.d.ts","sourceRoot":"","sources":["../../../src/types/sdk/AgentSessionTurn.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IAEzC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;;;;OAMG;IACH,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAEtC;;;;;;OAMG;IACH,QAAQ,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC3C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@downcity/agent",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.200",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Downcity Agent 运行时 — 单 Agent 执行壳与本机 RPC 能力",
|
|
6
6
|
"main": "./bin/index.js",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@ai-sdk/openai-compatible": "^2.0.48",
|
|
20
|
-
"@downcity/shell": "^0.1.
|
|
21
|
-
"@downcity/type": "0.1.
|
|
20
|
+
"@downcity/shell": "^0.1.69",
|
|
21
|
+
"@downcity/type": "0.1.102",
|
|
22
22
|
"ai": "^6.0.193",
|
|
23
23
|
"commander": "^15.0.0",
|
|
24
24
|
"dotenv": "^17.4.2",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file 验证
|
|
2
|
+
* @file 验证 action message 的持久化、模型输入过滤与 timeline 投影。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
5
|
+
* - action message 会作为 `type=action` item 写入 JSONL。
|
|
6
|
+
* - 同一个 action id 会被更新为一条历史记录,不拆成 running/completed 多条。
|
|
7
|
+
* - history composer 组装 LLM 输入时必须过滤 action message。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import test from "node:test";
|
|
@@ -18,14 +18,14 @@ import { JsonlSessionHistoryComposer } from "../bin/executor/composer/history/js
|
|
|
18
18
|
import { toSessionTimelineEvents } from "../bin/session/browse/Browse.js";
|
|
19
19
|
import { Agent } from "../bin/index.js";
|
|
20
20
|
|
|
21
|
-
test("
|
|
21
|
+
test("action message is upserted but filtered from LLM history", async () => {
|
|
22
22
|
const root_path = await fs.mkdtemp(
|
|
23
|
-
path.join(os.tmpdir(), "downcity-agent-
|
|
23
|
+
path.join(os.tmpdir(), "downcity-agent-action-message-"),
|
|
24
24
|
);
|
|
25
|
-
const session_id = "
|
|
25
|
+
const session_id = "action_session";
|
|
26
26
|
const store = new JsonlSessionHistoryStore({
|
|
27
27
|
rootPath: root_path,
|
|
28
|
-
agentId: "
|
|
28
|
+
agentId: "action_agent",
|
|
29
29
|
sessionId: session_id,
|
|
30
30
|
});
|
|
31
31
|
const composer = new JsonlSessionHistoryComposer({ store });
|
|
@@ -38,16 +38,26 @@ test("operation message is persisted but filtered from LLM history", async () =>
|
|
|
38
38
|
}),
|
|
39
39
|
);
|
|
40
40
|
await store.append(
|
|
41
|
-
store.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
store.action({
|
|
42
|
+
action: {
|
|
43
|
+
id: "action:1",
|
|
44
|
+
title: "Compacting session history",
|
|
45
|
+
state: "running",
|
|
46
|
+
turnId: "turn-1",
|
|
47
|
+
},
|
|
48
|
+
metadata: { sessionId: session_id },
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
await store.append(
|
|
52
|
+
store.action({
|
|
53
|
+
action: {
|
|
54
|
+
id: "action:1",
|
|
55
|
+
title: "Session history compacted",
|
|
56
|
+
description: "Compacted earlier messages.",
|
|
57
|
+
state: "completed",
|
|
47
58
|
turnId: "turn-1",
|
|
48
59
|
},
|
|
49
60
|
metadata: { sessionId: session_id },
|
|
50
|
-
id: "op:1",
|
|
51
61
|
}),
|
|
52
62
|
);
|
|
53
63
|
await store.append(
|
|
@@ -60,8 +70,10 @@ test("operation message is persisted but filtered from LLM history", async () =>
|
|
|
60
70
|
|
|
61
71
|
const persisted_messages = await store.list();
|
|
62
72
|
assert.equal(persisted_messages.length, 3);
|
|
63
|
-
assert.equal(persisted_messages[1].
|
|
64
|
-
assert.equal(persisted_messages[1].
|
|
73
|
+
assert.equal(persisted_messages[1].type, "action");
|
|
74
|
+
assert.equal(persisted_messages[1].title, "Session history compacted");
|
|
75
|
+
assert.equal(persisted_messages[1].description, "Compacted earlier messages.");
|
|
76
|
+
assert.equal(persisted_messages[1].state, "completed");
|
|
65
77
|
|
|
66
78
|
const model_messages = await composer.prepare({
|
|
67
79
|
query: "",
|
|
@@ -77,14 +89,17 @@ test("operation message is persisted but filtered from LLM history", async () =>
|
|
|
77
89
|
|
|
78
90
|
const timeline_events = toSessionTimelineEvents(persisted_messages[1]);
|
|
79
91
|
assert.equal(timeline_events.length, 1);
|
|
80
|
-
assert.equal(timeline_events[0].role, "
|
|
81
|
-
assert.equal(timeline_events[0].
|
|
82
|
-
assert.equal(timeline_events[0].
|
|
83
|
-
assert.equal(timeline_events[0].
|
|
84
|
-
assert.equal(
|
|
92
|
+
assert.equal(timeline_events[0].role, "action");
|
|
93
|
+
assert.equal(timeline_events[0].actionTitle, "Session history compacted");
|
|
94
|
+
assert.equal(timeline_events[0].actionDescription, "Compacted earlier messages.");
|
|
95
|
+
assert.equal(timeline_events[0].actionState, "completed");
|
|
96
|
+
assert.equal(
|
|
97
|
+
timeline_events[0].text,
|
|
98
|
+
"Session history compacted\nCompacted earlier messages.",
|
|
99
|
+
);
|
|
85
100
|
});
|
|
86
101
|
|
|
87
|
-
test("session.set persists and publishes model-switching
|
|
102
|
+
test("session.set persists and publishes model-switching actions", async () => {
|
|
88
103
|
const agent_path = await fs.mkdtemp(
|
|
89
104
|
path.join(os.tmpdir(), "downcity-agent-model-switching-"),
|
|
90
105
|
);
|
|
@@ -98,7 +113,7 @@ test("session.set persists and publishes model-switching operations", async () =
|
|
|
98
113
|
});
|
|
99
114
|
const events = [];
|
|
100
115
|
const unsubscribe = session.subscribe((event) => {
|
|
101
|
-
if (event.type === "
|
|
116
|
+
if (event.type === "action") events.push(event);
|
|
102
117
|
});
|
|
103
118
|
|
|
104
119
|
await session.set({
|
|
@@ -110,24 +125,25 @@ test("session.set persists and publishes model-switching operations", async () =
|
|
|
110
125
|
unsubscribe();
|
|
111
126
|
|
|
112
127
|
assert.deepEqual(
|
|
113
|
-
events.map((event) => `${event.
|
|
114
|
-
["model
|
|
128
|
+
events.map((event) => `${event.title}:${event.state}`),
|
|
129
|
+
["Switching session model:running", "Session model switched:completed"],
|
|
115
130
|
);
|
|
131
|
+
assert.equal(new Set(events.map((event) => event.id)).size, 1);
|
|
116
132
|
|
|
117
133
|
const history = await session.history({ view: "timeline" });
|
|
118
|
-
const
|
|
119
|
-
(item) => item.role === "
|
|
134
|
+
const action_events = history.items.filter(
|
|
135
|
+
(item) => item.role === "action",
|
|
120
136
|
);
|
|
121
137
|
assert.deepEqual(
|
|
122
|
-
|
|
123
|
-
["model
|
|
138
|
+
action_events.map((event) => `${event.actionTitle}:${event.actionState}`),
|
|
139
|
+
["Session model switched:completed"],
|
|
124
140
|
);
|
|
125
141
|
} finally {
|
|
126
142
|
await agent.dispose();
|
|
127
143
|
}
|
|
128
144
|
});
|
|
129
145
|
|
|
130
|
-
test("session.fork persists and publishes history-forking
|
|
146
|
+
test("session.fork persists and publishes history-forking actions on source session", async () => {
|
|
131
147
|
const agent_path = await fs.mkdtemp(
|
|
132
148
|
path.join(os.tmpdir(), "downcity-agent-history-forking-"),
|
|
133
149
|
);
|
|
@@ -149,7 +165,7 @@ test("session.fork persists and publishes history-forking operations on source s
|
|
|
149
165
|
|
|
150
166
|
const events = [];
|
|
151
167
|
const unsubscribe = session.subscribe((event) => {
|
|
152
|
-
if (event.type === "
|
|
168
|
+
if (event.type === "action") {
|
|
153
169
|
events.push(event);
|
|
154
170
|
}
|
|
155
171
|
});
|
|
@@ -157,25 +173,26 @@ test("session.fork persists and publishes history-forking operations on source s
|
|
|
157
173
|
unsubscribe();
|
|
158
174
|
|
|
159
175
|
assert.deepEqual(
|
|
160
|
-
events.map((event) => `${event.
|
|
161
|
-
["history
|
|
176
|
+
events.map((event) => `${event.title}:${event.state}`),
|
|
177
|
+
["Forking session history:running", "Session history forked:completed"],
|
|
162
178
|
);
|
|
179
|
+
assert.equal(new Set(events.map((event) => event.id)).size, 1);
|
|
163
180
|
assert.notEqual(forked.id, session.id);
|
|
164
181
|
|
|
165
182
|
const source_history = await session.history({ view: "timeline" });
|
|
166
|
-
const
|
|
167
|
-
(item) => item.
|
|
183
|
+
const source_fork_actions = source_history.items.filter(
|
|
184
|
+
(item) => item.role === "action" && item.actionTitle === "Session history forked",
|
|
168
185
|
);
|
|
169
186
|
assert.deepEqual(
|
|
170
|
-
|
|
171
|
-
["
|
|
187
|
+
source_fork_actions.map((event) => event.actionState),
|
|
188
|
+
["completed"],
|
|
172
189
|
);
|
|
173
190
|
|
|
174
191
|
const forked_history = await forked.history({ view: "timeline" });
|
|
175
|
-
const
|
|
176
|
-
(item) => item.
|
|
192
|
+
const forked_model_actions = forked_history.items.filter(
|
|
193
|
+
(item) => item.role === "action" && item.actionTitle === "Session model switched",
|
|
177
194
|
);
|
|
178
|
-
assert.equal(
|
|
195
|
+
assert.equal(forked_model_actions.length, 1);
|
|
179
196
|
} finally {
|
|
180
197
|
await agent.dispose();
|
|
181
198
|
}
|
package/src/executor/Executor.ts
CHANGED
|
@@ -28,7 +28,7 @@ import type { JsonObject } from "@/types/common/Json.js";
|
|
|
28
28
|
import type { SessionMessageV1 } from "@/executor/types/SessionMessages.js";
|
|
29
29
|
import type { SessionExecutor } from "@/executor/types/SessionExecutor.js";
|
|
30
30
|
import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
|
|
31
|
-
import type {
|
|
31
|
+
import type { AgentSessionActionRecord } from "@/types/sdk/AgentSessionAction.js";
|
|
32
32
|
import type {
|
|
33
33
|
SessionExecuteInput,
|
|
34
34
|
SessionRunResult,
|
|
@@ -362,7 +362,7 @@ export class Executor implements SessionExecutor {
|
|
|
362
362
|
const composed_context = await this.contextComposer.compose(run_context);
|
|
363
363
|
const tools = this.bind_run_scope_to_tools(composed_context.tools, run_context);
|
|
364
364
|
const system = await this.systemComposer.resolve(run_context);
|
|
365
|
-
let
|
|
365
|
+
let compaction_action_id = "";
|
|
366
366
|
|
|
367
367
|
try {
|
|
368
368
|
if (retry_count > 0) {
|
|
@@ -371,13 +371,13 @@ export class Executor implements SessionExecutor {
|
|
|
371
371
|
});
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
-
const
|
|
375
|
-
|
|
374
|
+
const emit_compaction_action = async (
|
|
375
|
+
action: AgentSessionActionRecord,
|
|
376
376
|
): Promise<void> => {
|
|
377
|
-
if (
|
|
378
|
-
|
|
377
|
+
if (action.state === "running") {
|
|
378
|
+
compaction_action_id = action.id;
|
|
379
379
|
}
|
|
380
|
-
await this.
|
|
380
|
+
await this.emitAction(run_context, action);
|
|
381
381
|
};
|
|
382
382
|
|
|
383
383
|
await this.compactionComposer.run({
|
|
@@ -385,17 +385,16 @@ export class Executor implements SessionExecutor {
|
|
|
385
385
|
model,
|
|
386
386
|
system,
|
|
387
387
|
retryCount: retry_count,
|
|
388
|
-
|
|
388
|
+
onAction: emit_compaction_action,
|
|
389
389
|
});
|
|
390
390
|
} catch (error) {
|
|
391
|
-
await this.
|
|
392
|
-
|
|
393
|
-
|
|
391
|
+
await this.emitAction(run_context, {
|
|
392
|
+
id:
|
|
393
|
+
compaction_action_id ||
|
|
394
394
|
`compacting:${this.sessionId}:failed:${Date.now()}:${generateId()}`,
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
error: error instanceof Error ? error.message : String(error),
|
|
395
|
+
title: "Session history compact failed",
|
|
396
|
+
description: error instanceof Error ? error.message : String(error),
|
|
397
|
+
state: "failed",
|
|
399
398
|
visible: false,
|
|
400
399
|
});
|
|
401
400
|
// 压缩失败不阻断主流程,继续使用当前历史消息执行。
|
|
@@ -492,8 +491,8 @@ export class Executor implements SessionExecutor {
|
|
|
492
491
|
...(typeof input?.onUiMessageChunkCallback === "function"
|
|
493
492
|
? { onUiMessageChunkCallback: input.onUiMessageChunkCallback }
|
|
494
493
|
: {}),
|
|
495
|
-
...(typeof input?.
|
|
496
|
-
? {
|
|
494
|
+
...(typeof input?.onActionCallback === "function"
|
|
495
|
+
? { onActionCallback: input.onActionCallback }
|
|
497
496
|
: {}),
|
|
498
497
|
...(input?.abortSignal ? { abortSignal: input.abortSignal } : {}),
|
|
499
498
|
injectedUserMessages: Array.isArray(input?.injectedUserMessages)
|
|
@@ -511,22 +510,22 @@ export class Executor implements SessionExecutor {
|
|
|
511
510
|
}
|
|
512
511
|
|
|
513
512
|
/**
|
|
514
|
-
* 发布一次 session
|
|
513
|
+
* 发布一次 session action。
|
|
515
514
|
*/
|
|
516
|
-
private async
|
|
515
|
+
private async emitAction(
|
|
517
516
|
run_context: SessionRunContext,
|
|
518
|
-
|
|
517
|
+
action: AgentSessionActionRecord,
|
|
519
518
|
): Promise<void> {
|
|
520
|
-
if (typeof run_context.
|
|
521
|
-
const
|
|
522
|
-
String(
|
|
523
|
-
`
|
|
524
|
-
await run_context.
|
|
525
|
-
type: "
|
|
519
|
+
if (typeof run_context.onActionCallback !== "function") return;
|
|
520
|
+
const action_id =
|
|
521
|
+
String(action.id || "").trim() ||
|
|
522
|
+
`action:${this.sessionId}:${Date.now()}:${generateId()}`;
|
|
523
|
+
await run_context.onActionCallback({
|
|
524
|
+
type: "action",
|
|
526
525
|
sessionId: run_context.sessionId || this.sessionId,
|
|
527
|
-
...
|
|
528
|
-
|
|
529
|
-
...(run_context.turnId && !
|
|
526
|
+
...action,
|
|
527
|
+
id: action_id,
|
|
528
|
+
...(run_context.turnId && !action.turnId
|
|
530
529
|
? { turnId: run_context.turnId }
|
|
531
530
|
: {}),
|
|
532
531
|
});
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { LanguageModel, SystemModelMessage } from "ai";
|
|
10
10
|
import type { SessionHistoryStore } from "@/executor/store/history/SessionHistoryStore.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type { AgentSessionActionRecord } from "@/types/sdk/AgentSessionAction.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* compaction Composer 执行输入。
|
|
@@ -35,13 +35,13 @@ export type SessionCompactionInput = {
|
|
|
35
35
|
retryCount: number;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* 可选
|
|
38
|
+
* 可选 action 发布回调。
|
|
39
39
|
*
|
|
40
40
|
* 说明(中文)
|
|
41
|
-
* - 默认 compaction Composer 可在真正开始压缩时发布
|
|
42
|
-
* - 回调由上层 Session 负责转成订阅事件与
|
|
41
|
+
* - 默认 compaction Composer 可在真正开始压缩时发布 action。
|
|
42
|
+
* - 回调由上层 Session 负责转成订阅事件与 action message。
|
|
43
43
|
*/
|
|
44
|
-
|
|
44
|
+
onAction?: (action: AgentSessionActionRecord) => Promise<void>;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -79,7 +79,7 @@ export class JsonlSessionCompactionComposer implements SessionCompactionComposer
|
|
|
79
79
|
maxInputTokensApprox: policy.maxInputTokensApprox,
|
|
80
80
|
archiveOnCompact: policy.archiveOnCompact,
|
|
81
81
|
compactRatio: policy.compactRatio,
|
|
82
|
-
...(input.
|
|
82
|
+
...(input.onAction ? { onAction: input.onAction } : {}),
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -20,10 +20,14 @@ import { getLogger } from "@/utils/logger/Logger.js";
|
|
|
20
20
|
import type {
|
|
21
21
|
SessionMessageV1,
|
|
22
22
|
SessionMetadataV1,
|
|
23
|
+
SessionModelMessageV1,
|
|
24
|
+
} from "@/executor/types/SessionMessages.js";
|
|
25
|
+
import {
|
|
26
|
+
isSessionActionMessage,
|
|
27
|
+
isSessionModelMessage,
|
|
23
28
|
} from "@/executor/types/SessionMessages.js";
|
|
24
|
-
import { isSessionOperationMessage } from "@/executor/types/SessionMessages.js";
|
|
25
29
|
import type { SessionHistoryMetaV1 } from "@/executor/types/SessionHistoryMeta.js";
|
|
26
|
-
import type {
|
|
30
|
+
import type { AgentSessionActionRecord } from "@/types/sdk/AgentSessionAction.js";
|
|
27
31
|
|
|
28
32
|
export type SessionCompactParams = {
|
|
29
33
|
model: LanguageModel;
|
|
@@ -32,7 +36,7 @@ export type SessionCompactParams = {
|
|
|
32
36
|
maxInputTokensApprox: number;
|
|
33
37
|
archiveOnCompact: boolean;
|
|
34
38
|
compactRatio: number;
|
|
35
|
-
|
|
39
|
+
onAction?: (action: AgentSessionActionRecord) => Promise<void>;
|
|
36
40
|
};
|
|
37
41
|
|
|
38
42
|
type SessionCompactDeps = {
|
|
@@ -63,17 +67,16 @@ export async function compactSessionMessagesIfNeeded(
|
|
|
63
67
|
params: SessionCompactParams,
|
|
64
68
|
): Promise<{ compacted: boolean; reason?: string }> {
|
|
65
69
|
const logger = getLogger(deps.rootPath, "info");
|
|
66
|
-
const
|
|
67
|
-
let
|
|
70
|
+
const action_id = `compacting:${deps.sessionId}:${Date.now()}:${generateId()}`;
|
|
71
|
+
let action_started = false;
|
|
68
72
|
|
|
69
|
-
const
|
|
70
|
-
|
|
73
|
+
const publish_action = async (
|
|
74
|
+
action: Omit<AgentSessionActionRecord, "id">,
|
|
71
75
|
): Promise<void> => {
|
|
72
|
-
if (typeof params.
|
|
73
|
-
await params.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
...operation,
|
|
76
|
+
if (typeof params.onAction !== "function") return;
|
|
77
|
+
await params.onAction({
|
|
78
|
+
id: action_id,
|
|
79
|
+
...action,
|
|
77
80
|
});
|
|
78
81
|
};
|
|
79
82
|
|
|
@@ -81,12 +84,10 @@ export async function compactSessionMessagesIfNeeded(
|
|
|
81
84
|
// phase 1:snapshot(短锁)
|
|
82
85
|
// - 仅负责拿一致性快照,不做耗时的模型调用。
|
|
83
86
|
// - 目的是把锁持有时间降到最低。
|
|
84
|
-
let snapshot:
|
|
87
|
+
let snapshot: SessionModelMessageV1[] = [];
|
|
85
88
|
let snapshotTailId = "";
|
|
86
89
|
await deps.withWriteLock(async () => {
|
|
87
|
-
snapshot = (await deps.loadAll()).filter(
|
|
88
|
-
(message) => !isSessionOperationMessage(message),
|
|
89
|
-
);
|
|
90
|
+
snapshot = (await deps.loadAll()).filter(isSessionModelMessage);
|
|
90
91
|
snapshotTailId =
|
|
91
92
|
snapshot.length > 0
|
|
92
93
|
? String(snapshot[snapshot.length - 1].id || "")
|
|
@@ -118,11 +119,10 @@ export async function compactSessionMessagesIfNeeded(
|
|
|
118
119
|
const older = snapshot.slice(0, compactCount);
|
|
119
120
|
if (older.length === 0) return { compacted: false, reason: "nothing_to_compact" };
|
|
120
121
|
|
|
121
|
-
|
|
122
|
-
await
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
progress: 0,
|
|
122
|
+
action_started = true;
|
|
123
|
+
await publish_action({
|
|
124
|
+
title: "Compacting session history",
|
|
125
|
+
state: "running",
|
|
126
126
|
});
|
|
127
127
|
|
|
128
128
|
const olderTextAll = extractPlainTextFromMessages(older);
|
|
@@ -163,11 +163,10 @@ export async function compactSessionMessagesIfNeeded(
|
|
|
163
163
|
},
|
|
164
164
|
);
|
|
165
165
|
summary = "(系统自动压缩:摘要生成失败,已丢弃更早历史,仅保留最近对话。)";
|
|
166
|
-
await
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
progress: 0.5,
|
|
166
|
+
await publish_action({
|
|
167
|
+
title: "Compacting session history",
|
|
168
|
+
description: "Summary generation failed; using a fallback summary.",
|
|
169
|
+
state: "running",
|
|
171
170
|
});
|
|
172
171
|
}
|
|
173
172
|
|
|
@@ -191,7 +190,7 @@ export async function compactSessionMessagesIfNeeded(
|
|
|
191
190
|
void snapshotTailId;
|
|
192
191
|
|
|
193
192
|
const current_model_messages = current.filter(
|
|
194
|
-
|
|
193
|
+
isSessionModelMessage,
|
|
195
194
|
);
|
|
196
195
|
const currentCompactCount = resolveCompactCount(
|
|
197
196
|
current_model_messages.length,
|
|
@@ -242,15 +241,11 @@ export async function compactSessionMessagesIfNeeded(
|
|
|
242
241
|
});
|
|
243
242
|
});
|
|
244
243
|
|
|
245
|
-
if (
|
|
246
|
-
await
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
result: {
|
|
251
|
-
archiveId,
|
|
252
|
-
compactedCount: older.length,
|
|
253
|
-
},
|
|
244
|
+
if (action_started) {
|
|
245
|
+
await publish_action({
|
|
246
|
+
title: "Session history compacted",
|
|
247
|
+
description: `Compacted ${String(older.length)} earlier messages into ${archiveId}.`,
|
|
248
|
+
state: "completed",
|
|
254
249
|
});
|
|
255
250
|
}
|
|
256
251
|
|
|
@@ -302,7 +297,7 @@ function estimateTokensApproxFromText(text: string): number {
|
|
|
302
297
|
* - 统一把 user / assistant 内容线性化,作为 compact 摘要输入。
|
|
303
298
|
* - tool 原始结构不会原样输出,避免把噪声日志喂给摘要模型。
|
|
304
299
|
*/
|
|
305
|
-
function extractPlainTextFromMessages(messages:
|
|
300
|
+
function extractPlainTextFromMessages(messages: SessionModelMessageV1[]): string {
|
|
306
301
|
const lines: string[] = [];
|
|
307
302
|
for (const m of messages) {
|
|
308
303
|
if (!m || typeof m !== "object") continue;
|
|
@@ -12,7 +12,10 @@ import type {
|
|
|
12
12
|
SessionContextComposer,
|
|
13
13
|
SessionContextComposeResult,
|
|
14
14
|
} from "@executor/composer/context/SessionContextComposer.js";
|
|
15
|
-
import type {
|
|
15
|
+
import type {
|
|
16
|
+
SessionMessageV1,
|
|
17
|
+
SessionModelMessageV1,
|
|
18
|
+
} from "@/executor/types/SessionMessages.js";
|
|
16
19
|
import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
|
|
17
20
|
import type { Tool } from "ai";
|
|
18
21
|
import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
|
|
@@ -147,7 +150,7 @@ export class LocalSessionContextComposer implements SessionContextComposer {
|
|
|
147
150
|
buildFallbackAssistantMessage(
|
|
148
151
|
text: string,
|
|
149
152
|
run_context: SessionRunContext,
|
|
150
|
-
):
|
|
153
|
+
): SessionModelMessageV1 {
|
|
151
154
|
const sessionId = String(
|
|
152
155
|
run_context.sessionId || this.sessionId || "",
|
|
153
156
|
).trim();
|
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { ModelMessage, Tool } from "ai";
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
SessionMessageV1,
|
|
12
|
+
SessionModelMessageV1,
|
|
13
|
+
} from "@/executor/types/SessionMessages.js";
|
|
11
14
|
import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
|
|
12
15
|
import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
|
|
13
16
|
|
|
@@ -76,5 +79,5 @@ export interface SessionContextComposer {
|
|
|
76
79
|
buildFallbackAssistantMessage(
|
|
77
80
|
text: string,
|
|
78
81
|
run_context: SessionRunContext,
|
|
79
|
-
):
|
|
82
|
+
): SessionModelMessageV1;
|
|
80
83
|
}
|
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Tool } from "ai";
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
isSessionActionMessage,
|
|
13
|
+
isSessionModelMessage,
|
|
13
14
|
type SessionMessageV1,
|
|
15
|
+
type SessionModelMessageV1,
|
|
14
16
|
} from "@/executor/types/SessionMessages.js";
|
|
15
17
|
import type { SessionHistoryStore } from "@/executor/store/history/SessionHistoryStore.js";
|
|
16
18
|
import type {
|
|
@@ -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: SessionModelMessageV1): string {
|
|
53
55
|
if (!message || typeof message !== "object" || message.role !== "user") {
|
|
54
56
|
return "";
|
|
55
57
|
}
|
|
@@ -76,7 +78,7 @@ 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 (!isSessionModelMessage(item) || item.role !== "user") continue;
|
|
80
82
|
return this.readUserSessionMessageText(item) === target;
|
|
81
83
|
}
|
|
82
84
|
return false;
|
|
@@ -85,6 +87,8 @@ export class JsonlSessionHistoryComposer implements SessionHistoryComposer {
|
|
|
85
87
|
private sanitizeMessages(messages: SessionMessageV1[]): SessionMessageV1[] {
|
|
86
88
|
if (!Array.isArray(messages)) return [];
|
|
87
89
|
return messages
|
|
90
|
+
.filter((message) => !isSessionActionMessage(message))
|
|
91
|
+
.filter(isSessionModelMessage)
|
|
88
92
|
.map((message) => {
|
|
89
93
|
const parts = Array.isArray(message.parts)
|
|
90
94
|
? message.parts.filter((part) => part && typeof part === "object")
|
|
@@ -94,7 +98,6 @@ 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
|
|
|
@@ -41,7 +41,10 @@ import type {
|
|
|
41
41
|
SessionExecuteInput,
|
|
42
42
|
SessionRunResult,
|
|
43
43
|
} from "@/executor/types/SessionRun.js";
|
|
44
|
-
import type {
|
|
44
|
+
import type {
|
|
45
|
+
SessionMessageV1,
|
|
46
|
+
SessionModelMessageV1,
|
|
47
|
+
} from "@/executor/types/SessionMessages.js";
|
|
45
48
|
|
|
46
49
|
const TURN_STOPPED_MESSAGE = "Turn stopped";
|
|
47
50
|
|
|
@@ -61,9 +64,9 @@ function build_file_part_key(part: FileUIPart): string {
|
|
|
61
64
|
* 把 tool/plugin 运行期产生的 file parts 并入最终 assistant UIMessage。
|
|
62
65
|
*/
|
|
63
66
|
function mergePendingAssistantFileParts(
|
|
64
|
-
message:
|
|
67
|
+
message: SessionModelMessageV1,
|
|
65
68
|
parts: FileUIPart[],
|
|
66
|
-
):
|
|
69
|
+
): SessionModelMessageV1 {
|
|
67
70
|
if (!Array.isArray(parts) || parts.length === 0) return message;
|
|
68
71
|
const current_parts = Array.isArray(message.parts) ? message.parts : [];
|
|
69
72
|
const seen = new Set<string>();
|
|
@@ -151,7 +154,7 @@ export class CoreEngineRunner {
|
|
|
151
154
|
: [];
|
|
152
155
|
const tools = input.execute_input.tools;
|
|
153
156
|
let last_observed_stream_error: unknown = undefined;
|
|
154
|
-
let final_assistant_ui_message:
|
|
157
|
+
let final_assistant_ui_message: SessionModelMessageV1 | null = null;
|
|
155
158
|
|
|
156
159
|
try {
|
|
157
160
|
const message_state = await CoreEngineMessageState.create({
|