@amodalai/runtime 0.1.26 → 0.2.0
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 +84 -0
- package/dist/src/__fixtures__/smoke-agent/amodal.json +11 -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 +718 -0
- package/dist/src/__fixtures__/smoke.test.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/local-server.d.ts +3 -3
- package/dist/src/agent/local-server.js +213 -122
- package/dist/src/agent/local-server.js.map +1 -1
- package/dist/src/agent/loop-types.d.ts +175 -0
- package/dist/src/agent/loop-types.js +20 -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 +139 -0
- package/dist/src/agent/loop.js.map +1 -0
- package/dist/src/agent/loop.test.js +1030 -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/proactive-runner.d.ts +24 -8
- package/dist/src/agent/proactive/proactive-runner.js +30 -32
- 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 +75 -87
- package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
- package/dist/src/agent/routes/admin-chat.d.ts +15 -3
- package/dist/src/agent/routes/admin-chat.js +63 -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 +70 -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/session-store.d.ts +11 -2
- package/dist/src/agent/session-store.js +1 -1
- package/dist/src/agent/session-store.js.map +1 -1
- package/dist/src/agent/snapshot-server.d.ts +2 -22
- package/dist/src/agent/snapshot-server.js +50 -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 +258 -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 +76 -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 +241 -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 +308 -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 +155 -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 +233 -0
- package/dist/src/agent/states/thinking.js.map +1 -0
- package/dist/src/agent/token-estimate.d.ts +17 -0
- package/dist/src/agent/token-estimate.js +13 -0
- package/dist/src/agent/token-estimate.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 +137 -0
- package/dist/src/api/create-agent.js.map +1 -0
- package/dist/src/api/types.d.ts +68 -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.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/index.d.ts +33 -6
- package/dist/src/index.js +35 -21
- package/dist/src/index.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/{agent/stores-e2e.test.d.ts → providers/create-provider.test.d.ts} +1 -1
- 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/types.d.ts +110 -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 +13 -10
- package/dist/src/routes/ai-stream.js +76 -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 +14 -4
- package/dist/src/routes/chat-stream.js +47 -29
- package/dist/src/routes/chat-stream.js.map +1 -1
- package/dist/src/routes/chat.d.ts +13 -4
- package/dist/src/routes/chat.js +60 -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 +72 -0
- package/dist/src/routes/session-resolver.js +123 -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 +206 -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 +12 -11
- package/dist/src/server.js +44 -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/manager.d.ts +98 -0
- package/dist/src/session/manager.js +364 -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 +315 -0
- package/dist/src/session/manager.test.js.map +1 -0
- package/dist/src/session/session-builder.d.ts +71 -0
- package/dist/src/session/session-builder.js +364 -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 +352 -0
- package/dist/src/session/session-builder.test.js.map +1 -0
- package/dist/src/session/store.d.ts +57 -0
- package/dist/src/session/store.js +167 -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 +145 -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 +60 -0
- package/dist/src/session/tool-context-factory.js +190 -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 +287 -0
- package/dist/src/session/tool-context-factory.test.js.map +1 -0
- package/dist/src/session/types.d.ts +188 -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 +491 -0
- package/dist/src/stores/schema.js +57 -0
- package/dist/src/stores/schema.js.map +1 -0
- package/dist/src/tools/admin-file-tools.d.ts +13 -0
- package/dist/src/tools/admin-file-tools.js +200 -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 +152 -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 +244 -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/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 +227 -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 +121 -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 +254 -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 +216 -0
- package/dist/src/tools/store-tools.test.js.map +1 -0
- package/dist/src/tools/types.d.ts +111 -0
- package/dist/src/tools/types.js +7 -0
- package/dist/src/tools/types.js.map +1 -0
- package/dist/src/types.d.ts +20 -12
- package/dist/src/types.js +3 -2
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -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/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/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__/smoke.test.d.ts} +0 -0
- /package/dist/src/{__tests__/tools.test.d.ts → agent/loop.test.d.ts} +0 -0
- /package/dist/src/{agent/write-repo-file.test.d.ts → context/compiler.test.d.ts} +0 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Tool Context Factory Tests.
|
|
8
|
+
*
|
|
9
|
+
* Covers:
|
|
10
|
+
* 1. ctx.request() — makes HTTP calls through connections with auth headers
|
|
11
|
+
* 2. ctx.request() — connection not found error with suggestion
|
|
12
|
+
* 3. ctx.request() — auth failure → ConnectionError
|
|
13
|
+
* 4. ctx.store() — writes to store backend with key resolution
|
|
14
|
+
* 5. ctx.store() — store not found error
|
|
15
|
+
* 6. ctx.env() — allowlisted vars exposed, others blocked
|
|
16
|
+
* 7. ctx.log() — emits structured log event
|
|
17
|
+
* 8. ctx.user, ctx.sessionId, ctx.tenantId — passthrough
|
|
18
|
+
* 9. Factory returns fresh context per callId
|
|
19
|
+
*/
|
|
20
|
+
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
21
|
+
import { createToolContextFactory } from './tool-context-factory.js';
|
|
22
|
+
import { StoreError } from '../errors.js';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Mocks
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
function makeMockLogger() {
|
|
27
|
+
return {
|
|
28
|
+
trace: vi.fn(),
|
|
29
|
+
debug: vi.fn(),
|
|
30
|
+
info: vi.fn(),
|
|
31
|
+
warn: vi.fn(),
|
|
32
|
+
error: vi.fn(),
|
|
33
|
+
fatal: vi.fn(),
|
|
34
|
+
child: vi.fn().mockReturnThis(),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function makeMockStoreBackend() {
|
|
38
|
+
return {
|
|
39
|
+
initialize: vi.fn(),
|
|
40
|
+
get: vi.fn(),
|
|
41
|
+
put: vi.fn().mockResolvedValue({ stored: true, key: 'resolved-key', version: 1 }),
|
|
42
|
+
list: vi.fn(),
|
|
43
|
+
delete: vi.fn(),
|
|
44
|
+
history: vi.fn(),
|
|
45
|
+
purgeExpired: vi.fn(),
|
|
46
|
+
close: vi.fn(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function makeStoreDefinition(overrides) {
|
|
50
|
+
return {
|
|
51
|
+
name: 'deals',
|
|
52
|
+
entity: {
|
|
53
|
+
name: 'Deal',
|
|
54
|
+
key: '{company}_{quarter}',
|
|
55
|
+
schema: {
|
|
56
|
+
company: { type: 'string' },
|
|
57
|
+
quarter: { type: 'string' },
|
|
58
|
+
amount: { type: 'number' },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
location: '/tmp/stores/deals.json',
|
|
62
|
+
...overrides,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function makeConnectionsMap() {
|
|
66
|
+
return {
|
|
67
|
+
stripe: {
|
|
68
|
+
base_url: 'https://api.stripe.com',
|
|
69
|
+
_request_config: {
|
|
70
|
+
base_url_field: 'base_url',
|
|
71
|
+
auth: [{ header: 'Authorization', value_template: 'Bearer {{STRIPE_KEY}}' }],
|
|
72
|
+
},
|
|
73
|
+
STRIPE_KEY: 'sk_test_123',
|
|
74
|
+
},
|
|
75
|
+
slack: {
|
|
76
|
+
base_url: 'https://slack.com/api',
|
|
77
|
+
_request_config: {
|
|
78
|
+
base_url_field: 'base_url',
|
|
79
|
+
auth: [{ header: 'Authorization', value_template: 'Bearer {{SLACK_TOKEN}}' }],
|
|
80
|
+
default_headers: { 'X-Custom': 'value' },
|
|
81
|
+
},
|
|
82
|
+
SLACK_TOKEN: 'xoxb-test',
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function makeFactoryOpts(overrides) {
|
|
87
|
+
return {
|
|
88
|
+
connectionsMap: makeConnectionsMap(),
|
|
89
|
+
storeBackend: makeMockStoreBackend(),
|
|
90
|
+
storeDefinitions: [makeStoreDefinition()],
|
|
91
|
+
appId: 'test-app',
|
|
92
|
+
envAllowlist: { ALLOWED_VAR: 'allowed-value' },
|
|
93
|
+
logger: makeMockLogger(),
|
|
94
|
+
user: { roles: ['analyst'] },
|
|
95
|
+
sessionId: 'sess-123',
|
|
96
|
+
tenantId: 'tenant-456',
|
|
97
|
+
...overrides,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// Tests
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
describe('createToolContextFactory', () => {
|
|
104
|
+
afterEach(() => {
|
|
105
|
+
vi.restoreAllMocks();
|
|
106
|
+
});
|
|
107
|
+
// -------------------------------------------------------------------------
|
|
108
|
+
// Basic factory behavior
|
|
109
|
+
// -------------------------------------------------------------------------
|
|
110
|
+
it('returns a factory function that produces ToolContext', () => {
|
|
111
|
+
const factory = createToolContextFactory(makeFactoryOpts());
|
|
112
|
+
const ctx = factory('call-1');
|
|
113
|
+
expect(ctx.sessionId).toBe('sess-123');
|
|
114
|
+
expect(ctx.tenantId).toBe('tenant-456');
|
|
115
|
+
expect(ctx.user.roles).toEqual(['analyst']);
|
|
116
|
+
expect(ctx.signal).toBeDefined();
|
|
117
|
+
expect(ctx.signal.aborted).toBe(false);
|
|
118
|
+
});
|
|
119
|
+
it('returns fresh context per callId', () => {
|
|
120
|
+
const factory = createToolContextFactory(makeFactoryOpts());
|
|
121
|
+
const ctx1 = factory('call-1');
|
|
122
|
+
const ctx2 = factory('call-2');
|
|
123
|
+
// Different objects
|
|
124
|
+
expect(ctx1).not.toBe(ctx2);
|
|
125
|
+
// Same session info
|
|
126
|
+
expect(ctx1.sessionId).toBe(ctx2.sessionId);
|
|
127
|
+
});
|
|
128
|
+
// -------------------------------------------------------------------------
|
|
129
|
+
// ctx.env()
|
|
130
|
+
// -------------------------------------------------------------------------
|
|
131
|
+
it('env() returns allowlisted vars', () => {
|
|
132
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
133
|
+
expect(ctx.env('ALLOWED_VAR')).toBe('allowed-value');
|
|
134
|
+
});
|
|
135
|
+
it('env() blocks non-allowlisted vars', () => {
|
|
136
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
137
|
+
expect(ctx.env('BLOCKED_VAR')).toBeUndefined();
|
|
138
|
+
expect(ctx.env('HOME')).toBeUndefined();
|
|
139
|
+
expect(ctx.env('PATH')).toBeUndefined();
|
|
140
|
+
});
|
|
141
|
+
// -------------------------------------------------------------------------
|
|
142
|
+
// ctx.log()
|
|
143
|
+
// -------------------------------------------------------------------------
|
|
144
|
+
it('log() emits structured event via logger', () => {
|
|
145
|
+
const logger = makeMockLogger();
|
|
146
|
+
const ctx = createToolContextFactory(makeFactoryOpts({ logger }))('call-42');
|
|
147
|
+
ctx.log('processing item');
|
|
148
|
+
expect(logger.info).toHaveBeenCalledWith('tool_log', {
|
|
149
|
+
callId: 'call-42',
|
|
150
|
+
message: 'processing item',
|
|
151
|
+
session: 'sess-123',
|
|
152
|
+
tenant: 'tenant-456',
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
// -------------------------------------------------------------------------
|
|
156
|
+
// ctx.store()
|
|
157
|
+
// -------------------------------------------------------------------------
|
|
158
|
+
it('store() writes to backend with resolved key', async () => {
|
|
159
|
+
const backend = makeMockStoreBackend();
|
|
160
|
+
const ctx = createToolContextFactory(makeFactoryOpts({ storeBackend: backend }))('call-1');
|
|
161
|
+
const result = await ctx.store('deals', { company: 'acme', quarter: 'Q1', amount: 5000 });
|
|
162
|
+
expect(result).toEqual({ key: 'acme_Q1' });
|
|
163
|
+
expect(backend.put).toHaveBeenCalledWith('test-app', 'deals', 'acme_Q1', { company: 'acme', quarter: 'Q1', amount: 5000 }, {});
|
|
164
|
+
});
|
|
165
|
+
it('store() throws StoreError when store not found', async () => {
|
|
166
|
+
const ctx = createToolContextFactory(makeFactoryOpts({ storeDefinitions: [] }))('call-1');
|
|
167
|
+
await expect(ctx.store('nonexistent', {})).rejects.toThrow(StoreError);
|
|
168
|
+
await expect(ctx.store('nonexistent', {})).rejects.toThrow(/Store "nonexistent" not found/);
|
|
169
|
+
});
|
|
170
|
+
it('store() throws when key template field is missing', async () => {
|
|
171
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
172
|
+
await expect(ctx.store('deals', { company: 'acme' })).rejects.toThrow(/field "quarter"/);
|
|
173
|
+
});
|
|
174
|
+
it('store() logs write with key and store name', async () => {
|
|
175
|
+
const logger = makeMockLogger();
|
|
176
|
+
const ctx = createToolContextFactory(makeFactoryOpts({ logger }))('call-1');
|
|
177
|
+
await ctx.store('deals', { company: 'acme', quarter: 'Q1', amount: 100 });
|
|
178
|
+
expect(logger.debug).toHaveBeenCalledWith('tool_context_store_write', expect.objectContaining({
|
|
179
|
+
store: 'deals',
|
|
180
|
+
key: 'acme_Q1',
|
|
181
|
+
}));
|
|
182
|
+
});
|
|
183
|
+
// -------------------------------------------------------------------------
|
|
184
|
+
// ctx.request()
|
|
185
|
+
// -------------------------------------------------------------------------
|
|
186
|
+
it('request() makes HTTP call with auth headers', async () => {
|
|
187
|
+
const mockResponse = new Response(JSON.stringify({ data: 'ok' }), { status: 200 });
|
|
188
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(mockResponse);
|
|
189
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
190
|
+
const result = await ctx.request('stripe', '/v1/customers', { method: 'GET' });
|
|
191
|
+
expect(result).toEqual({ data: 'ok' });
|
|
192
|
+
expect(fetchSpy).toHaveBeenCalledWith('https://api.stripe.com/v1/customers', expect.objectContaining({
|
|
193
|
+
method: 'GET',
|
|
194
|
+
headers: expect.objectContaining({
|
|
195
|
+
Authorization: 'Bearer sk_test_123',
|
|
196
|
+
}),
|
|
197
|
+
}));
|
|
198
|
+
});
|
|
199
|
+
it('request() includes default headers from connection config', async () => {
|
|
200
|
+
const mockResponse = new Response(JSON.stringify({ ok: true }), { status: 200 });
|
|
201
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(mockResponse);
|
|
202
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
203
|
+
await ctx.request('slack', '/chat.postMessage', { method: 'POST', data: { text: 'hi' } });
|
|
204
|
+
expect(fetchSpy).toHaveBeenCalledWith('https://slack.com/api/chat.postMessage', expect.objectContaining({
|
|
205
|
+
method: 'POST',
|
|
206
|
+
headers: expect.objectContaining({
|
|
207
|
+
'Authorization': 'Bearer xoxb-test',
|
|
208
|
+
'X-Custom': 'value',
|
|
209
|
+
}),
|
|
210
|
+
body: JSON.stringify({ text: 'hi' }),
|
|
211
|
+
}));
|
|
212
|
+
});
|
|
213
|
+
it('request() adds query params', async () => {
|
|
214
|
+
const mockResponse = new Response(JSON.stringify([]), { status: 200 });
|
|
215
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(mockResponse);
|
|
216
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
217
|
+
await ctx.request('stripe', '/v1/charges', { params: { limit: '10', status: 'paid' } });
|
|
218
|
+
const calledUrl = fetchSpy.mock.calls[0][0];
|
|
219
|
+
expect(calledUrl).toContain('limit=10');
|
|
220
|
+
expect(calledUrl).toContain('status=paid');
|
|
221
|
+
});
|
|
222
|
+
it('request() throws ConnectionError when connection not found', async () => {
|
|
223
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
224
|
+
await expect(ctx.request('unknown', '/foo')).rejects.toThrow(/Connection "unknown" not found/);
|
|
225
|
+
});
|
|
226
|
+
it('request() suggests similar connection name', async () => {
|
|
227
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
228
|
+
await expect(ctx.request('Stripe', '/foo')).rejects.toThrow(/Did you mean "stripe"/);
|
|
229
|
+
});
|
|
230
|
+
it('request() throws ConnectionError on auth failure', async () => {
|
|
231
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('Unauthorized', { status: 401 }));
|
|
232
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
233
|
+
await expect(ctx.request('stripe', '/v1/customers')).rejects.toThrow(/Authentication failed/);
|
|
234
|
+
});
|
|
235
|
+
it('request() throws ConnectionError on server error', async () => {
|
|
236
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('Server Error', { status: 500 }));
|
|
237
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
238
|
+
await expect(ctx.request('stripe', '/v1/customers')).rejects.toThrow(/HTTP 500/);
|
|
239
|
+
});
|
|
240
|
+
it('request() returns raw text when response is not JSON', async () => {
|
|
241
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('plain text', { status: 200 }));
|
|
242
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
243
|
+
const result = await ctx.request('stripe', '/v1/export');
|
|
244
|
+
expect(result).toBe('plain text');
|
|
245
|
+
});
|
|
246
|
+
it('request() defaults to GET method', async () => {
|
|
247
|
+
const mockResponse = new Response(JSON.stringify({ ok: true }), { status: 200 });
|
|
248
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(mockResponse);
|
|
249
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
250
|
+
await ctx.request('stripe', '/v1/customers');
|
|
251
|
+
expect(fetchSpy).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({ method: 'GET' }));
|
|
252
|
+
});
|
|
253
|
+
it('request() logs with connection and endpoint', async () => {
|
|
254
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('{}', { status: 200 }));
|
|
255
|
+
const logger = makeMockLogger();
|
|
256
|
+
const ctx = createToolContextFactory(makeFactoryOpts({ logger }))('call-7');
|
|
257
|
+
await ctx.request('stripe', '/v1/customers', { method: 'GET' });
|
|
258
|
+
expect(logger.debug).toHaveBeenCalledWith('tool_context_request', expect.objectContaining({
|
|
259
|
+
callId: 'call-7',
|
|
260
|
+
connection: 'stripe',
|
|
261
|
+
endpoint: '/v1/customers',
|
|
262
|
+
method: 'GET',
|
|
263
|
+
}));
|
|
264
|
+
});
|
|
265
|
+
it('request() uses ctx.signal for abort — propagates when mutated', async () => {
|
|
266
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('{}', { status: 200 }));
|
|
267
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
268
|
+
// Simulate what EXECUTING handler does: mutate signal with combined timeout
|
|
269
|
+
const controller = new AbortController();
|
|
270
|
+
ctx.signal = controller.signal;
|
|
271
|
+
await ctx.request('stripe', '/v1/customers');
|
|
272
|
+
// The fetch call should have received the mutated signal, not the default timeout
|
|
273
|
+
const fetchOpts = fetchSpy.mock.calls[0][1];
|
|
274
|
+
expect(fetchOpts.signal).toBe(controller.signal);
|
|
275
|
+
});
|
|
276
|
+
it('request() aborts when ctx.signal is aborted', async () => {
|
|
277
|
+
const controller = new AbortController();
|
|
278
|
+
controller.abort();
|
|
279
|
+
vi.spyOn(globalThis, 'fetch').mockImplementation(() => {
|
|
280
|
+
throw new DOMException('The operation was aborted', 'AbortError');
|
|
281
|
+
});
|
|
282
|
+
const ctx = createToolContextFactory(makeFactoryOpts())('call-1');
|
|
283
|
+
ctx.signal = controller.signal;
|
|
284
|
+
await expect(ctx.request('stripe', '/v1/customers')).rejects.toThrow('aborted');
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
//# sourceMappingURL=tool-context-factory.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-context-factory.test.js","sourceRoot":"","sources":["../../../src/session/tool-context-factory.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Session types for the standalone session manager.
|
|
8
|
+
*/
|
|
9
|
+
import type { ModelMessage } from 'ai';
|
|
10
|
+
import type { TokenUsage, LLMProvider } from '../providers/types.js';
|
|
11
|
+
import type { ToolRegistry, ToolContext } from '../tools/types.js';
|
|
12
|
+
import type { PermissionChecker } from '../security/permission-checker.js';
|
|
13
|
+
import type { Logger } from '../logger.js';
|
|
14
|
+
/**
|
|
15
|
+
* Token usage for a single turn (one LLM call + tool executions).
|
|
16
|
+
* Reported via the `onUsage` callback on AgentContext.
|
|
17
|
+
*/
|
|
18
|
+
export interface TurnUsage {
|
|
19
|
+
inputTokens: number;
|
|
20
|
+
outputTokens: number;
|
|
21
|
+
cachedInputTokens: number;
|
|
22
|
+
cacheCreationInputTokens: number;
|
|
23
|
+
totalTokens: number;
|
|
24
|
+
turnNumber: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Full automation configuration from the agent repo.
|
|
28
|
+
*
|
|
29
|
+
* All fields are defined here. Only `schedule`, `prompt`, and `enabled`
|
|
30
|
+
* are currently implemented. The parser reads and validates the full
|
|
31
|
+
* schema; unimplemented fields are stored but ignored, so when future
|
|
32
|
+
* features ship the config is already parsed.
|
|
33
|
+
*/
|
|
34
|
+
export interface AutomationConfig {
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
/** Cron expression */
|
|
38
|
+
schedule: string;
|
|
39
|
+
/** IANA timezone (default: UTC) */
|
|
40
|
+
timezone?: string;
|
|
41
|
+
prompt: string;
|
|
42
|
+
/** LLM model override (default: primary model) */
|
|
43
|
+
model?: string;
|
|
44
|
+
/** Max turns per run (default: 15) */
|
|
45
|
+
maxTurns?: number;
|
|
46
|
+
/** Max tokens per run */
|
|
47
|
+
budget?: number;
|
|
48
|
+
/** Delivery routing — parsed now, implemented in roadmap 3.1 */
|
|
49
|
+
delivery?: {
|
|
50
|
+
on: 'completion' | 'new_results';
|
|
51
|
+
targets: Array<{
|
|
52
|
+
type: 'webhook' | 'callback';
|
|
53
|
+
url?: string;
|
|
54
|
+
}>;
|
|
55
|
+
template?: string;
|
|
56
|
+
};
|
|
57
|
+
/** Failure alerting — parsed now, implemented in roadmap 3.1 */
|
|
58
|
+
failureAlert?: {
|
|
59
|
+
after: number;
|
|
60
|
+
targets: Array<{
|
|
61
|
+
type: 'webhook' | 'callback';
|
|
62
|
+
url?: string;
|
|
63
|
+
}>;
|
|
64
|
+
cooldownMinutes?: number;
|
|
65
|
+
};
|
|
66
|
+
enabled: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Result of an automation run (returned to onAutomationResult hook).
|
|
70
|
+
*/
|
|
71
|
+
export interface AutomationResult {
|
|
72
|
+
automation: string;
|
|
73
|
+
response: string;
|
|
74
|
+
toolCalls: Array<{
|
|
75
|
+
toolName: string;
|
|
76
|
+
toolId: string;
|
|
77
|
+
status: 'success' | 'error';
|
|
78
|
+
durationMs?: number;
|
|
79
|
+
}>;
|
|
80
|
+
outputSent: boolean;
|
|
81
|
+
durationMs: number;
|
|
82
|
+
usage: TokenUsage;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Shape of a persisted session record in the database.
|
|
86
|
+
* Versioned from day one so we can migrate the format later.
|
|
87
|
+
*/
|
|
88
|
+
export interface PersistedSession {
|
|
89
|
+
version: 1;
|
|
90
|
+
id: string;
|
|
91
|
+
tenantId: string;
|
|
92
|
+
userId: string;
|
|
93
|
+
messages: ModelMessage[];
|
|
94
|
+
tokenUsage: TokenUsage;
|
|
95
|
+
metadata: SessionMetadata;
|
|
96
|
+
createdAt: Date;
|
|
97
|
+
updatedAt: Date;
|
|
98
|
+
}
|
|
99
|
+
/** Metadata stored alongside a session. */
|
|
100
|
+
export interface SessionMetadata {
|
|
101
|
+
title?: string;
|
|
102
|
+
model?: string;
|
|
103
|
+
provider?: string;
|
|
104
|
+
appId?: string;
|
|
105
|
+
automationName?: string;
|
|
106
|
+
[key: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A live session managed by the standalone SessionManager.
|
|
110
|
+
*
|
|
111
|
+
* This is the runtime representation — it holds the components needed
|
|
112
|
+
* to execute messages via the agent loop. Separate from the persisted
|
|
113
|
+
* session which only holds serializable data.
|
|
114
|
+
*/
|
|
115
|
+
export interface Session {
|
|
116
|
+
id: string;
|
|
117
|
+
tenantId: string;
|
|
118
|
+
userId: string;
|
|
119
|
+
/** LLM provider for this session (pinned at creation) */
|
|
120
|
+
provider: LLMProvider;
|
|
121
|
+
/** Tool registry holding all available tools */
|
|
122
|
+
toolRegistry: ToolRegistry;
|
|
123
|
+
/** Permission checker for tool execution */
|
|
124
|
+
permissionChecker: PermissionChecker;
|
|
125
|
+
/** Logger scoped to this session */
|
|
126
|
+
logger: Logger;
|
|
127
|
+
/** Compiled system prompt */
|
|
128
|
+
systemPrompt: string;
|
|
129
|
+
/** Mutable: conversation messages */
|
|
130
|
+
messages: ModelMessage[];
|
|
131
|
+
/** Mutable: accumulated token usage */
|
|
132
|
+
usage: TokenUsage;
|
|
133
|
+
/** Model identifier (pinned at creation, survives resume) */
|
|
134
|
+
model: string;
|
|
135
|
+
/** Provider name (pinned at creation, survives resume) */
|
|
136
|
+
providerName: string;
|
|
137
|
+
/** User roles for permission checks and field guidance */
|
|
138
|
+
userRoles: string[];
|
|
139
|
+
/** App ID for multi-app isolation */
|
|
140
|
+
appId: string;
|
|
141
|
+
/** Session metadata (title, automation info, etc.) */
|
|
142
|
+
metadata: SessionMetadata;
|
|
143
|
+
/** Timestamps */
|
|
144
|
+
createdAt: number;
|
|
145
|
+
lastAccessedAt: number;
|
|
146
|
+
/** Max turns for the agent loop */
|
|
147
|
+
maxTurns: number;
|
|
148
|
+
/** Max context tokens (provider limit) */
|
|
149
|
+
maxContextTokens: number;
|
|
150
|
+
/** Tool context factory cached from session creation (avoids rebuilding per request) */
|
|
151
|
+
toolContextFactory?: (callId: string) => ToolContext;
|
|
152
|
+
}
|
|
153
|
+
/** Options for creating the standalone SessionManager. */
|
|
154
|
+
export interface SessionManagerOptions {
|
|
155
|
+
/** Session TTL in milliseconds (default: 30 minutes) */
|
|
156
|
+
ttlMs?: number;
|
|
157
|
+
/** Cleanup interval in milliseconds (default: 5 minutes) */
|
|
158
|
+
cleanupIntervalMs?: number;
|
|
159
|
+
/** Logger for the session manager itself */
|
|
160
|
+
logger: Logger;
|
|
161
|
+
/** Default max turns per session (default: 50) */
|
|
162
|
+
defaultMaxTurns?: number;
|
|
163
|
+
/** Default max context tokens (default: 200_000) */
|
|
164
|
+
defaultMaxContextTokens?: number;
|
|
165
|
+
}
|
|
166
|
+
/** Options for creating a new session. */
|
|
167
|
+
export interface CreateSessionOptions {
|
|
168
|
+
tenantId: string;
|
|
169
|
+
userId: string;
|
|
170
|
+
provider: LLMProvider;
|
|
171
|
+
toolRegistry: ToolRegistry;
|
|
172
|
+
permissionChecker: PermissionChecker;
|
|
173
|
+
systemPrompt: string;
|
|
174
|
+
appId?: string;
|
|
175
|
+
metadata?: SessionMetadata;
|
|
176
|
+
maxTurns?: number;
|
|
177
|
+
maxContextTokens?: number;
|
|
178
|
+
/** Optional: seed messages for resuming */
|
|
179
|
+
messages?: ModelMessage[];
|
|
180
|
+
/** Optional: seed token usage for resuming */
|
|
181
|
+
usage?: TokenUsage;
|
|
182
|
+
/** User roles for permission checks and field guidance */
|
|
183
|
+
userRoles?: string[];
|
|
184
|
+
/** Optional: onUsage callback fired after each turn */
|
|
185
|
+
onUsage?: (usage: TurnUsage) => void;
|
|
186
|
+
/** Optional: tool context factory to cache on the session */
|
|
187
|
+
toolContextFactory?: (callId: string) => ToolContext;
|
|
188
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/session/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Amodal Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
7
|
+
import type { LoadedStore } from '@amodalai/core';
|
|
8
|
+
import type { StoreBackend, StoreDocument, StoreDocumentMeta, StorePutResult, StoreListOptions, StoreListResult } from '@amodalai/types';
|
|
9
|
+
import type { Logger } from '../logger.js';
|
|
10
|
+
type AnyPgDatabase = PgDatabase<PgQueryResultHKT, Record<string, unknown>>;
|
|
11
|
+
export interface DrizzleStoreBackendOptions {
|
|
12
|
+
db: AnyPgDatabase;
|
|
13
|
+
stores: LoadedStore[];
|
|
14
|
+
logger: Logger;
|
|
15
|
+
onClose: () => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare class DrizzleStoreBackend implements StoreBackend {
|
|
18
|
+
private readonly db;
|
|
19
|
+
private readonly storeConfigs;
|
|
20
|
+
private readonly logger;
|
|
21
|
+
private readonly onClose;
|
|
22
|
+
private writeQueue;
|
|
23
|
+
private closed;
|
|
24
|
+
constructor(opts: DrizzleStoreBackendOptions);
|
|
25
|
+
/**
|
|
26
|
+
* StoreBackend.initialize() — no-op on this class. The concrete
|
|
27
|
+
* factory (createPGLiteStoreBackend / createPostgresStoreBackend)
|
|
28
|
+
* creates the db client and runs DDL before constructing this
|
|
29
|
+
* backend. Kept for interface compliance.
|
|
30
|
+
*/
|
|
31
|
+
initialize(_stores: LoadedStore[]): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Serialize write operations through a queue so that PGLite's
|
|
34
|
+
* single-threaded WASM engine never sees concurrent writes. Postgres
|
|
35
|
+
* doesn't need this strictly, but the overhead is negligible and the
|
|
36
|
+
* shared ordering semantics are valuable.
|
|
37
|
+
*/
|
|
38
|
+
private enqueue;
|
|
39
|
+
private ensureOpen;
|
|
40
|
+
get(appId: string, store: string, key: string): Promise<StoreDocument | null>;
|
|
41
|
+
put(appId: string, store: string, key: string, payload: Record<string, unknown>, meta: Partial<StoreDocumentMeta>): Promise<StorePutResult>;
|
|
42
|
+
list(appId: string, store: string, options?: StoreListOptions): Promise<StoreListResult>;
|
|
43
|
+
delete(appId: string, store: string, key: string): Promise<boolean>;
|
|
44
|
+
history(appId: string, store: string, key: string): Promise<StoreDocument[]>;
|
|
45
|
+
purgeExpired(appId: string, store?: string): Promise<number>;
|
|
46
|
+
close(): Promise<void>;
|
|
47
|
+
private rowToDocument;
|
|
48
|
+
}
|
|
49
|
+
export {};
|