@amodalai/runtime 0.1.26 → 0.2.1
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/dist/src/__fixtures__/README.md +88 -0
- package/dist/src/__fixtures__/e2e.test.js +211 -0
- package/dist/src/__fixtures__/e2e.test.js.map +1 -0
- package/dist/src/__fixtures__/smoke-agent/amodal.json +11 -0
- package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
- package/dist/src/__fixtures__/smoke-agent/automations/test-auto.md +5 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-api/access.json +11 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-api/spec.json +4 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-api/surface.md +9 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/access.json +3 -0
- package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +8 -0
- package/dist/src/__fixtures__/smoke-agent/evals/basic-eval.md +12 -0
- package/dist/src/__fixtures__/smoke-agent/knowledge/test-knowledge.md +3 -0
- package/dist/src/__fixtures__/smoke-agent/skills/test-skill/SKILL.md +11 -0
- package/dist/src/__fixtures__/smoke-agent/stores/test-items.json +11 -0
- package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.d.ts +18 -0
- package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js +22 -0
- package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/handler.js.map +1 -0
- package/dist/src/__fixtures__/smoke-agent/tools/echo_tool/tool.json +17 -0
- package/dist/src/__fixtures__/smoke.test.js +1404 -0
- package/dist/src/__fixtures__/smoke.test.js.map +1 -0
- package/dist/src/__fixtures__/test-env.d.ts +27 -0
- package/dist/src/__fixtures__/test-env.js +64 -0
- package/dist/src/__fixtures__/test-env.js.map +1 -0
- package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
- package/dist/src/__fixtures__/test-helpers.js +120 -0
- package/dist/src/__fixtures__/test-helpers.js.map +1 -0
- package/dist/src/__tests__/test-providers.d.ts +40 -0
- package/dist/src/__tests__/test-providers.js +61 -0
- package/dist/src/__tests__/test-providers.js.map +1 -0
- package/dist/src/agent/agent-types.d.ts +22 -0
- package/dist/src/agent/agent-types.js.map +1 -1
- package/dist/src/agent/automation-bridge.d.ts +9 -0
- package/dist/src/agent/automation-bridge.js +26 -0
- package/dist/src/agent/automation-bridge.js.map +1 -1
- package/dist/src/agent/automation-bridge.test.js +63 -0
- package/dist/src/agent/automation-bridge.test.js.map +1 -1
- package/dist/src/agent/local-server.d.ts +1 -8
- package/dist/src/agent/local-server.js +398 -163
- package/dist/src/agent/local-server.js.map +1 -1
- package/dist/src/agent/local-server.test.js +14 -8
- package/dist/src/agent/local-server.test.js.map +1 -1
- package/dist/src/agent/loop-types.d.ts +254 -0
- package/dist/src/agent/loop-types.js +24 -0
- package/dist/src/agent/loop-types.js.map +1 -0
- package/dist/src/agent/loop.d.ts +31 -0
- package/dist/src/agent/loop.js +152 -0
- package/dist/src/agent/loop.js.map +1 -0
- package/dist/src/agent/loop.test.js +1594 -0
- package/dist/src/agent/loop.test.js.map +1 -0
- package/dist/src/agent/mcp-config.d.ts +28 -0
- package/dist/src/agent/mcp-config.js +57 -0
- package/dist/src/agent/mcp-config.js.map +1 -0
- package/dist/src/agent/page-builder.js +6 -1
- package/dist/src/agent/page-builder.js.map +1 -1
- package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
- package/dist/src/agent/proactive/delivery-router.js +337 -0
- package/dist/src/agent/proactive/delivery-router.js.map +1 -0
- package/dist/src/agent/{stores-e2e.test.d.ts → proactive/delivery-router.test.d.ts} +1 -1
- package/dist/src/agent/proactive/delivery-router.test.js +455 -0
- package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
- package/dist/src/agent/proactive/proactive-runner.d.ts +46 -8
- package/dist/src/agent/proactive/proactive-runner.js +67 -37
- package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
- package/dist/src/agent/proactive/proactive-runner.test.d.ts +1 -1
- package/dist/src/agent/proactive/proactive-runner.test.js +73 -87
- package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
- package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
- package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
- package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
- package/dist/src/agent/routes/admin-chat.d.ts +15 -3
- package/dist/src/agent/routes/admin-chat.js +61 -18
- package/dist/src/agent/routes/admin-chat.js.map +1 -1
- package/dist/src/agent/routes/automations.js +5 -6
- package/dist/src/agent/routes/automations.js.map +1 -1
- package/dist/src/agent/routes/evals.d.ts +3 -2
- package/dist/src/agent/routes/evals.js +25 -12
- package/dist/src/agent/routes/evals.js.map +1 -1
- package/dist/src/agent/routes/files.js +7 -9
- package/dist/src/agent/routes/files.js.map +1 -1
- package/dist/src/agent/routes/inspect.d.ts +6 -2
- package/dist/src/agent/routes/inspect.js +31 -17
- package/dist/src/agent/routes/inspect.js.map +1 -1
- package/dist/src/agent/routes/inspect.test.js +18 -42
- package/dist/src/agent/routes/inspect.test.js.map +1 -1
- package/dist/src/agent/routes/stores.js +9 -12
- package/dist/src/agent/routes/stores.js.map +1 -1
- package/dist/src/agent/routes/task.d.ts +15 -3
- package/dist/src/agent/routes/task.js +16 -7
- package/dist/src/agent/routes/task.js.map +1 -1
- package/dist/src/agent/routes/task.test.d.ts +1 -1
- package/dist/src/agent/routes/task.test.js +68 -53
- package/dist/src/agent/routes/task.test.js.map +1 -1
- package/dist/src/agent/routes/webhooks.js +12 -3
- package/dist/src/agent/routes/webhooks.js.map +1 -1
- package/dist/src/agent/snapshot-server.d.ts +2 -22
- package/dist/src/agent/snapshot-server.js +48 -27
- package/dist/src/agent/snapshot-server.js.map +1 -1
- package/dist/src/agent/states/compacting.d.ts +14 -0
- package/dist/src/agent/states/compacting.js +260 -0
- package/dist/src/agent/states/compacting.js.map +1 -0
- package/dist/src/agent/states/confirming.d.ts +10 -0
- package/dist/src/agent/states/confirming.js +79 -0
- package/dist/src/agent/states/confirming.js.map +1 -0
- package/dist/src/agent/states/dispatching.d.ts +18 -0
- package/dist/src/agent/states/dispatching.js +285 -0
- package/dist/src/agent/states/dispatching.js.map +1 -0
- package/dist/src/agent/states/executing.d.ts +21 -0
- package/dist/src/agent/states/executing.js +452 -0
- package/dist/src/agent/states/executing.js.map +1 -0
- package/dist/src/agent/states/streaming.d.ts +10 -0
- package/dist/src/agent/states/streaming.js +169 -0
- package/dist/src/agent/states/streaming.js.map +1 -0
- package/dist/src/agent/states/thinking.d.ts +13 -0
- package/dist/src/agent/states/thinking.js +450 -0
- package/dist/src/agent/states/thinking.js.map +1 -0
- package/dist/src/agent/token-estimate.d.ts +31 -0
- package/dist/src/agent/token-estimate.js +34 -0
- package/dist/src/agent/token-estimate.js.map +1 -0
- package/dist/src/agent/token-estimate.test.d.ts +6 -0
- package/dist/src/agent/token-estimate.test.js +44 -0
- package/dist/src/agent/token-estimate.test.js.map +1 -0
- package/dist/src/agent/tool-executor-local.js +9 -18
- package/dist/src/agent/tool-executor-local.js.map +1 -1
- package/dist/src/agent/tool-executor-local.test.js +3 -5
- package/dist/src/agent/tool-executor-local.test.js.map +1 -1
- package/dist/src/api/create-agent.d.ts +15 -0
- package/dist/src/api/create-agent.js +134 -0
- package/dist/src/api/create-agent.js.map +1 -0
- package/dist/src/api/types.d.ts +66 -0
- package/dist/src/api/types.js +7 -0
- package/dist/src/api/types.js.map +1 -0
- package/dist/src/context/compiler.d.ts +13 -0
- package/dist/src/context/compiler.js +358 -0
- package/dist/src/context/compiler.js.map +1 -0
- package/dist/src/context/compiler.test.d.ts +6 -0
- package/dist/src/context/compiler.test.js +532 -0
- package/dist/src/context/compiler.test.js.map +1 -0
- package/dist/src/context/types.d.ts +110 -0
- package/dist/src/context/types.js +7 -0
- package/dist/src/context/types.js.map +1 -0
- package/dist/src/env-ref.d.ts +13 -0
- package/dist/src/env-ref.js +31 -0
- package/dist/src/env-ref.js.map +1 -0
- package/dist/src/env-ref.test.d.ts +6 -0
- package/dist/src/env-ref.test.js +34 -0
- package/dist/src/env-ref.test.js.map +1 -0
- package/dist/src/errors.d.ts +15 -0
- package/dist/src/errors.js +22 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/errors.test.js +2 -2
- package/dist/src/errors.test.js.map +1 -1
- package/dist/src/events/event-bus.d.ts +54 -0
- package/dist/src/events/event-bus.js +84 -0
- package/dist/src/events/event-bus.js.map +1 -0
- package/dist/src/events/event-bus.test.d.ts +6 -0
- package/dist/src/events/event-bus.test.js +112 -0
- package/dist/src/events/event-bus.test.js.map +1 -0
- package/dist/src/events/events-route.d.ts +36 -0
- package/dist/src/events/events-route.js +80 -0
- package/dist/src/events/events-route.js.map +1 -0
- package/dist/src/events/events-route.test.d.ts +6 -0
- package/dist/src/events/events-route.test.js +134 -0
- package/dist/src/events/events-route.test.js.map +1 -0
- package/dist/src/events/store-event-wrapper.d.ts +19 -0
- package/dist/src/events/store-event-wrapper.js +57 -0
- package/dist/src/events/store-event-wrapper.js.map +1 -0
- package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
- package/dist/src/events/store-event-wrapper.test.js +91 -0
- package/dist/src/events/store-event-wrapper.test.js.map +1 -0
- package/dist/src/index.d.ts +33 -6
- package/dist/src/index.js +35 -21
- package/dist/src/index.js.map +1 -1
- package/dist/src/middleware/auth.d.ts +0 -2
- package/dist/src/middleware/auth.js.map +1 -1
- package/dist/src/providers/create-provider.d.ts +23 -0
- package/dist/src/providers/create-provider.js +185 -0
- package/dist/src/providers/create-provider.js.map +1 -0
- package/dist/src/providers/create-provider.test.d.ts +6 -0
- package/dist/src/providers/create-provider.test.js +95 -0
- package/dist/src/providers/create-provider.test.js.map +1 -0
- package/dist/src/providers/failover.d.ts +38 -0
- package/dist/src/providers/failover.js +147 -0
- package/dist/src/providers/failover.js.map +1 -0
- package/dist/src/providers/failover.test.d.ts +6 -0
- package/dist/src/providers/failover.test.js +169 -0
- package/dist/src/providers/failover.test.js.map +1 -0
- package/dist/src/providers/search-provider.d.ts +64 -0
- package/dist/src/providers/search-provider.js +174 -0
- package/dist/src/providers/search-provider.js.map +1 -0
- package/dist/src/providers/types.d.ts +118 -0
- package/dist/src/providers/types.js +7 -0
- package/dist/src/providers/types.js.map +1 -0
- package/dist/src/routes/ai-stream.d.ts +28 -10
- package/dist/src/routes/ai-stream.js +85 -41
- package/dist/src/routes/ai-stream.js.map +1 -1
- package/dist/src/routes/chat-new.test.d.ts +6 -0
- package/dist/src/routes/chat-new.test.js +107 -0
- package/dist/src/routes/chat-new.test.js.map +1 -0
- package/dist/src/routes/chat-stream-new.test.d.ts +6 -0
- package/dist/src/routes/chat-stream-new.test.js +135 -0
- package/dist/src/routes/chat-stream-new.test.js.map +1 -0
- package/dist/src/routes/chat-stream.d.ts +20 -4
- package/dist/src/routes/chat-stream.js +49 -29
- package/dist/src/routes/chat-stream.js.map +1 -1
- package/dist/src/routes/chat.d.ts +19 -4
- package/dist/src/routes/chat.js +62 -23
- package/dist/src/routes/chat.js.map +1 -1
- package/dist/src/routes/health.d.ts +3 -2
- package/dist/src/routes/health.js.map +1 -1
- package/dist/src/routes/route-helpers.d.ts +50 -0
- package/dist/src/routes/route-helpers.js +80 -0
- package/dist/src/routes/route-helpers.js.map +1 -0
- package/dist/src/routes/session-resolver.d.ts +77 -0
- package/dist/src/routes/session-resolver.js +109 -0
- package/dist/src/routes/session-resolver.js.map +1 -0
- package/dist/src/routes/session-resolver.test.d.ts +6 -0
- package/dist/src/routes/session-resolver.test.js +207 -0
- package/dist/src/routes/session-resolver.test.js.map +1 -0
- package/dist/src/routes/webhooks.d.ts +3 -1
- package/dist/src/routes/webhooks.js +12 -4
- package/dist/src/routes/webhooks.js.map +1 -1
- package/dist/src/security/permission-checker.d.ts +80 -0
- package/dist/src/security/permission-checker.js +75 -0
- package/dist/src/security/permission-checker.js.map +1 -0
- package/dist/src/security/permission-checker.test.d.ts +6 -0
- package/dist/src/security/permission-checker.test.js +208 -0
- package/dist/src/security/permission-checker.test.js.map +1 -0
- package/dist/src/server.d.ts +18 -11
- package/dist/src/server.js +46 -46
- package/dist/src/server.js.map +1 -1
- package/dist/src/server.test.d.ts +1 -1
- package/dist/src/server.test.js +6 -144
- package/dist/src/server.test.js.map +1 -1
- package/dist/src/session/drizzle-session-store.d.ts +56 -0
- package/dist/src/session/drizzle-session-store.js +203 -0
- package/dist/src/session/drizzle-session-store.js.map +1 -0
- package/dist/src/session/manager.d.ts +101 -0
- package/dist/src/session/manager.js +394 -0
- package/dist/src/session/manager.js.map +1 -0
- package/dist/src/session/manager.test.d.ts +6 -0
- package/dist/src/session/manager.test.js +309 -0
- package/dist/src/session/manager.test.js.map +1 -0
- package/dist/src/session/pglite-session-store.d.ts +23 -0
- package/dist/src/session/pglite-session-store.js +70 -0
- package/dist/src/session/pglite-session-store.js.map +1 -0
- package/dist/src/session/postgres-session-store.d.ts +44 -0
- package/dist/src/session/postgres-session-store.js +138 -0
- package/dist/src/session/postgres-session-store.js.map +1 -0
- package/dist/src/session/session-builder.d.ts +69 -0
- package/dist/src/session/session-builder.js +384 -0
- package/dist/src/session/session-builder.js.map +1 -0
- package/dist/src/session/session-builder.test.d.ts +6 -0
- package/dist/src/session/session-builder.test.js +350 -0
- package/dist/src/session/session-builder.test.js.map +1 -0
- package/dist/src/session/session-store-selector.d.ts +49 -0
- package/dist/src/session/session-store-selector.js +60 -0
- package/dist/src/session/session-store-selector.js.map +1 -0
- package/dist/src/session/session-store-selector.test.d.ts +6 -0
- package/dist/src/session/session-store-selector.test.js +79 -0
- package/dist/src/session/session-store-selector.test.js.map +1 -0
- package/dist/src/session/store.d.ts +171 -0
- package/dist/src/session/store.js +155 -0
- package/dist/src/session/store.js.map +1 -0
- package/dist/src/session/store.test.d.ts +6 -0
- package/dist/src/session/store.test.js +423 -0
- package/dist/src/session/store.test.js.map +1 -0
- package/dist/src/session/stream-hooks.d.ts +39 -0
- package/dist/src/session/stream-hooks.js +7 -0
- package/dist/src/session/stream-hooks.js.map +1 -0
- package/dist/src/session/tool-context-factory.d.ts +61 -0
- package/dist/src/session/tool-context-factory.js +189 -0
- package/dist/src/session/tool-context-factory.js.map +1 -0
- package/dist/src/session/tool-context-factory.test.d.ts +6 -0
- package/dist/src/session/tool-context-factory.test.js +284 -0
- package/dist/src/session/tool-context-factory.test.js.map +1 -0
- package/dist/src/session/types.d.ts +195 -0
- package/dist/src/session/types.js +7 -0
- package/dist/src/session/types.js.map +1 -0
- package/dist/src/stores/drizzle-store-backend.d.ts +49 -0
- package/dist/src/stores/drizzle-store-backend.js +306 -0
- package/dist/src/stores/drizzle-store-backend.js.map +1 -0
- package/dist/src/stores/drizzle-store-backend.test.d.ts +6 -0
- package/dist/src/stores/drizzle-store-backend.test.js +215 -0
- package/dist/src/stores/drizzle-store-backend.test.js.map +1 -0
- package/dist/src/stores/index.d.ts +4 -0
- package/dist/src/stores/index.js +2 -0
- package/dist/src/stores/index.js.map +1 -1
- package/dist/src/stores/pglite-store-backend.d.ts +16 -19
- package/dist/src/stores/pglite-store-backend.js +85 -239
- package/dist/src/stores/pglite-store-backend.js.map +1 -1
- package/dist/src/stores/postgres-store-backend.d.ts +30 -0
- package/dist/src/stores/postgres-store-backend.js +100 -0
- package/dist/src/stores/postgres-store-backend.js.map +1 -0
- package/dist/src/stores/schema.d.ts +457 -0
- package/dist/src/stores/schema.js +59 -0
- package/dist/src/stores/schema.js.map +1 -0
- package/dist/src/tools/admin-file-tools.d.ts +42 -0
- package/dist/src/tools/admin-file-tools.js +714 -0
- package/dist/src/tools/admin-file-tools.js.map +1 -0
- package/dist/src/tools/admin-file-tools.test.d.ts +6 -0
- package/dist/src/tools/admin-file-tools.test.js +521 -0
- package/dist/src/tools/admin-file-tools.test.js.map +1 -0
- package/dist/src/tools/custom-tool-adapter.d.ts +41 -0
- package/dist/src/tools/custom-tool-adapter.js +190 -0
- package/dist/src/tools/custom-tool-adapter.js.map +1 -0
- package/dist/src/tools/custom-tool-adapter.test.d.ts +6 -0
- package/dist/src/tools/custom-tool-adapter.test.js +243 -0
- package/dist/src/tools/custom-tool-adapter.test.js.map +1 -0
- package/dist/src/tools/dispatch-tool.d.ts +52 -0
- package/dist/src/tools/dispatch-tool.js +71 -0
- package/dist/src/tools/dispatch-tool.js.map +1 -0
- package/dist/src/tools/dispatch-tool.test.d.ts +6 -0
- package/dist/src/tools/dispatch-tool.test.js +75 -0
- package/dist/src/tools/dispatch-tool.test.js.map +1 -0
- package/dist/src/tools/fetch-url-tool.d.ts +23 -0
- package/dist/src/tools/fetch-url-tool.js +333 -0
- package/dist/src/tools/fetch-url-tool.js.map +1 -0
- package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
- package/dist/src/tools/fetch-url-tool.test.js +228 -0
- package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
- package/dist/src/tools/mcp-tool-adapter.d.ts +18 -0
- package/dist/src/tools/mcp-tool-adapter.js +135 -0
- package/dist/src/tools/mcp-tool-adapter.js.map +1 -0
- package/dist/src/tools/mcp-tool-adapter.test.d.ts +6 -0
- package/dist/src/tools/mcp-tool-adapter.test.js +226 -0
- package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -0
- package/dist/src/tools/registry.d.ts +25 -0
- package/dist/src/tools/registry.js +72 -0
- package/dist/src/tools/registry.js.map +1 -0
- package/dist/src/tools/registry.test.d.ts +6 -0
- package/dist/src/tools/registry.test.js +120 -0
- package/dist/src/tools/registry.test.js.map +1 -0
- package/dist/src/tools/request-tool.d.ts +42 -0
- package/dist/src/tools/request-tool.js +190 -0
- package/dist/src/tools/request-tool.js.map +1 -0
- package/dist/src/tools/request-tool.test.d.ts +6 -0
- package/dist/src/tools/request-tool.test.js +253 -0
- package/dist/src/tools/request-tool.test.js.map +1 -0
- package/dist/src/tools/store-tools.d.ts +29 -0
- package/dist/src/tools/store-tools.js +224 -0
- package/dist/src/tools/store-tools.js.map +1 -0
- package/dist/src/tools/store-tools.test.d.ts +6 -0
- package/dist/src/tools/store-tools.test.js +215 -0
- package/dist/src/tools/store-tools.test.js.map +1 -0
- package/dist/src/tools/types.d.ts +129 -0
- package/dist/src/tools/types.js +7 -0
- package/dist/src/tools/types.js.map +1 -0
- package/dist/src/tools/web-search-tool.d.ts +31 -0
- package/dist/src/tools/web-search-tool.js +170 -0
- package/dist/src/tools/web-search-tool.js.map +1 -0
- package/dist/src/tools/web-search-tool.test.d.ts +6 -0
- package/dist/src/tools/web-search-tool.test.js +153 -0
- package/dist/src/tools/web-search-tool.test.js.map +1 -0
- package/dist/src/tools/web-tools-shared.d.ts +21 -0
- package/dist/src/tools/web-tools-shared.js +32 -0
- package/dist/src/tools/web-tools-shared.js.map +1 -0
- package/dist/src/types.d.ts +40 -12
- package/dist/src/types.js +16 -2
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +27 -4
- package/dist/src/__tests__/sse-contract.test.js +0 -464
- package/dist/src/__tests__/sse-contract.test.js.map +0 -1
- package/dist/src/__tests__/tools.test.js +0 -583
- package/dist/src/__tests__/tools.test.js.map +0 -1
- package/dist/src/agent/agent-runner.d.ts +0 -33
- package/dist/src/agent/agent-runner.js +0 -1040
- package/dist/src/agent/agent-runner.js.map +0 -1
- package/dist/src/agent/custom-tools-e2e.test.d.ts +0 -6
- package/dist/src/agent/custom-tools-e2e.test.js +0 -566
- package/dist/src/agent/custom-tools-e2e.test.js.map +0 -1
- package/dist/src/agent/request-helper.d.ts +0 -16
- package/dist/src/agent/request-helper.js +0 -96
- package/dist/src/agent/request-helper.js.map +0 -1
- package/dist/src/agent/session-store.d.ts +0 -62
- package/dist/src/agent/session-store.js +0 -151
- package/dist/src/agent/session-store.js.map +0 -1
- package/dist/src/agent/stores-e2e.test.js +0 -433
- package/dist/src/agent/stores-e2e.test.js.map +0 -1
- package/dist/src/agent/tool-context-builder.d.ts +0 -11
- package/dist/src/agent/tool-context-builder.js +0 -102
- package/dist/src/agent/tool-context-builder.js.map +0 -1
- package/dist/src/agent/tool-context-builder.test.d.ts +0 -6
- package/dist/src/agent/tool-context-builder.test.js +0 -152
- package/dist/src/agent/tool-context-builder.test.js.map +0 -1
- package/dist/src/agent/write-repo-file.test.js +0 -270
- package/dist/src/agent/write-repo-file.test.js.map +0 -1
- package/dist/src/cron/heartbeat-runner.d.ts +0 -21
- package/dist/src/cron/heartbeat-runner.js +0 -79
- package/dist/src/cron/heartbeat-runner.js.map +0 -1
- package/dist/src/cron/heartbeat-runner.test.d.ts +0 -6
- package/dist/src/cron/heartbeat-runner.test.js +0 -120
- package/dist/src/cron/heartbeat-runner.test.js.map +0 -1
- package/dist/src/cron/heartbeat-scheduler.d.ts +0 -26
- package/dist/src/cron/heartbeat-scheduler.js +0 -55
- package/dist/src/cron/heartbeat-scheduler.js.map +0 -1
- package/dist/src/cron/heartbeat-scheduler.test.d.ts +0 -6
- package/dist/src/cron/heartbeat-scheduler.test.js +0 -61
- package/dist/src/cron/heartbeat-scheduler.test.js.map +0 -1
- package/dist/src/routes/ai-stream.test.d.ts +0 -6
- package/dist/src/routes/ai-stream.test.js +0 -586
- package/dist/src/routes/ai-stream.test.js.map +0 -1
- package/dist/src/routes/ask-user-response.d.ts +0 -30
- package/dist/src/routes/ask-user-response.js +0 -61
- package/dist/src/routes/ask-user-response.js.map +0 -1
- package/dist/src/routes/ask-user-response.test.d.ts +0 -6
- package/dist/src/routes/ask-user-response.test.js +0 -88
- package/dist/src/routes/ask-user-response.test.js.map +0 -1
- package/dist/src/routes/chat-stream.test.d.ts +0 -6
- package/dist/src/routes/chat-stream.test.js +0 -155
- package/dist/src/routes/chat-stream.test.js.map +0 -1
- package/dist/src/routes/chat.test.d.ts +0 -6
- package/dist/src/routes/chat.test.js +0 -99
- package/dist/src/routes/chat.test.js.map +0 -1
- package/dist/src/routes/widget-actions.d.ts +0 -49
- package/dist/src/routes/widget-actions.js +0 -78
- package/dist/src/routes/widget-actions.js.map +0 -1
- package/dist/src/session/admin-file-tools.d.ts +0 -136
- package/dist/src/session/admin-file-tools.js +0 -240
- package/dist/src/session/admin-file-tools.js.map +0 -1
- package/dist/src/session/custom-tool-adapter.d.ts +0 -74
- package/dist/src/session/custom-tool-adapter.js +0 -180
- package/dist/src/session/custom-tool-adapter.js.map +0 -1
- package/dist/src/session/history-converter.d.ts +0 -21
- package/dist/src/session/history-converter.js +0 -59
- package/dist/src/session/history-converter.js.map +0 -1
- package/dist/src/session/history-converter.test.d.ts +0 -6
- package/dist/src/session/history-converter.test.js +0 -130
- package/dist/src/session/history-converter.test.js.map +0 -1
- package/dist/src/session/session-manager.d.ts +0 -219
- package/dist/src/session/session-manager.js +0 -915
- package/dist/src/session/session-manager.js.map +0 -1
- package/dist/src/session/session-manager.test.d.ts +0 -6
- package/dist/src/session/session-manager.test.js +0 -455
- package/dist/src/session/session-manager.test.js.map +0 -1
- package/dist/src/session/session-runner.d.ts +0 -45
- package/dist/src/session/session-runner.js +0 -719
- package/dist/src/session/session-runner.js.map +0 -1
- package/dist/src/session/session-runner.test.d.ts +0 -6
- package/dist/src/session/session-runner.test.js +0 -834
- package/dist/src/session/session-runner.test.js.map +0 -1
- /package/dist/src/{__tests__/sse-contract.test.d.ts → __fixtures__/e2e.test.d.ts} +0 -0
- /package/dist/src/{__tests__/tools.test.d.ts → __fixtures__/smoke.test.d.ts} +0 -0
- /package/dist/src/agent/{write-repo-file.test.d.ts → loop.test.d.ts} +0 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* COMPACTING state handler.
|
|
8
|
+
*
|
|
9
|
+
* Summarizes older conversation turns to free context space:
|
|
10
|
+
* 1. Keep the last N turns verbatim (active conversation)
|
|
11
|
+
* 2. Send older turns to a cheap model for structured summarization
|
|
12
|
+
* 3. Replace old turns with the summary
|
|
13
|
+
* 4. Circuit breaker: after N consecutive failures, give up and continue
|
|
14
|
+
*
|
|
15
|
+
* The summary is structured as a handoff document with sections for
|
|
16
|
+
* current state, original task, key data, actions taken, errors, and
|
|
17
|
+
* next steps. This preserves the information the agent needs to
|
|
18
|
+
* continue working without the full conversation history.
|
|
19
|
+
*/
|
|
20
|
+
import { SSEEventType } from '../../types.js';
|
|
21
|
+
import { CompactionError } from '../../errors.js';
|
|
22
|
+
import { estimateTokenCount } from '../token-estimate.js';
|
|
23
|
+
/** Prefix for the summary message injected after compaction. */
|
|
24
|
+
const COMPACTION_SUMMARY_PREFIX = '[Conversation Summary — older messages compacted]';
|
|
25
|
+
/** Timeout for the compaction generateText call (30 seconds). */
|
|
26
|
+
const COMPACTION_TIMEOUT_MS = 30_000;
|
|
27
|
+
const COMPACTION_PROMPT = `Summarize this conversation as a structured handoff into these sections:
|
|
28
|
+
|
|
29
|
+
1. **Current State** — what we're working on right now
|
|
30
|
+
2. **Original Task** — what the user originally asked for
|
|
31
|
+
3. **Key Data** — important values, IDs, file paths, or facts that must be preserved
|
|
32
|
+
4. **Actions Taken** — tools called and what they returned (summarized, not verbatim)
|
|
33
|
+
5. **Errors & Corrections** — what went wrong and what we tried instead
|
|
34
|
+
6. **Next Steps** — what should happen next
|
|
35
|
+
|
|
36
|
+
Keep each section under 500 tokens. Focus on information the agent needs to continue working. Omit sections that have no content.`;
|
|
37
|
+
/**
|
|
38
|
+
* Handle the COMPACTING state.
|
|
39
|
+
*
|
|
40
|
+
* Splits messages into "old" (to be summarized) and "recent" (kept verbatim).
|
|
41
|
+
* Calls generateText with a cheap model to produce a structured summary.
|
|
42
|
+
* Replaces old messages with a single summary message.
|
|
43
|
+
*/
|
|
44
|
+
export async function handleCompacting(state, ctx) {
|
|
45
|
+
const effects = [];
|
|
46
|
+
const { keepRecentTurns, maxSummaryTokens, compactionCircuitBreaker } = ctx.config;
|
|
47
|
+
// Circuit breaker — if we've failed too many times, skip compaction
|
|
48
|
+
if (ctx.compactionFailures >= compactionCircuitBreaker) {
|
|
49
|
+
ctx.logger.warn('compaction_circuit_breaker', {
|
|
50
|
+
session: ctx.sessionId,
|
|
51
|
+
failures: ctx.compactionFailures,
|
|
52
|
+
threshold: compactionCircuitBreaker,
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
next: { type: 'thinking', messages: state.messages },
|
|
56
|
+
effects,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Split messages: keep last N turns verbatim, summarize the rest.
|
|
60
|
+
// A "turn" is a user message + assistant response (+ any tool results).
|
|
61
|
+
// We count from the end by counting user messages.
|
|
62
|
+
const splitIndex = findSplitIndex(state.messages, keepRecentTurns);
|
|
63
|
+
if (splitIndex <= 0) {
|
|
64
|
+
// Not enough messages to compact — nothing older than the recent window
|
|
65
|
+
ctx.logger.debug('compaction_skipped_too_few', {
|
|
66
|
+
session: ctx.sessionId,
|
|
67
|
+
messageCount: state.messages.length,
|
|
68
|
+
keepRecentTurns,
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
next: { type: 'thinking', messages: state.messages },
|
|
72
|
+
effects,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const oldMessages = state.messages.slice(0, splitIndex);
|
|
76
|
+
const recentMessages = state.messages.slice(splitIndex);
|
|
77
|
+
const tokensBefore = state.estimatedTokens;
|
|
78
|
+
effects.push({
|
|
79
|
+
type: SSEEventType.CompactionStart,
|
|
80
|
+
estimated_tokens: tokensBefore,
|
|
81
|
+
threshold: ctx.config.compactThreshold,
|
|
82
|
+
timestamp: new Date().toISOString(),
|
|
83
|
+
});
|
|
84
|
+
ctx.logger.info('compaction_start', {
|
|
85
|
+
session: ctx.sessionId,
|
|
86
|
+
totalMessages: state.messages.length,
|
|
87
|
+
oldMessages: oldMessages.length,
|
|
88
|
+
recentMessages: recentMessages.length,
|
|
89
|
+
tokensBefore,
|
|
90
|
+
});
|
|
91
|
+
const summaryResult = await summarizeMessages(oldMessages, ctx, maxSummaryTokens);
|
|
92
|
+
if (!summaryResult.ok) {
|
|
93
|
+
ctx.compactionFailures++;
|
|
94
|
+
ctx.logger.error('compaction_failed', {
|
|
95
|
+
session: ctx.sessionId,
|
|
96
|
+
error: summaryResult.error.message,
|
|
97
|
+
failure: ctx.compactionFailures,
|
|
98
|
+
circuitBreakerAt: compactionCircuitBreaker,
|
|
99
|
+
});
|
|
100
|
+
// Continue without compaction — the agent can still work, just with
|
|
101
|
+
// a fuller context. Better than crashing the loop.
|
|
102
|
+
return {
|
|
103
|
+
next: { type: 'thinking', messages: state.messages },
|
|
104
|
+
effects,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Build the compacted message list: summary + recent turns.
|
|
108
|
+
// Uses 'user' role so it's valid for Anthropic (which rejects system
|
|
109
|
+
// messages after user/assistant turns). The "[Conversation Summary]"
|
|
110
|
+
// prefix makes the provenance clear to the model.
|
|
111
|
+
const summaryMessage = {
|
|
112
|
+
role: 'user',
|
|
113
|
+
content: `${COMPACTION_SUMMARY_PREFIX}\n\n${summaryResult.value.text}`,
|
|
114
|
+
};
|
|
115
|
+
const compactedMessages = [summaryMessage, ...recentMessages];
|
|
116
|
+
// Update context
|
|
117
|
+
ctx.messages = compactedMessages;
|
|
118
|
+
ctx.compactionFailures = 0; // Reset circuit breaker on success
|
|
119
|
+
const tokensAfter = estimateTokenCount(compactedMessages, ctx.provider);
|
|
120
|
+
const compactionTokens = summaryResult.value.usage.inputTokens + summaryResult.value.usage.outputTokens;
|
|
121
|
+
ctx.logger.info('compaction_end', {
|
|
122
|
+
session: ctx.sessionId,
|
|
123
|
+
tokensBefore,
|
|
124
|
+
tokensAfter,
|
|
125
|
+
messagesBefore: state.messages.length,
|
|
126
|
+
messagesAfter: compactedMessages.length,
|
|
127
|
+
});
|
|
128
|
+
effects.push({
|
|
129
|
+
type: SSEEventType.CompactionEnd,
|
|
130
|
+
tokens_before: tokensBefore,
|
|
131
|
+
tokens_after: tokensAfter,
|
|
132
|
+
compaction_tokens: compactionTokens,
|
|
133
|
+
timestamp: new Date().toISOString(),
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
next: { type: 'thinking', messages: compactedMessages },
|
|
137
|
+
effects,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Summarize old messages using generateText.
|
|
142
|
+
* Returns Result to avoid try/catch in the caller.
|
|
143
|
+
*/
|
|
144
|
+
async function summarizeMessages(messages, ctx, maxSummaryTokens) {
|
|
145
|
+
// Serialize old messages into a readable conversation format
|
|
146
|
+
const conversationText = messagesToText(messages);
|
|
147
|
+
// Per-call timeout composed with session abort signal — prevents a hung
|
|
148
|
+
// provider from blocking the loop until session-level abort.
|
|
149
|
+
const timeoutSignal = AbortSignal.timeout(COMPACTION_TIMEOUT_MS);
|
|
150
|
+
const combinedSignal = AbortSignal.any([ctx.signal, timeoutSignal]);
|
|
151
|
+
try {
|
|
152
|
+
const result = await ctx.provider.generateText({
|
|
153
|
+
messages: [
|
|
154
|
+
{ role: 'user', content: `Here is a conversation to summarize:\n\n${conversationText}` },
|
|
155
|
+
],
|
|
156
|
+
system: COMPACTION_PROMPT,
|
|
157
|
+
maxOutputTokens: maxSummaryTokens,
|
|
158
|
+
abortSignal: combinedSignal,
|
|
159
|
+
});
|
|
160
|
+
// Track compaction token usage
|
|
161
|
+
ctx.usage.inputTokens += result.usage.inputTokens;
|
|
162
|
+
ctx.usage.outputTokens += result.usage.outputTokens;
|
|
163
|
+
ctx.usage.totalTokens += result.usage.inputTokens + result.usage.outputTokens;
|
|
164
|
+
if (!result.text || result.text.trim().length === 0) {
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
error: new CompactionError('Summarization returned empty text', {
|
|
168
|
+
stage: 'summarize',
|
|
169
|
+
context: { messageCount: messages.length },
|
|
170
|
+
}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
ok: true,
|
|
175
|
+
value: {
|
|
176
|
+
text: result.text,
|
|
177
|
+
usage: { inputTokens: result.usage.inputTokens, outputTokens: result.usage.outputTokens },
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
// Specific expected failure with specific handling (reason #3):
|
|
183
|
+
// Provider errors during compaction are non-fatal — the caller degrades
|
|
184
|
+
// gracefully by continuing without compaction.
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
error: new CompactionError(`Summarization failed: ${err instanceof Error ? err.message : String(err)}`, { stage: 'summarize', cause: err, context: { messageCount: messages.length } }),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Convert messages to a readable text format for the summarizer.
|
|
193
|
+
*/
|
|
194
|
+
function messagesToText(messages) {
|
|
195
|
+
const lines = [];
|
|
196
|
+
for (const msg of messages) {
|
|
197
|
+
const role = msg.role.toUpperCase();
|
|
198
|
+
if (typeof msg.content === 'string') {
|
|
199
|
+
lines.push(`${role}: ${msg.content}`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (!Array.isArray(msg.content))
|
|
203
|
+
continue;
|
|
204
|
+
for (const part of msg.content) {
|
|
205
|
+
if (!('type' in part))
|
|
206
|
+
continue;
|
|
207
|
+
if (part.type === 'text' && 'text' in part) {
|
|
208
|
+
lines.push(`${role}: ${part.text}`);
|
|
209
|
+
}
|
|
210
|
+
else if (part.type === 'tool-call' && 'toolName' in part) {
|
|
211
|
+
const args = 'input' in part ? JSON.stringify(part.input) : '{}';
|
|
212
|
+
lines.push(`${role} [tool_call: ${part.toolName}(${args})]`);
|
|
213
|
+
}
|
|
214
|
+
else if (part.type === 'tool-result' && 'output' in part) {
|
|
215
|
+
const output = extractToolResultText(part.output);
|
|
216
|
+
// Truncate long tool results for the summarizer — it doesn't need 20K
|
|
217
|
+
const truncated = output.length > 2_000
|
|
218
|
+
? output.slice(0, 2_000) + '... [truncated for summarization]'
|
|
219
|
+
: output;
|
|
220
|
+
lines.push(`TOOL_RESULT: ${truncated}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return lines.join('\n');
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Extract text from a tool result output field.
|
|
228
|
+
*/
|
|
229
|
+
function extractToolResultText(output) {
|
|
230
|
+
if (typeof output === 'string')
|
|
231
|
+
return output;
|
|
232
|
+
if (typeof output === 'object' && output !== null && 'value' in output) {
|
|
233
|
+
// `in` narrows to `object & Record<'value', unknown>` — safe to access
|
|
234
|
+
return String(output.value);
|
|
235
|
+
}
|
|
236
|
+
return JSON.stringify(output);
|
|
237
|
+
}
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
// Helpers
|
|
240
|
+
// ---------------------------------------------------------------------------
|
|
241
|
+
/**
|
|
242
|
+
* Find the index to split messages: everything before this index gets
|
|
243
|
+
* summarized, everything at or after is kept verbatim.
|
|
244
|
+
*
|
|
245
|
+
* Counts user messages from the end to find `keepTurns` turn boundaries.
|
|
246
|
+
*/
|
|
247
|
+
function findSplitIndex(messages, keepTurns) {
|
|
248
|
+
let userMessagesSeen = 0;
|
|
249
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
250
|
+
if (messages[i].role === 'user') {
|
|
251
|
+
userMessagesSeen++;
|
|
252
|
+
if (userMessagesSeen >= keepTurns) {
|
|
253
|
+
return i;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Not enough turns to split — return 0 (don't compact)
|
|
258
|
+
return 0;
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=compacting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compacting.js","sourceRoot":"","sources":["../../../../src/agent/states/compacting.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAG5C,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAOhD,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAExD,gEAAgE;AAChE,MAAM,yBAAyB,GAAG,mDAAmD,CAAC;AAEtF,iEAAiE;AACjE,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAErC,MAAM,iBAAiB,GAAG;;;;;;;;;kIASwG,CAAC;AAEnI;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,GAAiB;IAEjB,MAAM,OAAO,GAAe,EAAE,CAAC;IAC/B,MAAM,EAAC,eAAe,EAAE,gBAAgB,EAAE,wBAAwB,EAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAEjF,oEAAoE;IACpE,IAAI,GAAG,CAAC,kBAAkB,IAAI,wBAAwB,EAAE,CAAC;QACvD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;YAC5C,OAAO,EAAE,GAAG,CAAC,SAAS;YACtB,QAAQ,EAAE,GAAG,CAAC,kBAAkB;YAChC,SAAS,EAAE,wBAAwB;SACpC,CAAC,CAAC;QACH,OAAO;YACL,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAC;YAClD,OAAO;SACR,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,wEAAwE;IACxE,mDAAmD;IACnD,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAEnE,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,wEAAwE;QACxE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE;YAC7C,OAAO,EAAE,GAAG,CAAC,SAAS;YACtB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;YACnC,eAAe;SAChB,CAAC,CAAC;QACH,OAAO;YACL,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAC;YAClD,OAAO;SACR,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,KAAK,CAAC,eAAe,CAAC;IAE3C,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,YAAY,CAAC,eAAe;QAClC,gBAAgB,EAAE,YAAY;QAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,gBAAgB;QACtC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE;QAClC,OAAO,EAAE,GAAG,CAAC,SAAS;QACtB,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;QACpC,WAAW,EAAE,WAAW,CAAC,MAAM;QAC/B,cAAc,EAAE,cAAc,CAAC,MAAM;QACrC,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAElF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;QACtB,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE;YACpC,OAAO,EAAE,GAAG,CAAC,SAAS;YACtB,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO;YAClC,OAAO,EAAE,GAAG,CAAC,kBAAkB;YAC/B,gBAAgB,EAAE,wBAAwB;SAC3C,CAAC,CAAC;QACH,oEAAoE;QACpE,mDAAmD;QACnD,OAAO;YACL,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAC;YAClD,OAAO;SACR,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,qEAAqE;IACrE,qEAAqE;IACrE,kDAAkD;IAClD,MAAM,cAAc,GAAiB;QACnC,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,GAAG,yBAAyB,OAAO,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE;KACvE,CAAC;IACF,MAAM,iBAAiB,GAAG,CAAC,cAAc,EAAE,GAAG,cAAc,CAAC,CAAC;IAE9D,iBAAiB;IACjB,GAAG,CAAC,QAAQ,GAAG,iBAAiB,CAAC;IACjC,GAAG,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,mCAAmC;IAE/D,MAAM,WAAW,GAAG,kBAAkB,CAAC,iBAAiB,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,gBAAgB,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC;IAExG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAChC,OAAO,EAAE,GAAG,CAAC,SAAS;QACtB,YAAY;QACZ,WAAW;QACX,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;QACrC,aAAa,EAAE,iBAAiB,CAAC,MAAM;KACxC,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,YAAY,CAAC,aAAa;QAChC,aAAa,EAAE,YAAY;QAC3B,YAAY,EAAE,WAAW;QACzB,iBAAiB,EAAE,gBAAgB;QACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAC;QACrD,OAAO;KACR,CAAC;AACJ,CAAC;AAWD;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAC9B,QAAwB,EACxB,GAAiB,EACjB,gBAAwB;IAExB,6DAA6D;IAC7D,MAAM,gBAAgB,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAElD,wEAAwE;IACxE,6DAA6D;IAC7D,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACjE,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAEpE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC7C,QAAQ,EAAE;gBACR,EAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,2CAA2C,gBAAgB,EAAE,EAAC;aACvF;YACD,MAAM,EAAE,iBAAiB;YACzB,eAAe,EAAE,gBAAgB;YACjC,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAC;QAEH,+BAA+B;QAC/B,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC;QACpD,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC;QAE9E,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,IAAI,eAAe,CAAC,mCAAmC,EAAE;oBAC9D,KAAK,EAAE,WAAW;oBAClB,OAAO,EAAE,EAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAC;iBACzC,CAAC;aACH,CAAC;QACJ,CAAC;QAED,OAAO;YACL,EAAE,EAAE,IAAI;YACR,KAAK,EAAE;gBACL,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,EAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,EAAC;aACxF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,gEAAgE;QAChE,wEAAwE;QACxE,+CAA+C;QAC/C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,IAAI,eAAe,CACxB,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC3E,EAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAC,EAAC,CAC3E;SACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,QAAwB;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAEpC,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,SAAS;QAE1C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC;gBAAE,SAAS;YAEhC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBAC3C,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACtC,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC3D,MAAM,IAAI,GAAG,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,gBAAgB,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,CAAC;YAC/D,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;gBAC3D,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAClD,sEAAsE;gBACtE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK;oBACrC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,mCAAmC;oBAC9D,CAAC,CAAC,MAAM,CAAC;gBACX,KAAK,CAAC,IAAI,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,MAAe;IAC5C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QACvE,uEAAuE;QACvE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,cAAc,CAAC,QAAwB,EAAE,SAAiB;IACjE,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,gBAAgB,EAAE,CAAC;YACnB,IAAI,gBAAgB,IAAI,SAAS,EAAE,CAAC;gBAClC,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import type { ConfirmingState, AgentContext, TransitionResult } from '../loop-types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Handle the CONFIRMING state.
|
|
9
|
+
*/
|
|
10
|
+
export declare function handleConfirming(state: ConfirmingState, ctx: AgentContext): Promise<TransitionResult>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* CONFIRMING state handler.
|
|
8
|
+
*
|
|
9
|
+
* Waits for user confirmation on a tool call (via ctx.waitForConfirmation).
|
|
10
|
+
* - Approved → resume EXECUTING with the confirmed call
|
|
11
|
+
* - Denied → tell the model the tool call was denied, back to THINKING
|
|
12
|
+
*/
|
|
13
|
+
import { SSEEventType } from '../../types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Handle the CONFIRMING state.
|
|
16
|
+
*/
|
|
17
|
+
export async function handleConfirming(state, ctx) {
|
|
18
|
+
const effects = [];
|
|
19
|
+
ctx.logger.info('tool_confirmation_waiting', {
|
|
20
|
+
tool: state.call.toolName,
|
|
21
|
+
callId: state.call.toolCallId,
|
|
22
|
+
session: ctx.sessionId,
|
|
23
|
+
});
|
|
24
|
+
// Race confirmation against a timeout — don't hang forever if user never responds
|
|
25
|
+
const timeoutMs = ctx.config.confirmationTimeoutMs;
|
|
26
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
27
|
+
setTimeout(() => resolve(false), timeoutMs);
|
|
28
|
+
});
|
|
29
|
+
const approved = await Promise.race([
|
|
30
|
+
ctx.waitForConfirmation(state.call.toolCallId),
|
|
31
|
+
timeoutPromise,
|
|
32
|
+
]);
|
|
33
|
+
if (approved) {
|
|
34
|
+
ctx.logger.info('tool_confirmation_approved', {
|
|
35
|
+
tool: state.call.toolName,
|
|
36
|
+
callId: state.call.toolCallId,
|
|
37
|
+
session: ctx.sessionId,
|
|
38
|
+
});
|
|
39
|
+
// Mark this call as confirmed so EXECUTING does not re-route it back
|
|
40
|
+
// to CONFIRMING on the next pass (infinite-loop guard).
|
|
41
|
+
ctx.confirmedCallIds.add(state.call.toolCallId);
|
|
42
|
+
effects.push({
|
|
43
|
+
type: SSEEventType.Approved,
|
|
44
|
+
resource_type: 'tool_call',
|
|
45
|
+
preview_id: state.call.toolCallId,
|
|
46
|
+
timestamp: new Date().toISOString(),
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
next: {
|
|
50
|
+
type: 'executing',
|
|
51
|
+
queue: state.remainingQueue,
|
|
52
|
+
current: state.call,
|
|
53
|
+
results: [],
|
|
54
|
+
},
|
|
55
|
+
effects,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Denied — inject a tool result message telling the model
|
|
59
|
+
ctx.logger.info('tool_confirmation_denied', {
|
|
60
|
+
tool: state.call.toolName,
|
|
61
|
+
callId: state.call.toolCallId,
|
|
62
|
+
session: ctx.sessionId,
|
|
63
|
+
});
|
|
64
|
+
const denialMessage = {
|
|
65
|
+
role: 'tool',
|
|
66
|
+
content: [{
|
|
67
|
+
type: 'tool-result',
|
|
68
|
+
toolCallId: state.call.toolCallId,
|
|
69
|
+
toolName: state.call.toolName,
|
|
70
|
+
output: { type: 'text', value: 'Tool call denied by user. Do not retry this action without asking the user first.' },
|
|
71
|
+
}],
|
|
72
|
+
};
|
|
73
|
+
ctx.messages = [...ctx.messages, denialMessage];
|
|
74
|
+
return {
|
|
75
|
+
next: { type: 'thinking', messages: ctx.messages },
|
|
76
|
+
effects,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=confirming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirming.js","sourceRoot":"","sources":["../../../../src/agent/states/confirming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAQ5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAsB,EACtB,GAAiB;IAEjB,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;QAC3C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;QACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;QAC7B,OAAO,EAAE,GAAG,CAAC,SAAS;KACvB,CAAC,CAAC;IAEH,kFAAkF;IAClF,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,qBAAqB,CAAC;IACnD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,OAAO,EAAE,EAAE;QACpD,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QAClC,GAAG,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;QAC9C,cAAc;KACf,CAAC,CAAC;IAEH,IAAI,QAAQ,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;YAC5C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;YACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;YAC7B,OAAO,EAAE,GAAG,CAAC,SAAS;SACvB,CAAC,CAAC;QAEH,qEAAqE;QACrE,wDAAwD;QACxD,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEhD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,YAAY,CAAC,QAAQ;YAC3B,aAAa,EAAE,WAAW;YAC1B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;YACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE;gBACJ,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,KAAK,CAAC,cAAc;gBAC3B,OAAO,EAAE,KAAK,CAAC,IAAI;gBACnB,OAAO,EAAE,EAAE;aACZ;YACD,OAAO;SACR,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;QAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;QACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;QAC7B,OAAO,EAAE,GAAG,CAAC,SAAS;KACvB,CAAC,CAAC;IAEH,MAAM,aAAa,GAA8B;QAC/C,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,aAAsB;gBAC5B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;gBACjC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;gBAC7B,MAAM,EAAE,EAAC,IAAI,EAAE,MAAe,EAAE,KAAK,EAAE,mFAAmF,EAAC;aAC5H,CAAC;KACH,CAAC;IAEF,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEhD,OAAO;QACL,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAC;QAChD,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import type { DispatchingState, AgentContext, TransitionResult } from '../loop-types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Handle the DISPATCHING state — run a child agent loop.
|
|
9
|
+
*
|
|
10
|
+
* Creates a child AgentContext with:
|
|
11
|
+
* - Same provider, logger, signal, tenant, user, permission checker
|
|
12
|
+
* - Tool registry subset (only the requested tools, never dispatch_task)
|
|
13
|
+
* - Same buildToolContext factory (child shares parent's connections/stores)
|
|
14
|
+
* - Reduced maxTurns (default 10) and maxContextTokens
|
|
15
|
+
* - Fresh messages (dispatch prompt as user message)
|
|
16
|
+
* - Fresh usage counters (merged back to parent after completion)
|
|
17
|
+
*/
|
|
18
|
+
export declare function handleDispatching(state: DispatchingState, ctx: AgentContext): Promise<TransitionResult>;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* DISPATCHING state handler.
|
|
8
|
+
*
|
|
9
|
+
* Spawns a child agent with a subset of tools and a specific prompt.
|
|
10
|
+
* The child runs its own runAgent() loop; each child event is wrapped
|
|
11
|
+
* as an SSESubagentEvent and yielded as an effect so the client can
|
|
12
|
+
* display real-time sub-agent activity.
|
|
13
|
+
*
|
|
14
|
+
* After the child completes, the handler builds a ToolResult from the
|
|
15
|
+
* child's text response and transitions back through the normal
|
|
16
|
+
* EXECUTING post-result flow (queue, compaction, thinking).
|
|
17
|
+
*/
|
|
18
|
+
import { SSEEventType } from '../../types.js';
|
|
19
|
+
import { createToolRegistry } from '../../tools/registry.js';
|
|
20
|
+
import { DEFAULT_LOOP_CONFIG } from '../loop-types.js';
|
|
21
|
+
import { runAgent } from '../loop.js';
|
|
22
|
+
import { nextAfterToolResult } from './executing.js';
|
|
23
|
+
import { DEFAULT_CHILD_MAX_TURNS, DISPATCH_TOOL_NAME } from '../../tools/dispatch-tool.js';
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Constants
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
const DEFAULT_CHILD_MAX_CONTEXT_TOKENS = 100_000;
|
|
28
|
+
const DEFAULT_CHILD_TIMEOUT_MS = 60_000;
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Handler
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Handle the DISPATCHING state — run a child agent loop.
|
|
34
|
+
*
|
|
35
|
+
* Creates a child AgentContext with:
|
|
36
|
+
* - Same provider, logger, signal, tenant, user, permission checker
|
|
37
|
+
* - Tool registry subset (only the requested tools, never dispatch_task)
|
|
38
|
+
* - Same buildToolContext factory (child shares parent's connections/stores)
|
|
39
|
+
* - Reduced maxTurns (default 10) and maxContextTokens
|
|
40
|
+
* - Fresh messages (dispatch prompt as user message)
|
|
41
|
+
* - Fresh usage counters (merged back to parent after completion)
|
|
42
|
+
*/
|
|
43
|
+
export async function handleDispatching(state, ctx) {
|
|
44
|
+
const { task, toolCallId } = state;
|
|
45
|
+
const effects = [];
|
|
46
|
+
const startedAt = Date.now();
|
|
47
|
+
ctx.logger.info('dispatch_start', {
|
|
48
|
+
session: ctx.sessionId,
|
|
49
|
+
agent: task.agentName,
|
|
50
|
+
tools: task.toolSubset,
|
|
51
|
+
maxTurns: task.maxTurns ?? DEFAULT_CHILD_MAX_TURNS,
|
|
52
|
+
parentToolCallId: toolCallId,
|
|
53
|
+
});
|
|
54
|
+
// Short-circuit: if the parent is already out of budget, don't bother
|
|
55
|
+
// spinning up a child only to have it run one doomed turn. The child
|
|
56
|
+
// would inherit maxSessionTokens=0, burn through its first streaming
|
|
57
|
+
// call, and stop on budget_exceeded anyway. Surface a clean error
|
|
58
|
+
// result to the parent instead.
|
|
59
|
+
if (ctx.maxSessionTokens !== undefined &&
|
|
60
|
+
ctx.usage.totalTokens >= ctx.maxSessionTokens) {
|
|
61
|
+
ctx.logger.warn('dispatch_skipped_budget_exhausted', {
|
|
62
|
+
session: ctx.sessionId,
|
|
63
|
+
agent: task.agentName,
|
|
64
|
+
totalTokens: ctx.usage.totalTokens,
|
|
65
|
+
maxSessionTokens: ctx.maxSessionTokens,
|
|
66
|
+
parentToolCallId: toolCallId,
|
|
67
|
+
});
|
|
68
|
+
const result = {
|
|
69
|
+
callId: toolCallId,
|
|
70
|
+
toolName: DISPATCH_TOOL_NAME,
|
|
71
|
+
status: 'error',
|
|
72
|
+
content: `Sub-agent dispatch skipped: session token budget (${ctx.maxSessionTokens}) already reached.`,
|
|
73
|
+
};
|
|
74
|
+
effects.push({
|
|
75
|
+
type: SSEEventType.ToolCallResult,
|
|
76
|
+
tool_id: toolCallId,
|
|
77
|
+
status: result.status,
|
|
78
|
+
duration_ms: Date.now() - startedAt,
|
|
79
|
+
error: result.content,
|
|
80
|
+
timestamp: new Date().toISOString(),
|
|
81
|
+
});
|
|
82
|
+
const executingState = {
|
|
83
|
+
type: 'executing',
|
|
84
|
+
current: { toolCallId, toolName: DISPATCH_TOOL_NAME, args: {} },
|
|
85
|
+
queue: state.queue,
|
|
86
|
+
results: state.results,
|
|
87
|
+
};
|
|
88
|
+
return nextAfterToolResult(executingState, result, effects, ctx);
|
|
89
|
+
}
|
|
90
|
+
// Build child tool registry from the parent's subset
|
|
91
|
+
const childRegistry = createToolRegistry();
|
|
92
|
+
const subsetTools = ctx.toolRegistry.subset(task.toolSubset);
|
|
93
|
+
for (const [name, def] of Object.entries(subsetTools)) {
|
|
94
|
+
childRegistry.register(name, def);
|
|
95
|
+
}
|
|
96
|
+
// Child-specific timeout — prevents a slow child from starving the parent.
|
|
97
|
+
// Combined with parent's signal so parent abort also stops child.
|
|
98
|
+
const childTimeoutMs = task.timeoutMs ?? DEFAULT_CHILD_TIMEOUT_MS;
|
|
99
|
+
const childSignal = AbortSignal.any([ctx.signal, AbortSignal.timeout(childTimeoutMs)]);
|
|
100
|
+
// Minimal system prompt for the child — the full parent prompt (skills,
|
|
101
|
+
// knowledge, connection docs) is unnecessary for a focused sub-task and
|
|
102
|
+
// wastes tokens. The child gets a task-scoped prompt with available tools.
|
|
103
|
+
const childToolNames = childRegistry.names();
|
|
104
|
+
const childSystemPrompt = buildChildSystemPrompt(task.agentName, task.prompt, childToolNames);
|
|
105
|
+
// Build child context
|
|
106
|
+
const childCtx = {
|
|
107
|
+
provider: ctx.provider,
|
|
108
|
+
toolRegistry: childRegistry,
|
|
109
|
+
permissionChecker: ctx.permissionChecker,
|
|
110
|
+
logger: ctx.logger,
|
|
111
|
+
signal: childSignal,
|
|
112
|
+
sessionId: ctx.sessionId,
|
|
113
|
+
user: ctx.user,
|
|
114
|
+
systemPrompt: childSystemPrompt,
|
|
115
|
+
messages: [],
|
|
116
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
117
|
+
turnCount: 0,
|
|
118
|
+
maxTurns: task.maxTurns ?? DEFAULT_CHILD_MAX_TURNS,
|
|
119
|
+
maxContextTokens: task.maxContextTokens ?? DEFAULT_CHILD_MAX_CONTEXT_TOKENS,
|
|
120
|
+
// Propagate parent's remaining token budget so a child can't blow through
|
|
121
|
+
// more than the parent had left. Child usage merges back into parent after
|
|
122
|
+
// the child completes, so the parent's next budget check catches any
|
|
123
|
+
// overshoot on subsequent turns regardless.
|
|
124
|
+
maxSessionTokens: ctx.maxSessionTokens !== undefined
|
|
125
|
+
? Math.max(0, ctx.maxSessionTokens - ctx.usage.totalTokens)
|
|
126
|
+
: undefined,
|
|
127
|
+
config: { ...DEFAULT_LOOP_CONFIG },
|
|
128
|
+
compactionFailures: 0,
|
|
129
|
+
preExecutionCache: new Map(),
|
|
130
|
+
confirmedCallIds: new Set(),
|
|
131
|
+
disabledToolsUntilTurn: new Map(),
|
|
132
|
+
waitForConfirmation: ctx.waitForConfirmation,
|
|
133
|
+
buildToolContext: ctx.buildToolContext,
|
|
134
|
+
};
|
|
135
|
+
// Run child agent loop and translate events to SubagentEvents
|
|
136
|
+
let childResponse = '';
|
|
137
|
+
let childFailed = false;
|
|
138
|
+
try {
|
|
139
|
+
for await (const childEvent of runAgent({ messages: [{ role: 'user', content: task.prompt }], context: childCtx })) {
|
|
140
|
+
if (ctx.signal.aborted)
|
|
141
|
+
break;
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- intentionally skip child-internal events (Init, Widget, etc.)
|
|
143
|
+
switch (childEvent.type) {
|
|
144
|
+
case SSEEventType.TextDelta:
|
|
145
|
+
childResponse += childEvent.content;
|
|
146
|
+
effects.push({
|
|
147
|
+
type: SSEEventType.SubagentEvent,
|
|
148
|
+
parent_tool_id: toolCallId,
|
|
149
|
+
agent_name: task.agentName,
|
|
150
|
+
event_type: 'thought',
|
|
151
|
+
text: childEvent.content,
|
|
152
|
+
timestamp: childEvent.timestamp,
|
|
153
|
+
});
|
|
154
|
+
break;
|
|
155
|
+
case SSEEventType.ToolCallStart:
|
|
156
|
+
effects.push({
|
|
157
|
+
type: SSEEventType.SubagentEvent,
|
|
158
|
+
parent_tool_id: toolCallId,
|
|
159
|
+
agent_name: task.agentName,
|
|
160
|
+
event_type: 'tool_call_start',
|
|
161
|
+
tool_name: childEvent.tool_name,
|
|
162
|
+
tool_args: childEvent.parameters,
|
|
163
|
+
timestamp: childEvent.timestamp,
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
case SSEEventType.ToolCallResult:
|
|
167
|
+
effects.push({
|
|
168
|
+
type: SSEEventType.SubagentEvent,
|
|
169
|
+
parent_tool_id: toolCallId,
|
|
170
|
+
agent_name: task.agentName,
|
|
171
|
+
event_type: 'tool_call_end',
|
|
172
|
+
tool_name: undefined,
|
|
173
|
+
result: childEvent.status === 'error' ? childEvent.error : undefined,
|
|
174
|
+
timestamp: childEvent.timestamp,
|
|
175
|
+
});
|
|
176
|
+
break;
|
|
177
|
+
case SSEEventType.Error:
|
|
178
|
+
effects.push({
|
|
179
|
+
type: SSEEventType.SubagentEvent,
|
|
180
|
+
parent_tool_id: toolCallId,
|
|
181
|
+
agent_name: task.agentName,
|
|
182
|
+
event_type: 'error',
|
|
183
|
+
error: childEvent.message,
|
|
184
|
+
timestamp: childEvent.timestamp,
|
|
185
|
+
});
|
|
186
|
+
break;
|
|
187
|
+
case SSEEventType.Done:
|
|
188
|
+
effects.push({
|
|
189
|
+
type: SSEEventType.SubagentEvent,
|
|
190
|
+
parent_tool_id: toolCallId,
|
|
191
|
+
agent_name: task.agentName,
|
|
192
|
+
event_type: 'complete',
|
|
193
|
+
timestamp: childEvent.timestamp,
|
|
194
|
+
});
|
|
195
|
+
break;
|
|
196
|
+
default:
|
|
197
|
+
// Skip Init and other events — they're child-internal
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
204
|
+
ctx.logger.error('dispatch_child_error', {
|
|
205
|
+
session: ctx.sessionId,
|
|
206
|
+
agent: task.agentName,
|
|
207
|
+
error: errorMessage,
|
|
208
|
+
parentToolCallId: toolCallId,
|
|
209
|
+
});
|
|
210
|
+
effects.push({
|
|
211
|
+
type: SSEEventType.SubagentEvent,
|
|
212
|
+
parent_tool_id: toolCallId,
|
|
213
|
+
agent_name: task.agentName,
|
|
214
|
+
event_type: 'error',
|
|
215
|
+
error: errorMessage,
|
|
216
|
+
timestamp: new Date().toISOString(),
|
|
217
|
+
});
|
|
218
|
+
childResponse = `Sub-agent "${task.agentName}" failed: ${errorMessage}`;
|
|
219
|
+
childFailed = true;
|
|
220
|
+
}
|
|
221
|
+
// Merge child usage into parent
|
|
222
|
+
ctx.usage.inputTokens += childCtx.usage.inputTokens;
|
|
223
|
+
ctx.usage.outputTokens += childCtx.usage.outputTokens;
|
|
224
|
+
ctx.usage.totalTokens += childCtx.usage.totalTokens;
|
|
225
|
+
if (childCtx.usage.cachedInputTokens) {
|
|
226
|
+
ctx.usage.cachedInputTokens = (ctx.usage.cachedInputTokens ?? 0) + childCtx.usage.cachedInputTokens;
|
|
227
|
+
}
|
|
228
|
+
if (childCtx.usage.cacheCreationInputTokens) {
|
|
229
|
+
ctx.usage.cacheCreationInputTokens = (ctx.usage.cacheCreationInputTokens ?? 0) + childCtx.usage.cacheCreationInputTokens;
|
|
230
|
+
}
|
|
231
|
+
const duration = Date.now() - startedAt;
|
|
232
|
+
ctx.logger.info('dispatch_complete', {
|
|
233
|
+
session: ctx.sessionId,
|
|
234
|
+
agent: task.agentName,
|
|
235
|
+
childTurns: childCtx.turnCount,
|
|
236
|
+
childUsage: childCtx.usage,
|
|
237
|
+
responseLength: childResponse.length,
|
|
238
|
+
parentToolCallId: toolCallId,
|
|
239
|
+
duration,
|
|
240
|
+
});
|
|
241
|
+
// Build tool result from child response
|
|
242
|
+
const result = {
|
|
243
|
+
callId: toolCallId,
|
|
244
|
+
toolName: DISPATCH_TOOL_NAME,
|
|
245
|
+
status: childFailed ? 'error' : 'success',
|
|
246
|
+
content: childResponse || '(no response from sub-agent)',
|
|
247
|
+
};
|
|
248
|
+
// Emit ToolCallResult for the dispatch_task call
|
|
249
|
+
effects.push({
|
|
250
|
+
type: SSEEventType.ToolCallResult,
|
|
251
|
+
tool_id: toolCallId,
|
|
252
|
+
status: result.status,
|
|
253
|
+
duration_ms: duration,
|
|
254
|
+
...(result.status === 'error' ? { error: result.content } : {}),
|
|
255
|
+
timestamp: new Date().toISOString(),
|
|
256
|
+
});
|
|
257
|
+
// Use the shared post-result transition logic from EXECUTING.
|
|
258
|
+
// This handles: append tool result message, continue queue, compaction check.
|
|
259
|
+
const executingState = {
|
|
260
|
+
type: 'executing',
|
|
261
|
+
current: { toolCallId, toolName: DISPATCH_TOOL_NAME, args: {} },
|
|
262
|
+
queue: state.queue,
|
|
263
|
+
results: state.results,
|
|
264
|
+
};
|
|
265
|
+
return nextAfterToolResult(executingState, result, effects, ctx);
|
|
266
|
+
}
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// Child system prompt
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
/**
|
|
271
|
+
* Build a minimal system prompt for the child agent.
|
|
272
|
+
*
|
|
273
|
+
* The full parent prompt (30K+ chars of skills, knowledge, connection docs)
|
|
274
|
+
* is wasteful for a focused sub-task. The child gets a concise, task-scoped
|
|
275
|
+
* prompt listing only its available tools.
|
|
276
|
+
*/
|
|
277
|
+
function buildChildSystemPrompt(agentName, taskPrompt, toolNames) {
|
|
278
|
+
const toolList = toolNames.length > 0
|
|
279
|
+
? `\n\nAvailable tools: ${toolNames.join(', ')}`
|
|
280
|
+
: '';
|
|
281
|
+
return `You are "${agentName}", a sub-agent executing a delegated task. Complete the task and return a concise summary of your findings or actions.
|
|
282
|
+
|
|
283
|
+
Do not ask clarifying questions — work with what you have. If you cannot complete the task, explain what went wrong.${toolList}`;
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=dispatching.js.map
|