@downcity/agent 1.1.238 → 1.1.259
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -45
- package/bin/agent/{local/Agent.d.ts → Agent.d.ts} +37 -27
- package/bin/agent/Agent.d.ts.map +1 -0
- package/bin/agent/Agent.js +211 -0
- package/bin/agent/Agent.js.map +1 -0
- package/bin/agent/AgentContext.d.ts +64 -0
- package/bin/agent/AgentContext.d.ts.map +1 -0
- package/bin/agent/AgentContext.js +53 -0
- package/bin/agent/AgentContext.js.map +1 -0
- package/bin/agent/{local/AgentInstructions.d.ts → AgentInstructions.d.ts} +1 -6
- package/bin/agent/AgentInstructions.d.ts.map +1 -0
- package/bin/agent/{local/AgentInstructions.js → AgentInstructions.js} +1 -10
- package/bin/agent/AgentInstructions.js.map +1 -0
- package/bin/{model/CityModelAdapter.d.ts → agent/AgentModel.d.ts} +3 -3
- package/bin/agent/AgentModel.d.ts.map +1 -0
- package/bin/{model/CityModelAdapter.js → agent/AgentModel.js} +11 -4
- package/bin/agent/AgentModel.js.map +1 -0
- package/bin/agent/{local/services/AgentSessions.d.ts → AgentSessions.d.ts} +30 -40
- package/bin/agent/AgentSessions.d.ts.map +1 -0
- package/bin/agent/{local/services/AgentSessions.js → AgentSessions.js} +62 -79
- package/bin/agent/AgentSessions.js.map +1 -0
- package/bin/agent/AgentState.d.ts +64 -0
- package/bin/agent/AgentState.d.ts.map +1 -0
- package/bin/agent/AgentState.js +118 -0
- package/bin/agent/AgentState.js.map +1 -0
- package/bin/config/Paths.d.ts +0 -43
- package/bin/config/Paths.d.ts.map +1 -1
- package/bin/config/Paths.js +0 -79
- package/bin/config/Paths.js.map +1 -1
- package/bin/config/ProjectSetup.d.ts.map +1 -0
- package/bin/{agent/local → config}/ProjectSetup.js +1 -1
- package/bin/config/ProjectSetup.js.map +1 -0
- package/bin/executor/Executor.d.ts +20 -86
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +109 -260
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts +1 -1
- package/bin/executor/composer/system/default/DefaultSessionSystemComposer.d.ts.map +1 -1
- package/bin/executor/composer/system/default/SystemDomain.d.ts +1 -1
- package/bin/executor/composer/system/default/SystemDomain.d.ts.map +1 -1
- package/bin/executor/composer/system/default/SystemDomain.js +4 -1
- package/bin/executor/composer/system/default/SystemDomain.js.map +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.d.ts.map +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.js.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.d.ts +7 -13
- package/bin/executor/core-engine/CoreEngineRunner.d.ts.map +1 -1
- package/bin/executor/core-engine/CoreEngineRunner.js +81 -34
- package/bin/executor/core-engine/CoreEngineRunner.js.map +1 -1
- package/bin/executor/services/ExecutorRecoveryPolicy.d.ts +6 -12
- package/bin/executor/services/ExecutorRecoveryPolicy.d.ts.map +1 -1
- package/bin/executor/services/ExecutorRecoveryPolicy.js +20 -6
- package/bin/executor/services/ExecutorRecoveryPolicy.js.map +1 -1
- package/bin/executor/tools/file/ReadImageToolBridge.d.ts +21 -0
- package/bin/executor/tools/file/ReadImageToolBridge.d.ts.map +1 -0
- package/bin/executor/tools/file/ReadImageToolBridge.js +69 -0
- package/bin/executor/tools/file/ReadImageToolBridge.js.map +1 -0
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.js +6 -5
- package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolDefinition.js +15 -2
- package/bin/executor/tools/plugin/PluginToolDefinition.js.map +1 -1
- package/bin/executor/types/SessionHistoryMeta.d.ts +0 -2
- package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
- package/bin/index.d.ts +17 -21
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +9 -11
- package/bin/index.js.map +1 -1
- package/bin/plugin/core/ActionScheduleExecutor.d.ts +1 -1
- package/bin/plugin/core/ActionScheduleExecutor.d.ts.map +1 -1
- package/bin/plugin/core/ActionScheduleRuntime.d.ts +1 -1
- package/bin/plugin/core/ActionScheduleRuntime.d.ts.map +1 -1
- package/bin/plugin/core/BasePlugin.d.ts +4 -3
- package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
- package/bin/plugin/core/BasePlugin.js.map +1 -1
- package/bin/plugin/core/HookRegistry.d.ts +5 -8
- package/bin/plugin/core/HookRegistry.d.ts.map +1 -1
- package/bin/plugin/core/HookRegistry.js +12 -12
- package/bin/plugin/core/HookRegistry.js.map +1 -1
- package/bin/plugin/core/PluginActionFactory.d.ts +6 -3
- package/bin/plugin/core/PluginActionFactory.d.ts.map +1 -1
- package/bin/plugin/core/PluginActionFactory.js.map +1 -1
- package/bin/plugin/core/PluginActionRunner.d.ts +1 -1
- package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
- package/bin/plugin/core/PluginCatalog.d.ts +1 -1
- package/bin/plugin/core/PluginCatalog.d.ts.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 -5
- package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +4 -12
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/core/PluginRegistry.d.ts +16 -12
- package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginRegistry.js +43 -22
- package/bin/plugin/core/PluginRegistry.js.map +1 -1
- package/bin/plugin/core/PluginStateController.d.ts +1 -1
- package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
- package/bin/{agent/remote → remote}/RemoteAgent.d.ts +4 -4
- package/bin/remote/RemoteAgent.d.ts.map +1 -0
- package/bin/{agent/remote → remote}/RemoteAgent.js +3 -3
- package/bin/remote/RemoteAgent.js.map +1 -0
- package/bin/{agent/remote → remote}/RemoteSession.d.ts +9 -11
- package/bin/remote/RemoteSession.d.ts.map +1 -0
- package/bin/{agent/remote → remote}/RemoteSession.js +3 -33
- package/bin/remote/RemoteSession.js.map +1 -0
- package/bin/{agent/remote → remote}/RemoteTransport.d.ts +7 -9
- package/bin/remote/RemoteTransport.d.ts.map +1 -0
- package/bin/remote/RemoteTransport.js.map +1 -0
- package/bin/{agent/remote → remote}/TransportFactory.d.ts +1 -1
- package/bin/remote/TransportFactory.d.ts.map +1 -0
- package/bin/{agent/remote → remote}/TransportFactory.js +2 -2
- package/bin/remote/TransportFactory.js.map +1 -0
- package/bin/{agent/remote → remote}/transports/HttpRemoteAgentTransport.d.ts +8 -9
- package/bin/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -0
- package/bin/{agent/remote → remote}/transports/HttpRemoteAgentTransport.js +0 -13
- package/bin/remote/transports/HttpRemoteAgentTransport.js.map +1 -0
- package/bin/{rpc/Client.d.ts → remote/transports/RpcClient.d.ts} +15 -22
- package/bin/remote/transports/RpcClient.d.ts.map +1 -0
- package/bin/{rpc/Client.js → remote/transports/RpcClient.js} +2 -13
- package/bin/remote/transports/RpcClient.js.map +1 -0
- package/bin/{agent/remote → remote}/transports/RpcRemoteAgentTransport.d.ts +8 -9
- package/bin/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -0
- package/bin/{agent/remote → remote}/transports/RpcRemoteAgentTransport.js +1 -4
- package/bin/remote/transports/RpcRemoteAgentTransport.js.map +1 -0
- package/bin/session/DefaultSessionComposer.d.ts +18 -0
- package/bin/session/DefaultSessionComposer.d.ts.map +1 -0
- package/bin/session/DefaultSessionComposer.js +62 -0
- package/bin/session/DefaultSessionComposer.js.map +1 -0
- package/bin/session/Session.d.ts +44 -33
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +440 -274
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionMessages.d.ts +133 -0
- package/bin/session/SessionMessages.d.ts.map +1 -0
- package/bin/session/{recorder/SessionRecorder.js → SessionMessages.js} +247 -284
- package/bin/session/SessionMessages.js.map +1 -0
- package/bin/session/SessionQueue.d.ts +34 -0
- package/bin/session/SessionQueue.d.ts.map +1 -0
- package/bin/session/SessionQueue.js +60 -0
- package/bin/session/SessionQueue.js.map +1 -0
- package/bin/session/SessionState.d.ts +70 -0
- package/bin/session/SessionState.d.ts.map +1 -0
- package/bin/session/SessionState.js +267 -0
- package/bin/session/SessionState.js.map +1 -0
- package/bin/session/SessionSystem.d.ts +15 -0
- package/bin/session/SessionSystem.d.ts.map +1 -0
- package/bin/session/SessionSystem.js +95 -0
- package/bin/session/SessionSystem.js.map +1 -0
- package/bin/session/SessionTurn.d.ts +84 -0
- package/bin/session/SessionTurn.d.ts.map +1 -0
- package/bin/session/SessionTurn.js +588 -0
- package/bin/session/SessionTurn.js.map +1 -0
- package/bin/session/approval/SessionApprovalBroker.d.ts +48 -0
- package/bin/session/approval/SessionApprovalBroker.d.ts.map +1 -0
- package/bin/session/approval/SessionApprovalBroker.js +126 -0
- package/bin/session/approval/SessionApprovalBroker.js.map +1 -0
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +1 -4
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/{recorder → messages}/JsonlSessionMessageStore.d.ts.map +1 -1
- package/bin/session/{recorder → messages}/JsonlSessionMessageStore.js.map +1 -1
- package/bin/session/messages/SessionAssistantMessageWriter.d.ts +62 -0
- package/bin/session/messages/SessionAssistantMessageWriter.d.ts.map +1 -0
- package/bin/session/messages/SessionAssistantMessageWriter.js +287 -0
- package/bin/session/messages/SessionAssistantMessageWriter.js.map +1 -0
- package/bin/session/messages/SessionJsonValue.d.ts +10 -0
- package/bin/session/messages/SessionJsonValue.d.ts.map +1 -0
- package/bin/session/messages/SessionJsonValue.js +23 -0
- package/bin/session/messages/SessionJsonValue.js.map +1 -0
- package/bin/session/{recorder → messages}/SessionMessageCodec.d.ts +4 -1
- package/bin/session/messages/SessionMessageCodec.d.ts.map +1 -0
- package/bin/session/{recorder → messages}/SessionMessageCodec.js +33 -19
- package/bin/session/messages/SessionMessageCodec.js.map +1 -0
- package/bin/session/messages/SessionMessageCompaction.d.ts +22 -0
- package/bin/session/messages/SessionMessageCompaction.d.ts.map +1 -0
- package/bin/session/{recorder/SessionRecorderCompaction.js → messages/SessionMessageCompaction.js} +19 -51
- package/bin/session/messages/SessionMessageCompaction.js.map +1 -0
- package/bin/session/runtime/SessionEventHub.d.ts +1 -8
- package/bin/session/runtime/SessionEventHub.d.ts.map +1 -1
- package/bin/session/runtime/SessionEventHub.js +1 -6
- package/bin/session/runtime/SessionEventHub.js.map +1 -1
- package/bin/session/storage/Metadata.d.ts +23 -5
- package/bin/session/storage/Metadata.d.ts.map +1 -1
- package/bin/session/storage/Metadata.js +32 -29
- package/bin/session/storage/Metadata.js.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.d.ts +5 -10
- package/bin/session/storage/RuntimeSessionPort.d.ts.map +1 -1
- package/bin/session/storage/RuntimeSessionPort.js +2 -4
- package/bin/session/storage/RuntimeSessionPort.js.map +1 -1
- package/bin/types/agent/AgentOptions.d.ts +6 -35
- package/bin/types/agent/AgentOptions.d.ts.map +1 -1
- package/bin/types/agent/AgentState.d.ts +28 -0
- package/bin/types/agent/AgentState.d.ts.map +1 -0
- package/bin/types/agent/AgentState.js +9 -0
- package/bin/types/agent/AgentState.js.map +1 -0
- package/bin/types/agent/SessionActor.d.ts +0 -2
- package/bin/types/agent/SessionActor.d.ts.map +1 -1
- package/bin/types/agent/SessionTypes.d.ts +5 -18
- package/bin/types/agent/SessionTypes.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.d.ts +8 -2
- package/bin/types/executor/SessionRunContext.d.ts.map +1 -1
- package/bin/types/executor/SessionRunContext.js +1 -1
- package/bin/types/executor/SessionToolExecutionContext.d.ts +20 -0
- package/bin/types/executor/SessionToolExecutionContext.d.ts.map +1 -0
- package/bin/types/executor/SessionToolExecutionContext.js +10 -0
- package/bin/types/executor/SessionToolExecutionContext.js.map +1 -0
- package/bin/types/plugin/PluginAction.d.ts +10 -1
- package/bin/types/plugin/PluginAction.d.ts.map +1 -1
- package/bin/types/plugin/PluginCommand.d.ts +3 -11
- package/bin/types/plugin/PluginCommand.d.ts.map +1 -1
- package/bin/types/plugin/PluginConfig.d.ts +12 -0
- package/bin/types/plugin/PluginConfig.d.ts.map +1 -0
- package/bin/types/plugin/PluginConfig.js +5 -0
- package/bin/types/plugin/PluginConfig.js.map +1 -0
- package/bin/types/plugin/PluginDefinition.d.ts +10 -3
- package/bin/types/plugin/PluginDefinition.d.ts.map +1 -1
- package/bin/types/plugin/PluginHttp.d.ts +1 -1
- package/bin/types/plugin/PluginHttp.d.ts.map +1 -1
- package/bin/types/plugin/PluginRunContext.d.ts +26 -0
- package/bin/types/plugin/PluginRunContext.d.ts.map +1 -0
- package/bin/types/plugin/PluginRunContext.js +10 -0
- package/bin/types/plugin/PluginRunContext.js.map +1 -0
- package/bin/types/plugin/PluginRuntime.d.ts +9 -3
- package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
- package/bin/types/plugin/PluginToolRuntime.d.ts +11 -0
- package/bin/types/plugin/PluginToolRuntime.d.ts.map +1 -1
- package/bin/types/rpc/RpcProtocol.d.ts +1 -13
- package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
- package/bin/types/session/SessionApproval.d.ts +4 -38
- package/bin/types/session/SessionApproval.d.ts.map +1 -1
- package/bin/types/session/SessionApprovalBroker.d.ts +17 -0
- package/bin/types/session/SessionApprovalBroker.d.ts.map +1 -0
- package/bin/types/session/SessionApprovalBroker.js +7 -0
- package/bin/types/session/SessionApprovalBroker.js.map +1 -0
- package/bin/types/session/SessionComposer.d.ts +99 -0
- package/bin/types/session/SessionComposer.d.ts.map +1 -0
- package/bin/types/session/SessionComposer.js +8 -0
- package/bin/types/session/SessionComposer.js.map +1 -0
- package/bin/types/session/SessionLocalState.d.ts +6 -6
- package/bin/types/session/SessionLocalState.d.ts.map +1 -1
- package/bin/types/session/SessionLocalState.js +1 -1
- package/bin/types/session/SessionMessage.d.ts +3 -2
- package/bin/types/session/SessionMessage.d.ts.map +1 -1
- package/bin/types/session/SessionMessages.d.ts +115 -0
- package/bin/types/session/SessionMessages.d.ts.map +1 -0
- package/bin/types/session/SessionMessages.js +7 -0
- package/bin/types/session/SessionMessages.js.map +1 -0
- package/bin/types/session/SessionMutation.d.ts +1 -10
- package/bin/types/session/SessionMutation.d.ts.map +1 -1
- package/bin/types/session/SessionMutation.js.map +1 -1
- package/bin/types/session/SessionOptions.d.ts +8 -23
- package/bin/types/session/SessionOptions.d.ts.map +1 -1
- package/bin/types/session/SessionPort.d.ts +72 -0
- package/bin/types/session/SessionPort.d.ts.map +1 -0
- package/bin/types/session/SessionPort.js +9 -0
- package/bin/types/session/SessionPort.js.map +1 -0
- package/bin/types/session/SessionQueue.d.ts +104 -0
- package/bin/types/session/SessionQueue.d.ts.map +1 -0
- package/bin/types/session/SessionQueue.js +7 -0
- package/bin/types/session/SessionQueue.js.map +1 -0
- package/bin/types/session/SessionState.d.ts +43 -0
- package/bin/types/session/SessionState.d.ts.map +1 -0
- package/bin/types/session/SessionState.js +7 -0
- package/bin/types/session/SessionState.js.map +1 -0
- package/bin/types/session/SessionSystem.d.ts +26 -0
- package/bin/types/session/SessionSystem.d.ts.map +1 -0
- package/bin/types/session/SessionSystem.js +7 -0
- package/bin/types/session/SessionSystem.js.map +1 -0
- package/bin/types/session/SessionTool.d.ts +23 -0
- package/bin/types/session/SessionTool.d.ts.map +1 -0
- package/bin/types/session/SessionTool.js +7 -0
- package/bin/types/session/SessionTool.js.map +1 -0
- package/bin/types/session/SessionTurn.d.ts +52 -0
- package/bin/types/session/SessionTurn.d.ts.map +1 -0
- package/bin/types/session/SessionTurn.js +7 -0
- package/bin/types/session/SessionTurn.js.map +1 -0
- package/package.json +3 -3
- package/scripts/agent-env.test.mjs +4 -18
- package/scripts/agent-ready.test.mjs +33 -2
- package/scripts/agent-session-maintenance.test.mjs +52 -0
- package/scripts/city-model-tool-loop.test.mjs +3 -4
- package/scripts/core-engine-context-compaction.test.mjs +5 -22
- package/scripts/image-plugin-job.test.mjs +4 -6
- package/scripts/plugin-tool-bridge.test.mjs +44 -36
- package/scripts/read-image-tool-bridge.test.mjs +71 -0
- package/scripts/remote-session-reconnect.test.mjs +1 -34
- package/scripts/session-compaction-prompts.test.mjs +1 -49
- package/scripts/session-composer.test.mjs +163 -0
- package/scripts/session-config-turn-boundary.test.mjs +2 -5
- package/scripts/session-list-title.test.mjs +3 -2
- package/scripts/session-messages-error.test.mjs +57 -0
- package/scripts/{session-recorder.test.mjs → session-messages.test.mjs} +245 -93
- package/scripts/session-queue.test.mjs +64 -0
- package/scripts/session-shell-approval.test.mjs +171 -0
- package/scripts/session-system-blocks.test.mjs +10 -10
- package/scripts/session-title-event.test.mjs +1 -0
- package/src/agent/Agent.ts +241 -0
- package/src/agent/AgentContext.ts +92 -0
- package/src/agent/{local/AgentInstructions.ts → AgentInstructions.ts} +0 -11
- package/src/{model/CityModelAdapter.ts → agent/AgentModel.ts} +10 -3
- package/src/agent/{local/services/AgentSessions.ts → AgentSessions.ts} +81 -110
- package/src/agent/AgentState.ts +151 -0
- package/src/config/Paths.ts +0 -91
- package/src/executor/Executor.ts +180 -386
- package/src/executor/README.md +62 -86
- package/src/executor/composer/system/default/DefaultSessionSystemComposer.ts +1 -1
- package/src/executor/composer/system/default/SystemDomain.ts +4 -2
- package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
- package/src/executor/composer/system/default/assets/core.prompt.ts.txt +15 -2
- package/src/executor/core-engine/CoreEngineRunner.ts +95 -54
- package/src/executor/services/ExecutorRecoveryPolicy.ts +24 -19
- package/src/executor/tools/file/ReadImageToolBridge.ts +79 -0
- package/src/executor/tools/plugin/PluginToolBridge.ts +6 -8
- package/src/executor/tools/plugin/PluginToolDefinition.ts +23 -3
- package/src/executor/types/SessionHistoryMeta.ts +0 -2
- package/src/index.ts +34 -53
- package/src/plugin/core/ActionScheduleExecutor.ts +1 -1
- package/src/plugin/core/ActionScheduleRuntime.ts +1 -1
- package/src/plugin/core/BasePlugin.ts +7 -3
- package/src/plugin/core/HookRegistry.ts +15 -18
- package/src/plugin/core/PluginActionFactory.ts +9 -3
- package/src/plugin/core/PluginActionRunner.ts +1 -1
- package/src/plugin/core/PluginCatalog.ts +1 -1
- package/src/plugin/core/PluginHttpRoutes.ts +1 -1
- package/src/plugin/core/PluginLocalExecution.ts +11 -24
- package/src/plugin/core/PluginRegistry.ts +55 -32
- package/src/plugin/core/PluginStateController.ts +1 -1
- package/src/{agent/remote → remote}/RemoteAgent.ts +4 -4
- package/src/{agent/remote → remote}/RemoteSession.ts +2 -35
- package/src/{agent/remote → remote}/RemoteTransport.ts +0 -3
- package/src/{agent/remote → remote}/TransportFactory.ts +3 -3
- package/src/{agent/remote → remote}/transports/HttpRemoteAgentTransport.ts +1 -23
- package/src/{rpc/Client.ts → remote/transports/RpcClient.ts} +1 -19
- package/src/{agent/remote → remote}/transports/RpcRemoteAgentTransport.ts +2 -10
- package/src/session/DefaultSessionComposer.ts +79 -0
- package/src/session/Session.ts +496 -332
- package/src/session/{recorder/SessionRecorder.ts → SessionMessages.ts} +324 -428
- package/src/session/SessionQueue.ts +86 -0
- package/src/session/SessionState.ts +322 -0
- package/src/session/SessionSystem.ts +117 -0
- package/src/session/SessionTurn.ts +684 -0
- package/src/session/approval/SessionApprovalBroker.ts +164 -0
- package/src/session/browse/Browse.ts +1 -4
- package/src/session/messages/SessionAssistantMessageWriter.ts +345 -0
- package/src/session/messages/SessionJsonValue.ts +25 -0
- package/src/session/{recorder → messages}/SessionMessageCodec.ts +38 -20
- package/src/session/{recorder/SessionRecorderCompaction.ts → messages/SessionMessageCompaction.ts} +30 -69
- package/src/session/runtime/SessionEventHub.ts +1 -14
- package/src/session/storage/Metadata.ts +60 -34
- package/src/session/storage/RuntimeSessionPort.ts +7 -14
- package/src/types/agent/AgentOptions.ts +6 -38
- package/src/types/agent/AgentState.ts +33 -0
- package/src/types/agent/SessionActor.ts +0 -3
- package/src/types/agent/SessionTypes.ts +5 -18
- package/src/types/executor/SessionRunContext.ts +10 -2
- package/src/types/executor/SessionToolExecutionContext.ts +21 -0
- package/src/types/plugin/PluginAction.ts +10 -1
- package/src/types/plugin/PluginCommand.ts +3 -14
- package/src/types/plugin/PluginConfig.ts +13 -0
- package/src/types/plugin/PluginDefinition.ts +13 -6
- package/src/types/plugin/PluginHttp.ts +1 -1
- package/src/types/plugin/PluginRunContext.ts +31 -0
- package/src/types/plugin/PluginRuntime.ts +13 -6
- package/src/types/plugin/PluginToolRuntime.ts +13 -1
- package/src/types/rpc/RpcProtocol.ts +0 -14
- package/src/types/session/SessionApproval.ts +4 -43
- package/src/types/session/SessionApprovalBroker.ts +18 -0
- package/src/types/session/SessionComposer.ts +114 -0
- package/src/types/session/SessionLocalState.ts +6 -6
- package/src/types/session/SessionMessage.ts +3 -2
- package/src/types/session/SessionMessages.ts +127 -0
- package/src/types/session/SessionMutation.ts +0 -11
- package/src/types/session/SessionOptions.ts +8 -40
- package/src/types/session/SessionPort.ts +97 -0
- package/src/types/session/SessionQueue.ts +122 -0
- package/src/types/session/SessionState.ts +47 -0
- package/src/types/session/SessionSystem.ts +27 -0
- package/src/types/session/SessionTool.ts +25 -0
- package/src/types/session/SessionTurn.ts +56 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/agent/local/Agent.d.ts.map +0 -1
- package/bin/agent/local/Agent.js +0 -216
- package/bin/agent/local/Agent.js.map +0 -1
- package/bin/agent/local/AgentInstructions.d.ts.map +0 -1
- package/bin/agent/local/AgentInstructions.js.map +0 -1
- package/bin/agent/local/AgentPluginFactory.d.ts +0 -26
- package/bin/agent/local/AgentPluginFactory.d.ts.map +0 -1
- package/bin/agent/local/AgentPluginFactory.js +0 -33
- package/bin/agent/local/AgentPluginFactory.js.map +0 -1
- package/bin/agent/local/AgentRuntimeAssembly.d.ts +0 -10
- package/bin/agent/local/AgentRuntimeAssembly.d.ts.map +0 -1
- package/bin/agent/local/AgentRuntimeAssembly.js +0 -43
- package/bin/agent/local/AgentRuntimeAssembly.js.map +0 -1
- package/bin/agent/local/ProjectSetup.d.ts.map +0 -1
- package/bin/agent/local/ProjectSetup.js.map +0 -1
- package/bin/agent/local/services/AgentAssemblyService.d.ts +0 -105
- package/bin/agent/local/services/AgentAssemblyService.d.ts.map +0 -1
- package/bin/agent/local/services/AgentAssemblyService.js +0 -184
- package/bin/agent/local/services/AgentAssemblyService.js.map +0 -1
- package/bin/agent/local/services/AgentBackgroundService.d.ts +0 -55
- package/bin/agent/local/services/AgentBackgroundService.d.ts.map +0 -1
- package/bin/agent/local/services/AgentBackgroundService.js +0 -85
- package/bin/agent/local/services/AgentBackgroundService.js.map +0 -1
- package/bin/agent/local/services/AgentSessions.d.ts.map +0 -1
- package/bin/agent/local/services/AgentSessions.js.map +0 -1
- package/bin/agent/remote/RemoteAgent.d.ts.map +0 -1
- package/bin/agent/remote/RemoteAgent.js.map +0 -1
- package/bin/agent/remote/RemoteSession.d.ts.map +0 -1
- package/bin/agent/remote/RemoteSession.js.map +0 -1
- package/bin/agent/remote/RemoteTransport.d.ts.map +0 -1
- package/bin/agent/remote/RemoteTransport.js.map +0 -1
- package/bin/agent/remote/TransportFactory.d.ts.map +0 -1
- package/bin/agent/remote/TransportFactory.js.map +0 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +0 -1
- package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +0 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +0 -1
- package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +0 -1
- package/bin/executor/SessionRunScope.d.ts +0 -68
- package/bin/executor/SessionRunScope.d.ts.map +0 -1
- package/bin/executor/SessionRunScope.js +0 -96
- package/bin/executor/SessionRunScope.js.map +0 -1
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts +0 -74
- package/bin/executor/composer/compaction/SessionCompactionComposer.d.ts.map +0 -1
- package/bin/executor/composer/compaction/SessionCompactionComposer.js +0 -9
- package/bin/executor/composer/compaction/SessionCompactionComposer.js.map +0 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts +0 -27
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.d.ts.map +0 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js +0 -39
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.js.map +0 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts +0 -44
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +0 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +0 -218
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +0 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts +0 -27
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.d.ts.map +0 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js +0 -181
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js.map +0 -1
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts +0 -50
- package/bin/executor/composer/context/LocalSessionContextComposer.d.ts.map +0 -1
- package/bin/executor/composer/context/LocalSessionContextComposer.js +0 -108
- package/bin/executor/composer/context/LocalSessionContextComposer.js.map +0 -1
- package/bin/executor/composer/context/SessionContextComposer.d.ts +0 -67
- package/bin/executor/composer/context/SessionContextComposer.d.ts.map +0 -1
- package/bin/executor/composer/context/SessionContextComposer.js +0 -9
- package/bin/executor/composer/context/SessionContextComposer.js.map +0 -1
- package/bin/executor/composer/history/SessionHistoryComposer.d.ts +0 -54
- package/bin/executor/composer/history/SessionHistoryComposer.d.ts.map +0 -1
- package/bin/executor/composer/history/SessionHistoryComposer.js +0 -10
- package/bin/executor/composer/history/SessionHistoryComposer.js.map +0 -1
- package/bin/executor/composer/history/SessionHistoryWriter.d.ts +0 -46
- package/bin/executor/composer/history/SessionHistoryWriter.d.ts.map +0 -1
- package/bin/executor/composer/history/SessionHistoryWriter.js +0 -65
- package/bin/executor/composer/history/SessionHistoryWriter.js.map +0 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts +0 -35
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.d.ts.map +0 -1
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js +0 -105
- package/bin/executor/composer/history/jsonl/JsonlSessionHistoryComposer.js.map +0 -1
- package/bin/executor/messages/AssistantResultPersistence.d.ts +0 -66
- package/bin/executor/messages/AssistantResultPersistence.d.ts.map +0 -1
- package/bin/executor/messages/AssistantResultPersistence.js +0 -44
- package/bin/executor/messages/AssistantResultPersistence.js.map +0 -1
- package/bin/executor/services/ExecutorInflightService.d.ts +0 -34
- package/bin/executor/services/ExecutorInflightService.d.ts.map +0 -1
- package/bin/executor/services/ExecutorInflightService.js +0 -73
- package/bin/executor/services/ExecutorInflightService.js.map +0 -1
- package/bin/executor/store/history/SessionHistoryStore.d.ts +0 -140
- package/bin/executor/store/history/SessionHistoryStore.d.ts.map +0 -1
- package/bin/executor/store/history/SessionHistoryStore.js +0 -10
- package/bin/executor/store/history/SessionHistoryStore.js.map +0 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +0 -116
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +0 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +0 -709
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +0 -1
- package/bin/executor/types/SessionHistoryPaths.d.ts +0 -34
- package/bin/executor/types/SessionHistoryPaths.d.ts.map +0 -1
- package/bin/executor/types/SessionHistoryPaths.js +0 -2
- package/bin/executor/types/SessionHistoryPaths.js.map +0 -1
- package/bin/model/CityModelAdapter.d.ts.map +0 -1
- package/bin/model/CityModelAdapter.js.map +0 -1
- package/bin/rpc/Client.d.ts.map +0 -1
- package/bin/rpc/Client.js.map +0 -1
- package/bin/session/SessionSystemBuilder.d.ts +0 -107
- package/bin/session/SessionSystemBuilder.d.ts.map +0 -1
- package/bin/session/SessionSystemBuilder.js +0 -148
- package/bin/session/SessionSystemBuilder.js.map +0 -1
- package/bin/session/recorder/SessionMessageCodec.d.ts.map +0 -1
- package/bin/session/recorder/SessionMessageCodec.js.map +0 -1
- package/bin/session/recorder/SessionRecorder.d.ts +0 -217
- package/bin/session/recorder/SessionRecorder.d.ts.map +0 -1
- package/bin/session/recorder/SessionRecorder.js.map +0 -1
- package/bin/session/recorder/SessionRecorderCompaction.d.ts +0 -18
- package/bin/session/recorder/SessionRecorderCompaction.d.ts.map +0 -1
- package/bin/session/recorder/SessionRecorderCompaction.js.map +0 -1
- package/bin/session/recorder/SessionRecorderHistoryStore.d.ts +0 -66
- package/bin/session/recorder/SessionRecorderHistoryStore.d.ts.map +0 -1
- package/bin/session/recorder/SessionRecorderHistoryStore.js +0 -190
- package/bin/session/recorder/SessionRecorderHistoryStore.js.map +0 -1
- package/bin/session/runtime/SessionPromptRuntime.d.ts +0 -112
- package/bin/session/runtime/SessionPromptRuntime.d.ts.map +0 -1
- package/bin/session/runtime/SessionPromptRuntime.js +0 -357
- package/bin/session/runtime/SessionPromptRuntime.js.map +0 -1
- package/bin/session/services/SessionStateService.d.ts +0 -187
- package/bin/session/services/SessionStateService.d.ts.map +0 -1
- package/bin/session/services/SessionStateService.js +0 -467
- package/bin/session/services/SessionStateService.js.map +0 -1
- package/bin/session/services/SessionTurnService.d.ts +0 -90
- package/bin/session/services/SessionTurnService.d.ts.map +0 -1
- package/bin/session/services/SessionTurnService.js +0 -293
- package/bin/session/services/SessionTurnService.js.map +0 -1
- package/bin/session/services/SessionViewService.d.ts +0 -114
- package/bin/session/services/SessionViewService.d.ts.map +0 -1
- package/bin/session/services/SessionViewService.js +0 -204
- package/bin/session/services/SessionViewService.js.map +0 -1
- package/bin/session/storage/Persistence.d.ts +0 -73
- package/bin/session/storage/Persistence.d.ts.map +0 -1
- package/bin/session/storage/Persistence.js +0 -63
- package/bin/session/storage/Persistence.js.map +0 -1
- package/bin/types/agent/AgentRuntimeAssembly.d.ts +0 -72
- package/bin/types/agent/AgentRuntimeAssembly.d.ts.map +0 -1
- package/bin/types/agent/AgentRuntimeAssembly.js +0 -10
- package/bin/types/agent/AgentRuntimeAssembly.js.map +0 -1
- package/bin/types/runtime/agent/AgentContext.d.ts +0 -306
- package/bin/types/runtime/agent/AgentContext.d.ts.map +0 -1
- package/bin/types/runtime/agent/AgentContext.js +0 -128
- package/bin/types/runtime/agent/AgentContext.js.map +0 -1
- package/bin/types/session/SessionComposerOptions.d.ts +0 -90
- package/bin/types/session/SessionComposerOptions.d.ts.map +0 -1
- package/bin/types/session/SessionComposerOptions.js +0 -10
- package/bin/types/session/SessionComposerOptions.js.map +0 -1
- package/bin/types/session/SessionQueueCommand.d.ts +0 -68
- package/bin/types/session/SessionQueueCommand.d.ts.map +0 -1
- package/bin/types/session/SessionQueueCommand.js +0 -10
- package/bin/types/session/SessionQueueCommand.js.map +0 -1
- package/scripts/session-action-message.test.mjs +0 -410
- package/scripts/session-compaction-context-window.test.mjs +0 -96
- package/scripts/session-history-inflight.test.mjs +0 -146
- package/scripts/session-history-writer-error.test.mjs +0 -57
- package/scripts/session-prompt-runtime.test.mjs +0 -390
- package/src/agent/local/Agent.ts +0 -250
- package/src/agent/local/AgentPluginFactory.ts +0 -51
- package/src/agent/local/AgentRuntimeAssembly.ts +0 -65
- package/src/agent/local/services/AgentAssemblyService.ts +0 -307
- package/src/agent/local/services/AgentBackgroundService.ts +0 -115
- package/src/executor/SessionRunScope.ts +0 -122
- package/src/executor/composer/compaction/SessionCompactionComposer.ts +0 -84
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionComposer.ts +0 -51
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +0 -294
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.ts +0 -197
- package/src/executor/composer/context/LocalSessionContextComposer.ts +0 -175
- package/src/executor/composer/context/SessionContextComposer.ts +0 -83
- package/src/executor/composer/history/SessionHistoryComposer.ts +0 -62
- package/src/executor/composer/history/SessionHistoryWriter.ts +0 -100
- package/src/executor/composer/history/jsonl/JsonlSessionHistoryComposer.ts +0 -133
- package/src/executor/messages/AssistantResultPersistence.ts +0 -106
- package/src/executor/services/ExecutorInflightService.ts +0 -95
- package/src/executor/store/history/SessionHistoryStore.ts +0 -172
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +0 -879
- package/src/executor/types/SessionHistoryPaths.ts +0 -38
- package/src/session/SessionSystemBuilder.ts +0 -262
- package/src/session/recorder/SessionRecorderHistoryStore.ts +0 -256
- package/src/session/runtime/SessionPromptRuntime.ts +0 -518
- package/src/session/services/SessionStateService.ts +0 -628
- package/src/session/services/SessionTurnService.ts +0 -368
- package/src/session/services/SessionViewService.ts +0 -335
- package/src/session/storage/Persistence.ts +0 -137
- package/src/types/agent/AgentRuntimeAssembly.ts +0 -74
- package/src/types/runtime/agent/AgentContext.ts +0 -387
- package/src/types/session/SessionComposerOptions.ts +0 -107
- package/src/types/session/SessionQueueCommand.ts +0 -78
- /package/bin/{agent/local → config}/ProjectSetup.d.ts +0 -0
- /package/bin/{agent/remote → remote}/RemoteTransport.js +0 -0
- /package/bin/session/{recorder → messages}/JsonlSessionMessageStore.d.ts +0 -0
- /package/bin/session/{recorder → messages}/JsonlSessionMessageStore.js +0 -0
- /package/src/{agent/local → config}/ProjectSetup.ts +0 -0
- /package/src/session/{recorder → messages}/JsonlSessionMessageStore.ts +0 -0
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* SessionMessages:Session Message 的唯一领域入口。
|
|
3
3
|
*
|
|
4
4
|
* 完整 Message 与 Assistant 草稿先持久化,成功后再发布实时 Mutation。
|
|
5
|
+
* 同一 Assistant Message 的流式、审批与关闭操作共享一条写队列,保证 revision
|
|
6
|
+
* 从最新快照严格递增。
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
|
-
import type { UIMessage
|
|
9
|
+
import type { UIMessage } from "ai";
|
|
8
10
|
import { generateId } from "@/utils/Id.js";
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
+
import { SessionAssistantMessageWriter } from "@/session/messages/SessionAssistantMessageWriter.js";
|
|
12
|
+
import { to_session_json_value } from "@/session/messages/SessionJsonValue.js";
|
|
13
|
+
import { JsonlSessionMessageStore } from "@/session/messages/JsonlSessionMessageStore.js";
|
|
14
|
+
import type { JsonObject } from "@/types/common/Json.js";
|
|
11
15
|
import type {
|
|
12
16
|
ListSessionMessagesInput,
|
|
13
17
|
SessionActionMessage,
|
|
14
|
-
SessionAssistantFilePart,
|
|
15
18
|
SessionAssistantMessage,
|
|
16
19
|
SessionAssistantMessagePart,
|
|
17
20
|
SessionAssistantToolPart,
|
|
@@ -30,104 +33,49 @@ import type {
|
|
|
30
33
|
SessionMessageStorageStats,
|
|
31
34
|
SessionSegmentSummary,
|
|
32
35
|
} from "@/types/session/SessionSegment.js";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export
|
|
60
|
-
/** 当前 assistant 所属 turn。 */
|
|
61
|
-
turn_id: string;
|
|
62
|
-
/** 当前 assistant 在 turn 内的 segment 序号。 */
|
|
63
|
-
segment_index: number;
|
|
64
|
-
/** 普通 assistant 或 compact summary。 */
|
|
65
|
-
kind?: "normal" | "summary";
|
|
66
|
-
/** 默认展示范围。 */
|
|
67
|
-
visibility?: "visible" | "internal";
|
|
68
|
-
/** 可选指定 Message ID。 */
|
|
69
|
-
message_id?: string;
|
|
70
|
-
/** Summary 已覆盖到的来源 Message。 */
|
|
71
|
-
summary_through_message_id?: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** 已完成 Assistant Message 直接写入参数。 */
|
|
75
|
-
export interface AppendCompletedAssistantMessageInput {
|
|
76
|
-
/** Assistant 所属 turn。 */
|
|
77
|
-
turn_id?: string;
|
|
78
|
-
/** Assistant 完整 parts。 */
|
|
79
|
-
parts: SessionAssistantMessagePart[];
|
|
80
|
-
/** 普通 assistant 或 compact summary。 */
|
|
81
|
-
kind?: "normal" | "summary";
|
|
82
|
-
/** 默认展示范围。 */
|
|
83
|
-
visibility?: "visible" | "internal";
|
|
84
|
-
/** Summary 已覆盖到的来源 Message。 */
|
|
85
|
-
summary_through_message_id?: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Action Message 创建参数。 */
|
|
89
|
-
export interface OpenSessionActionMessageInput {
|
|
90
|
-
/** 可选稳定 Message ID;业务 action 生命周期使用该值定位。 */
|
|
91
|
-
message_id?: string;
|
|
92
|
-
/** Action 所属 turn。 */
|
|
93
|
-
turn_id?: string;
|
|
94
|
-
/** Action 业务类型。 */
|
|
95
|
-
action_type: string;
|
|
96
|
-
/** Action 标题。 */
|
|
97
|
-
title: string;
|
|
98
|
-
/** Action 描述。 */
|
|
99
|
-
description?: string;
|
|
100
|
-
/** Action 附加数据。 */
|
|
101
|
-
data?: JsonObject;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/** Error Message 创建参数。 */
|
|
105
|
-
export interface AppendSessionErrorMessageInput {
|
|
106
|
-
/** 错误影响范围。 */
|
|
107
|
-
scope: "session" | "turn";
|
|
108
|
-
/** 错误所属 turn。 */
|
|
109
|
-
turn_id?: string;
|
|
110
|
-
/** 稳定错误码。 */
|
|
111
|
-
code: string;
|
|
112
|
-
/** 用户可见错误文本。 */
|
|
113
|
-
message: string;
|
|
114
|
-
/** 是否允许恢复。 */
|
|
115
|
-
recoverable: boolean;
|
|
116
|
-
}
|
|
36
|
+
import type { SessionStreamingToolLocation } from "@/types/session/SessionTool.js";
|
|
37
|
+
import type { SessionApproval } from "@/types/session/SessionApproval.js";
|
|
38
|
+
import type {
|
|
39
|
+
SessionActionRecordV1,
|
|
40
|
+
SessionRecordV1,
|
|
41
|
+
SessionUserMessageV1,
|
|
42
|
+
} from "@/executor/types/SessionRecords.js";
|
|
43
|
+
import { is_session_action_record } from "@/executor/types/SessionRecords.js";
|
|
44
|
+
import {
|
|
45
|
+
from_ui_assistant_parts,
|
|
46
|
+
from_ui_user_parts,
|
|
47
|
+
to_executor_ui_message,
|
|
48
|
+
} from "@/session/messages/SessionMessageCodec.js";
|
|
49
|
+
import { hydrateUserPromptFileParts } from "@executor/messages/SessionAttachmentMapper.js";
|
|
50
|
+
import type {
|
|
51
|
+
AppendCompletedAssistantMessageInput,
|
|
52
|
+
AppendExternalSessionAssistantMessageInput,
|
|
53
|
+
AppendExternalSessionUserMessageInput,
|
|
54
|
+
AppendSessionErrorMessageInput,
|
|
55
|
+
AppendSessionPromptMessageInput,
|
|
56
|
+
AppendSessionUserMessageInput,
|
|
57
|
+
OpenSessionActionMessageInput,
|
|
58
|
+
OpenSessionAssistantMessageInput,
|
|
59
|
+
SessionMessagesOptions,
|
|
60
|
+
} from "@/types/session/SessionMessages.js";
|
|
61
|
+
|
|
62
|
+
export { SessionAssistantMessageWriter } from "@/session/messages/SessionAssistantMessageWriter.js";
|
|
117
63
|
|
|
118
64
|
/** 唯一 Session Message 写入服务。 */
|
|
119
|
-
export class
|
|
65
|
+
export class SessionMessages {
|
|
120
66
|
readonly session_id: string;
|
|
121
67
|
private readonly store: JsonlSessionMessageStore;
|
|
122
|
-
private readonly publish:
|
|
68
|
+
private readonly publish: SessionMessagesOptions["publish"];
|
|
123
69
|
private readonly messages_by_id = new Map<string, SessionMessage>();
|
|
70
|
+
/** 按 Assistant Message 隔离的完整写事务链。 */
|
|
71
|
+
private readonly assistant_write_chains = new Map<string, Promise<void>>();
|
|
124
72
|
private initialized = false;
|
|
125
73
|
|
|
126
|
-
constructor(options:
|
|
74
|
+
constructor(options: SessionMessagesOptions) {
|
|
127
75
|
this.session_id = String(options.session_id || "").trim();
|
|
128
76
|
this.store = options.store;
|
|
129
77
|
this.publish = options.publish;
|
|
130
|
-
if (!this.session_id) throw new Error("
|
|
78
|
+
if (!this.session_id) throw new Error("SessionMessages requires session_id");
|
|
131
79
|
}
|
|
132
80
|
|
|
133
81
|
/** 恢复已有 Message,并收口进程中断遗留的运行状态。 */
|
|
@@ -224,6 +172,160 @@ export class SessionRecorder {
|
|
|
224
172
|
return this.get_message(writer.message_id) as SessionAssistantMessage;
|
|
225
173
|
}
|
|
226
174
|
|
|
175
|
+
/** 把内部 Executor Record 收口为 canonical Session Message。 */
|
|
176
|
+
async append_record(record: SessionRecordV1): Promise<void> {
|
|
177
|
+
if (is_session_action_record(record)) {
|
|
178
|
+
const action = record as SessionActionRecordV1;
|
|
179
|
+
const existing = this.get_message(action.id);
|
|
180
|
+
if (existing?.type === "action") {
|
|
181
|
+
if (action.state !== "running") {
|
|
182
|
+
await this.update_action_message(action.id, action.state, {
|
|
183
|
+
title: action.title,
|
|
184
|
+
description: action.description,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const writer = await this.open_action_message({
|
|
190
|
+
message_id: action.id,
|
|
191
|
+
turn_id: action.metadata.turnId,
|
|
192
|
+
action_type: String(action.id || "").split(":")[0] || "action",
|
|
193
|
+
title: action.title,
|
|
194
|
+
description: action.description,
|
|
195
|
+
});
|
|
196
|
+
if (action.state === "completed") await writer.complete();
|
|
197
|
+
if (action.state === "failed") {
|
|
198
|
+
await writer.fail(action.description || action.title);
|
|
199
|
+
}
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const turn_id = String(
|
|
204
|
+
record.metadata?.turnId || `external:${this.session_id}:${generateId()}`,
|
|
205
|
+
);
|
|
206
|
+
if (record.role === "user") {
|
|
207
|
+
await this.append_user_message({
|
|
208
|
+
turn_id,
|
|
209
|
+
input_type:
|
|
210
|
+
record.metadata?.extra?.inputType === "steer" ? "steer" : "prompt",
|
|
211
|
+
parts: from_ui_user_parts(record.parts),
|
|
212
|
+
});
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
await this.append_completed_assistant_message({
|
|
216
|
+
turn_id,
|
|
217
|
+
parts: from_ui_assistant_parts(record.parts),
|
|
218
|
+
visibility:
|
|
219
|
+
record.metadata?.extra?.visibility === "internal"
|
|
220
|
+
? "internal"
|
|
221
|
+
: "visible",
|
|
222
|
+
kind: record.metadata?.kind === "summary" ? "summary" : "normal",
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** 把公开 Session API 的 User 输入转换为 canonical Message 并持久化。 */
|
|
227
|
+
async append_external_user_message(
|
|
228
|
+
input: AppendExternalSessionUserMessageInput,
|
|
229
|
+
): Promise<boolean> {
|
|
230
|
+
const parts = input.message && "role" in input.message
|
|
231
|
+
? from_ui_user_parts(input.message.parts)
|
|
232
|
+
: [{
|
|
233
|
+
part_id: `external-user-text:${Date.now()}`,
|
|
234
|
+
type: "text" as const,
|
|
235
|
+
text: String(input.text || "").trim(),
|
|
236
|
+
state: "done" as const,
|
|
237
|
+
}];
|
|
238
|
+
if (parts.length === 0) return false;
|
|
239
|
+
await this.append_user_message({
|
|
240
|
+
turn_id: `external:${this.session_id}:${Date.now()}`,
|
|
241
|
+
input_type: "prompt",
|
|
242
|
+
parts,
|
|
243
|
+
});
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** 把公开 Session API 的 Assistant 输入转换为 canonical Message 并持久化。 */
|
|
248
|
+
async append_external_assistant_message(
|
|
249
|
+
input: AppendExternalSessionAssistantMessageInput,
|
|
250
|
+
): Promise<boolean> {
|
|
251
|
+
const parts = input.message && "role" in input.message
|
|
252
|
+
? from_ui_assistant_parts(input.message.parts)
|
|
253
|
+
: [{
|
|
254
|
+
part_id: `external-assistant-text:${Date.now()}`,
|
|
255
|
+
sequence: 1,
|
|
256
|
+
type: "text" as const,
|
|
257
|
+
text: String(input.fallback_text || "").trim(),
|
|
258
|
+
state: "done" as const,
|
|
259
|
+
}];
|
|
260
|
+
if (parts.length === 0) return false;
|
|
261
|
+
await this.append_completed_assistant_message({ parts });
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** 把 Session prompt 转换为 canonical User Message 并持久化。 */
|
|
266
|
+
async append_prompt_message(
|
|
267
|
+
input: AppendSessionPromptMessageInput,
|
|
268
|
+
): Promise<SessionUserMessageV1> {
|
|
269
|
+
const query = input.prompt.query;
|
|
270
|
+
const ui_parts = typeof query === "string"
|
|
271
|
+
? [{ type: "text" as const, text: query.trim() }]
|
|
272
|
+
: await hydrateUserPromptFileParts(
|
|
273
|
+
Array.isArray(query) ? query : [],
|
|
274
|
+
input.project_root,
|
|
275
|
+
);
|
|
276
|
+
const canonical = await this.append_user_message({
|
|
277
|
+
turn_id: input.turn_id,
|
|
278
|
+
input_type: input.input_type,
|
|
279
|
+
parts: normalize_session_user_parts(ui_parts),
|
|
280
|
+
});
|
|
281
|
+
return to_executor_ui_message(canonical) as SessionUserMessageV1;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** 持久化 Executor 在本轮延迟产生的 User Message。 */
|
|
285
|
+
async append_deferred_user_messages(
|
|
286
|
+
deferred_messages?: SessionUserMessageV1[],
|
|
287
|
+
): Promise<number> {
|
|
288
|
+
const messages = Array.isArray(deferred_messages)
|
|
289
|
+
? deferred_messages
|
|
290
|
+
: [];
|
|
291
|
+
for (const message of messages) {
|
|
292
|
+
await this.append_user_message({
|
|
293
|
+
turn_id: String(
|
|
294
|
+
message.metadata?.turnId ||
|
|
295
|
+
`deferred:${this.session_id}:${Date.now()}`,
|
|
296
|
+
),
|
|
297
|
+
input_type: "steer",
|
|
298
|
+
parts: from_ui_user_parts(message.parts),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return messages.length;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** 按稳定 Action ID 创建或更新 canonical Action Message。 */
|
|
305
|
+
async persist_action_record(event: SessionActionRecordV1): Promise<void> {
|
|
306
|
+
const existing = this.get_message(event.id);
|
|
307
|
+
if (!existing) {
|
|
308
|
+
const writer = await this.open_action_message({
|
|
309
|
+
message_id: event.id,
|
|
310
|
+
turn_id: event.metadata.turnId,
|
|
311
|
+
action_type: infer_action_type(event.id),
|
|
312
|
+
title: event.title,
|
|
313
|
+
description: event.description,
|
|
314
|
+
});
|
|
315
|
+
if (event.state === "completed") await writer.complete();
|
|
316
|
+
if (event.state === "failed") {
|
|
317
|
+
await writer.fail(event.description || event.title);
|
|
318
|
+
}
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
if (existing.type === "action" && event.state !== "running") {
|
|
322
|
+
await this.update_action_message(event.id, event.state, {
|
|
323
|
+
title: event.title,
|
|
324
|
+
description: event.description,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
227
329
|
/** 创建 running Action Message。 */
|
|
228
330
|
async open_action_message(
|
|
229
331
|
input: OpenSessionActionMessageInput,
|
|
@@ -416,6 +518,18 @@ export class SessionRecorder {
|
|
|
416
518
|
delta: string,
|
|
417
519
|
): Promise<void> {
|
|
418
520
|
if (!delta) return;
|
|
521
|
+
await this.enqueue_assistant_write(message_id, async () => {
|
|
522
|
+
await this.append_assistant_delta_serialized(message_id, part_id, type, delta);
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** 在 Assistant 写队列内追加文本 delta。 */
|
|
527
|
+
private async append_assistant_delta_serialized(
|
|
528
|
+
message_id: string,
|
|
529
|
+
part_id: string,
|
|
530
|
+
type: "text" | "reasoning",
|
|
531
|
+
delta: string,
|
|
532
|
+
): Promise<void> {
|
|
419
533
|
const current = require_message([...this.messages_by_id.values()], message_id, "assistant");
|
|
420
534
|
require_streaming_assistant(current);
|
|
421
535
|
const part = current.parts.find((item) => item.part_id === part_id);
|
|
@@ -453,6 +567,16 @@ export class SessionRecorder {
|
|
|
453
567
|
async update_assistant_part(
|
|
454
568
|
message_id: string,
|
|
455
569
|
part: SessionAssistantMessagePart,
|
|
570
|
+
): Promise<void> {
|
|
571
|
+
await this.enqueue_assistant_write(message_id, async () => {
|
|
572
|
+
await this.update_assistant_part_serialized(message_id, part);
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** 在 Assistant 写队列内提交完整 Part 快照。 */
|
|
577
|
+
private async update_assistant_part_serialized(
|
|
578
|
+
message_id: string,
|
|
579
|
+
part: SessionAssistantMessagePart,
|
|
456
580
|
): Promise<void> {
|
|
457
581
|
const current = require_message([...this.messages_by_id.values()], message_id, "assistant");
|
|
458
582
|
require_streaming_assistant(current);
|
|
@@ -490,6 +614,16 @@ export class SessionRecorder {
|
|
|
490
614
|
async complete_assistant_message(
|
|
491
615
|
message_id: string,
|
|
492
616
|
status: "completed" | "stopped" | "failed",
|
|
617
|
+
): Promise<void> {
|
|
618
|
+
await this.enqueue_assistant_write(message_id, async () => {
|
|
619
|
+
await this.complete_assistant_message_serialized(message_id, status);
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/** 在 Assistant 写队列内关闭草稿并写入 Active。 */
|
|
624
|
+
private async complete_assistant_message_serialized(
|
|
625
|
+
message_id: string,
|
|
626
|
+
status: "completed" | "stopped" | "failed",
|
|
493
627
|
): Promise<void> {
|
|
494
628
|
const current = require_message([...this.messages_by_id.values()], message_id, "assistant");
|
|
495
629
|
require_streaming_assistant(current);
|
|
@@ -509,42 +643,11 @@ export class SessionRecorder {
|
|
|
509
643
|
this.accept_message(message);
|
|
510
644
|
}
|
|
511
645
|
|
|
512
|
-
/** @internal 将 Shell Runtime 审批请求更新到当前 Tool Part。 */
|
|
513
|
-
async require_tool_approval(input: {
|
|
514
|
-
tool_call_id: string;
|
|
515
|
-
approval_id: string;
|
|
516
|
-
}): Promise<void> {
|
|
517
|
-
const tool = this.find_streaming_tool(input.tool_call_id);
|
|
518
|
-
await this.update_assistant_part(tool.message_id, {
|
|
519
|
-
...tool.part,
|
|
520
|
-
state: "approval-required",
|
|
521
|
-
approval_id: input.approval_id,
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
/** @internal 将审批结果更新到当前 Tool Part。 */
|
|
526
|
-
async resolve_tool_approval(input: {
|
|
527
|
-
tool_call_id: string;
|
|
528
|
-
approval_id: string;
|
|
529
|
-
decision: "approved" | "denied" | "expired";
|
|
530
|
-
}): Promise<void> {
|
|
531
|
-
const tool = this.find_streaming_tool(input.tool_call_id);
|
|
532
|
-
if (tool.part.approval_id && tool.part.approval_id !== input.approval_id) {
|
|
533
|
-
throw new Error(`Tool approval identity mismatch: ${input.approval_id}`);
|
|
534
|
-
}
|
|
535
|
-
await this.update_assistant_part(tool.message_id, {
|
|
536
|
-
...tool.part,
|
|
537
|
-
state: input.decision === "approved" ? "running" : "failed",
|
|
538
|
-
...(input.decision === "approved"
|
|
539
|
-
? {}
|
|
540
|
-
: { error: input.decision === "expired" ? "Approval expired" : "Approval denied" }),
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
|
|
544
646
|
private async create_message(
|
|
545
647
|
factory: (sequence: number, created_at: number) => SessionMessage,
|
|
546
648
|
draft = false,
|
|
547
649
|
): Promise<SessionMessage> {
|
|
650
|
+
await this.ensure_initialized();
|
|
548
651
|
if (draft) {
|
|
549
652
|
const message = await this.store.create_assistant_message((state) => {
|
|
550
653
|
const candidate = factory(state.message_sequence, Date.now());
|
|
@@ -563,10 +666,8 @@ export class SessionRecorder {
|
|
|
563
666
|
return message;
|
|
564
667
|
}
|
|
565
668
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
part: SessionAssistantToolPart;
|
|
569
|
-
} {
|
|
669
|
+
/** 读取当前流式 Assistant 中的指定 Tool Part。 */
|
|
670
|
+
find_streaming_tool(tool_call_id: string): SessionStreamingToolLocation | undefined {
|
|
570
671
|
for (const message of this.messages_by_id.values()) {
|
|
571
672
|
if (message.type !== "assistant" || message.status !== "streaming") continue;
|
|
572
673
|
const part = message.parts.find(
|
|
@@ -575,6 +676,89 @@ export class SessionRecorder {
|
|
|
575
676
|
);
|
|
576
677
|
if (part) return { message_id: message.message_id, part };
|
|
577
678
|
}
|
|
679
|
+
return undefined;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/** 把完整审批请求写入对应的流式 Tool Part。 */
|
|
683
|
+
async request_tool_approval(approval: SessionApproval): Promise<void> {
|
|
684
|
+
const { message_id } = this.require_streaming_tool(approval.tool_call_id);
|
|
685
|
+
await this.enqueue_assistant_write(message_id, async () => {
|
|
686
|
+
const tool = this.require_streaming_tool(approval.tool_call_id);
|
|
687
|
+
if (tool.message_id !== message_id) {
|
|
688
|
+
throw new Error(`Tool Assistant Message changed: ${approval.tool_call_id}`);
|
|
689
|
+
}
|
|
690
|
+
if (tool.part.state !== "ready") {
|
|
691
|
+
throw new Error(
|
|
692
|
+
`Tool approval requires ready input: ${approval.tool_call_id} (${tool.part.state})`,
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
await this.update_assistant_part_serialized(message_id, {
|
|
696
|
+
...tool.part,
|
|
697
|
+
state: "approval-required",
|
|
698
|
+
approval,
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/** 在 Tool 恢复执行前提交审批决定对应的 Part 状态。 */
|
|
704
|
+
async resolve_tool_approval(input: {
|
|
705
|
+
/** 当前审批请求标识。 */
|
|
706
|
+
approval_id: string;
|
|
707
|
+
/** 当前审批最终决定。 */
|
|
708
|
+
decision: "approved" | "denied" | "expired";
|
|
709
|
+
/** 当前审批关联的 Tool Call。 */
|
|
710
|
+
tool_call_id: string;
|
|
711
|
+
}): Promise<void> {
|
|
712
|
+
const { message_id } = this.require_streaming_tool(input.tool_call_id);
|
|
713
|
+
await this.enqueue_assistant_write(message_id, async () => {
|
|
714
|
+
const tool = this.require_streaming_tool(input.tool_call_id);
|
|
715
|
+
if (tool.message_id !== message_id) {
|
|
716
|
+
throw new Error(`Tool Assistant Message changed: ${input.tool_call_id}`);
|
|
717
|
+
}
|
|
718
|
+
if (tool.part.approval?.approval_id !== input.approval_id) {
|
|
719
|
+
throw new Error(`Tool approval identity mismatch: ${input.approval_id}`);
|
|
720
|
+
}
|
|
721
|
+
await this.update_assistant_part_serialized(message_id, {
|
|
722
|
+
...tool.part,
|
|
723
|
+
state: input.decision === "approved" ? "running" : "failed",
|
|
724
|
+
...(input.decision === "approved"
|
|
725
|
+
? {}
|
|
726
|
+
: {
|
|
727
|
+
error:
|
|
728
|
+
input.decision === "expired"
|
|
729
|
+
? "Approval expired"
|
|
730
|
+
: "Approval denied",
|
|
731
|
+
}),
|
|
732
|
+
});
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* 串行执行同一 Assistant Message 的完整写事务。
|
|
738
|
+
*
|
|
739
|
+
* 失败事务不会阻塞后续写入;链尾仅用于排序,真实错误仍返回给调用方。
|
|
740
|
+
*/
|
|
741
|
+
private async enqueue_assistant_write<T>(
|
|
742
|
+
message_id: string,
|
|
743
|
+
operation: () => Promise<T>,
|
|
744
|
+
): Promise<T> {
|
|
745
|
+
const previous = this.assistant_write_chains.get(message_id) || Promise.resolve();
|
|
746
|
+
const result = previous.then(operation, operation);
|
|
747
|
+
const chain = result.then(() => undefined, () => undefined);
|
|
748
|
+
this.assistant_write_chains.set(message_id, chain);
|
|
749
|
+
try {
|
|
750
|
+
return await result;
|
|
751
|
+
} finally {
|
|
752
|
+
if (this.assistant_write_chains.get(message_id) === chain) {
|
|
753
|
+
this.assistant_write_chains.delete(message_id);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/** 查找当前流式 Assistant 中的 Tool Part,否则抛出明确错误。 */
|
|
759
|
+
private require_streaming_tool(tool_call_id: string): SessionStreamingToolLocation {
|
|
760
|
+
const tool = this.find_streaming_tool(tool_call_id);
|
|
761
|
+
if (tool) return tool;
|
|
578
762
|
throw new Error(`Streaming Tool Part not found: ${tool_call_id}`);
|
|
579
763
|
}
|
|
580
764
|
|
|
@@ -609,311 +793,28 @@ export class SessionRecorder {
|
|
|
609
793
|
}
|
|
610
794
|
|
|
611
795
|
}
|
|
612
|
-
|
|
613
|
-
/** 单个 Assistant segment 的流式 writer。 */
|
|
614
|
-
export class SessionAssistantMessageWriter {
|
|
615
|
-
readonly message_id: string;
|
|
616
|
-
private readonly recorder: SessionRecorder;
|
|
617
|
-
private readonly pending_text_parts = new Map<string, "text" | "reasoning">();
|
|
618
|
-
private readonly active_text_part_ids = new Map<string, string>();
|
|
619
|
-
private closed = false;
|
|
620
|
-
|
|
621
|
-
constructor(recorder: SessionRecorder, message_id: string) {
|
|
622
|
-
this.recorder = recorder;
|
|
623
|
-
this.message_id = message_id;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
/** 应用一个原始 AI SDK UI chunk。 */
|
|
627
|
-
async apply_chunk(chunk: UIMessageChunk): Promise<void> {
|
|
628
|
-
if (this.closed) throw new Error("Assistant Message writer is closed");
|
|
629
|
-
const current = this.current_message();
|
|
630
|
-
switch (chunk.type) {
|
|
631
|
-
case "text-start":
|
|
632
|
-
case "reasoning-start": {
|
|
633
|
-
const type = chunk.type === "text-start" ? "text" : "reasoning";
|
|
634
|
-
const part_id = this.resolve_text_part_id(type, chunk.id);
|
|
635
|
-
if (!current.parts.some((part) => part.part_id === part_id)) {
|
|
636
|
-
this.pending_text_parts.set(part_id, type);
|
|
637
|
-
}
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
case "text-delta":
|
|
641
|
-
case "reasoning-delta": {
|
|
642
|
-
const type = chunk.type === "text-delta" ? "text" : "reasoning";
|
|
643
|
-
const part_id = this.resolve_text_part_id(type, chunk.id);
|
|
644
|
-
await this.ensure_text_part(part_id, type);
|
|
645
|
-
await this.recorder.append_assistant_delta(
|
|
646
|
-
this.message_id,
|
|
647
|
-
part_id,
|
|
648
|
-
type,
|
|
649
|
-
chunk.delta,
|
|
650
|
-
);
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
case "text-end":
|
|
654
|
-
case "reasoning-end": {
|
|
655
|
-
const type = chunk.type === "text-end" ? "text" : "reasoning";
|
|
656
|
-
const source_part_id = this.source_text_part_id(type, chunk.id);
|
|
657
|
-
const part_id = this.active_text_part_ids.get(source_part_id);
|
|
658
|
-
if (!part_id) return;
|
|
659
|
-
const part = current.parts.find((item) => item.part_id === part_id);
|
|
660
|
-
if (part?.type === "text" || part?.type === "reasoning") {
|
|
661
|
-
await this.upsert_part({ ...part, state: "done" });
|
|
662
|
-
} else {
|
|
663
|
-
this.pending_text_parts.delete(part_id);
|
|
664
|
-
}
|
|
665
|
-
this.active_text_part_ids.delete(source_part_id);
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
case "tool-input-start":
|
|
669
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
670
|
-
tool_name: chunk.toolName,
|
|
671
|
-
state: "input-streaming",
|
|
672
|
-
input_text: "",
|
|
673
|
-
});
|
|
674
|
-
return;
|
|
675
|
-
case "tool-input-delta": {
|
|
676
|
-
const tool = this.find_tool(chunk.toolCallId);
|
|
677
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
678
|
-
tool_name: tool?.tool_name || "unknown",
|
|
679
|
-
state: "input-streaming",
|
|
680
|
-
input_text: `${tool?.input_text || ""}${chunk.inputTextDelta}`,
|
|
681
|
-
});
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
case "tool-input-available":
|
|
685
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
686
|
-
tool_name: chunk.toolName,
|
|
687
|
-
state: "ready",
|
|
688
|
-
input: to_json_value(chunk.input),
|
|
689
|
-
});
|
|
690
|
-
return;
|
|
691
|
-
case "tool-input-error":
|
|
692
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
693
|
-
tool_name: chunk.toolName,
|
|
694
|
-
state: "failed",
|
|
695
|
-
input: to_json_value(chunk.input),
|
|
696
|
-
error: chunk.errorText,
|
|
697
|
-
});
|
|
698
|
-
return;
|
|
699
|
-
case "tool-approval-request": {
|
|
700
|
-
const tool = this.find_tool(chunk.toolCallId);
|
|
701
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
702
|
-
tool_name: tool?.tool_name || "unknown",
|
|
703
|
-
state: "approval-required",
|
|
704
|
-
approval_id: chunk.approvalId,
|
|
705
|
-
});
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
case "tool-output-available": {
|
|
709
|
-
const tool = this.find_tool(chunk.toolCallId);
|
|
710
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
711
|
-
tool_name: tool?.tool_name || "unknown",
|
|
712
|
-
state: "completed",
|
|
713
|
-
output: to_json_value(chunk.output),
|
|
714
|
-
});
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
case "tool-output-error":
|
|
718
|
-
case "tool-output-denied": {
|
|
719
|
-
const tool = this.find_tool(chunk.toolCallId);
|
|
720
|
-
await this.upsert_tool(chunk.toolCallId, {
|
|
721
|
-
tool_name: tool?.tool_name || "unknown",
|
|
722
|
-
state: "failed",
|
|
723
|
-
error:
|
|
724
|
-
chunk.type === "tool-output-error"
|
|
725
|
-
? chunk.errorText
|
|
726
|
-
: "Tool output denied",
|
|
727
|
-
});
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
case "file":
|
|
731
|
-
await this.append_file_part({
|
|
732
|
-
media_type: chunk.mediaType,
|
|
733
|
-
url: chunk.url,
|
|
734
|
-
});
|
|
735
|
-
return;
|
|
736
|
-
default:
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
/** 写入一个完整 Assistant part。 */
|
|
742
|
-
async upsert_part(part: SessionAssistantMessagePart): Promise<void> {
|
|
743
|
-
await this.recorder.update_assistant_part(this.message_id, part);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
/**
|
|
747
|
-
* 把最终结果中的文件补入当前 Assistant,并对流式已写入文件去重。
|
|
748
|
-
*/
|
|
749
|
-
async append_file_part(
|
|
750
|
-
input: Pick<SessionAssistantFilePart, "filename" | "media_type" | "url">,
|
|
751
|
-
): Promise<void> {
|
|
752
|
-
const filename = String(input.filename || "").trim();
|
|
753
|
-
const current = this.current_message();
|
|
754
|
-
const existing = current.parts.find(
|
|
755
|
-
(part) =>
|
|
756
|
-
part.type === "file" &&
|
|
757
|
-
part.url === input.url &&
|
|
758
|
-
part.media_type === input.media_type,
|
|
759
|
-
);
|
|
760
|
-
if (existing?.type === "file") {
|
|
761
|
-
if (filename && String(existing.filename || "").trim() !== filename) {
|
|
762
|
-
await this.upsert_part({ ...existing, filename });
|
|
763
|
-
}
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
await this.upsert_part({
|
|
767
|
-
part_id: `file:${generateId()}`,
|
|
768
|
-
sequence: this.next_part_sequence(),
|
|
769
|
-
type: "file",
|
|
770
|
-
media_type: input.media_type,
|
|
771
|
-
url: input.url,
|
|
772
|
-
...(filename ? { filename } : {}),
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
/** 当前实现逐 chunk 等待落盘,因此 flush 在返回时天然完成。 */
|
|
777
|
-
async flush(): Promise<void> {}
|
|
778
|
-
|
|
779
|
-
/** 正常完成当前 assistant segment。 */
|
|
780
|
-
async complete(): Promise<void> {
|
|
781
|
-
await this.close("completed");
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
/** 停止当前 assistant segment,并保留已有 parts。 */
|
|
785
|
-
async stop(): Promise<void> {
|
|
786
|
-
await this.close("stopped");
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
/** 以失败状态关闭当前 assistant segment。 */
|
|
790
|
-
async fail(_error: unknown): Promise<void> {
|
|
791
|
-
await this.close("failed");
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
private current_message(): SessionAssistantMessage {
|
|
795
|
-
const message = this.recorder.get_message(this.message_id);
|
|
796
|
-
if (!message || message.type !== "assistant") {
|
|
797
|
-
throw new Error(`Assistant Message not found: ${this.message_id}`);
|
|
798
|
-
}
|
|
799
|
-
return message;
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
private find_tool(tool_call_id: string): SessionAssistantToolPart | undefined {
|
|
803
|
-
return this.current_message().parts.find(
|
|
804
|
-
(part): part is SessionAssistantToolPart =>
|
|
805
|
-
part.type === "tool" && part.tool_call_id === tool_call_id,
|
|
806
|
-
);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
private next_part_sequence(): number {
|
|
810
|
-
return this.current_message().parts.reduce(
|
|
811
|
-
(value, part) => Math.max(value, part.sequence + 1),
|
|
812
|
-
1,
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
/**
|
|
817
|
-
* 把 AI SDK 当前 stream 内的临时 chunk ID 映射为 Message 内唯一 Part ID。
|
|
818
|
-
*
|
|
819
|
-
* AI SDK 会在不同 `streamText()` 调用中重复使用 `txt-0`、`reasoning-0`
|
|
820
|
-
* 等 ID,因此这些 ID 只能用于关联当前尚未结束的文本片段。
|
|
821
|
-
*/
|
|
822
|
-
private resolve_text_part_id(
|
|
823
|
-
type: "text" | "reasoning",
|
|
824
|
-
chunk_id: string,
|
|
825
|
-
): string {
|
|
826
|
-
const source_part_id = this.source_text_part_id(type, chunk_id);
|
|
827
|
-
const active_part_id = this.active_text_part_ids.get(source_part_id);
|
|
828
|
-
if (active_part_id) return active_part_id;
|
|
829
|
-
const part_id = `${type}:${generateId()}`;
|
|
830
|
-
this.active_text_part_ids.set(source_part_id, part_id);
|
|
831
|
-
return part_id;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
/** 构造当前流片段使用的临时关联键。 */
|
|
835
|
-
private source_text_part_id(
|
|
836
|
-
type: "text" | "reasoning",
|
|
837
|
-
chunk_id: string,
|
|
838
|
-
): string {
|
|
839
|
-
return `${type}:${chunk_id}`;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
/** 在首个有效 Delta 到达时才固定文本 Part 的真实顺序。 */
|
|
843
|
-
private async ensure_text_part(
|
|
844
|
-
part_id: string,
|
|
845
|
-
type: "text" | "reasoning",
|
|
846
|
-
): Promise<void> {
|
|
847
|
-
const existing = this.current_message().parts.find(
|
|
848
|
-
(part) => part.part_id === part_id,
|
|
849
|
-
);
|
|
850
|
-
if (existing) {
|
|
851
|
-
if (existing.type !== type) {
|
|
852
|
-
throw new Error(`Assistant Part type changed: ${part_id}`);
|
|
853
|
-
}
|
|
854
|
-
return;
|
|
855
|
-
}
|
|
856
|
-
const pending_type = this.pending_text_parts.get(part_id);
|
|
857
|
-
if (pending_type && pending_type !== type) {
|
|
858
|
-
throw new Error(`Assistant pending Part type changed: ${part_id}`);
|
|
859
|
-
}
|
|
860
|
-
await this.upsert_part({
|
|
861
|
-
part_id,
|
|
862
|
-
sequence: this.next_part_sequence(),
|
|
863
|
-
type,
|
|
864
|
-
text: "",
|
|
865
|
-
state: "streaming",
|
|
866
|
-
});
|
|
867
|
-
this.pending_text_parts.delete(part_id);
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
private async upsert_tool(
|
|
871
|
-
tool_call_id: string,
|
|
872
|
-
changes: Pick<SessionAssistantToolPart, "tool_name" | "state"> &
|
|
873
|
-
Partial<Omit<SessionAssistantToolPart, "part_id" | "type" | "tool_call_id" | "tool_name" | "state">>,
|
|
874
|
-
): Promise<void> {
|
|
875
|
-
const current = this.find_tool(tool_call_id);
|
|
876
|
-
await this.upsert_part({
|
|
877
|
-
...(current || {}),
|
|
878
|
-
part_id: `tool:${tool_call_id}`,
|
|
879
|
-
sequence: current?.sequence || this.next_part_sequence(),
|
|
880
|
-
type: "tool",
|
|
881
|
-
tool_call_id,
|
|
882
|
-
...changes,
|
|
883
|
-
});
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
private async close(status: "completed" | "stopped" | "failed"): Promise<void> {
|
|
887
|
-
if (this.closed) return;
|
|
888
|
-
this.pending_text_parts.clear();
|
|
889
|
-
this.active_text_part_ids.clear();
|
|
890
|
-
await this.recorder.complete_assistant_message(this.message_id, status);
|
|
891
|
-
this.closed = true;
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
796
|
/** 单个 Action Message 的生命周期 writer。 */
|
|
896
797
|
export class SessionActionMessageWriter {
|
|
897
798
|
readonly message_id: string;
|
|
898
|
-
private readonly
|
|
799
|
+
private readonly messages: SessionMessages;
|
|
899
800
|
private closed = false;
|
|
900
801
|
|
|
901
|
-
constructor(
|
|
902
|
-
this.
|
|
802
|
+
constructor(messages: SessionMessages, message_id: string) {
|
|
803
|
+
this.messages = messages;
|
|
903
804
|
this.message_id = message_id;
|
|
904
805
|
}
|
|
905
806
|
|
|
906
807
|
/** 把 Action 更新为 completed。 */
|
|
907
808
|
async complete(input?: { title?: string; description?: string; data?: JsonObject }): Promise<void> {
|
|
908
809
|
if (this.closed) return;
|
|
909
|
-
await this.
|
|
810
|
+
await this.messages.update_action_message(this.message_id, "completed", input);
|
|
910
811
|
this.closed = true;
|
|
911
812
|
}
|
|
912
813
|
|
|
913
814
|
/** 把 Action 更新为 failed。 */
|
|
914
815
|
async fail(error: unknown): Promise<void> {
|
|
915
816
|
if (this.closed) return;
|
|
916
|
-
await this.
|
|
817
|
+
await this.messages.update_action_message(this.message_id, "failed", {
|
|
917
818
|
description: error instanceof Error ? error.message : String(error),
|
|
918
819
|
});
|
|
919
820
|
this.closed = true;
|
|
@@ -950,7 +851,7 @@ export function normalize_session_user_parts(
|
|
|
950
851
|
part_id: `user-data:${index + 1}`,
|
|
951
852
|
type: "data",
|
|
952
853
|
data_type: String(candidate.type),
|
|
953
|
-
data:
|
|
854
|
+
data: to_session_json_value(candidate.data),
|
|
954
855
|
}];
|
|
955
856
|
}
|
|
956
857
|
return [];
|
|
@@ -981,16 +882,6 @@ function require_streaming_assistant(
|
|
|
981
882
|
return message;
|
|
982
883
|
}
|
|
983
884
|
|
|
984
|
-
function to_json_value(input: unknown): JsonValue {
|
|
985
|
-
if (input === undefined || input === null) return null;
|
|
986
|
-
if (typeof input === "string" || typeof input === "number" || typeof input === "boolean") return input;
|
|
987
|
-
try {
|
|
988
|
-
return JSON.parse(JSON.stringify(input)) as JsonValue;
|
|
989
|
-
} catch {
|
|
990
|
-
return String(input);
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
|
|
994
885
|
function resolve_import_id(map: Map<string, string>, source_id: string, prefix: string): string {
|
|
995
886
|
const existing = map.get(source_id);
|
|
996
887
|
if (existing) return existing;
|
|
@@ -999,6 +890,11 @@ function resolve_import_id(map: Map<string, string>, source_id: string, prefix:
|
|
|
999
890
|
return created;
|
|
1000
891
|
}
|
|
1001
892
|
|
|
893
|
+
/** 从 Action Message ID 提取稳定业务类型。 */
|
|
894
|
+
function infer_action_type(message_id: string): string {
|
|
895
|
+
return String(message_id || "").split(":")[0] || "action";
|
|
896
|
+
}
|
|
897
|
+
|
|
1002
898
|
/** 按真实 Message sequence 升序排序。 */
|
|
1003
899
|
function compare_message_sequence(left: SessionMessage, right: SessionMessage): number {
|
|
1004
900
|
return left.sequence - right.sequence;
|