@downcity/agent 1.1.208 → 1.1.210
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 -3
- package/bin/agent/local/Agent.d.ts.map +1 -1
- package/bin/agent/local/Agent.js +0 -3
- package/bin/agent/local/Agent.js.map +1 -1
- package/bin/agent/local/AgentInstructions.d.ts +1 -1
- package/bin/agent/local/AgentInstructions.d.ts.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.d.ts +3 -8
- package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.js +0 -1
- package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
- package/bin/agent/local/services/AgentSessions.d.ts +5 -7
- package/bin/agent/local/services/AgentSessions.d.ts.map +1 -1
- package/bin/agent/local/services/AgentSessions.js +2 -3
- package/bin/agent/local/services/AgentSessions.js.map +1 -1
- package/bin/agent/remote/RemoteAgent.d.ts +3 -1
- package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
- package/bin/agent/remote/RemoteAgent.js.map +1 -1
- package/bin/agent/remote/RemoteSession.d.ts +10 -1
- package/bin/agent/remote/RemoteSession.d.ts.map +1 -1
- package/bin/agent/remote/RemoteSession.js +18 -0
- package/bin/agent/remote/RemoteSession.js.map +1 -1
- package/bin/agent/remote/RemoteTransport.d.ts +5 -1
- package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +4 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +7 -0
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +4 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +1 -0
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
- package/bin/executor/Executor.d.ts +0 -16
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +0 -16
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +1 -3
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +1 -5
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/composer/history/SessionHistoryWriter.d.ts +0 -10
- package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +1 -1
- package/bin/executor/composer/history/SessionHistoryWriter.js +31 -61
- package/bin/executor/composer/history/SessionHistoryWriter.js.map +1 -1
- package/bin/executor/messages/AssistantFileResource.d.ts.map +1 -1
- package/bin/executor/messages/AssistantFileResource.js +58 -15
- package/bin/executor/messages/AssistantFileResource.js.map +1 -1
- package/bin/executor/services/ExecutorInflightService.d.ts +0 -5
- package/bin/executor/services/ExecutorInflightService.d.ts.map +1 -1
- package/bin/executor/services/ExecutorInflightService.js +0 -6
- package/bin/executor/services/ExecutorInflightService.js.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +4 -0
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +115 -3
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/types/SessionHistoryMeta.d.ts +6 -0
- package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
- package/bin/index.d.ts +38 -6
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +14 -1
- package/bin/index.js.map +1 -1
- package/bin/plugin/core/ActionScheduleExecutor.js +1 -1
- package/bin/plugin/core/ActionScheduleExecutor.js.map +1 -1
- package/bin/plugin/core/BasePlugin.d.ts +7 -9
- package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
- package/bin/plugin/core/BasePlugin.js +1 -14
- package/bin/plugin/core/BasePlugin.js.map +1 -1
- package/bin/plugin/core/HookRegistry.d.ts +1 -1
- package/bin/plugin/core/HookRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginActionFactory.d.ts +1 -5
- package/bin/plugin/core/PluginActionFactory.d.ts.map +1 -1
- package/bin/plugin/core/PluginActionFactory.js +0 -3
- package/bin/plugin/core/PluginActionFactory.js.map +1 -1
- package/bin/plugin/core/PluginActionRunner.d.ts +6 -4
- package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
- package/bin/plugin/core/PluginActionRunner.js +2 -2
- package/bin/plugin/core/PluginActionRunner.js.map +1 -1
- package/bin/plugin/core/PluginCatalog.d.ts +2 -1
- package/bin/plugin/core/PluginCatalog.d.ts.map +1 -1
- package/bin/plugin/core/PluginCatalog.js.map +1 -1
- package/bin/plugin/core/PluginCommand.d.ts +1 -1
- package/bin/plugin/core/PluginCommand.d.ts.map +1 -1
- package/bin/plugin/core/PluginCommand.js.map +1 -1
- package/bin/plugin/core/PluginHttpRoutes.d.ts +1 -1
- package/bin/plugin/core/PluginHttpRoutes.d.ts.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.d.ts +4 -1
- package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +0 -1
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/core/PluginRegistry.d.ts +4 -2
- package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginRegistry.js +7 -6
- package/bin/plugin/core/PluginRegistry.js.map +1 -1
- package/bin/plugin/core/PluginStateController.d.ts +7 -27
- package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
- package/bin/plugin/core/PluginStateController.js +5 -39
- package/bin/plugin/core/PluginStateController.js.map +1 -1
- package/bin/plugin/types/PluginApi.d.ts +3 -79
- package/bin/plugin/types/PluginApi.d.ts.map +1 -1
- package/bin/rpc/Client.d.ts +11 -6
- package/bin/rpc/Client.d.ts.map +1 -1
- package/bin/rpc/Client.js +2 -0
- package/bin/rpc/Client.js.map +1 -1
- package/bin/session/Session.d.ts +2 -5
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +3 -16
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionSystemBuilder.d.ts +1 -1
- package/bin/session/SessionSystemBuilder.d.ts.map +1 -1
- package/bin/session/browse/Browse.d.ts +4 -6
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +71 -71
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/preview/SessionMessagePreview.d.ts +13 -0
- package/bin/session/preview/SessionMessagePreview.d.ts.map +1 -0
- package/bin/session/preview/SessionMessagePreview.js +61 -0
- package/bin/session/preview/SessionMessagePreview.js.map +1 -0
- package/bin/session/services/SessionStateService.d.ts +1 -1
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +2 -2
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/session/services/SessionViewService.d.ts +2 -1
- package/bin/session/services/SessionViewService.d.ts.map +1 -1
- package/bin/session/services/SessionViewService.js +4 -1
- package/bin/session/services/SessionViewService.js.map +1 -1
- package/bin/session/storage/Metadata.d.ts.map +1 -1
- package/bin/session/storage/Metadata.js +23 -0
- package/bin/session/storage/Metadata.js.map +1 -1
- package/bin/session/storage/Persistence.d.ts +1 -1
- package/bin/session/storage/Persistence.d.ts.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.d.ts +0 -12
- package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.js +0 -8
- package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
- package/bin/types/plugin/PluginAction.d.ts +0 -10
- package/bin/types/plugin/PluginAction.d.ts.map +1 -1
- package/bin/types/plugin/PluginCommand.d.ts +2 -3
- package/bin/types/plugin/PluginCommand.d.ts.map +1 -1
- package/bin/types/plugin/PluginControl.d.ts +74 -0
- package/bin/types/plugin/PluginControl.d.ts.map +1 -0
- package/bin/types/plugin/PluginControl.js +9 -0
- package/bin/types/plugin/PluginControl.js.map +1 -0
- package/bin/types/plugin/PluginDefinition.d.ts +1 -1
- package/bin/types/plugin/PluginDefinition.d.ts.map +1 -1
- package/bin/types/plugin/PluginRuntime.d.ts +1 -3
- package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
- package/bin/types/plugin/PluginState.d.ts +3 -16
- package/bin/types/plugin/PluginState.d.ts.map +1 -1
- package/bin/types/rpc/RpcProtocol.d.ts +3 -3
- package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.d.ts +1 -9
- package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.js.map +1 -1
- package/bin/types/session/SessionLocalState.d.ts +1 -1
- package/bin/types/session/SessionLocalState.d.ts.map +1 -1
- package/package.json +4 -7
- package/scripts/agent-ready.test.mjs +38 -0
- package/scripts/assistant-file-resource.test.mjs +39 -0
- package/scripts/city-model-tool-loop.test.mjs +18 -30
- package/scripts/image-plugin-job.test.mjs +13 -13
- package/scripts/plugin-tool-bridge.test.mjs +2 -3
- package/scripts/remote-session-reconnect.test.mjs +67 -0
- package/scripts/session-history-writer-error.test.mjs +57 -0
- package/scripts/session-list-title.test.mjs +114 -23
- package/src/agent/local/Agent.ts +4 -10
- package/src/agent/local/AgentInstructions.ts +1 -1
- package/src/agent/local/services/AgentAssemblyService.ts +3 -9
- package/src/agent/local/services/AgentSessions.ts +8 -15
- package/src/agent/remote/RemoteAgent.ts +5 -4
- package/src/agent/remote/RemoteSession.ts +21 -2
- package/src/agent/remote/RemoteTransport.ts +6 -2
- package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +13 -3
- package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +6 -2
- package/src/executor/Executor.ts +0 -23
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +2 -8
- package/src/executor/composer/history/SessionHistoryWriter.ts +33 -64
- package/src/executor/messages/AssistantFileResource.ts +61 -17
- package/src/executor/services/ExecutorInflightService.ts +0 -10
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +130 -4
- package/src/executor/types/SessionHistoryMeta.ts +6 -0
- package/src/index.ts +100 -29
- package/src/plugin/core/ActionScheduleExecutor.ts +1 -1
- package/src/plugin/core/BasePlugin.ts +8 -22
- package/src/plugin/core/HookRegistry.ts +1 -1
- package/src/plugin/core/PluginActionFactory.ts +1 -8
- package/src/plugin/core/PluginActionRunner.ts +8 -11
- package/src/plugin/core/PluginCatalog.ts +2 -5
- package/src/plugin/core/PluginCommand.ts +2 -1
- package/src/plugin/core/PluginHttpRoutes.ts +1 -1
- package/src/plugin/core/PluginLocalExecution.ts +4 -7
- package/src/plugin/core/PluginRegistry.ts +10 -10
- package/src/plugin/core/PluginStateController.ts +12 -60
- package/src/plugin/types/PluginApi.ts +6 -81
- package/src/rpc/Client.ts +22 -16
- package/src/session/Session.ts +5 -21
- package/src/session/SessionSystemBuilder.ts +1 -1
- package/src/session/browse/Browse.ts +103 -84
- package/src/session/preview/SessionMessagePreview.ts +75 -0
- package/src/session/services/SessionStateService.ts +3 -4
- package/src/session/services/SessionViewService.ts +6 -6
- package/src/session/storage/Metadata.ts +26 -0
- package/src/session/storage/Persistence.ts +1 -1
- package/src/session/storage/RuntimeSessionPort.ts +0 -20
- package/src/types/plugin/PluginAction.ts +0 -10
- package/src/types/plugin/PluginCommand.ts +2 -3
- package/src/types/plugin/PluginControl.ts +80 -0
- package/src/types/plugin/PluginDefinition.ts +1 -1
- package/src/types/plugin/PluginRuntime.ts +1 -3
- package/src/types/plugin/PluginState.ts +3 -20
- package/src/types/rpc/RpcProtocol.ts +4 -4
- package/src/types/runtime/agent/AgentContext.ts +1 -9
- package/src/types/session/SessionLocalState.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/config/DowncitySchema.d.ts +0 -20
- package/bin/config/DowncitySchema.d.ts.map +0 -1
- package/bin/config/DowncitySchema.js +0 -160
- package/bin/config/DowncitySchema.js.map +0 -1
- package/bin/plugin/core/Activation.d.ts +0 -18
- package/bin/plugin/core/Activation.d.ts.map +0 -1
- package/bin/plugin/core/Activation.js +0 -21
- package/bin/plugin/core/Activation.js.map +0 -1
- package/bin/plugin/core/Manager.d.ts +0 -7
- package/bin/plugin/core/Manager.d.ts.map +0 -1
- package/bin/plugin/core/Manager.js +0 -6
- package/bin/plugin/core/Manager.js.map +0 -1
- package/bin/plugin/types/Plugin.d.ts +0 -15
- package/bin/plugin/types/Plugin.d.ts.map +0 -1
- package/bin/plugin/types/Plugin.js +0 -9
- package/bin/plugin/types/Plugin.js.map +0 -1
- package/bin/plugin/types/PluginLifecycle.d.ts +0 -34
- package/bin/plugin/types/PluginLifecycle.d.ts.map +0 -1
- package/bin/plugin/types/PluginLifecycle.js +0 -9
- package/bin/plugin/types/PluginLifecycle.js.map +0 -1
- package/bin/plugin/types/PluginState.d.ts +0 -5
- package/bin/plugin/types/PluginState.d.ts.map +0 -1
- package/bin/plugin/types/PluginState.js +0 -5
- package/bin/plugin/types/PluginState.js.map +0 -1
- package/bin/plugin/types/Plugins.d.ts +0 -61
- package/bin/plugin/types/Plugins.d.ts.map +0 -1
- package/bin/plugin/types/Plugins.js +0 -5
- package/bin/plugin/types/Plugins.js.map +0 -1
- package/bin/session/index.d.ts +0 -15
- package/bin/session/index.d.ts.map +0 -1
- package/bin/session/index.js +0 -15
- package/bin/session/index.js.map +0 -1
- package/bin/types/agent/AgentTypes.d.ts +0 -18
- package/bin/types/agent/AgentTypes.d.ts.map +0 -1
- package/bin/types/agent/AgentTypes.js +0 -10
- package/bin/types/agent/AgentTypes.js.map +0 -1
- package/bin/utils/logger/Format.d.ts +0 -11
- package/bin/utils/logger/Format.d.ts.map +0 -1
- package/bin/utils/logger/Format.js +0 -10
- package/bin/utils/logger/Format.js.map +0 -1
- package/src/config/DowncitySchema.ts +0 -175
- package/src/plugin/core/Activation.ts +0 -26
- package/src/plugin/core/Manager.ts +0 -17
- package/src/plugin/types/Plugin.ts +0 -63
- package/src/plugin/types/PluginLifecycle.ts +0 -35
- package/src/plugin/types/PluginState.ts +0 -12
- package/src/plugin/types/Plugins.ts +0 -67
- package/src/session/index.ts +0 -57
- package/src/types/agent/AgentTypes.ts +0 -58
- package/src/utils/logger/Format.ts +0 -15
|
@@ -7,70 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { JsonValue } from "@/types/common/Json.js";
|
|
10
|
+
import type {
|
|
11
|
+
PluginAvailability,
|
|
12
|
+
PluginView,
|
|
13
|
+
} from "@/types/plugin/PluginRuntime.js";
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
export interface PluginView {
|
|
15
|
-
/**
|
|
16
|
-
* Plugin 稳定名称。
|
|
17
|
-
*/
|
|
18
|
-
name: string;
|
|
19
|
-
/**
|
|
20
|
-
* Plugin 展示标题。
|
|
21
|
-
*/
|
|
22
|
-
title: string;
|
|
23
|
-
/**
|
|
24
|
-
* Plugin 面向人类的用途说明。
|
|
25
|
-
*/
|
|
26
|
-
description: string;
|
|
27
|
-
/**
|
|
28
|
-
* 已声明的 Action 名称列表。
|
|
29
|
-
*/
|
|
30
|
-
actions: string[];
|
|
31
|
-
/**
|
|
32
|
-
* 已声明的 pipeline 点名称列表。
|
|
33
|
-
*/
|
|
34
|
-
pipelines: string[];
|
|
35
|
-
/**
|
|
36
|
-
* 已声明的 guard 点名称列表。
|
|
37
|
-
*/
|
|
38
|
-
guards: string[];
|
|
39
|
-
/**
|
|
40
|
-
* 已声明的 effect 点名称列表。
|
|
41
|
-
*/
|
|
42
|
-
effects: string[];
|
|
43
|
-
/**
|
|
44
|
-
* 已声明的 resolve 点名称列表。
|
|
45
|
-
*/
|
|
46
|
-
resolves: string[];
|
|
47
|
-
/**
|
|
48
|
-
* 是否声明了 system 注入。
|
|
49
|
-
*/
|
|
50
|
-
hasSystem: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* 是否声明了 availability 检查。
|
|
53
|
-
*/
|
|
54
|
-
hasAvailability: boolean;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Plugin 可用性响应视图。
|
|
59
|
-
*/
|
|
60
|
-
export interface PluginAvailabilityView {
|
|
61
|
-
/**
|
|
62
|
-
* Plugin 是否启用。
|
|
63
|
-
*/
|
|
64
|
-
enabled: boolean;
|
|
65
|
-
/**
|
|
66
|
-
* Plugin 当前是否可用。
|
|
67
|
-
*/
|
|
68
|
-
available: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* 不可用原因列表。
|
|
71
|
-
*/
|
|
72
|
-
reasons: string[];
|
|
73
|
-
}
|
|
15
|
+
export type { PluginView } from "@/types/plugin/PluginRuntime.js";
|
|
16
|
+
export type PluginAvailabilityView = PluginAvailability;
|
|
74
17
|
|
|
75
18
|
/**
|
|
76
19
|
* plugin catalog 响应。
|
|
@@ -141,21 +84,3 @@ export interface PluginActionResponse {
|
|
|
141
84
|
*/
|
|
142
85
|
error?: string;
|
|
143
86
|
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* plugin CLI 通用选项。
|
|
147
|
-
*/
|
|
148
|
-
export interface PluginCliBaseOptions {
|
|
149
|
-
/**
|
|
150
|
-
* agent 项目路径(默认当前目录)。
|
|
151
|
-
*/
|
|
152
|
-
path?: string;
|
|
153
|
-
/**
|
|
154
|
-
* 是否输出 JSON。
|
|
155
|
-
*/
|
|
156
|
-
json?: boolean;
|
|
157
|
-
/**
|
|
158
|
-
* agent id(从 managed agent registry 解析到项目路径)。
|
|
159
|
-
*/
|
|
160
|
-
agent?: string;
|
|
161
|
-
}
|
package/src/rpc/Client.ts
CHANGED
|
@@ -19,21 +19,22 @@ import type {
|
|
|
19
19
|
AgentSessionRecordsInput,
|
|
20
20
|
AgentSessionRecordsPage,
|
|
21
21
|
AgentSessionInfo,
|
|
22
|
-
AgentSessionStopResult,
|
|
23
22
|
AgentSessionSummaryPage,
|
|
24
23
|
AgentSessionSystemSnapshot,
|
|
25
|
-
} from "@/types/agent/
|
|
24
|
+
} from "@/types/agent/SessionTypes.js";
|
|
26
25
|
import type { JsonValue } from "@/types/common/Json.js";
|
|
27
26
|
import type { JsonObject } from "@/types/common/Json.js";
|
|
27
|
+
import type { AgentSessionStopResult } from "@/types/sdk/AgentSessionStop.js";
|
|
28
28
|
import type {
|
|
29
29
|
PluginActionResult,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
} from "@/types/plugin/PluginAction.js";
|
|
31
|
+
import type { PluginCommandResult } from "@/types/plugin/PluginCommand.js";
|
|
32
|
+
import type { PluginAvailability, PluginView } from "@/types/plugin/PluginRuntime.js";
|
|
33
|
+
import type {
|
|
34
|
+
PluginControlAction,
|
|
35
|
+
PluginControlResult,
|
|
36
|
+
PluginSnapshot,
|
|
37
|
+
} from "@/types/plugin/PluginState.js";
|
|
37
38
|
import type { AgentSessionEvent } from "@/types/sdk/AgentSessionEvent.js";
|
|
38
39
|
import type { AgentSessionPromptInput } from "@/types/sdk/AgentSessionPrompt.js";
|
|
39
40
|
import type {
|
|
@@ -66,6 +67,8 @@ type PendingRequest = {
|
|
|
66
67
|
type RpcSubscription = {
|
|
67
68
|
on_ready: () => void;
|
|
68
69
|
on_event: (event: AgentSessionEvent) => void;
|
|
70
|
+
/** 底层 RPC 连接结束后的通知。 */
|
|
71
|
+
on_close: (error?: unknown) => void;
|
|
69
72
|
};
|
|
70
73
|
|
|
71
74
|
/**
|
|
@@ -249,6 +252,7 @@ export class RpcClient {
|
|
|
249
252
|
session_id: string;
|
|
250
253
|
on_ready: () => void;
|
|
251
254
|
on_event: (event: AgentSessionEvent) => void;
|
|
255
|
+
on_close: (error?: unknown) => void;
|
|
252
256
|
}): Promise<RpcSessionSubscription> {
|
|
253
257
|
const data = await this.request<{ subscriptionId: string }>({
|
|
254
258
|
method: "sdk.sessions.subscribe",
|
|
@@ -263,6 +267,7 @@ export class RpcClient {
|
|
|
263
267
|
this.subscriptions.set(subscription_id, {
|
|
264
268
|
on_ready: params.on_ready,
|
|
265
269
|
on_event: params.on_event,
|
|
270
|
+
on_close: params.on_close,
|
|
266
271
|
});
|
|
267
272
|
params.on_ready();
|
|
268
273
|
return {
|
|
@@ -343,8 +348,8 @@ export class RpcClient {
|
|
|
343
348
|
/**
|
|
344
349
|
* 列出 Agent runtime 内 plugin 状态。
|
|
345
350
|
*/
|
|
346
|
-
async list_internal_plugin_states(): Promise<
|
|
347
|
-
const data = await this.request<{ plugins:
|
|
351
|
+
async list_internal_plugin_states(): Promise<PluginSnapshot[]> {
|
|
352
|
+
const data = await this.request<{ plugins: PluginSnapshot[] }>({
|
|
348
353
|
method: "internal.plugins.list",
|
|
349
354
|
});
|
|
350
355
|
return Array.isArray(data.plugins) ? data.plugins : [];
|
|
@@ -355,9 +360,9 @@ export class RpcClient {
|
|
|
355
360
|
*/
|
|
356
361
|
async control_internal_plugin(params: {
|
|
357
362
|
plugin_name: string;
|
|
358
|
-
action:
|
|
359
|
-
}): Promise<
|
|
360
|
-
return await this.request<
|
|
363
|
+
action: PluginControlAction;
|
|
364
|
+
}): Promise<PluginControlResult> {
|
|
365
|
+
return await this.request<PluginControlResult>({
|
|
361
366
|
method: "internal.plugins.control",
|
|
362
367
|
params: {
|
|
363
368
|
pluginName: params.plugin_name,
|
|
@@ -374,8 +379,8 @@ export class RpcClient {
|
|
|
374
379
|
command: string;
|
|
375
380
|
payload?: JsonValue;
|
|
376
381
|
schedule?: JsonValue;
|
|
377
|
-
}): Promise<PluginCommandResult & { plugin?:
|
|
378
|
-
return await this.request<PluginCommandResult & { plugin?:
|
|
382
|
+
}): Promise<PluginCommandResult & { plugin?: PluginSnapshot }> {
|
|
383
|
+
return await this.request<PluginCommandResult & { plugin?: PluginSnapshot }>({
|
|
379
384
|
method: "internal.plugins.command",
|
|
380
385
|
params: {
|
|
381
386
|
pluginName: params.plugin_name,
|
|
@@ -650,6 +655,7 @@ export class RpcClient {
|
|
|
650
655
|
type: "error",
|
|
651
656
|
message,
|
|
652
657
|
});
|
|
658
|
+
subscription.on_close(new Error(message));
|
|
653
659
|
}
|
|
654
660
|
this.subscriptions.clear();
|
|
655
661
|
}
|
package/src/session/Session.ts
CHANGED
|
@@ -12,7 +12,6 @@ import type { Tool } from "ai";
|
|
|
12
12
|
import { JsonlSessionHistoryComposer } from "@executor/composer/history/jsonl/JsonlSessionHistoryComposer.js";
|
|
13
13
|
import { JsonlSessionHistoryStore } from "@/executor/store/history/jsonl/JsonlSessionHistoryStore.js";
|
|
14
14
|
import type {
|
|
15
|
-
AgentSession,
|
|
16
15
|
AgentSessionConfigSnapshot,
|
|
17
16
|
AgentSessionForkInput,
|
|
18
17
|
AgentSessionRecordsInput,
|
|
@@ -21,14 +20,15 @@ import type {
|
|
|
21
20
|
AgentSessionSetInput,
|
|
22
21
|
AgentSessionSystemBlock,
|
|
23
22
|
AgentSessionSystemSnapshot,
|
|
24
|
-
} from "@/types/agent/
|
|
23
|
+
} from "@/types/agent/SessionTypes.js";
|
|
24
|
+
import type { AgentSession } from "@/types/agent/SessionActor.js";
|
|
25
25
|
import {
|
|
26
26
|
getSdkAgentSessionArchiveDirPath,
|
|
27
27
|
getSdkAgentSessionDirPath,
|
|
28
28
|
getSdkAgentSessionInflightPath,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} from "@/session/
|
|
29
|
+
} from "@/session/storage/Paths.js";
|
|
30
|
+
import { resolveSystemTimezone } from "@/session/storage/Metadata.js";
|
|
31
|
+
import { createRuntimeSessionPort } from "@/session/storage/RuntimeSessionPort.js";
|
|
32
32
|
import { SessionSystemBuilder } from "@/session/SessionSystemBuilder.js";
|
|
33
33
|
import type { SessionPort } from "@/types/runtime/agent/AgentContext.js";
|
|
34
34
|
import type {
|
|
@@ -256,13 +256,6 @@ export class Session implements AgentSession {
|
|
|
256
256
|
return this.turnService.is_prompt_runtime_active() || this.executor.isExecuting();
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
/**
|
|
260
|
-
* 清理当前 session 的执行器缓存。
|
|
261
|
-
*/
|
|
262
|
-
clearExecutor(): void {
|
|
263
|
-
this.executor.clearExecutor();
|
|
264
|
-
}
|
|
265
|
-
|
|
266
259
|
/**
|
|
267
260
|
* 从当前 session 创建一个分叉会话。
|
|
268
261
|
*/
|
|
@@ -284,12 +277,6 @@ export class Session implements AgentSession {
|
|
|
284
277
|
publishEvent: (event) => {
|
|
285
278
|
this.eventHub.publish(event);
|
|
286
279
|
},
|
|
287
|
-
clearExecutor: () => {
|
|
288
|
-
this.executor.clearExecutor();
|
|
289
|
-
},
|
|
290
|
-
afterSessionUpdatedAsync: async () => {
|
|
291
|
-
await this.executor.afterSessionUpdatedAsync();
|
|
292
|
-
},
|
|
293
280
|
append_user_message: async (message_params) => {
|
|
294
281
|
await this.stateService.append_user_message(message_params);
|
|
295
282
|
},
|
|
@@ -301,9 +288,6 @@ export class Session implements AgentSession {
|
|
|
301
288
|
ensureReadyForExecution: async () => {
|
|
302
289
|
await this.ensureReadyForExecution();
|
|
303
290
|
},
|
|
304
|
-
touchMetadata: async () => {
|
|
305
|
-
await this.stateService.touch_metadata();
|
|
306
|
-
},
|
|
307
291
|
});
|
|
308
292
|
return this.runtimePort;
|
|
309
293
|
}
|
|
@@ -12,7 +12,7 @@ import type { SessionSystemMessage } from "@/executor/types/SessionPrompts.js";
|
|
|
12
12
|
import type {
|
|
13
13
|
AgentSessionSystemBlock,
|
|
14
14
|
AgentSessionSystemSessionInfo,
|
|
15
|
-
} from "@/types/agent/
|
|
15
|
+
} from "@/types/agent/SessionTypes.js";
|
|
16
16
|
import type { SessionRunContext } from "@/types/executor/SessionRunContext.js";
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import fs from "fs-extra";
|
|
12
|
+
import path from "node:path";
|
|
12
13
|
import {
|
|
13
14
|
getToolName,
|
|
14
15
|
isTextUIPart,
|
|
@@ -24,7 +25,7 @@ import type {
|
|
|
24
25
|
AgentSessionSummary,
|
|
25
26
|
AgentSessionSummaryPage,
|
|
26
27
|
AgentSessionTimelineEvent,
|
|
27
|
-
} from "@/types/agent/
|
|
28
|
+
} from "@/types/agent/SessionTypes.js";
|
|
28
29
|
import type {
|
|
29
30
|
SessionActionRecordV1,
|
|
30
31
|
SessionRecordV1,
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
is_session_message_record,
|
|
37
38
|
} from "@/executor/types/SessionRecords.js";
|
|
38
39
|
import type { SessionHistoryMetaV1 } from "@/executor/types/SessionHistoryMeta.js";
|
|
39
|
-
import {
|
|
40
|
+
import { resolve_session_message_preview } from "@/session/preview/SessionMessagePreview.js";
|
|
40
41
|
import { getSdkAgentSessionMessagesPath } from "@/session/storage/Paths.js";
|
|
41
42
|
import { getSdkAgentSessionMetaPath } from "@/session/storage/Paths.js";
|
|
42
43
|
import { getSdkAgentSessionsRootDirPath } from "@/session/storage/Paths.js";
|
|
@@ -80,8 +81,10 @@ type SessionBrowseBaseInput = {
|
|
|
80
81
|
|
|
81
82
|
/**
|
|
82
83
|
* 当前 session 已读取到的完整消息。
|
|
84
|
+
*
|
|
85
|
+
* 说明(中文):列表查询已有 metadata 摘要时可省略,详情查询仍传完整记录。
|
|
83
86
|
*/
|
|
84
|
-
messages
|
|
87
|
+
messages?: SessionRecordV1[];
|
|
85
88
|
|
|
86
89
|
/**
|
|
87
90
|
* 当前 session 是否正在执行。
|
|
@@ -163,52 +166,6 @@ function stringifyForDisplay(input: unknown, maxChars = 2400): string {
|
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
168
|
|
|
166
|
-
function extractMessageText(parts: unknown): string {
|
|
167
|
-
if (!Array.isArray(parts)) return "";
|
|
168
|
-
const texts: string[] = [];
|
|
169
|
-
for (const part of parts) {
|
|
170
|
-
if (!part || typeof part !== "object") continue;
|
|
171
|
-
const textPart = part as { type?: unknown; text?: unknown };
|
|
172
|
-
if (textPart.type !== "text" || typeof textPart.text !== "string") continue;
|
|
173
|
-
const text = textPart.text.trim();
|
|
174
|
-
if (!text) continue;
|
|
175
|
-
texts.push(text);
|
|
176
|
-
}
|
|
177
|
-
return texts.join("\n").trim();
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function extractAssistantToolSummary(message: SessionMessageRecordV1): string {
|
|
181
|
-
if (!Array.isArray(message.parts)) return "";
|
|
182
|
-
const toolNames = new Set<string>();
|
|
183
|
-
for (const part of message.parts as AnyUiPart[]) {
|
|
184
|
-
if (!part || typeof part !== "object") continue;
|
|
185
|
-
if (!isToolUIPart(part)) continue;
|
|
186
|
-
const toolName = String(getToolName(part) || "").trim();
|
|
187
|
-
if (toolName) toolNames.add(toolName);
|
|
188
|
-
}
|
|
189
|
-
if (toolNames.size === 0) return "";
|
|
190
|
-
return `[tool] ${Array.from(toolNames).join(", ")}`;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* 解析单条 session 消息的用户可见预览文本。
|
|
195
|
-
*/
|
|
196
|
-
export function resolveSessionMessagePreview(message: SessionRecordV1): string {
|
|
197
|
-
if (is_session_action_record(message)) {
|
|
198
|
-
return message.description
|
|
199
|
-
? `${message.title}\n${message.description}`
|
|
200
|
-
: message.title;
|
|
201
|
-
}
|
|
202
|
-
if (!is_session_message_record(message)) return "";
|
|
203
|
-
const plainText = extractMessageText(message.parts);
|
|
204
|
-
if (plainText) return plainText;
|
|
205
|
-
if (message.role !== "assistant") return "";
|
|
206
|
-
|
|
207
|
-
const userVisible = pickLastSuccessfulChatSendText(message).trim();
|
|
208
|
-
if (userVisible) return userVisible;
|
|
209
|
-
return extractAssistantToolSummary(message);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
169
|
function resolveToolName(part: ToolPartCompatShape, aiToolName?: string): string {
|
|
213
170
|
const fromAi = String(aiToolName || "").trim();
|
|
214
171
|
if (fromAi) return fromAi;
|
|
@@ -263,7 +220,7 @@ function toActionTimelineEvent(
|
|
|
263
220
|
id: `${String(message.id || "")}:0`,
|
|
264
221
|
role: "action",
|
|
265
222
|
...(typeof metadata?.ts === "number" ? { ts: metadata.ts } : {}),
|
|
266
|
-
text:
|
|
223
|
+
text: resolve_session_message_preview(message),
|
|
267
224
|
actionTitle: message.title,
|
|
268
225
|
...(message.description ? { actionDescription: message.description } : {}),
|
|
269
226
|
actionState: message.state,
|
|
@@ -286,7 +243,7 @@ export function toSessionTimelineEvents(
|
|
|
286
243
|
toTimelineEvent({
|
|
287
244
|
message,
|
|
288
245
|
role: message.role === "user" ? "user" : "assistant",
|
|
289
|
-
text:
|
|
246
|
+
text: resolve_session_message_preview(message),
|
|
290
247
|
sequence: 0,
|
|
291
248
|
}),
|
|
292
249
|
];
|
|
@@ -352,7 +309,7 @@ export function toSessionTimelineEvents(
|
|
|
352
309
|
toTimelineEvent({
|
|
353
310
|
message,
|
|
354
311
|
role: "assistant",
|
|
355
|
-
text:
|
|
312
|
+
text: resolve_session_message_preview(message),
|
|
356
313
|
sequence: 0,
|
|
357
314
|
}),
|
|
358
315
|
);
|
|
@@ -467,12 +424,16 @@ function filterUserVisibleHistoryMessages(
|
|
|
467
424
|
export function buildSessionInfo(
|
|
468
425
|
input: SessionBrowseBaseInput,
|
|
469
426
|
): AgentSessionInfo {
|
|
470
|
-
const
|
|
427
|
+
const messages = input.messages;
|
|
428
|
+
const previewText = messages && messages.length > 0
|
|
471
429
|
? truncateText(
|
|
472
|
-
|
|
430
|
+
resolve_session_message_preview(messages[messages.length - 1]),
|
|
473
431
|
180,
|
|
474
432
|
)
|
|
475
|
-
:
|
|
433
|
+
: input.metadata.previewText;
|
|
434
|
+
const message_count = messages
|
|
435
|
+
? messages.length
|
|
436
|
+
: input.metadata.messageCount || 0;
|
|
476
437
|
const title =
|
|
477
438
|
typeof input.metadata.title === "string" && input.metadata.title.trim()
|
|
478
439
|
? input.metadata.title.trim()
|
|
@@ -482,7 +443,7 @@ export function buildSessionInfo(
|
|
|
482
443
|
sessionId: input.sessionId,
|
|
483
444
|
...(title ? { title } : {}),
|
|
484
445
|
...(previewText ? { previewText } : {}),
|
|
485
|
-
messageCount:
|
|
446
|
+
messageCount: message_count,
|
|
486
447
|
...(typeof input.metadata.createdAt === "number"
|
|
487
448
|
? { createdAt: input.metadata.createdAt }
|
|
488
449
|
: {}),
|
|
@@ -499,6 +460,56 @@ export function buildSessionInfo(
|
|
|
499
460
|
};
|
|
500
461
|
}
|
|
501
462
|
|
|
463
|
+
/**
|
|
464
|
+
* 读取列表所需的轻量 session 摘要。
|
|
465
|
+
*
|
|
466
|
+
* 关键点(中文)
|
|
467
|
+
* - 新记录直接使用 metadata 摘要,不扫描 messages.jsonl。
|
|
468
|
+
* - 旧记录或执行中记录回退读取一次完整历史,并把摘要补写回 metadata。
|
|
469
|
+
*/
|
|
470
|
+
async function resolve_session_summary_metadata(input: {
|
|
471
|
+
/** 当前 session metadata。 */
|
|
472
|
+
metadata: SessionHistoryMetaV1;
|
|
473
|
+
/** 当前消息 JSONL 路径。 */
|
|
474
|
+
messagesPath: string;
|
|
475
|
+
/** 当前 metadata 路径。 */
|
|
476
|
+
metaPath: string;
|
|
477
|
+
/** 是否强制刷新摘要。 */
|
|
478
|
+
refresh: boolean;
|
|
479
|
+
}): Promise<SessionHistoryMetaV1> {
|
|
480
|
+
const history_bytes = await fs.stat(input.messagesPath)
|
|
481
|
+
.then((file_stat) => file_stat.size)
|
|
482
|
+
.catch(() => 0);
|
|
483
|
+
const inflight_path = `${input.messagesPath.slice(0, -"messages.jsonl".length)}inflight.json`;
|
|
484
|
+
const has_inflight = await fs.pathExists(inflight_path);
|
|
485
|
+
if (
|
|
486
|
+
!input.refresh &&
|
|
487
|
+
!has_inflight &&
|
|
488
|
+
typeof input.metadata.messageCount === "number" &&
|
|
489
|
+
input.metadata.historyBytes === history_bytes
|
|
490
|
+
) {
|
|
491
|
+
return input.metadata;
|
|
492
|
+
}
|
|
493
|
+
const messages = await loadSessionMessagesFromPath(input.messagesPath);
|
|
494
|
+
const last_message = messages[messages.length - 1];
|
|
495
|
+
const preview_text = last_message
|
|
496
|
+
? truncateText(resolve_session_message_preview(last_message), 180)
|
|
497
|
+
: "";
|
|
498
|
+
const { previewText: _previous_preview, ...metadata_without_preview } = input.metadata;
|
|
499
|
+
void _previous_preview;
|
|
500
|
+
const next_metadata: SessionHistoryMetaV1 = {
|
|
501
|
+
...metadata_without_preview,
|
|
502
|
+
messageCount: messages.length,
|
|
503
|
+
historyBytes: history_bytes,
|
|
504
|
+
...(preview_text ? { previewText: preview_text } : {}),
|
|
505
|
+
};
|
|
506
|
+
const temp_path = `${input.metaPath}.${process.pid}.${Date.now()}.tmp`;
|
|
507
|
+
await fs.ensureDir(path.dirname(input.metaPath));
|
|
508
|
+
await fs.writeJson(temp_path, next_metadata, { spaces: 2 });
|
|
509
|
+
await fs.move(temp_path, input.metaPath, { overwrite: true });
|
|
510
|
+
return next_metadata;
|
|
511
|
+
}
|
|
512
|
+
|
|
502
513
|
/**
|
|
503
514
|
* 基于完整消息列表构建 session records 分页结果。
|
|
504
515
|
*/
|
|
@@ -584,28 +595,32 @@ export async function listAgentSessionSummaryPage(params: {
|
|
|
584
595
|
if (!entry.isDirectory()) continue;
|
|
585
596
|
const sessionId = decodeMaybe(entry.name);
|
|
586
597
|
if (!sessionId) continue;
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
598
|
+
const meta_path = getSdkAgentSessionMetaPath(
|
|
599
|
+
params.projectRoot,
|
|
600
|
+
params.agentId,
|
|
601
|
+
sessionId,
|
|
602
|
+
);
|
|
603
|
+
const messages_path = getSdkAgentSessionMessagesPath(
|
|
604
|
+
params.projectRoot,
|
|
605
|
+
params.agentId,
|
|
606
|
+
sessionId,
|
|
607
|
+
);
|
|
608
|
+
const persisted_metadata = await readSessionMetadataFromPath({
|
|
609
|
+
filePath: meta_path,
|
|
593
610
|
sessionId,
|
|
594
611
|
agentId: params.agentId,
|
|
595
612
|
});
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
);
|
|
613
|
+
const metadata = await resolve_session_summary_metadata({
|
|
614
|
+
metadata: persisted_metadata,
|
|
615
|
+
messagesPath: messages_path,
|
|
616
|
+
metaPath: meta_path,
|
|
617
|
+
refresh: params.executingSessionIds?.has(sessionId) === true,
|
|
618
|
+
});
|
|
603
619
|
const info = buildSessionInfo({
|
|
604
620
|
projectRoot: params.projectRoot,
|
|
605
621
|
agentId: params.agentId,
|
|
606
622
|
sessionId,
|
|
607
623
|
metadata,
|
|
608
|
-
messages,
|
|
609
624
|
executing: params.executingSessionIds?.has(sessionId),
|
|
610
625
|
});
|
|
611
626
|
const summary: AgentSessionSummary = {
|
|
@@ -679,29 +694,33 @@ export async function listArchivedAgentSessionSummaryPage(params: {
|
|
|
679
694
|
if (!entry.isDirectory()) continue;
|
|
680
695
|
const sessionId = decodeMaybe(entry.name);
|
|
681
696
|
if (!sessionId) continue;
|
|
682
|
-
const
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
697
|
+
const meta_path = getSdkAgentArchivedSessionMetaPath(
|
|
698
|
+
params.projectRoot,
|
|
699
|
+
params.agentId,
|
|
700
|
+
sessionId,
|
|
701
|
+
);
|
|
702
|
+
const messages_path = getSdkAgentArchivedSessionMessagesPath(
|
|
703
|
+
params.projectRoot,
|
|
704
|
+
params.agentId,
|
|
705
|
+
sessionId,
|
|
706
|
+
);
|
|
707
|
+
const persisted_metadata = await readSessionMetadataFromPath({
|
|
708
|
+
filePath: meta_path,
|
|
688
709
|
sessionId,
|
|
689
710
|
agentId: params.agentId,
|
|
690
711
|
});
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
);
|
|
712
|
+
const metadata = await resolve_session_summary_metadata({
|
|
713
|
+
metadata: persisted_metadata,
|
|
714
|
+
messagesPath: messages_path,
|
|
715
|
+
metaPath: meta_path,
|
|
716
|
+
refresh: false,
|
|
717
|
+
});
|
|
698
718
|
// 关键点(中文):归档 session 不再生成新 title,仅读取归档目录内已有 meta。
|
|
699
719
|
const info = buildSessionInfo({
|
|
700
720
|
projectRoot: params.projectRoot,
|
|
701
721
|
agentId: params.agentId,
|
|
702
722
|
sessionId,
|
|
703
723
|
metadata,
|
|
704
|
-
messages,
|
|
705
724
|
executing: false,
|
|
706
725
|
});
|
|
707
726
|
const summary: AgentSessionSummary = {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session 消息预览投影。
|
|
3
|
+
*
|
|
4
|
+
* 关键点(中文)
|
|
5
|
+
* - 只负责从单条持久化 record 提取用户可见文本。
|
|
6
|
+
* - history store 与浏览层共用该投影,避免摘要写入和读取采用不同规则。
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
getToolName,
|
|
11
|
+
isToolUIPart,
|
|
12
|
+
type UIMessagePart,
|
|
13
|
+
} from "ai";
|
|
14
|
+
import { pickLastSuccessfulChatSendText } from "@/executor/messages/UserVisibleText.js";
|
|
15
|
+
import type {
|
|
16
|
+
SessionMessageRecordV1,
|
|
17
|
+
SessionRecordV1,
|
|
18
|
+
} from "@/executor/types/SessionRecords.js";
|
|
19
|
+
import {
|
|
20
|
+
is_session_action_record,
|
|
21
|
+
is_session_message_record,
|
|
22
|
+
} from "@/executor/types/SessionRecords.js";
|
|
23
|
+
|
|
24
|
+
type SessionPreviewPart = UIMessagePart<
|
|
25
|
+
Record<string, never>,
|
|
26
|
+
Record<string, never>
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
function extract_message_text(parts: unknown): string {
|
|
30
|
+
if (!Array.isArray(parts)) return "";
|
|
31
|
+
const texts: string[] = [];
|
|
32
|
+
for (const part of parts) {
|
|
33
|
+
if (!part || typeof part !== "object") continue;
|
|
34
|
+
const text_part = part as { type?: unknown; text?: unknown };
|
|
35
|
+
if (text_part.type !== "text" || typeof text_part.text !== "string") continue;
|
|
36
|
+
const text = text_part.text.trim();
|
|
37
|
+
if (text) texts.push(text);
|
|
38
|
+
}
|
|
39
|
+
return texts.join("\n").trim();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function extract_assistant_tool_summary(
|
|
43
|
+
message: SessionMessageRecordV1,
|
|
44
|
+
): string {
|
|
45
|
+
if (!Array.isArray(message.parts)) return "";
|
|
46
|
+
const tool_names = new Set<string>();
|
|
47
|
+
for (const part of message.parts as SessionPreviewPart[]) {
|
|
48
|
+
if (!part || typeof part !== "object" || !isToolUIPart(part)) continue;
|
|
49
|
+
const tool_name = String(getToolName(part) || "").trim();
|
|
50
|
+
if (tool_name) tool_names.add(tool_name);
|
|
51
|
+
}
|
|
52
|
+
return tool_names.size > 0
|
|
53
|
+
? `[tool] ${Array.from(tool_names).join(", ")}`
|
|
54
|
+
: "";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 解析单条 session record 的用户可见预览文本。
|
|
59
|
+
*/
|
|
60
|
+
export function resolve_session_message_preview(
|
|
61
|
+
message: SessionRecordV1,
|
|
62
|
+
): string {
|
|
63
|
+
if (is_session_action_record(message)) {
|
|
64
|
+
return message.description
|
|
65
|
+
? `${message.title}\n${message.description}`
|
|
66
|
+
: message.title;
|
|
67
|
+
}
|
|
68
|
+
if (!is_session_message_record(message)) return "";
|
|
69
|
+
const plain_text = extract_message_text(message.parts);
|
|
70
|
+
if (plain_text) return plain_text;
|
|
71
|
+
if (message.role !== "assistant") return "";
|
|
72
|
+
|
|
73
|
+
const user_visible = pickLastSuccessfulChatSendText(message).trim();
|
|
74
|
+
return user_visible || extract_assistant_tool_summary(message);
|
|
75
|
+
}
|
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
patchSessionModelLabel,
|
|
16
16
|
readSessionMetadata,
|
|
17
17
|
resolveSystemTimezone,
|
|
18
|
-
touchSessionMetadata,
|
|
19
18
|
writeSessionMetadata,
|
|
20
|
-
} from "@/session/
|
|
19
|
+
} from "@/session/storage/Metadata.js";
|
|
20
|
+
import { touchSessionMetadata } from "@/session/storage/Persistence.js";
|
|
21
21
|
import { ensureSessionTitle } from "@/session/SessionTitle.js";
|
|
22
22
|
import { persistSdkAssistantResult } from "@/session/storage/Persistence.js";
|
|
23
23
|
import { hydrateUserPromptFileParts } from "@executor/messages/SessionAttachmentMapper.js";
|
|
@@ -26,7 +26,7 @@ import type { JsonlSessionHistoryStore } from "@/executor/store/history/jsonl/Js
|
|
|
26
26
|
import type {
|
|
27
27
|
AgentSessionConfigSnapshot,
|
|
28
28
|
AgentSessionSetInput,
|
|
29
|
-
} from "@/types/agent/
|
|
29
|
+
} from "@/types/agent/SessionTypes.js";
|
|
30
30
|
import type {
|
|
31
31
|
AgentSessionEvent,
|
|
32
32
|
} from "@/types/sdk/AgentSessionEvent.js";
|
|
@@ -259,7 +259,6 @@ export class SessionStateService {
|
|
|
259
259
|
if (input.model) {
|
|
260
260
|
this.state.sessionConfig.model = normalizeAgentModel(input.model);
|
|
261
261
|
this.state.sessionConfig.modelLabel = next_model_label;
|
|
262
|
-
this.executor.clearExecutor();
|
|
263
262
|
}
|
|
264
263
|
await patchSessionModelLabel({
|
|
265
264
|
projectRoot: this.project_root,
|