@downcity/agent 1.1.237 → 1.1.258
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 +21 -20
- 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 +117 -0
- package/bin/session/SessionMessages.d.ts.map +1 -0
- package/bin/session/{recorder/SessionRecorder.js → SessionMessages.js} +194 -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} +131 -90
- 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 +29 -89
- 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} +254 -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
|
@@ -18,9 +18,8 @@ import {
|
|
|
18
18
|
} from "../bin/executor/tools/plugin/PluginToolBridge.js";
|
|
19
19
|
import { createPluginTools } from "../bin/executor/tools/plugin/PluginToolDefinition.js";
|
|
20
20
|
import { plugin_call_input_schema } from "../bin/executor/tools/plugin/PluginToolSchemas.js";
|
|
21
|
-
import { withSessionRunScope } from "../bin/executor/SessionRunScope.js";
|
|
22
21
|
import { createAction, createPlugin } from "../bin/plugin/core/PluginActionFactory.js";
|
|
23
|
-
import {
|
|
22
|
+
import { PluginRegistry } from "../bin/plugin/core/PluginRegistry.js";
|
|
24
23
|
import { z } from "zod";
|
|
25
24
|
|
|
26
25
|
function create_run_context(project_root) {
|
|
@@ -33,6 +32,12 @@ function create_run_context(project_root) {
|
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
function create_registry(plugin) {
|
|
36
|
+
const registry = new PluginRegistry([plugin]);
|
|
37
|
+
registry.bind_context({ rootPath: process.cwd() });
|
|
38
|
+
return registry;
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
test("plugin_call payload schema allows arbitrary object properties", async () => {
|
|
37
42
|
const plugin_call_schema = await plugin_call_input_schema.jsonSchema;
|
|
38
43
|
const payload_schema = plugin_call_schema.properties.payload;
|
|
@@ -80,16 +85,15 @@ test("invokePluginCallTool returns absolute paths for materialized file parts",
|
|
|
80
85
|
};
|
|
81
86
|
|
|
82
87
|
const run_context = create_run_context(project_root);
|
|
83
|
-
const result = await
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
);
|
|
88
|
+
const result = await invokePluginCallTool({
|
|
89
|
+
plugins,
|
|
90
|
+
run_context,
|
|
91
|
+
input: {
|
|
92
|
+
plugin: "image",
|
|
93
|
+
action: "image_result",
|
|
94
|
+
payload: { job_id: "img_1" },
|
|
95
|
+
},
|
|
96
|
+
});
|
|
93
97
|
|
|
94
98
|
assert.equal(result.success, true);
|
|
95
99
|
assert.equal(result.assistant_file_count, 1);
|
|
@@ -149,6 +153,7 @@ test("invokePluginReadTool returns plugin action metadata", async () => {
|
|
|
149
153
|
|
|
150
154
|
const result = await invokePluginReadTool({
|
|
151
155
|
plugins,
|
|
156
|
+
run_context: create_run_context(process.cwd()),
|
|
152
157
|
input: {
|
|
153
158
|
plugin: "image",
|
|
154
159
|
action: "image_create",
|
|
@@ -190,11 +195,7 @@ test("PluginRegistry validates action payload with metadata schema", async () =>
|
|
|
190
195
|
}),
|
|
191
196
|
},
|
|
192
197
|
});
|
|
193
|
-
const registry =
|
|
194
|
-
plugins: [plugin],
|
|
195
|
-
plugin_instances: new Map(),
|
|
196
|
-
get_context: () => ({ rootPath: process.cwd() }),
|
|
197
|
-
});
|
|
198
|
+
const registry = create_registry(plugin);
|
|
198
199
|
|
|
199
200
|
const metadata = registry.read({ plugin: "demo", action: "echo" });
|
|
200
201
|
assert.equal(metadata.actions[0].description, "Echo text");
|
|
@@ -226,41 +227,56 @@ test("createPluginTools binds plugin_call to the current registry", async () =>
|
|
|
226
227
|
actions: {
|
|
227
228
|
lookup: createAction({
|
|
228
229
|
description: "Return registry owner",
|
|
229
|
-
execute: async () => ({
|
|
230
|
+
execute: async ({ run_context }) => ({
|
|
230
231
|
success: true,
|
|
231
|
-
data: {
|
|
232
|
+
data: {
|
|
233
|
+
owner,
|
|
234
|
+
session_id: run_context?.sessionId,
|
|
235
|
+
},
|
|
232
236
|
message: owner,
|
|
233
237
|
}),
|
|
234
238
|
}),
|
|
235
239
|
},
|
|
236
240
|
});
|
|
237
|
-
return
|
|
238
|
-
plugins: [plugin],
|
|
239
|
-
plugin_instances: new Map(),
|
|
240
|
-
get_context: () => ({ rootPath: process.cwd() }),
|
|
241
|
-
});
|
|
241
|
+
return create_registry(plugin);
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
const registry_a = create_owner_registry("agent_a");
|
|
245
245
|
const registry_b = create_owner_registry("agent_b");
|
|
246
246
|
const tools_a = createPluginTools({ plugins: registry_a });
|
|
247
247
|
const tools_b = createPluginTools({ plugins: registry_b });
|
|
248
|
+
const create_execution_options = (session_id) => {
|
|
249
|
+
const run_context = create_run_context(process.cwd());
|
|
250
|
+
run_context.sessionId = session_id;
|
|
251
|
+
return {
|
|
252
|
+
toolCallId: `call_${session_id}`,
|
|
253
|
+
messages: [],
|
|
254
|
+
experimental_context: {
|
|
255
|
+
session_run_context: run_context,
|
|
256
|
+
shell_run_context: {
|
|
257
|
+
ownerContextId: session_id,
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
};
|
|
248
262
|
|
|
249
263
|
const result_a = await tools_a.plugin_call.execute({
|
|
250
264
|
plugin: "skill",
|
|
251
265
|
action: "lookup",
|
|
252
266
|
payload: { name: "anything" },
|
|
253
|
-
});
|
|
267
|
+
}, create_execution_options("session_a"));
|
|
254
268
|
const result_b = await tools_b.plugin_call.execute({
|
|
255
269
|
plugin: "skill",
|
|
256
270
|
action: "lookup",
|
|
257
271
|
payload: { name: "anything" },
|
|
258
|
-
});
|
|
272
|
+
}, create_execution_options("session_b"));
|
|
259
273
|
|
|
260
274
|
assert.equal(result_a.success, true);
|
|
261
275
|
assert.equal(result_a.data.value.owner, "agent_a");
|
|
276
|
+
assert.equal(result_a.data.value.session_id, "session_a");
|
|
262
277
|
assert.equal(result_b.success, true);
|
|
263
278
|
assert.equal(result_b.data.value.owner, "agent_b");
|
|
279
|
+
assert.equal(result_b.data.value.session_id, "session_b");
|
|
264
280
|
});
|
|
265
281
|
|
|
266
282
|
test("PluginRegistry keeps plugin ready after action business failure", async () => {
|
|
@@ -290,11 +306,7 @@ test("PluginRegistry keeps plugin ready after action business failure", async ()
|
|
|
290
306
|
}),
|
|
291
307
|
},
|
|
292
308
|
});
|
|
293
|
-
const registry =
|
|
294
|
-
plugins: [plugin],
|
|
295
|
-
plugin_instances: new Map(),
|
|
296
|
-
get_context: () => ({ rootPath: process.cwd() }),
|
|
297
|
-
});
|
|
309
|
+
const registry = create_registry(plugin);
|
|
298
310
|
|
|
299
311
|
const failed = await registry.runAction({
|
|
300
312
|
plugin: "skill",
|
|
@@ -340,11 +352,7 @@ test("PluginRegistry delays lifecycle stop until the active execution lease is r
|
|
|
340
352
|
}),
|
|
341
353
|
},
|
|
342
354
|
});
|
|
343
|
-
const registry =
|
|
344
|
-
plugins: [plugin],
|
|
345
|
-
plugin_instances: new Map(),
|
|
346
|
-
get_context: () => ({ rootPath: process.cwd() }),
|
|
347
|
-
});
|
|
355
|
+
const registry = create_registry(plugin);
|
|
348
356
|
await registry.startAll();
|
|
349
357
|
const lease = registry.execution_view().acquire();
|
|
350
358
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 验证 read 图片结果会作为临时 UserMessage file part 注入模型输入。
|
|
3
|
+
*
|
|
4
|
+
* 关键点(中文)
|
|
5
|
+
* - data URL 只进入注入消息,不保留在普通 tool result。
|
|
6
|
+
* - 注入消息包含非空文本 part,能够通过 step 合并消息筛选。
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import test from "node:test";
|
|
10
|
+
import assert from "node:assert/strict";
|
|
11
|
+
|
|
12
|
+
import { inject_read_image_user_message } from "../bin/executor/tools/file/ReadImageToolBridge.js";
|
|
13
|
+
import {
|
|
14
|
+
pickMergedUserMessages,
|
|
15
|
+
toModelMessages,
|
|
16
|
+
} from "../bin/executor/messages/SessionMessageCodec.js";
|
|
17
|
+
|
|
18
|
+
test("read image data is injected as a user file part", async () => {
|
|
19
|
+
const data_url = "data:image/png;base64,iVBORw0KGgo=";
|
|
20
|
+
const run_context = {
|
|
21
|
+
sessionId: "session-1",
|
|
22
|
+
turnId: "turn-1",
|
|
23
|
+
injectedUserMessages: [],
|
|
24
|
+
deferredPersistedUserMessages: [],
|
|
25
|
+
pendingAssistantFileParts: [],
|
|
26
|
+
};
|
|
27
|
+
const output = inject_read_image_user_message({
|
|
28
|
+
tool_name: "read",
|
|
29
|
+
output: {
|
|
30
|
+
success: true,
|
|
31
|
+
type: "image",
|
|
32
|
+
file_path: "/project/input.png",
|
|
33
|
+
mime_type: "image/png",
|
|
34
|
+
data_url,
|
|
35
|
+
},
|
|
36
|
+
run_context,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
assert.equal(output.data_url, undefined);
|
|
40
|
+
assert.equal(output.image_attached, true);
|
|
41
|
+
assert.equal(run_context.injectedUserMessages.length, 1);
|
|
42
|
+
const message = run_context.injectedUserMessages[0];
|
|
43
|
+
assert.equal(message.role, "user");
|
|
44
|
+
assert.equal(message.parts[0].type, "text");
|
|
45
|
+
assert.equal(message.parts[1].type, "file");
|
|
46
|
+
assert.equal(message.parts[1].url, data_url);
|
|
47
|
+
assert.equal(message.parts[1].mediaType, "image/png");
|
|
48
|
+
assert.equal(pickMergedUserMessages([message]).length, 1);
|
|
49
|
+
|
|
50
|
+
const model_messages = await toModelMessages([message], {});
|
|
51
|
+
assert.equal(model_messages.length, 1);
|
|
52
|
+
assert.equal(model_messages[0].role, "user");
|
|
53
|
+
assert.match(JSON.stringify(model_messages[0]), /iVBORw0KGgo=/);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("non-image tool results are unchanged", () => {
|
|
57
|
+
const output = { success: true, type: "text", content: "hello" };
|
|
58
|
+
const run_context = {
|
|
59
|
+
sessionId: "session-1",
|
|
60
|
+
injectedUserMessages: [],
|
|
61
|
+
deferredPersistedUserMessages: [],
|
|
62
|
+
pendingAssistantFileParts: [],
|
|
63
|
+
};
|
|
64
|
+
const result = inject_read_image_user_message({
|
|
65
|
+
tool_name: "read",
|
|
66
|
+
output,
|
|
67
|
+
run_context,
|
|
68
|
+
});
|
|
69
|
+
assert.equal(result, output);
|
|
70
|
+
assert.deepEqual(run_context.injectedUserMessages, []);
|
|
71
|
+
});
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import test from "node:test";
|
|
10
10
|
import assert from "node:assert/strict";
|
|
11
11
|
|
|
12
|
-
import { RemoteSession } from "../bin/
|
|
12
|
+
import { RemoteSession } from "../bin/remote/RemoteSession.js";
|
|
13
13
|
|
|
14
14
|
test("RemoteSession reconnects the event pump after transport close", async () => {
|
|
15
15
|
const subscriptions = [];
|
|
@@ -70,39 +70,6 @@ test("RemoteSession reconnects the event pump after transport close", async () =
|
|
|
70
70
|
assert.equal((await second_turn.finished).text, "done");
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
test("RemoteSession switches models by stable id without local model instances", async () => {
|
|
74
|
-
const updates = [];
|
|
75
|
-
const transport = {
|
|
76
|
-
async set(_session_id, input) {
|
|
77
|
-
updates.push(input);
|
|
78
|
-
return {
|
|
79
|
-
agentId: "agent_test",
|
|
80
|
-
sessionId: "session_test",
|
|
81
|
-
messageCount: 0,
|
|
82
|
-
modelId: input.modelId,
|
|
83
|
-
modelLabel: input.modelId,
|
|
84
|
-
};
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
const session = new RemoteSession(transport, {
|
|
88
|
-
agentId: "agent_test",
|
|
89
|
-
sessionId: "session_test",
|
|
90
|
-
messageCount: 0,
|
|
91
|
-
modelId: "old-model",
|
|
92
|
-
modelLabel: "old-model",
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
await session.set({ modelId: "next-model" });
|
|
96
|
-
|
|
97
|
-
assert.deepEqual(updates, [{ modelId: "next-model" }]);
|
|
98
|
-
assert.equal(session.config.modelId, "next-model");
|
|
99
|
-
assert.equal(session.config.modelLabel, "next-model");
|
|
100
|
-
await assert.rejects(
|
|
101
|
-
session.set({ model: { modelId: "local-model", provider: "test" } }),
|
|
102
|
-
/does not accept a local model instance/,
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
73
|
test("RemoteSession queues compact through its transport", async () => {
|
|
107
74
|
const compacted_session_ids = [];
|
|
108
75
|
const transport = {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file 验证
|
|
2
|
+
* @file 验证 Session compact prompt 的结构化摘要格式。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - compact prompt 必须保持结构化摘要格式稳定。
|
|
6
6
|
* - 迭代更新 prompt 需要携带 previous-summary 标签。
|
|
7
|
-
* - 文件操作 XML 由本地解析追加,不依赖模型复述工具日志。
|
|
8
7
|
*/
|
|
9
8
|
|
|
10
9
|
import test from "node:test";
|
|
@@ -12,15 +11,10 @@ import assert from "node:assert/strict";
|
|
|
12
11
|
|
|
13
12
|
import {
|
|
14
13
|
SESSION_COMPACTION_SYSTEM_PROMPT,
|
|
15
|
-
append_session_compaction_file_operations,
|
|
16
14
|
build_initial_session_compaction_prompt,
|
|
17
15
|
build_turn_prefix_session_compaction_prompt,
|
|
18
16
|
build_update_session_compaction_prompt,
|
|
19
17
|
} from "../bin/executor/composer/compaction/jsonl/JsonlSessionCompactionPrompts.js";
|
|
20
|
-
import {
|
|
21
|
-
collect_session_compaction_file_operations,
|
|
22
|
-
format_session_compaction_file_operations,
|
|
23
|
-
} from "../bin/executor/composer/compaction/jsonl/JsonlSessionCompactionFileOperations.js";
|
|
24
18
|
|
|
25
19
|
test("session compaction prompts preserve structured formats", () => {
|
|
26
20
|
assert.match(
|
|
@@ -53,45 +47,3 @@ test("session compaction prompts preserve structured formats", () => {
|
|
|
53
47
|
assert.match(prefix_prompt, /## Original Request/);
|
|
54
48
|
assert.match(prefix_prompt, /## Context for Suffix/);
|
|
55
49
|
});
|
|
56
|
-
|
|
57
|
-
test("session compaction file operations are appended as xml", () => {
|
|
58
|
-
const messages = [
|
|
59
|
-
{
|
|
60
|
-
id: "a:1",
|
|
61
|
-
role: "assistant",
|
|
62
|
-
parts: [
|
|
63
|
-
{
|
|
64
|
-
type: "tool-exec_command",
|
|
65
|
-
input: {
|
|
66
|
-
cmd: "sed -n '1,40p' packages/agent/src/foo.ts && rg -n compact packages/agent/src",
|
|
67
|
-
},
|
|
68
|
-
output: [
|
|
69
|
-
"*** Update File: packages/agent/src/bar.ts",
|
|
70
|
-
" M packages/agent/src/baz.ts",
|
|
71
|
-
].join("\n"),
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
const operations = collect_session_compaction_file_operations(messages);
|
|
78
|
-
assert.deepEqual(operations.read_files, [
|
|
79
|
-
"packages/agent/src",
|
|
80
|
-
"packages/agent/src/foo.ts",
|
|
81
|
-
]);
|
|
82
|
-
assert.deepEqual(operations.modified_files, [
|
|
83
|
-
"packages/agent/src/bar.ts",
|
|
84
|
-
"packages/agent/src/baz.ts",
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
const xml = format_session_compaction_file_operations(messages);
|
|
88
|
-
assert.match(xml, /<read-files>\npackages\/agent\/src/);
|
|
89
|
-
assert.match(xml, /<modified-files>\npackages\/agent\/src\/bar\.ts/);
|
|
90
|
-
|
|
91
|
-
const summary = append_session_compaction_file_operations({
|
|
92
|
-
summary: "## Goal\n完成 compact",
|
|
93
|
-
file_operations_xml: xml,
|
|
94
|
-
});
|
|
95
|
-
assert.match(summary, /## Goal\n完成 compact\n\n<read-files>/);
|
|
96
|
-
assert.match(summary, /<\/modified-files>$/);
|
|
97
|
-
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 验证统一 SessionComposer 只读取快照并返回模型输入或压缩计划。
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import os from "node:os";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { MockLanguageModelV3 } from "ai/test";
|
|
11
|
+
import {
|
|
12
|
+
Agent,
|
|
13
|
+
DefaultSessionComposer,
|
|
14
|
+
Session,
|
|
15
|
+
} from "../bin/index.js";
|
|
16
|
+
|
|
17
|
+
function create_input(model) {
|
|
18
|
+
return {
|
|
19
|
+
session: {
|
|
20
|
+
agent_id: "composer-agent",
|
|
21
|
+
session_id: "composer-session",
|
|
22
|
+
project_root: "/tmp/composer-project",
|
|
23
|
+
created_at: 1,
|
|
24
|
+
timezone: "UTC",
|
|
25
|
+
},
|
|
26
|
+
state: {
|
|
27
|
+
model,
|
|
28
|
+
env: {},
|
|
29
|
+
systems: ["Base instruction"],
|
|
30
|
+
tools: {},
|
|
31
|
+
instruction_system_blocks: [{
|
|
32
|
+
source: "instruction",
|
|
33
|
+
name: "agent",
|
|
34
|
+
content: "Base instruction",
|
|
35
|
+
}],
|
|
36
|
+
managed_plugin_system_blocks: [],
|
|
37
|
+
plugin_system_blocks: [],
|
|
38
|
+
},
|
|
39
|
+
history: {
|
|
40
|
+
summary: null,
|
|
41
|
+
messages: [{
|
|
42
|
+
message_id: "user-1",
|
|
43
|
+
session_id: "composer-session",
|
|
44
|
+
turn_id: "turn-1",
|
|
45
|
+
sequence: 1,
|
|
46
|
+
revision: 1,
|
|
47
|
+
visibility: "visible",
|
|
48
|
+
created_at: 1,
|
|
49
|
+
updated_at: 1,
|
|
50
|
+
type: "user",
|
|
51
|
+
input_type: "prompt",
|
|
52
|
+
parts: [{
|
|
53
|
+
part_id: "text-1",
|
|
54
|
+
type: "text",
|
|
55
|
+
text: "hello",
|
|
56
|
+
state: "done",
|
|
57
|
+
}],
|
|
58
|
+
}],
|
|
59
|
+
},
|
|
60
|
+
turn: { turn_id: "turn-1", retry_count: 0 },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
test("DefaultSessionComposer 从 canonical 快照组装 Step 输入", async () => {
|
|
65
|
+
const model = new MockLanguageModelV3({ modelId: "composer-model" });
|
|
66
|
+
const input = create_input(model);
|
|
67
|
+
const step = await new DefaultSessionComposer().compose(input);
|
|
68
|
+
|
|
69
|
+
assert.equal(step.messages.length, 1);
|
|
70
|
+
assert.equal(step.messages[0].parts[0].text, "hello");
|
|
71
|
+
assert.equal(step.system_blocks[0].content, "Base instruction");
|
|
72
|
+
assert.match(step.system.at(-1).content, /composer-session/);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("Custom Composer 可以覆盖组装结果而不接触持久化", async () => {
|
|
76
|
+
class CustomComposer extends DefaultSessionComposer {
|
|
77
|
+
async compose(input) {
|
|
78
|
+
const step = await super.compose(input);
|
|
79
|
+
return {
|
|
80
|
+
...step,
|
|
81
|
+
system: [
|
|
82
|
+
...step.system,
|
|
83
|
+
{ role: "system", content: "Custom behavior" },
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const model = new MockLanguageModelV3({ modelId: "custom-composer-model" });
|
|
90
|
+
const input = create_input(model);
|
|
91
|
+
const before = structuredClone(input.history);
|
|
92
|
+
const step = await new CustomComposer().compose(input);
|
|
93
|
+
|
|
94
|
+
assert.equal(step.system.at(-1).content, "Custom behavior");
|
|
95
|
+
assert.deepEqual(input.history, before);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("Session system 快照与 Custom Composer 的实际模型输入一致", async () => {
|
|
99
|
+
class CustomComposer extends DefaultSessionComposer {
|
|
100
|
+
async compose(input) {
|
|
101
|
+
const step = await super.compose(input);
|
|
102
|
+
return {
|
|
103
|
+
...step,
|
|
104
|
+
system: [
|
|
105
|
+
...step.system,
|
|
106
|
+
{ role: "system", content: "Custom snapshot behavior" },
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
class CustomSession extends Session {
|
|
113
|
+
constructor(options) {
|
|
114
|
+
super({ ...options, composer: new CustomComposer() });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const project_root = await fs.mkdtemp(
|
|
119
|
+
path.join(os.tmpdir(), "downcity-session-composer-system-"),
|
|
120
|
+
);
|
|
121
|
+
const agent = new Agent({
|
|
122
|
+
id: "custom_composer_agent",
|
|
123
|
+
path: project_root,
|
|
124
|
+
model: new MockLanguageModelV3({ modelId: "custom-composer-model" }),
|
|
125
|
+
Session: CustomSession,
|
|
126
|
+
});
|
|
127
|
+
try {
|
|
128
|
+
const session = await agent.sessions.create({
|
|
129
|
+
sessionId: "custom_composer_session",
|
|
130
|
+
});
|
|
131
|
+
const snapshot = await session.system();
|
|
132
|
+
assert.equal(snapshot.blocks.at(-1).content, "Custom snapshot behavior");
|
|
133
|
+
assert.equal(snapshot.blocks.at(-1).source, "session");
|
|
134
|
+
} finally {
|
|
135
|
+
await agent.dispose();
|
|
136
|
+
await fs.rm(project_root, { recursive: true, force: true });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("Composer compact 只返回计划,不修改 Message 快照", async () => {
|
|
141
|
+
const model = new MockLanguageModelV3({
|
|
142
|
+
modelId: "composer-compact-model",
|
|
143
|
+
doGenerate: async () => ({
|
|
144
|
+
content: [{ type: "text", text: "Composer summary" }],
|
|
145
|
+
finishReason: { unified: "stop", raw: "stop" },
|
|
146
|
+
usage: {
|
|
147
|
+
inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },
|
|
148
|
+
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
149
|
+
},
|
|
150
|
+
warnings: [],
|
|
151
|
+
}),
|
|
152
|
+
});
|
|
153
|
+
const input = create_input(model);
|
|
154
|
+
const before = structuredClone(input.history);
|
|
155
|
+
const plan = await new DefaultSessionComposer().compact({
|
|
156
|
+
...input,
|
|
157
|
+
force: true,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
assert.equal(plan.through_sequence, 1);
|
|
161
|
+
assert.equal(plan.summary.text, "Composer summary");
|
|
162
|
+
assert.deepEqual(input.history, before);
|
|
163
|
+
});
|
|
@@ -222,10 +222,7 @@ test("running session model changes apply with steer at the next Session step",
|
|
|
222
222
|
message.type === "action" &&
|
|
223
223
|
message.title === "Session model switched from old-model to new-model",
|
|
224
224
|
);
|
|
225
|
-
assert.deepEqual(
|
|
226
|
-
model_actions.map((message) => message.status),
|
|
227
|
-
["completed"],
|
|
228
|
-
);
|
|
225
|
+
assert.deepEqual(model_actions, []);
|
|
229
226
|
} finally {
|
|
230
227
|
release_old_model.resolve();
|
|
231
228
|
await agent.dispose();
|
|
@@ -261,7 +258,7 @@ test("config remains effective when its action message cannot be persisted", asy
|
|
|
261
258
|
const session = await agent.sessions.create({
|
|
262
259
|
sessionId: "config_action_observability_session",
|
|
263
260
|
});
|
|
264
|
-
session.
|
|
261
|
+
session.emit_action_event = async () => {
|
|
265
262
|
throw new Error("action store unavailable");
|
|
266
263
|
};
|
|
267
264
|
|
|
@@ -67,6 +67,7 @@ async function create_agent_with_titled_session(input) {
|
|
|
67
67
|
const session = await collection.create({
|
|
68
68
|
sessionId: input.session_id,
|
|
69
69
|
});
|
|
70
|
+
await session.set({ model: create_mock_title_model(input.title) });
|
|
70
71
|
|
|
71
72
|
await session.append_user_message({
|
|
72
73
|
text: input.first_user_text,
|
|
@@ -141,7 +142,7 @@ test("list_sessions returns persisted title from active session metadata", async
|
|
|
141
142
|
}
|
|
142
143
|
});
|
|
143
144
|
|
|
144
|
-
test("list_sessions reflects canonical
|
|
145
|
+
test("list_sessions reflects canonical SessionMessages changes", async () => {
|
|
145
146
|
const { agent, collection, session } = await create_agent_with_titled_session({
|
|
146
147
|
tmp_prefix: "downcity-agent-session-summary-repair-",
|
|
147
148
|
agent_id: "summary_repair_agent",
|
|
@@ -165,7 +166,7 @@ test("list_sessions reflects canonical Recorder history changes", async () => {
|
|
|
165
166
|
await session.append_assistant_message({
|
|
166
167
|
text: "Recorder appended history",
|
|
167
168
|
});
|
|
168
|
-
await session.
|
|
169
|
+
await session.session_messages.compact_active({
|
|
169
170
|
through_sequence: 1,
|
|
170
171
|
summary: {
|
|
171
172
|
record_type: "summary",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 验证 SessionMessages 不会掩盖 canonical Store 写入失败。
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { SessionMessages } from "../bin/session/SessionMessages.js";
|
|
8
|
+
|
|
9
|
+
function create_messages(store) {
|
|
10
|
+
return new SessionMessages({
|
|
11
|
+
session_id: "messages-error-session",
|
|
12
|
+
store: {
|
|
13
|
+
initialize: async () => {},
|
|
14
|
+
list_messages: async () => [],
|
|
15
|
+
...store,
|
|
16
|
+
},
|
|
17
|
+
publish: () => {},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
test("append_user_message 透传 Store 写入失败", async () => {
|
|
22
|
+
const messages = create_messages({
|
|
23
|
+
append_message: async () => {
|
|
24
|
+
throw new Error("disk full");
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
await messages.initialize();
|
|
28
|
+
await assert.rejects(
|
|
29
|
+
messages.append_user_message({
|
|
30
|
+
turn_id: "turn-1",
|
|
31
|
+
input_type: "prompt",
|
|
32
|
+
parts: [{
|
|
33
|
+
part_id: "text-1",
|
|
34
|
+
type: "text",
|
|
35
|
+
text: "hello",
|
|
36
|
+
state: "done",
|
|
37
|
+
}],
|
|
38
|
+
}),
|
|
39
|
+
/disk full/,
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("open_assistant_message 透传草稿写入失败", async () => {
|
|
44
|
+
const messages = create_messages({
|
|
45
|
+
create_assistant_message: async () => {
|
|
46
|
+
throw new Error("disk full");
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
await messages.initialize();
|
|
50
|
+
await assert.rejects(
|
|
51
|
+
messages.open_assistant_message({
|
|
52
|
+
turn_id: "turn-1",
|
|
53
|
+
segment_index: 1,
|
|
54
|
+
}),
|
|
55
|
+
/disk full/,
|
|
56
|
+
);
|
|
57
|
+
});
|