@roj-ai/sdk 0.1.35 → 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/bootstrap.d.ts +420 -26
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +55 -24
- package/dist/bootstrap.js.map +1 -1
- package/dist/bun-platform/fs.d.ts.map +1 -1
- package/dist/bun-platform/fs.js +1 -0
- package/dist/bun-platform/fs.js.map +1 -1
- package/dist/bun-platform/index.d.ts +4 -1
- package/dist/bun-platform/index.d.ts.map +1 -1
- package/dist/bun-platform/index.js +7 -1
- package/dist/bun-platform/index.js.map +1 -1
- package/dist/bun-platform/server-lifecycle.d.ts +30 -0
- package/dist/bun-platform/server-lifecycle.d.ts.map +1 -0
- package/dist/bun-platform/server-lifecycle.js +182 -0
- package/dist/bun-platform/server-lifecycle.js.map +1 -0
- package/dist/bun-platform/shell.d.ts +33 -0
- package/dist/bun-platform/shell.d.ts.map +1 -0
- package/dist/bun-platform/shell.js +322 -0
- package/dist/bun-platform/shell.js.map +1 -0
- package/dist/config.d.ts +34 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +97 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agents/agent.d.ts +42 -7
- package/dist/core/agents/agent.d.ts.map +1 -1
- package/dist/core/agents/agent.js +209 -90
- package/dist/core/agents/agent.js.map +1 -1
- package/dist/core/agents/config.d.ts +8 -1
- package/dist/core/agents/config.d.ts.map +1 -1
- package/dist/core/agents/config.js +5 -1
- package/dist/core/agents/config.js.map +1 -1
- package/dist/core/agents/retry.d.ts +1 -1
- package/dist/core/agents/retry.d.ts.map +1 -1
- package/dist/core/agents/retry.js +14 -16
- package/dist/core/agents/retry.js.map +1 -1
- package/dist/core/agents/state.d.ts +27 -1
- package/dist/core/agents/state.d.ts.map +1 -1
- package/dist/core/agents/state.js +1 -1
- package/dist/core/agents/state.js.map +1 -1
- package/dist/core/context/state.d.ts +3 -3
- package/dist/core/context/state.d.ts.map +1 -1
- package/dist/core/context/state.js +6 -2
- package/dist/core/context/state.js.map +1 -1
- package/dist/core/events/base-event-store.d.ts.map +1 -1
- package/dist/core/events/base-event-store.js +22 -14
- package/dist/core/events/base-event-store.js.map +1 -1
- package/dist/core/events/file.d.ts +39 -1
- package/dist/core/events/file.d.ts.map +1 -1
- package/dist/core/events/file.js +159 -20
- package/dist/core/events/file.js.map +1 -1
- package/dist/core/events/types.d.ts +1 -1
- package/dist/core/file-store/containment.d.ts +19 -0
- package/dist/core/file-store/containment.d.ts.map +1 -0
- package/dist/core/file-store/containment.js +62 -0
- package/dist/core/file-store/containment.js.map +1 -0
- package/dist/core/file-store/file-store.d.ts +22 -2
- package/dist/core/file-store/file-store.d.ts.map +1 -1
- package/dist/core/file-store/file-store.js +88 -20
- package/dist/core/file-store/file-store.js.map +1 -1
- package/dist/core/file-store/types.d.ts +13 -1
- package/dist/core/file-store/types.d.ts.map +1 -1
- package/dist/core/image/image-processor.d.ts.map +1 -1
- package/dist/core/image/image-processor.js +3 -1
- package/dist/core/image/image-processor.js.map +1 -1
- package/dist/core/image/types.d.ts +2 -0
- package/dist/core/image/types.d.ts.map +1 -1
- package/dist/core/image/vips-resizer.d.ts.map +1 -1
- package/dist/core/image/vips-resizer.js +81 -33
- package/dist/core/image/vips-resizer.js.map +1 -1
- package/dist/core/llm/anthropic.d.ts +0 -1
- package/dist/core/llm/anthropic.d.ts.map +1 -1
- package/dist/core/llm/anthropic.js +101 -74
- package/dist/core/llm/anthropic.js.map +1 -1
- package/dist/core/llm/logger.d.ts +14 -2
- package/dist/core/llm/logger.d.ts.map +1 -1
- package/dist/core/llm/logger.js +161 -36
- package/dist/core/llm/logger.js.map +1 -1
- package/dist/core/llm/openrouter.d.ts +0 -1
- package/dist/core/llm/openrouter.d.ts.map +1 -1
- package/dist/core/llm/openrouter.js +70 -74
- package/dist/core/llm/openrouter.js.map +1 -1
- package/dist/core/llm/provider-request.d.ts +10 -0
- package/dist/core/llm/provider-request.d.ts.map +1 -0
- package/dist/core/llm/provider-request.js +41 -0
- package/dist/core/llm/provider-request.js.map +1 -0
- package/dist/core/llm/provider.d.ts +45 -3
- package/dist/core/llm/provider.d.ts.map +1 -1
- package/dist/core/llm/provider.js +26 -0
- package/dist/core/llm/provider.js.map +1 -1
- package/dist/core/llm/state.d.ts +4 -2
- package/dist/core/llm/state.d.ts.map +1 -1
- package/dist/core/llm/state.js +15 -4
- package/dist/core/llm/state.js.map +1 -1
- package/dist/core/plugins/plugin-builder.d.ts +57 -3
- package/dist/core/plugins/plugin-builder.d.ts.map +1 -1
- package/dist/core/plugins/plugin-builder.js +68 -14
- package/dist/core/plugins/plugin-builder.js.map +1 -1
- package/dist/core/preset/preset-builder.d.ts +3 -2
- package/dist/core/preset/preset-builder.d.ts.map +1 -1
- package/dist/core/preset/preset-builder.js +7 -16
- package/dist/core/preset/preset-builder.js.map +1 -1
- package/dist/core/sessions/context.d.ts +23 -5
- package/dist/core/sessions/context.d.ts.map +1 -1
- package/dist/core/sessions/runtime-activity.d.ts +33 -0
- package/dist/core/sessions/runtime-activity.d.ts.map +1 -0
- package/dist/core/sessions/runtime-activity.js +55 -0
- package/dist/core/sessions/runtime-activity.js.map +1 -0
- package/dist/core/sessions/schema.d.ts +23 -2
- package/dist/core/sessions/schema.d.ts.map +1 -1
- package/dist/core/sessions/schema.js +24 -3
- package/dist/core/sessions/schema.js.map +1 -1
- package/dist/core/sessions/session-manager.d.ts +83 -6
- package/dist/core/sessions/session-manager.d.ts.map +1 -1
- package/dist/core/sessions/session-manager.js +517 -118
- package/dist/core/sessions/session-manager.js.map +1 -1
- package/dist/core/sessions/session-store.d.ts +18 -0
- package/dist/core/sessions/session-store.d.ts.map +1 -1
- package/dist/core/sessions/session-store.js +33 -0
- package/dist/core/sessions/session-store.js.map +1 -1
- package/dist/core/sessions/session.d.ts +42 -6
- package/dist/core/sessions/session.d.ts.map +1 -1
- package/dist/core/sessions/session.js +176 -44
- package/dist/core/sessions/session.js.map +1 -1
- package/dist/core/sessions/state.d.ts +10 -1
- package/dist/core/sessions/state.d.ts.map +1 -1
- package/dist/core/sessions/state.js +16 -1
- package/dist/core/sessions/state.js.map +1 -1
- package/dist/core/system.d.ts +9 -0
- package/dist/core/system.d.ts.map +1 -1
- package/dist/core/system.js +4 -1
- package/dist/core/system.js.map +1 -1
- package/dist/core/tools/executor.d.ts +1 -1
- package/dist/core/wake-key.d.ts +34 -0
- package/dist/core/wake-key.d.ts.map +1 -0
- package/dist/core/wake-key.js +51 -0
- package/dist/core/wake-key.js.map +1 -0
- package/dist/index.d.ts +24 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/archive/archive-inspection.d.ts +48 -0
- package/dist/lib/archive/archive-inspection.d.ts.map +1 -0
- package/dist/lib/archive/archive-inspection.fixtures.d.ts +7 -0
- package/dist/lib/archive/archive-inspection.fixtures.d.ts.map +1 -0
- package/dist/lib/archive/archive-inspection.fixtures.js +134 -0
- package/dist/lib/archive/archive-inspection.fixtures.js.map +1 -0
- package/dist/lib/archive/archive-inspection.js +253 -0
- package/dist/lib/archive/archive-inspection.js.map +1 -0
- package/dist/lib/archive/index.d.ts +3 -0
- package/dist/lib/archive/index.d.ts.map +1 -0
- package/dist/lib/archive/index.js +2 -0
- package/dist/lib/archive/index.js.map +1 -0
- package/dist/lib/logger/console.d.ts +5 -12
- package/dist/lib/logger/console.d.ts.map +1 -1
- package/dist/lib/logger/console.js +5 -47
- package/dist/lib/logger/console.js.map +1 -1
- package/dist/lib/logger/file.d.ts +8 -11
- package/dist/lib/logger/file.d.ts.map +1 -1
- package/dist/lib/logger/file.js +26 -37
- package/dist/lib/logger/file.js.map +1 -1
- package/dist/lib/logger/index.d.ts +3 -1
- package/dist/lib/logger/index.d.ts.map +1 -1
- package/dist/lib/logger/index.js +3 -1
- package/dist/lib/logger/index.js.map +1 -1
- package/dist/lib/logger/jsonl.d.ts +21 -0
- package/dist/lib/logger/jsonl.d.ts.map +1 -0
- package/dist/lib/logger/jsonl.js +29 -0
- package/dist/lib/logger/jsonl.js.map +1 -0
- package/dist/lib/logger/logger.d.ts +22 -0
- package/dist/lib/logger/logger.d.ts.map +1 -1
- package/dist/lib/logger/logger.js +37 -0
- package/dist/lib/logger/logger.js.map +1 -1
- package/dist/lib/logger/session-log.d.ts +21 -0
- package/dist/lib/logger/session-log.d.ts.map +1 -0
- package/dist/lib/logger/session-log.js +37 -0
- package/dist/lib/logger/session-log.js.map +1 -0
- package/dist/lib/utils/concurrency.d.ts +1 -1
- package/dist/lib/utils/concurrency.d.ts.map +1 -1
- package/dist/lib/utils/concurrency.js +30 -7
- package/dist/lib/utils/concurrency.js.map +1 -1
- package/dist/lib/utils/fs-batch.d.ts +17 -0
- package/dist/lib/utils/fs-batch.d.ts.map +1 -0
- package/dist/lib/utils/fs-batch.js +38 -0
- package/dist/lib/utils/fs-batch.js.map +1 -0
- package/dist/lib/utils/result.d.ts +7 -22
- package/dist/lib/utils/result.d.ts.map +1 -1
- package/dist/lib/utils/result.js +6 -17
- package/dist/lib/utils/result.js.map +1 -1
- package/dist/lib/utils/sleep.d.ts +10 -0
- package/dist/lib/utils/sleep.d.ts.map +1 -0
- package/dist/lib/utils/sleep.js +26 -0
- package/dist/lib/utils/sleep.js.map +1 -0
- package/dist/platform/fs-revision.d.ts +21 -0
- package/dist/platform/fs-revision.d.ts.map +1 -0
- package/dist/platform/fs-revision.js +9 -0
- package/dist/platform/fs-revision.js.map +1 -0
- package/dist/platform/fs.d.ts +104 -1
- package/dist/platform/fs.d.ts.map +1 -1
- package/dist/platform/git.d.ts +59 -0
- package/dist/platform/git.d.ts.map +1 -0
- package/dist/platform/git.js +8 -0
- package/dist/platform/git.js.map +1 -0
- package/dist/platform/index.d.ts +40 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +1 -1
- package/dist/platform/index.js.map +1 -1
- package/dist/platform/llm-call-log.d.ts +80 -0
- package/dist/platform/llm-call-log.d.ts.map +1 -0
- package/dist/platform/llm-call-log.js +12 -0
- package/dist/platform/llm-call-log.js.map +1 -0
- package/dist/platform/scheduler.d.ts +32 -0
- package/dist/platform/scheduler.d.ts.map +1 -0
- package/dist/platform/scheduler.js +46 -0
- package/dist/platform/scheduler.js.map +1 -0
- package/dist/platform/session-log.d.ts +36 -0
- package/dist/platform/session-log.d.ts.map +1 -0
- package/dist/platform/session-log.js +12 -0
- package/dist/platform/session-log.js.map +1 -0
- package/dist/platform/shell.d.ts +83 -0
- package/dist/platform/shell.d.ts.map +1 -0
- package/dist/platform/shell.js +13 -0
- package/dist/platform/shell.js.map +1 -0
- package/dist/plugins/agent-status/plugin.d.ts.map +1 -1
- package/dist/plugins/agent-status/plugin.js +1 -0
- package/dist/plugins/agent-status/plugin.js.map +1 -1
- package/dist/plugins/agents/plugin.d.ts.map +1 -1
- package/dist/plugins/agents/plugin.js +129 -62
- package/dist/plugins/agents/plugin.js.map +1 -1
- package/dist/plugins/filesystem/listing.d.ts +3 -0
- package/dist/plugins/filesystem/listing.d.ts.map +1 -1
- package/dist/plugins/filesystem/listing.js +66 -10
- package/dist/plugins/filesystem/listing.js.map +1 -1
- package/dist/plugins/filesystem/plugin.d.ts.map +1 -1
- package/dist/plugins/filesystem/plugin.js +8 -6
- package/dist/plugins/filesystem/plugin.js.map +1 -1
- package/dist/plugins/git-status/plugin.d.ts +34 -7
- package/dist/plugins/git-status/plugin.d.ts.map +1 -1
- package/dist/plugins/git-status/plugin.js +168 -64
- package/dist/plugins/git-status/plugin.js.map +1 -1
- package/dist/plugins/llm-debug/plugin.d.ts.map +1 -1
- package/dist/plugins/llm-debug/plugin.js +1 -0
- package/dist/plugins/llm-debug/plugin.js.map +1 -1
- package/dist/plugins/logs/plugin.d.ts +1 -4
- package/dist/plugins/logs/plugin.d.ts.map +1 -1
- package/dist/plugins/logs/plugin.js +7 -0
- package/dist/plugins/logs/plugin.js.map +1 -1
- package/dist/plugins/mailbox/helpers.d.ts +2 -2
- package/dist/plugins/mailbox/helpers.js +1 -1
- package/dist/plugins/mailbox/plugin.d.ts.map +1 -1
- package/dist/plugins/mailbox/plugin.js +38 -43
- package/dist/plugins/mailbox/plugin.js.map +1 -1
- package/dist/plugins/mailbox/query.d.ts +7 -2
- package/dist/plugins/mailbox/query.d.ts.map +1 -1
- package/dist/plugins/mailbox/query.js +14 -7
- package/dist/plugins/mailbox/query.js.map +1 -1
- package/dist/plugins/mailbox/state.d.ts +5 -4
- package/dist/plugins/mailbox/state.d.ts.map +1 -1
- package/dist/plugins/mailbox/state.js +6 -5
- package/dist/plugins/mailbox/state.js.map +1 -1
- package/dist/plugins/resources/filename.d.ts +4 -0
- package/dist/plugins/resources/filename.d.ts.map +1 -0
- package/dist/plugins/resources/filename.js +18 -0
- package/dist/plugins/resources/filename.js.map +1 -0
- package/dist/plugins/resources/plugin.d.ts +3 -0
- package/dist/plugins/resources/plugin.d.ts.map +1 -1
- package/dist/plugins/resources/plugin.js +97 -60
- package/dist/plugins/resources/plugin.js.map +1 -1
- package/dist/plugins/resources/state.d.ts +1 -1
- package/dist/plugins/resources/state.js +1 -1
- package/dist/plugins/result-eviction/plugin.d.ts.map +1 -1
- package/dist/plugins/result-eviction/plugin.js +6 -1
- package/dist/plugins/result-eviction/plugin.js.map +1 -1
- package/dist/plugins/services/plugin.d.ts +4 -1
- package/dist/plugins/services/plugin.d.ts.map +1 -1
- package/dist/plugins/services/plugin.js +251 -100
- package/dist/plugins/services/plugin.js.map +1 -1
- package/dist/plugins/services/prompt.d.ts.map +1 -1
- package/dist/plugins/services/prompt.js +1 -4
- package/dist/plugins/services/prompt.js.map +1 -1
- package/dist/plugins/services/schema.d.ts +15 -5
- package/dist/plugins/services/schema.d.ts.map +1 -1
- package/dist/plugins/services/service.d.ts +100 -18
- package/dist/plugins/services/service.d.ts.map +1 -1
- package/dist/plugins/services/service.js +680 -230
- package/dist/plugins/services/service.js.map +1 -1
- package/dist/plugins/session-lifecycle/plugin.d.ts +21 -1
- package/dist/plugins/session-lifecycle/plugin.d.ts.map +1 -1
- package/dist/plugins/session-lifecycle/plugin.js +53 -40
- package/dist/plugins/session-lifecycle/plugin.js.map +1 -1
- package/dist/plugins/session-state/plugin.d.ts +21 -13
- package/dist/plugins/session-state/plugin.d.ts.map +1 -1
- package/dist/plugins/session-state/plugin.js +214 -79
- package/dist/plugins/session-state/plugin.js.map +1 -1
- package/dist/plugins/session-stats/plugin.d.ts.map +1 -1
- package/dist/plugins/session-stats/plugin.js +1 -0
- package/dist/plugins/session-stats/plugin.js.map +1 -1
- package/dist/plugins/shell/executor.d.ts +17 -15
- package/dist/plugins/shell/executor.d.ts.map +1 -1
- package/dist/plugins/shell/executor.js +130 -195
- package/dist/plugins/shell/executor.js.map +1 -1
- package/dist/plugins/shell/index.d.ts +2 -2
- package/dist/plugins/shell/index.d.ts.map +1 -1
- package/dist/plugins/shell/index.js +2 -2
- package/dist/plugins/shell/index.js.map +1 -1
- package/dist/plugins/shell/plugin.d.ts +5 -4
- package/dist/plugins/shell/plugin.d.ts.map +1 -1
- package/dist/plugins/shell/plugin.js +4 -8
- package/dist/plugins/shell/plugin.js.map +1 -1
- package/dist/plugins/skills/discovery.d.ts.map +1 -1
- package/dist/plugins/skills/discovery.js +10 -8
- package/dist/plugins/skills/discovery.js.map +1 -1
- package/dist/plugins/skills/index.d.ts +1 -1
- package/dist/plugins/skills/index.d.ts.map +1 -1
- package/dist/plugins/skills/plugin.d.ts +1 -1
- package/dist/plugins/skills/plugin.d.ts.map +1 -1
- package/dist/plugins/skills/plugin.js +23 -30
- package/dist/plugins/skills/plugin.js.map +1 -1
- package/dist/plugins/skills/prompts.d.ts +3 -3
- package/dist/plugins/skills/prompts.d.ts.map +1 -1
- package/dist/plugins/skills/prompts.js.map +1 -1
- package/dist/plugins/skills/schema.d.ts +4 -2
- package/dist/plugins/skills/schema.d.ts.map +1 -1
- package/dist/plugins/todo/schema.d.ts +1 -1
- package/dist/plugins/uploads/plugin.d.ts +11 -4
- package/dist/plugins/uploads/plugin.d.ts.map +1 -1
- package/dist/plugins/uploads/plugin.js +891 -225
- package/dist/plugins/uploads/plugin.js.map +1 -1
- package/dist/plugins/uploads/preprocessor.d.ts +14 -0
- package/dist/plugins/uploads/preprocessor.d.ts.map +1 -1
- package/dist/plugins/uploads/preprocessor.js +11 -0
- package/dist/plugins/uploads/preprocessor.js.map +1 -1
- package/dist/plugins/uploads/preprocessors/image-classifier.d.ts +1 -1
- package/dist/plugins/uploads/preprocessors/image-classifier.d.ts.map +1 -1
- package/dist/plugins/uploads/preprocessors/image-classifier.js +51 -26
- package/dist/plugins/uploads/preprocessors/image-classifier.js.map +1 -1
- package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts +2 -2
- package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts.map +1 -1
- package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js +41 -16
- package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js.map +1 -1
- package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts +1 -1
- package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts.map +1 -1
- package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js +29 -14
- package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js.map +1 -1
- package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts +1 -1
- package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts.map +1 -1
- package/dist/plugins/uploads/preprocessors/zip-preprocessor.js +62 -34
- package/dist/plugins/uploads/preprocessors/zip-preprocessor.js.map +1 -1
- package/dist/plugins/uploads/schema.d.ts +25 -2
- package/dist/plugins/uploads/schema.d.ts.map +1 -1
- package/dist/plugins/uploads/schema.js +24 -3
- package/dist/plugins/uploads/schema.js.map +1 -1
- package/dist/plugins/uploads/state.d.ts +13 -1
- package/dist/plugins/uploads/state.d.ts.map +1 -1
- package/dist/plugins/uploads/state.js +4 -1
- package/dist/plugins/uploads/state.js.map +1 -1
- package/dist/plugins/user-chat/plugin.d.ts +12 -5
- package/dist/plugins/user-chat/plugin.d.ts.map +1 -1
- package/dist/plugins/user-chat/plugin.js +141 -32
- package/dist/plugins/user-chat/plugin.js.map +1 -1
- package/dist/plugins/workers/context.d.ts +35 -13
- package/dist/plugins/workers/context.d.ts.map +1 -1
- package/dist/plugins/workers/context.js +82 -32
- package/dist/plugins/workers/context.js.map +1 -1
- package/dist/plugins/workers/definition.d.ts +7 -0
- package/dist/plugins/workers/definition.d.ts.map +1 -1
- package/dist/plugins/workers/definition.js.map +1 -1
- package/dist/plugins/workers/index.d.ts +4 -4
- package/dist/plugins/workers/index.d.ts.map +1 -1
- package/dist/plugins/workers/index.js +2 -2
- package/dist/plugins/workers/index.js.map +1 -1
- package/dist/plugins/workers/plugin.d.ts +10 -57
- package/dist/plugins/workers/plugin.d.ts.map +1 -1
- package/dist/plugins/workers/plugin.js +385 -123
- package/dist/plugins/workers/plugin.js.map +1 -1
- package/dist/plugins/workers/state.d.ts +69 -0
- package/dist/plugins/workers/state.d.ts.map +1 -0
- package/dist/plugins/workers/state.js +52 -0
- package/dist/plugins/workers/state.js.map +1 -0
- package/dist/plugins/workers/worker.d.ts +15 -4
- package/dist/plugins/workers/worker.d.ts.map +1 -1
- package/dist/testing/conformance.d.ts +106 -0
- package/dist/testing/conformance.d.ts.map +1 -0
- package/dist/testing/conformance.js +1463 -0
- package/dist/testing/conformance.js.map +1 -0
- package/dist/testing/node-platform.d.ts.map +1 -1
- package/dist/testing/node-platform.js +5 -0
- package/dist/testing/node-platform.js.map +1 -1
- package/dist/testing/test-harness.d.ts +11 -1
- package/dist/testing/test-harness.d.ts.map +1 -1
- package/dist/testing/test-harness.js +17 -37
- package/dist/testing/test-harness.js.map +1 -1
- package/dist/testing/wait-helpers.d.ts.map +1 -1
- package/dist/testing/wait-helpers.js +1 -3
- package/dist/testing/wait-helpers.js.map +1 -1
- package/dist/transport/adapter/client-adapter.d.ts +6 -0
- package/dist/transport/adapter/client-adapter.d.ts.map +1 -1
- package/dist/transport/adapter/client-adapter.js +50 -3
- package/dist/transport/adapter/client-adapter.js.map +1 -1
- package/dist/transport/adapter/heartbeat.d.ts +16 -0
- package/dist/transport/adapter/heartbeat.d.ts.map +1 -0
- package/dist/transport/adapter/heartbeat.js +41 -0
- package/dist/transport/adapter/heartbeat.js.map +1 -0
- package/dist/transport/adapter/server-adapter.d.ts.map +1 -1
- package/dist/transport/adapter/server-adapter.js +6 -0
- package/dist/transport/adapter/server-adapter.js.map +1 -1
- package/dist/transport/http/app.d.ts +3 -30
- package/dist/transport/http/app.d.ts.map +1 -1
- package/dist/transport/http/app.js +3 -7
- package/dist/transport/http/app.js.map +1 -1
- package/dist/transport/http/context.d.ts +40 -0
- package/dist/transport/http/context.d.ts.map +1 -0
- package/dist/transport/http/context.js +17 -0
- package/dist/transport/http/context.js.map +1 -0
- package/dist/transport/http/fetch-guard.d.ts +49 -0
- package/dist/transport/http/fetch-guard.d.ts.map +1 -0
- package/dist/transport/http/fetch-guard.js +312 -0
- package/dist/transport/http/fetch-guard.js.map +1 -0
- package/dist/transport/http/index.d.ts +1 -1
- package/dist/transport/http/index.d.ts.map +1 -1
- package/dist/transport/http/middleware/bearer-auth.d.ts +1 -1
- package/dist/transport/http/middleware/bearer-auth.d.ts.map +1 -1
- package/dist/transport/http/middleware/error-handler.d.ts +2 -2
- package/dist/transport/http/middleware/error-handler.d.ts.map +1 -1
- package/dist/transport/http/path-containment.d.ts +20 -0
- package/dist/transport/http/path-containment.d.ts.map +1 -0
- package/dist/transport/http/path-containment.js +31 -0
- package/dist/transport/http/path-containment.js.map +1 -0
- package/dist/transport/http/responses.d.ts +30 -0
- package/dist/transport/http/responses.d.ts.map +1 -0
- package/dist/transport/http/responses.js +5 -0
- package/dist/transport/http/responses.js.map +1 -0
- package/dist/transport/http/routes/files.d.ts +1 -1
- package/dist/transport/http/routes/files.d.ts.map +1 -1
- package/dist/transport/http/routes/files.js +54 -155
- package/dist/transport/http/routes/files.js.map +1 -1
- package/dist/transport/http/routes/resources.d.ts +1 -1
- package/dist/transport/http/routes/resources.d.ts.map +1 -1
- package/dist/transport/http/routes/resources.js +92 -57
- package/dist/transport/http/routes/resources.js.map +1 -1
- package/dist/transport/http/routes/rpc.d.ts +6 -1
- package/dist/transport/http/routes/rpc.d.ts.map +1 -1
- package/dist/transport/http/routes/rpc.js +51 -21
- package/dist/transport/http/routes/rpc.js.map +1 -1
- package/dist/transport/http/routes/upload.d.ts +1 -1
- package/dist/transport/http/routes/upload.d.ts.map +1 -1
- package/dist/transport/http/routes/upload.js +256 -169
- package/dist/transport/http/routes/upload.js.map +1 -1
- package/dist/user-config.d.ts +34 -7
- package/dist/user-config.d.ts.map +1 -1
- package/dist/user-config.js +71 -0
- package/dist/user-config.js.map +1 -1
- package/package.json +18 -8
- package/src/bootstrap.ts +119 -35
- package/src/bun-platform/fs.ts +1 -0
- package/src/bun-platform/index.ts +18 -1
- package/src/bun-platform/server-lifecycle.ts +218 -0
- package/src/bun-platform/shell.ts +362 -0
- package/src/config.ts +130 -0
- package/src/core/agents/agent.ts +219 -95
- package/src/core/agents/config.ts +8 -0
- package/src/core/agents/retry.ts +16 -17
- package/src/core/agents/state.ts +28 -0
- package/src/core/context/state.ts +4 -0
- package/src/core/events/base-event-store.ts +24 -16
- package/src/core/events/file.ts +198 -22
- package/src/core/file-store/containment.ts +75 -0
- package/src/core/file-store/file-store.ts +106 -25
- package/src/core/file-store/types.ts +14 -1
- package/src/core/image/image-processor.ts +3 -1
- package/src/core/image/types.ts +2 -0
- package/src/core/image/vips-resizer.ts +102 -37
- package/src/core/llm/anthropic.ts +127 -82
- package/src/core/llm/logger.ts +175 -37
- package/src/core/llm/openrouter.ts +82 -81
- package/src/core/llm/provider-request.ts +40 -0
- package/src/core/llm/provider.ts +72 -3
- package/src/core/llm/state.ts +12 -0
- package/src/core/plugins/plugin-builder.ts +106 -14
- package/src/core/preset/preset-builder.ts +12 -22
- package/src/core/sessions/context.ts +18 -0
- package/src/core/sessions/runtime-activity.ts +78 -0
- package/src/core/sessions/schema.ts +29 -3
- package/src/core/sessions/session-manager.ts +560 -140
- package/src/core/sessions/session-store.ts +38 -0
- package/src/core/sessions/session.ts +187 -47
- package/src/core/sessions/state.ts +16 -0
- package/src/core/system.ts +15 -0
- package/src/core/wake-key.ts +65 -0
- package/src/index.ts +31 -12
- package/src/lib/archive/archive-inspection.fixtures.ts +138 -0
- package/src/lib/archive/archive-inspection.ts +359 -0
- package/src/lib/archive/index.ts +17 -0
- package/src/lib/logger/console.ts +7 -57
- package/src/lib/logger/file.ts +28 -50
- package/src/lib/logger/index.ts +3 -1
- package/src/lib/logger/jsonl.ts +36 -0
- package/src/lib/logger/logger.ts +48 -0
- package/src/lib/logger/session-log.ts +42 -0
- package/src/lib/utils/concurrency.ts +37 -8
- package/src/lib/utils/fs-batch.ts +49 -0
- package/src/lib/utils/result.ts +7 -31
- package/src/lib/utils/sleep.ts +23 -0
- package/src/platform/fs-revision.ts +21 -0
- package/src/platform/fs.ts +109 -1
- package/src/platform/git.ts +67 -0
- package/src/platform/index.ts +51 -1
- package/src/platform/llm-call-log.ts +86 -0
- package/src/platform/scheduler.ts +71 -0
- package/src/platform/session-log.ts +39 -0
- package/src/platform/shell.ts +89 -0
- package/src/plugins/agent-status/plugin.ts +1 -0
- package/src/plugins/agents/plugin.ts +134 -81
- package/src/plugins/filesystem/listing.ts +70 -12
- package/src/plugins/filesystem/plugin.ts +8 -6
- package/src/plugins/git-status/plugin.ts +204 -77
- package/src/plugins/llm-debug/plugin.ts +1 -0
- package/src/plugins/logs/plugin.ts +9 -0
- package/src/plugins/mailbox/plugin.ts +46 -64
- package/src/plugins/mailbox/query.ts +15 -7
- package/src/plugins/mailbox/state.ts +1 -0
- package/src/plugins/resources/filename.ts +19 -0
- package/src/plugins/resources/plugin.ts +111 -59
- package/src/plugins/result-eviction/plugin.ts +6 -1
- package/src/plugins/services/plugin.ts +254 -98
- package/src/plugins/services/prompt.ts +1 -6
- package/src/plugins/services/schema.ts +17 -3
- package/src/plugins/services/service.ts +702 -252
- package/src/plugins/session-lifecycle/plugin.ts +56 -41
- package/src/plugins/session-state/plugin.ts +242 -88
- package/src/plugins/session-stats/plugin.ts +1 -0
- package/src/plugins/shell/executor.ts +144 -226
- package/src/plugins/shell/index.ts +1 -4
- package/src/plugins/shell/plugin.ts +7 -9
- package/src/plugins/skills/discovery.ts +10 -8
- package/src/plugins/skills/index.ts +1 -1
- package/src/plugins/skills/plugin.ts +19 -27
- package/src/plugins/skills/prompts.ts +3 -3
- package/src/plugins/skills/schema.ts +5 -2
- package/src/plugins/uploads/plugin.ts +991 -273
- package/src/plugins/uploads/preprocessor.ts +25 -0
- package/src/plugins/uploads/preprocessors/image-classifier.ts +56 -25
- package/src/plugins/uploads/preprocessors/markitdown-preprocessor.ts +41 -15
- package/src/plugins/uploads/preprocessors/pdf-preprocessor.ts +32 -16
- package/src/plugins/uploads/preprocessors/zip-preprocessor.ts +67 -38
- package/src/plugins/uploads/schema.ts +30 -3
- package/src/plugins/uploads/state.ts +12 -0
- package/src/plugins/user-chat/plugin.ts +196 -40
- package/src/plugins/workers/context.ts +102 -39
- package/src/plugins/workers/definition.ts +7 -0
- package/src/plugins/workers/index.ts +4 -4
- package/src/plugins/workers/plugin.ts +461 -151
- package/src/plugins/workers/state.ts +64 -0
- package/src/plugins/workers/worker.ts +15 -4
- package/src/testing/conformance.ts +1751 -0
- package/src/testing/node-platform.ts +5 -0
- package/src/testing/test-harness.ts +21 -38
- package/src/testing/wait-helpers.ts +1 -4
- package/src/transport/adapter/client-adapter.ts +60 -3
- package/src/transport/adapter/heartbeat.ts +50 -0
- package/src/transport/adapter/server-adapter.ts +6 -0
- package/src/transport/http/app.ts +7 -35
- package/src/transport/http/context.ts +46 -0
- package/src/transport/http/fetch-guard.ts +318 -0
- package/src/transport/http/index.ts +1 -1
- package/src/transport/http/middleware/bearer-auth.ts +1 -1
- package/src/transport/http/middleware/error-handler.ts +1 -1
- package/src/transport/http/path-containment.ts +44 -0
- package/src/transport/http/responses.ts +20 -0
- package/src/transport/http/routes/files.ts +69 -159
- package/src/transport/http/routes/resources.ts +124 -93
- package/src/transport/http/routes/rpc.ts +63 -26
- package/src/transport/http/routes/upload.ts +327 -258
- package/src/user-config.ts +93 -7
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -155
- package/dist/config.test.js.map +0 -1
- package/dist/core/agent-loop.integration.test.d.ts +0 -2
- package/dist/core/agent-loop.integration.test.d.ts.map +0 -1
- package/dist/core/agent-loop.integration.test.js +0 -414
- package/dist/core/agent-loop.integration.test.js.map +0 -1
- package/dist/core/agents/agent-config.test.d.ts +0 -2
- package/dist/core/agents/agent-config.test.d.ts.map +0 -1
- package/dist/core/agents/agent-config.test.js +0 -194
- package/dist/core/agents/agent-config.test.js.map +0 -1
- package/dist/core/agents/agent-shutdown.test.d.ts +0 -6
- package/dist/core/agents/agent-shutdown.test.d.ts.map +0 -1
- package/dist/core/agents/agent-shutdown.test.js +0 -180
- package/dist/core/agents/agent-shutdown.test.js.map +0 -1
- package/dist/core/agents/agent.test.d.ts +0 -2
- package/dist/core/agents/agent.test.d.ts.map +0 -1
- package/dist/core/agents/agent.test.js +0 -313
- package/dist/core/agents/agent.test.js.map +0 -1
- package/dist/core/agents/communicator.d.ts +0 -3
- package/dist/core/agents/communicator.d.ts.map +0 -1
- package/dist/core/agents/communicator.js +0 -13
- package/dist/core/agents/communicator.js.map +0 -1
- package/dist/core/agents/handler-events.test.d.ts +0 -5
- package/dist/core/agents/handler-events.test.d.ts.map +0 -1
- package/dist/core/agents/handler-events.test.js +0 -115
- package/dist/core/agents/handler-events.test.js.map +0 -1
- package/dist/core/agents/response-sanitizer.test.d.ts +0 -2
- package/dist/core/agents/response-sanitizer.test.d.ts.map +0 -1
- package/dist/core/agents/response-sanitizer.test.js +0 -101
- package/dist/core/agents/response-sanitizer.test.js.map +0 -1
- package/dist/core/error-recovery.integration.test.d.ts +0 -2
- package/dist/core/error-recovery.integration.test.d.ts.map +0 -1
- package/dist/core/error-recovery.integration.test.js +0 -288
- package/dist/core/error-recovery.integration.test.js.map +0 -1
- package/dist/core/event-sourcing.integration.test.d.ts +0 -2
- package/dist/core/event-sourcing.integration.test.d.ts.map +0 -1
- package/dist/core/event-sourcing.integration.test.js +0 -154
- package/dist/core/event-sourcing.integration.test.js.map +0 -1
- package/dist/core/events/file.test.d.ts +0 -2
- package/dist/core/events/file.test.d.ts.map +0 -1
- package/dist/core/events/file.test.js +0 -284
- package/dist/core/events/file.test.js.map +0 -1
- package/dist/core/events/memory.test.d.ts +0 -2
- package/dist/core/events/memory.test.d.ts.map +0 -1
- package/dist/core/events/memory.test.js +0 -502
- package/dist/core/events/memory.test.js.map +0 -1
- package/dist/core/image/image-processor.test.d.ts +0 -2
- package/dist/core/image/image-processor.test.d.ts.map +0 -1
- package/dist/core/image/image-processor.test.js +0 -171
- package/dist/core/image/image-processor.test.js.map +0 -1
- package/dist/core/image/vips-resizer.test.d.ts +0 -2
- package/dist/core/image/vips-resizer.test.d.ts.map +0 -1
- package/dist/core/image/vips-resizer.test.js +0 -336
- package/dist/core/image/vips-resizer.test.js.map +0 -1
- package/dist/core/llm/anthropic.test.d.ts +0 -2
- package/dist/core/llm/anthropic.test.d.ts.map +0 -1
- package/dist/core/llm/anthropic.test.js +0 -464
- package/dist/core/llm/anthropic.test.js.map +0 -1
- package/dist/core/llm/cache-breakpoints.test.d.ts +0 -2
- package/dist/core/llm/cache-breakpoints.test.d.ts.map +0 -1
- package/dist/core/llm/cache-breakpoints.test.js +0 -69
- package/dist/core/llm/cache-breakpoints.test.js.map +0 -1
- package/dist/core/llm/cache-live.test.d.ts +0 -16
- package/dist/core/llm/cache-live.test.d.ts.map +0 -1
- package/dist/core/llm/cache-live.test.js +0 -137
- package/dist/core/llm/cache-live.test.js.map +0 -1
- package/dist/core/llm/logger.test.d.ts +0 -7
- package/dist/core/llm/logger.test.d.ts.map +0 -1
- package/dist/core/llm/logger.test.js +0 -228
- package/dist/core/llm/logger.test.js.map +0 -1
- package/dist/core/llm/message-sanitization.test.d.ts +0 -2
- package/dist/core/llm/message-sanitization.test.d.ts.map +0 -1
- package/dist/core/llm/message-sanitization.test.js +0 -181
- package/dist/core/llm/message-sanitization.test.js.map +0 -1
- package/dist/core/llm/mock.test.d.ts +0 -2
- package/dist/core/llm/mock.test.d.ts.map +0 -1
- package/dist/core/llm/mock.test.js +0 -318
- package/dist/core/llm/mock.test.js.map +0 -1
- package/dist/core/llm/openrouter-mapping.test.d.ts +0 -2
- package/dist/core/llm/openrouter-mapping.test.d.ts.map +0 -1
- package/dist/core/llm/openrouter-mapping.test.js +0 -172
- package/dist/core/llm/openrouter-mapping.test.js.map +0 -1
- package/dist/core/llm/openrouter.test.d.ts +0 -2
- package/dist/core/llm/openrouter.test.d.ts.map +0 -1
- package/dist/core/llm/openrouter.test.js +0 -377
- package/dist/core/llm/openrouter.test.js.map +0 -1
- package/dist/core/llm/provider-integration.test.d.ts +0 -12
- package/dist/core/llm/provider-integration.test.d.ts.map +0 -1
- package/dist/core/llm/provider-integration.test.js +0 -350
- package/dist/core/llm/provider-integration.test.js.map +0 -1
- package/dist/core/llm/routing-provider.test.d.ts +0 -2
- package/dist/core/llm/routing-provider.test.d.ts.map +0 -1
- package/dist/core/llm/routing-provider.test.js +0 -94
- package/dist/core/llm/routing-provider.test.js.map +0 -1
- package/dist/core/llm/snapshot-middleware.test.d.ts +0 -2
- package/dist/core/llm/snapshot-middleware.test.d.ts.map +0 -1
- package/dist/core/llm/snapshot-middleware.test.js +0 -144
- package/dist/core/llm/snapshot-middleware.test.js.map +0 -1
- package/dist/core/multi-agent.integration.test.d.ts +0 -2
- package/dist/core/multi-agent.integration.test.d.ts.map +0 -1
- package/dist/core/multi-agent.integration.test.js +0 -298
- package/dist/core/multi-agent.integration.test.js.map +0 -1
- package/dist/core/plugin-hooks.integration.test.d.ts +0 -2
- package/dist/core/plugin-hooks.integration.test.d.ts.map +0 -1
- package/dist/core/plugin-hooks.integration.test.js +0 -458
- package/dist/core/plugin-hooks.integration.test.js.map +0 -1
- package/dist/core/session-lifecycle.integration.test.d.ts +0 -2
- package/dist/core/session-lifecycle.integration.test.d.ts.map +0 -1
- package/dist/core/session-lifecycle.integration.test.js +0 -159
- package/dist/core/session-lifecycle.integration.test.js.map +0 -1
- package/dist/core/sessions/fork-utils.test.d.ts +0 -2
- package/dist/core/sessions/fork-utils.test.d.ts.map +0 -1
- package/dist/core/sessions/fork-utils.test.js +0 -129
- package/dist/core/sessions/fork-utils.test.js.map +0 -1
- package/dist/core/sessions/session-overrides.integration.test.d.ts +0 -2
- package/dist/core/sessions/session-overrides.integration.test.d.ts.map +0 -1
- package/dist/core/sessions/session-overrides.integration.test.js +0 -154
- package/dist/core/sessions/session-overrides.integration.test.js.map +0 -1
- package/dist/core/sessions/session.test.d.ts +0 -2
- package/dist/core/sessions/session.test.d.ts.map +0 -1
- package/dist/core/sessions/session.test.js +0 -1100
- package/dist/core/sessions/session.test.js.map +0 -1
- package/dist/core/tools/executor.test.d.ts +0 -2
- package/dist/core/tools/executor.test.d.ts.map +0 -1
- package/dist/core/tools/executor.test.js +0 -144
- package/dist/core/tools/executor.test.js.map +0 -1
- package/dist/lib/logger/console.test.d.ts +0 -2
- package/dist/lib/logger/console.test.d.ts.map +0 -1
- package/dist/lib/logger/console.test.js +0 -258
- package/dist/lib/logger/console.test.js.map +0 -1
- package/dist/lib/never.d.ts +0 -2
- package/dist/lib/never.d.ts.map +0 -1
- package/dist/lib/never.js +0 -4
- package/dist/lib/never.js.map +0 -1
- package/dist/lib/utils/concurrency.test.d.ts +0 -2
- package/dist/lib/utils/concurrency.test.d.ts.map +0 -1
- package/dist/lib/utils/concurrency.test.js +0 -135
- package/dist/lib/utils/concurrency.test.js.map +0 -1
- package/dist/plugins/agent-status/agent-status.test.d.ts +0 -2
- package/dist/plugins/agent-status/agent-status.test.d.ts.map +0 -1
- package/dist/plugins/agent-status/agent-status.test.js +0 -136
- package/dist/plugins/agent-status/agent-status.test.js.map +0 -1
- package/dist/plugins/agents/agents.integration.test.d.ts +0 -2
- package/dist/plugins/agents/agents.integration.test.d.ts.map +0 -1
- package/dist/plugins/agents/agents.integration.test.js +0 -830
- package/dist/plugins/agents/agents.integration.test.js.map +0 -1
- package/dist/plugins/agents/supervision.integration.test.d.ts +0 -2
- package/dist/plugins/agents/supervision.integration.test.d.ts.map +0 -1
- package/dist/plugins/agents/supervision.integration.test.js +0 -215
- package/dist/plugins/agents/supervision.integration.test.js.map +0 -1
- package/dist/plugins/context-compact/compaction-live.test.d.ts +0 -17
- package/dist/plugins/context-compact/compaction-live.test.d.ts.map +0 -1
- package/dist/plugins/context-compact/compaction-live.test.js +0 -177
- package/dist/plugins/context-compact/compaction-live.test.js.map +0 -1
- package/dist/plugins/context-compact/context-compact.integration.test.d.ts +0 -2
- package/dist/plugins/context-compact/context-compact.integration.test.d.ts.map +0 -1
- package/dist/plugins/context-compact/context-compact.integration.test.js +0 -364
- package/dist/plugins/context-compact/context-compact.integration.test.js.map +0 -1
- package/dist/plugins/context-compact/context-compactor.test.d.ts +0 -2
- package/dist/plugins/context-compact/context-compactor.test.d.ts.map +0 -1
- package/dist/plugins/context-compact/context-compactor.test.js +0 -858
- package/dist/plugins/context-compact/context-compactor.test.js.map +0 -1
- package/dist/plugins/context-compact/history-offloader.test.d.ts +0 -2
- package/dist/plugins/context-compact/history-offloader.test.d.ts.map +0 -1
- package/dist/plugins/context-compact/history-offloader.test.js +0 -77
- package/dist/plugins/context-compact/history-offloader.test.js.map +0 -1
- package/dist/plugins/filesystem/filesystem.integration.test.d.ts +0 -2
- package/dist/plugins/filesystem/filesystem.integration.test.d.ts.map +0 -1
- package/dist/plugins/filesystem/filesystem.integration.test.js +0 -447
- package/dist/plugins/filesystem/filesystem.integration.test.js.map +0 -1
- package/dist/plugins/filesystem/schema.d.ts +0 -7
- package/dist/plugins/filesystem/schema.d.ts.map +0 -1
- package/dist/plugins/filesystem/schema.js +0 -2
- package/dist/plugins/filesystem/schema.js.map +0 -1
- package/dist/plugins/limits-guard/limit-guard.test.d.ts +0 -2
- package/dist/plugins/limits-guard/limit-guard.test.d.ts.map +0 -1
- package/dist/plugins/limits-guard/limit-guard.test.js +0 -194
- package/dist/plugins/limits-guard/limit-guard.test.js.map +0 -1
- package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts +0 -2
- package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts.map +0 -1
- package/dist/plugins/limits-guard/limits-guard.integration.test.js +0 -887
- package/dist/plugins/limits-guard/limits-guard.integration.test.js.map +0 -1
- package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts +0 -2
- package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts.map +0 -1
- package/dist/plugins/llm-debug/llm-debug.integration.test.js +0 -157
- package/dist/plugins/llm-debug/llm-debug.integration.test.js.map +0 -1
- package/dist/plugins/mailbox/mailbox.integration.test.d.ts +0 -2
- package/dist/plugins/mailbox/mailbox.integration.test.d.ts.map +0 -1
- package/dist/plugins/mailbox/mailbox.integration.test.js +0 -678
- package/dist/plugins/mailbox/mailbox.integration.test.js.map +0 -1
- package/dist/plugins/resources/resources.integration.test.d.ts +0 -2
- package/dist/plugins/resources/resources.integration.test.d.ts.map +0 -1
- package/dist/plugins/resources/resources.integration.test.js +0 -62
- package/dist/plugins/resources/resources.integration.test.js.map +0 -1
- package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts +0 -2
- package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts.map +0 -1
- package/dist/plugins/result-eviction/result-eviction.integration.test.js +0 -294
- package/dist/plugins/result-eviction/result-eviction.integration.test.js.map +0 -1
- package/dist/plugins/services/pid-registry.test.d.ts +0 -2
- package/dist/plugins/services/pid-registry.test.d.ts.map +0 -1
- package/dist/plugins/services/pid-registry.test.js +0 -161
- package/dist/plugins/services/pid-registry.test.js.map +0 -1
- package/dist/plugins/services/services.integration.test.d.ts +0 -2
- package/dist/plugins/services/services.integration.test.d.ts.map +0 -1
- package/dist/plugins/services/services.integration.test.js +0 -1057
- package/dist/plugins/services/services.integration.test.js.map +0 -1
- package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts +0 -2
- package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts.map +0 -1
- package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js +0 -498
- package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js.map +0 -1
- package/dist/plugins/session-stats/plugin.test.d.ts +0 -2
- package/dist/plugins/session-stats/plugin.test.d.ts.map +0 -1
- package/dist/plugins/session-stats/plugin.test.js +0 -145
- package/dist/plugins/session-stats/plugin.test.js.map +0 -1
- package/dist/plugins/shell/shell.integration.test.d.ts +0 -2
- package/dist/plugins/shell/shell.integration.test.d.ts.map +0 -1
- package/dist/plugins/shell/shell.integration.test.js +0 -234
- package/dist/plugins/shell/shell.integration.test.js.map +0 -1
- package/dist/plugins/shell/shell.test.d.ts +0 -2
- package/dist/plugins/shell/shell.test.d.ts.map +0 -1
- package/dist/plugins/shell/shell.test.js +0 -236
- package/dist/plugins/shell/shell.test.js.map +0 -1
- package/dist/plugins/skills/discovery.test.d.ts +0 -2
- package/dist/plugins/skills/discovery.test.d.ts.map +0 -1
- package/dist/plugins/skills/discovery.test.js +0 -312
- package/dist/plugins/skills/discovery.test.js.map +0 -1
- package/dist/plugins/skills/skills.integration.test.d.ts +0 -2
- package/dist/plugins/skills/skills.integration.test.d.ts.map +0 -1
- package/dist/plugins/skills/skills.integration.test.js +0 -475
- package/dist/plugins/skills/skills.integration.test.js.map +0 -1
- package/dist/plugins/todo/todo.integration.test.d.ts +0 -2
- package/dist/plugins/todo/todo.integration.test.d.ts.map +0 -1
- package/dist/plugins/todo/todo.integration.test.js +0 -605
- package/dist/plugins/todo/todo.integration.test.js.map +0 -1
- package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts +0 -2
- package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts.map +0 -1
- package/dist/plugins/uploads/preprocessors/image-classifier.test.js +0 -113
- package/dist/plugins/uploads/preprocessors/image-classifier.test.js.map +0 -1
- package/dist/plugins/uploads/uploads.integration.test.d.ts +0 -2
- package/dist/plugins/uploads/uploads.integration.test.d.ts.map +0 -1
- package/dist/plugins/uploads/uploads.integration.test.js +0 -639
- package/dist/plugins/uploads/uploads.integration.test.js.map +0 -1
- package/dist/plugins/user-chat/user-chat.integration.test.d.ts +0 -2
- package/dist/plugins/user-chat/user-chat.integration.test.d.ts.map +0 -1
- package/dist/plugins/user-chat/user-chat.integration.test.js +0 -754
- package/dist/plugins/user-chat/user-chat.integration.test.js.map +0 -1
- package/dist/plugins/workers/workers.integration.test.d.ts +0 -2
- package/dist/plugins/workers/workers.integration.test.d.ts.map +0 -1
- package/dist/plugins/workers/workers.integration.test.js +0 -629
- package/dist/plugins/workers/workers.integration.test.js.map +0 -1
- package/dist/prompts/macros.test.d.ts +0 -2
- package/dist/prompts/macros.test.d.ts.map +0 -1
- package/dist/prompts/macros.test.js +0 -80
- package/dist/prompts/macros.test.js.map +0 -1
- package/dist/testing/test-harness.test.d.ts +0 -2
- package/dist/testing/test-harness.test.d.ts.map +0 -1
- package/dist/testing/test-harness.test.js +0 -92
- package/dist/testing/test-harness.test.js.map +0 -1
- package/dist/transport/http/routes/rpc.integration.test.d.ts +0 -2
- package/dist/transport/http/routes/rpc.integration.test.d.ts.map +0 -1
- package/dist/transport/http/routes/rpc.integration.test.js +0 -189
- package/dist/transport/http/routes/rpc.integration.test.js.map +0 -1
- package/dist/transport/http/routes/rpc.test.d.ts +0 -2
- package/dist/transport/http/routes/rpc.test.d.ts.map +0 -1
- package/dist/transport/http/routes/rpc.test.js +0 -316
- package/dist/transport/http/routes/rpc.test.js.map +0 -1
- package/src/config.test.ts +0 -174
- package/src/core/agent-loop.integration.test.ts +0 -503
- package/src/core/agents/agent-config.test.ts +0 -240
- package/src/core/agents/agent-shutdown.test.ts +0 -236
- package/src/core/agents/agent.test.ts +0 -387
- package/src/core/agents/communicator.ts +0 -16
- package/src/core/agents/handler-events.test.ts +0 -167
- package/src/core/agents/response-sanitizer.test.ts +0 -137
- package/src/core/error-recovery.integration.test.ts +0 -343
- package/src/core/event-sourcing.integration.test.ts +0 -191
- package/src/core/events/file.test.ts +0 -436
- package/src/core/events/memory.test.ts +0 -741
- package/src/core/image/image-processor.test.ts +0 -218
- package/src/core/image/vips-resizer.test.ts +0 -388
- package/src/core/llm/anthropic.test.ts +0 -546
- package/src/core/llm/cache-breakpoints.test.ts +0 -85
- package/src/core/llm/cache-live.test.ts +0 -155
- package/src/core/llm/logger.test.ts +0 -270
- package/src/core/llm/message-sanitization.test.ts +0 -217
- package/src/core/llm/mock.test.ts +0 -402
- package/src/core/llm/openrouter-mapping.test.ts +0 -210
- package/src/core/llm/openrouter.test.ts +0 -499
- package/src/core/llm/provider-integration.test.ts +0 -408
- package/src/core/llm/routing-provider.test.ts +0 -113
- package/src/core/llm/snapshot-middleware.test.ts +0 -168
- package/src/core/multi-agent.integration.test.ts +0 -340
- package/src/core/plugin-hooks.integration.test.ts +0 -568
- package/src/core/session-lifecycle.integration.test.ts +0 -202
- package/src/core/sessions/fork-utils.test.ts +0 -158
- package/src/core/sessions/session-overrides.integration.test.ts +0 -210
- package/src/core/sessions/session.test.ts +0 -1736
- package/src/core/tools/executor.test.ts +0 -161
- package/src/lib/logger/console.test.ts +0 -348
- package/src/lib/never.ts +0 -3
- package/src/lib/utils/concurrency.test.ts +0 -169
- package/src/plugins/agent-status/agent-status.test.ts +0 -164
- package/src/plugins/agents/agents.integration.test.ts +0 -976
- package/src/plugins/agents/supervision.integration.test.ts +0 -249
- package/src/plugins/context-compact/compaction-live.test.ts +0 -221
- package/src/plugins/context-compact/context-compact.integration.test.ts +0 -418
- package/src/plugins/context-compact/context-compactor.test.ts +0 -1036
- package/src/plugins/context-compact/history-offloader.test.ts +0 -100
- package/src/plugins/filesystem/filesystem.integration.test.ts +0 -529
- package/src/plugins/filesystem/schema.ts +0 -6
- package/src/plugins/limits-guard/limit-guard.test.ts +0 -253
- package/src/plugins/limits-guard/limits-guard.integration.test.ts +0 -1012
- package/src/plugins/llm-debug/llm-debug.integration.test.ts +0 -192
- package/src/plugins/mailbox/mailbox.integration.test.ts +0 -794
- package/src/plugins/resources/resources.integration.test.ts +0 -68
- package/src/plugins/result-eviction/result-eviction.integration.test.ts +0 -332
- package/src/plugins/services/pid-registry.test.ts +0 -180
- package/src/plugins/services/services.integration.test.ts +0 -1223
- package/src/plugins/session-lifecycle/session-lifecycle.integration.test.ts +0 -639
- package/src/plugins/session-stats/plugin.test.ts +0 -160
- package/src/plugins/shell/shell.integration.test.ts +0 -273
- package/src/plugins/shell/shell.test.ts +0 -314
- package/src/plugins/skills/discovery.test.ts +0 -395
- package/src/plugins/skills/skills.integration.test.ts +0 -580
- package/src/plugins/todo/todo.integration.test.ts +0 -687
- package/src/plugins/uploads/preprocessors/image-classifier.test.ts +0 -142
- package/src/plugins/uploads/uploads.integration.test.ts +0 -831
- package/src/plugins/user-chat/user-chat.integration.test.ts +0 -893
- package/src/plugins/workers/workers.integration.test.ts +0 -778
- package/src/prompts/macros.test.ts +0 -107
- package/src/testing/test-harness.test.ts +0 -114
- package/src/transport/http/routes/rpc.integration.test.ts +0 -243
- package/src/transport/http/routes/rpc.test.ts +0 -372
|
@@ -8,15 +8,19 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { join } from 'node:path';
|
|
10
10
|
import { COMMUNICATOR_ROLE, ORCHESTRATOR_ROLE } from '../../core/agents/agent-roles.js';
|
|
11
|
+
import { parseAgentWakeKey, parsePluginWakeKey } from '../../core/wake-key.js';
|
|
11
12
|
import { generateAgentId } from '../../core/agents/schema.js';
|
|
12
13
|
import { agentEvents } from '../../core/agents/state.js';
|
|
13
14
|
import { PresetErrors, SessionErrors, ValidationErrors } from '../../core/errors.js';
|
|
14
15
|
import { withSessionId } from '../../core/events/test-helpers.js';
|
|
16
|
+
import { DEFAULT_PLUGIN_ORDER } from '../../core/plugins/plugin-builder.js';
|
|
17
|
+
import { AGENT_CALLER } from '../../core/plugins/plugin-builder.js';
|
|
15
18
|
import { knownDefinitionNames, unknownOverrideTargets } from '../../core/preset/overrides.js';
|
|
16
|
-
import { generateSessionId } from '../../core/sessions/schema.js';
|
|
19
|
+
import { generateSessionId, isValidSessionId, SessionId } from '../../core/sessions/schema.js';
|
|
17
20
|
import { checkRecoveryNeeded, isSessionCreatedEvent, reconstructSessionState, sessionEvents } from '../../core/sessions/state.js';
|
|
18
|
-
import {
|
|
21
|
+
import { createSessionLogger } from '../../lib/logger/session-log.js';
|
|
19
22
|
import { TeeLogger } from '../../lib/logger/tee.js';
|
|
23
|
+
import { isLiveScheduler } from '../../platform/index.js';
|
|
20
24
|
import { Err, Ok } from '../../lib/utils/result.js';
|
|
21
25
|
import { getAgentUnconsumedMailbox, selectMailboxState } from '../../plugins/mailbox/query.js';
|
|
22
26
|
import { selectSessionStats } from '../../plugins/session-stats/index.js';
|
|
@@ -24,6 +28,7 @@ import { createApplyEvent } from './apply-event.js';
|
|
|
24
28
|
import { rewriteEventsForFork } from './fork-utils.js';
|
|
25
29
|
import { SessionStore } from './session-store.js';
|
|
26
30
|
import { Session } from './session.js';
|
|
31
|
+
import { SessionRuntimeActivityController } from './runtime-activity.js';
|
|
27
32
|
// ============================================================================
|
|
28
33
|
// Errors
|
|
29
34
|
// ============================================================================
|
|
@@ -39,13 +44,18 @@ class SessionLoadError extends Error {
|
|
|
39
44
|
this.name = 'SessionLoadError';
|
|
40
45
|
}
|
|
41
46
|
}
|
|
47
|
+
// Both parking causes map to `evicted`: the session survives and the next access rebuilds its runtime.
|
|
48
|
+
const RUNTIME_DISPOSAL_CLOSE_REASON = {
|
|
49
|
+
idle: 'evicted',
|
|
50
|
+
disposed: 'evicted',
|
|
51
|
+
closed: 'closed',
|
|
52
|
+
shutdown: 'shutdown',
|
|
53
|
+
};
|
|
42
54
|
/**
|
|
43
55
|
* SessionManager manages session lifecycle and caching.
|
|
44
56
|
*/
|
|
45
57
|
export class SessionManager {
|
|
46
58
|
sessions = new Map();
|
|
47
|
-
/** Unsubscribe functions for session event listeners, keyed by sessionId */
|
|
48
|
-
sessionListenerCleanup = new Map();
|
|
49
59
|
/** Manager-level methods collected from plugin definitions across all presets */
|
|
50
60
|
managerMethods;
|
|
51
61
|
eventStore;
|
|
@@ -58,12 +68,24 @@ export class SessionManager {
|
|
|
58
68
|
dataFileStore;
|
|
59
69
|
onUserOutput;
|
|
60
70
|
preprocessorRegistry;
|
|
71
|
+
uploadArchiveLimits;
|
|
72
|
+
resourceArchiveLimits;
|
|
61
73
|
llmLogger;
|
|
62
74
|
portPool;
|
|
63
75
|
pidRegistry;
|
|
64
76
|
platform;
|
|
65
77
|
systemPlugins;
|
|
78
|
+
sessionIdleTimeoutMs;
|
|
79
|
+
evictionSweepTimer;
|
|
80
|
+
cacheHits = 0;
|
|
81
|
+
cacheMisses = 0;
|
|
82
|
+
cacheEvictions = 0;
|
|
83
|
+
/** Set by shutdown(). Also fences wakes: one armed before it must not reload a session after it. */
|
|
84
|
+
shuttingDown = false;
|
|
66
85
|
constructor(options) {
|
|
86
|
+
if (options.sessionIdleTimeoutMs !== undefined && (!Number.isSafeInteger(options.sessionIdleTimeoutMs) || options.sessionIdleTimeoutMs < 0)) {
|
|
87
|
+
throw new Error(`Invalid sessionIdleTimeoutMs: ${options.sessionIdleTimeoutMs}`);
|
|
88
|
+
}
|
|
67
89
|
this.eventStore = options.eventStore;
|
|
68
90
|
this.llmProvider = options.llmProvider;
|
|
69
91
|
this.llmProviders = options.llmProviders ?? new Map();
|
|
@@ -74,21 +96,111 @@ export class SessionManager {
|
|
|
74
96
|
this.dataFileStore = options.dataFileStore;
|
|
75
97
|
this.onUserOutput = options.onUserOutput;
|
|
76
98
|
this.preprocessorRegistry = options.preprocessorRegistry;
|
|
99
|
+
this.uploadArchiveLimits = options.uploadArchiveLimits;
|
|
100
|
+
this.resourceArchiveLimits = options.resourceArchiveLimits;
|
|
77
101
|
this.llmLogger = options.llmLogger;
|
|
78
102
|
this.portPool = options.portPool;
|
|
79
103
|
this.pidRegistry = options.pidRegistry;
|
|
80
104
|
this.platform = options.platform;
|
|
81
105
|
this.systemPlugins = options.systemPlugins ?? [];
|
|
106
|
+
this.sessionIdleTimeoutMs = options.sessionIdleTimeoutMs ?? 0;
|
|
82
107
|
this.managerMethods = this.collectManagerMethods();
|
|
108
|
+
if (this.sessionIdleTimeoutMs > 0) {
|
|
109
|
+
const sweepIntervalMs = Math.min(this.sessionIdleTimeoutMs, 60_000);
|
|
110
|
+
this.evictionSweepTimer = setInterval(() => {
|
|
111
|
+
void this.evictIdleSessions();
|
|
112
|
+
}, sweepIntervalMs);
|
|
113
|
+
this.evictionSweepTimer.unref();
|
|
114
|
+
}
|
|
115
|
+
// A live scheduler has nowhere else to deliver. Hosts that wake out-of-band
|
|
116
|
+
// (a Durable Object alarm) call dispatchWake() from their own handler.
|
|
117
|
+
const scheduler = this.platform.scheduler;
|
|
118
|
+
if (isLiveScheduler(scheduler)) {
|
|
119
|
+
scheduler.onWake(async (key) => {
|
|
120
|
+
try {
|
|
121
|
+
await this.dispatchWake(key);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
this.logger.error('Scheduler wake dispatch failed', error instanceof Error ? error : new Error(String(error)), { key });
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
83
128
|
}
|
|
84
129
|
/** Expose platform adapters (used by Session for building contexts). */
|
|
85
130
|
getPlatform() {
|
|
86
131
|
return this.platform;
|
|
87
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Deliver a scheduler wake that has come due.
|
|
135
|
+
*
|
|
136
|
+
* The host's entry point back into the SDK — on Cloudflare, called from
|
|
137
|
+
* `alarm()` in an isolate that never armed the wake. SessionManager owns it
|
|
138
|
+
* because it is the only thing that can turn a session id back into a live
|
|
139
|
+
* session, so the key alone is enough input.
|
|
140
|
+
*
|
|
141
|
+
* Two vocabularies route here: `agent:` wakes re-enter the agent loop,
|
|
142
|
+
* `plugin:` wakes call a plugin method. Anything else is a quiet no-op, and so
|
|
143
|
+
* is a key naming a session, agent or plugin that is gone — wakes outlive what
|
|
144
|
+
* they point at. Only genuinely unexpected failures (event store IO) throw, so
|
|
145
|
+
* a host that retries alarms retries those and only those.
|
|
146
|
+
*/
|
|
147
|
+
async dispatchWake(key) {
|
|
148
|
+
const agentWake = parseAgentWakeKey(key);
|
|
149
|
+
if (agentWake) {
|
|
150
|
+
await this.withWakeTarget(key, agentWake.sessionId, async (session) => {
|
|
151
|
+
await session.getAgent(agentWake.agentId)?.deliverWake(agentWake.kind);
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const pluginWake = parsePluginWakeKey(key);
|
|
156
|
+
if (pluginWake) {
|
|
157
|
+
await this.withWakeTarget(key, pluginWake.sessionId, async (session) => {
|
|
158
|
+
const result = await session.callPluginMethod(`${pluginWake.pluginName}.${pluginWake.method}`, pluginWake.agentId === undefined ? {} : { agentId: pluginWake.agentId }, pluginWake.agentId, AGENT_CALLER);
|
|
159
|
+
// A preset that no longer registers the plugin lands here, same as a
|
|
160
|
+
// missing agent does: the wake points at something that is gone.
|
|
161
|
+
if (!result.ok)
|
|
162
|
+
this.logger.debug('Scheduler wake method rejected', { key, error: result.error.type });
|
|
163
|
+
});
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
this.logger.debug('Ignoring unrecognized scheduler wake key', { key });
|
|
167
|
+
}
|
|
168
|
+
/** Run `deliver` against the session a due wake names, under a runtime lease. */
|
|
169
|
+
async withWakeTarget(key, sessionId, deliver) {
|
|
170
|
+
// Nothing armed before shutdown may load a session back in afterwards.
|
|
171
|
+
if (this.shuttingDown)
|
|
172
|
+
return;
|
|
173
|
+
// Nor may a wake that lands mid-teardown rebuild what is being torn down —
|
|
174
|
+
// getSession() would wait out the unload and reload. onSessionReady re-arms.
|
|
175
|
+
const resident = this.sessions.get(sessionId);
|
|
176
|
+
if (resident && (resident.state === 'evicting' || resident.activity.getSnapshot().state !== 'ready'))
|
|
177
|
+
return;
|
|
178
|
+
const sessionResult = await this.getSession(sessionId);
|
|
179
|
+
if (!sessionResult.ok) {
|
|
180
|
+
this.logger.debug('Scheduler wake for a session that no longer loads', { key, error: sessionResult.error.type });
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const session = sessionResult.value;
|
|
184
|
+
// A closed session's log is sealed; re-entering it would only fail to write.
|
|
185
|
+
if (session.state.status === 'closed')
|
|
186
|
+
return;
|
|
187
|
+
// Lease the delivery, not the delay before it — an idle session stays evictable while it waits.
|
|
188
|
+
const release = session.tryAcquireRuntimeLease(`wake:${key}`);
|
|
189
|
+
if (!release)
|
|
190
|
+
return;
|
|
191
|
+
try {
|
|
192
|
+
await deliver(session);
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
release();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
88
198
|
/**
|
|
89
199
|
* Create a new session with the given preset.
|
|
90
200
|
*/
|
|
91
201
|
async createSession(presetId, options) {
|
|
202
|
+
if (this.shuttingDown)
|
|
203
|
+
return Err(ValidationErrors.invalid('Session manager is shutting down'));
|
|
92
204
|
const preset = this.presets.get(presetId);
|
|
93
205
|
if (!preset) {
|
|
94
206
|
return Err(PresetErrors.notFound(presetId));
|
|
@@ -99,7 +211,12 @@ export class SessionManager {
|
|
|
99
211
|
return Err(ValidationErrors.invalid(`Unknown agent definitions in overrides: ${unknown.join(', ')}. Preset '${presetId}' defines: ${knownDefinitionNames(preset).join(', ')}`));
|
|
100
212
|
}
|
|
101
213
|
}
|
|
102
|
-
|
|
214
|
+
// Validate before anything derives a path from it — the id reaches join() for the
|
|
215
|
+
// session dir, the event log and the file logger, and path.join collapses `..`.
|
|
216
|
+
if (options?.sessionId !== undefined && !isValidSessionId(options.sessionId)) {
|
|
217
|
+
return Err(ValidationErrors.invalid(`Invalid session id: ${JSON.stringify(options.sessionId)}`));
|
|
218
|
+
}
|
|
219
|
+
const sessionId = options?.sessionId ? SessionId(options.sessionId) : generateSessionId();
|
|
103
220
|
// First orchestrator gets seq 1
|
|
104
221
|
const orchestratorId = generateAgentId(ORCHESTRATOR_ROLE, 1);
|
|
105
222
|
// Resolve workspaceDir: API input overrides preset default
|
|
@@ -145,21 +262,45 @@ export class SessionManager {
|
|
|
145
262
|
orchestratorId,
|
|
146
263
|
})));
|
|
147
264
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
265
|
+
if (this.sessions.has(sessionId))
|
|
266
|
+
return Err(SessionErrors.alreadyExists(String(sessionId)));
|
|
267
|
+
const activity = new SessionRuntimeActivityController();
|
|
268
|
+
let entry;
|
|
269
|
+
const creationPromise = Promise.resolve().then(async () => {
|
|
270
|
+
if (await this.eventStore.exists(sessionId))
|
|
271
|
+
throw new SessionLoadError(SessionErrors.alreadyExists(String(sessionId)));
|
|
272
|
+
await this.eventStore.appendBatch(sessionId, events);
|
|
273
|
+
const plugins = this.buildPlugins(preset);
|
|
274
|
+
const composedReducer = createApplyEvent(plugins);
|
|
275
|
+
const state = reconstructSessionState(events, composedReducer);
|
|
276
|
+
if (!state)
|
|
277
|
+
throw new SessionLoadError(ValidationErrors.invalid('Failed to reconstruct session'));
|
|
278
|
+
const store = new SessionStore(sessionId, this.eventStore, state, composedReducer);
|
|
279
|
+
return this.createSessionInstance(store, preset, plugins, entry);
|
|
280
|
+
});
|
|
281
|
+
entry = {
|
|
282
|
+
state: 'loading',
|
|
283
|
+
promise: creationPromise,
|
|
284
|
+
activity,
|
|
285
|
+
lastAccessAt: performance.now(),
|
|
286
|
+
};
|
|
287
|
+
this.sessions.set(sessionId, entry);
|
|
288
|
+
let session;
|
|
289
|
+
try {
|
|
290
|
+
session = await creationPromise;
|
|
291
|
+
if (this.sessions.get(sessionId) === entry && entry.state === 'loading') {
|
|
292
|
+
entry.state = 'ready';
|
|
293
|
+
entry.lastAccessAt = performance.now();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
if (this.sessions.get(sessionId) === entry)
|
|
298
|
+
this.sessions.delete(sessionId);
|
|
299
|
+
entry.listenerCleanup?.();
|
|
300
|
+
if (error instanceof SessionLoadError)
|
|
301
|
+
return Err(error.domainError);
|
|
302
|
+
throw error;
|
|
303
|
+
}
|
|
163
304
|
this.logger.info('Session created', {
|
|
164
305
|
sessionId,
|
|
165
306
|
presetId,
|
|
@@ -172,8 +313,12 @@ export class SessionManager {
|
|
|
172
313
|
* The forked session gets a copy of all events up to the fork point.
|
|
173
314
|
*/
|
|
174
315
|
async forkSession(sourceSessionId, eventIndex) {
|
|
316
|
+
if (this.shuttingDown)
|
|
317
|
+
return Err(ValidationErrors.invalid('Session manager is shutting down'));
|
|
175
318
|
// Load source events
|
|
176
319
|
const sourceEvents = await this.eventStore.load(sourceSessionId);
|
|
320
|
+
if (this.shuttingDown)
|
|
321
|
+
return Err(ValidationErrors.invalid('Session manager is shutting down'));
|
|
177
322
|
if (sourceEvents.length === 0) {
|
|
178
323
|
return Err(SessionErrors.notFound(String(sourceSessionId)));
|
|
179
324
|
}
|
|
@@ -210,32 +355,48 @@ export class SessionManager {
|
|
|
210
355
|
return event;
|
|
211
356
|
});
|
|
212
357
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
358
|
+
const activity = new SessionRuntimeActivityController();
|
|
359
|
+
let entry;
|
|
360
|
+
const forkPromise = Promise.resolve().then(async () => {
|
|
361
|
+
await this.eventStore.appendBatch(newSessionId, forkedEvents);
|
|
362
|
+
const plugins = this.buildPlugins(preset);
|
|
363
|
+
const composedReducer = createApplyEvent(plugins);
|
|
364
|
+
const state = reconstructSessionState(forkedEvents, composedReducer);
|
|
365
|
+
if (!state)
|
|
366
|
+
throw new SessionLoadError(ValidationErrors.invalid('Failed to reconstruct forked session'));
|
|
367
|
+
const store = new SessionStore(newSessionId, this.eventStore, state, composedReducer);
|
|
368
|
+
const recoveryData = checkRecoveryNeeded(state);
|
|
369
|
+
if (recoveryData) {
|
|
370
|
+
await store.emit(withSessionId(newSessionId, sessionEvents.create('session_restarted', {
|
|
371
|
+
resetAgentIds: recoveryData.resetAgentIds,
|
|
372
|
+
clearedToolAgentIds: recoveryData.clearedToolAgentIds,
|
|
373
|
+
})));
|
|
374
|
+
}
|
|
375
|
+
return this.createSessionInstance(store, preset, plugins, entry);
|
|
376
|
+
});
|
|
377
|
+
entry = {
|
|
378
|
+
state: 'loading',
|
|
379
|
+
promise: forkPromise,
|
|
380
|
+
activity,
|
|
381
|
+
lastAccessAt: performance.now(),
|
|
382
|
+
};
|
|
383
|
+
this.sessions.set(newSessionId, entry);
|
|
384
|
+
let session;
|
|
385
|
+
try {
|
|
386
|
+
session = await forkPromise;
|
|
387
|
+
if (this.sessions.get(newSessionId) === entry && entry.state === 'loading')
|
|
388
|
+
entry.state = 'ready';
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
if (this.sessions.get(newSessionId) === entry)
|
|
392
|
+
this.sessions.delete(newSessionId);
|
|
393
|
+
entry.listenerCleanup?.();
|
|
394
|
+
if (error instanceof SessionLoadError)
|
|
395
|
+
return Err(error.domainError);
|
|
396
|
+
throw error;
|
|
232
397
|
}
|
|
233
|
-
// Create session instance (auto-start services run via onSessionReady)
|
|
234
|
-
const session = await this.createSessionInstance(store, preset, plugins);
|
|
235
398
|
// Check for pending agents
|
|
236
399
|
session.checkPendingAgents();
|
|
237
|
-
// Cache session
|
|
238
|
-
this.sessions.set(newSessionId, Promise.resolve(session));
|
|
239
400
|
this.logger.info('Session forked', {
|
|
240
401
|
sourceSessionId,
|
|
241
402
|
newSessionId,
|
|
@@ -247,39 +408,62 @@ export class SessionManager {
|
|
|
247
408
|
* Get a session by ID - from cache or load from event store.
|
|
248
409
|
*/
|
|
249
410
|
async getSession(sessionId) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
411
|
+
while (true) {
|
|
412
|
+
if (this.shuttingDown)
|
|
413
|
+
return Err(ValidationErrors.invalid('Session manager is shutting down'));
|
|
414
|
+
let entry = this.sessions.get(sessionId);
|
|
415
|
+
if (entry?.state === 'evicting') {
|
|
416
|
+
await entry.unloadPromise;
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
if (entry?.state === 'ready' && entry.activity.getSnapshot().state !== 'ready') {
|
|
420
|
+
const session = await entry.promise;
|
|
421
|
+
await this.beginCacheEntryDisposal(sessionId, entry, session, 'disposed');
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
if (entry) {
|
|
425
|
+
this.cacheHits++;
|
|
426
|
+
entry.lastAccessAt = performance.now();
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
this.cacheMisses++;
|
|
430
|
+
const activity = new SessionRuntimeActivityController();
|
|
431
|
+
let loadingEntry;
|
|
432
|
+
const promise = Promise.resolve().then(() => this.loadSession(sessionId, loadingEntry));
|
|
433
|
+
loadingEntry = {
|
|
434
|
+
state: 'loading',
|
|
435
|
+
activity,
|
|
436
|
+
lastAccessAt: performance.now(),
|
|
437
|
+
promise,
|
|
438
|
+
};
|
|
439
|
+
entry = loadingEntry;
|
|
440
|
+
this.sessions.set(sessionId, entry);
|
|
441
|
+
}
|
|
253
442
|
try {
|
|
254
|
-
|
|
443
|
+
const session = await entry.promise;
|
|
444
|
+
if (this.sessions.get(sessionId) === entry && entry.state === 'loading') {
|
|
445
|
+
if (session.state.status === 'closed')
|
|
446
|
+
this.sessions.delete(sessionId);
|
|
447
|
+
else {
|
|
448
|
+
entry.state = 'ready';
|
|
449
|
+
entry.lastAccessAt = performance.now();
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return Ok(session);
|
|
255
453
|
}
|
|
256
454
|
catch (error) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (error instanceof SessionLoadError)
|
|
455
|
+
if (this.sessions.get(sessionId) === entry)
|
|
456
|
+
this.sessions.delete(sessionId);
|
|
457
|
+
if (error instanceof SessionLoadError)
|
|
260
458
|
return Err(error.domainError);
|
|
261
|
-
}
|
|
262
459
|
throw error;
|
|
263
460
|
}
|
|
264
461
|
}
|
|
265
|
-
// Store promise immediately to prevent concurrent loads
|
|
266
|
-
const loadPromise = this.loadSession(sessionId);
|
|
267
|
-
this.sessions.set(sessionId, loadPromise);
|
|
268
|
-
try {
|
|
269
|
-
return Ok(await loadPromise);
|
|
270
|
-
}
|
|
271
|
-
catch (error) {
|
|
272
|
-
this.sessions.delete(sessionId);
|
|
273
|
-
if (error instanceof SessionLoadError) {
|
|
274
|
-
return Err(error.domainError);
|
|
275
|
-
}
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
462
|
}
|
|
279
463
|
/**
|
|
280
464
|
* Internal session loading - throws SessionLoadError on domain errors.
|
|
281
465
|
*/
|
|
282
|
-
async loadSession(sessionId) {
|
|
466
|
+
async loadSession(sessionId, entry) {
|
|
283
467
|
// We need to peek at events first to determine the preset, so we can build plugins
|
|
284
468
|
// and compose the reducer before loading the store
|
|
285
469
|
const events = await this.eventStore.load(sessionId);
|
|
@@ -298,18 +482,16 @@ export class SessionManager {
|
|
|
298
482
|
const plugins = this.buildPlugins(preset);
|
|
299
483
|
const composedReducer = createApplyEvent(plugins);
|
|
300
484
|
// Load store with composed reducer
|
|
301
|
-
const store = await SessionStore.
|
|
485
|
+
const store = await SessionStore.fromEvents(sessionId, this.eventStore, events, composedReducer);
|
|
302
486
|
if (!store) {
|
|
303
487
|
throw new SessionLoadError(SessionErrors.notFound(String(sessionId)));
|
|
304
488
|
}
|
|
305
489
|
const state = store.getState();
|
|
306
490
|
// Don't cache closed sessions
|
|
307
491
|
if (state.status === 'closed') {
|
|
308
|
-
// Remove from cache since we don't cache closed sessions
|
|
309
|
-
this.sessions.delete(sessionId);
|
|
310
492
|
// Skip onSessionReady hooks — closed sessions are immutable, firing hooks
|
|
311
493
|
// would emit events to a sealed event log on every read / restart.
|
|
312
|
-
return await this.createSessionInstance(store, preset, plugins, { skipReadyHooks: true });
|
|
494
|
+
return await this.createSessionInstance(store, preset, plugins, entry, { skipReadyHooks: true });
|
|
313
495
|
}
|
|
314
496
|
// Check if recovery is needed after restart
|
|
315
497
|
const recoveryData = checkRecoveryNeeded(state);
|
|
@@ -325,7 +507,7 @@ export class SessionManager {
|
|
|
325
507
|
});
|
|
326
508
|
}
|
|
327
509
|
// Create session (auto-start services run via onSessionReady)
|
|
328
|
-
const session = await this.createSessionInstance(store, preset, plugins);
|
|
510
|
+
const session = await this.createSessionInstance(store, preset, plugins, entry);
|
|
329
511
|
// Check for pending agents
|
|
330
512
|
session.checkPendingAgents();
|
|
331
513
|
return session;
|
|
@@ -338,10 +520,48 @@ export class SessionManager {
|
|
|
338
520
|
* @param agentId - Agent ID (optional — some methods don't operate on a specific agent)
|
|
339
521
|
*/
|
|
340
522
|
async callPluginMethod(sessionId, method, input, agentId, caller) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
523
|
+
return this.withSessionLease(sessionId, `request:${method}`, (session) => (session.callPluginMethod(method, input, agentId, caller)));
|
|
524
|
+
}
|
|
525
|
+
/** Run an operation while atomically keeping the selected runtime resident. */
|
|
526
|
+
async withSessionLease(sessionId, reason, operation) {
|
|
527
|
+
const acquired = await this.acquireSessionLease(sessionId, reason);
|
|
528
|
+
if (!acquired.ok)
|
|
529
|
+
return acquired;
|
|
530
|
+
try {
|
|
531
|
+
return await operation(acquired.value.session);
|
|
532
|
+
}
|
|
533
|
+
finally {
|
|
534
|
+
acquired.value.release();
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/** Atomically look up a runtime and acquire a caller-managed lease on it. */
|
|
538
|
+
async acquireSessionLease(sessionId, reason) {
|
|
539
|
+
while (true) {
|
|
540
|
+
const sessionResult = await this.getSession(sessionId);
|
|
541
|
+
if (!sessionResult.ok)
|
|
542
|
+
return sessionResult;
|
|
543
|
+
const entry = this.sessions.get(sessionId);
|
|
544
|
+
if (!entry)
|
|
545
|
+
return Ok({ session: sessionResult.value, release: () => { } });
|
|
546
|
+
const release = entry.activity.tryAcquire(reason);
|
|
547
|
+
if (!release) {
|
|
548
|
+
if (entry.unloadPromise)
|
|
549
|
+
await entry.unloadPromise;
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
entry.lastAccessAt = performance.now();
|
|
553
|
+
let released = false;
|
|
554
|
+
return Ok({
|
|
555
|
+
session: sessionResult.value,
|
|
556
|
+
release: () => {
|
|
557
|
+
if (released)
|
|
558
|
+
return;
|
|
559
|
+
released = true;
|
|
560
|
+
entry.lastAccessAt = performance.now();
|
|
561
|
+
release();
|
|
562
|
+
},
|
|
563
|
+
});
|
|
564
|
+
}
|
|
345
565
|
}
|
|
346
566
|
/**
|
|
347
567
|
* Call a manager-level plugin method.
|
|
@@ -415,14 +635,16 @@ export class SessionManager {
|
|
|
415
635
|
let pendingAgents = 0;
|
|
416
636
|
let processingAgents = 0;
|
|
417
637
|
let lastActivityAt = null;
|
|
418
|
-
|
|
419
|
-
const
|
|
638
|
+
const metadataResult = await this.eventStore.listSessionsWithMetadata();
|
|
639
|
+
const openMetadata = metadataResult.sessions.filter((metadata) => metadata.status !== 'closed');
|
|
640
|
+
// Wait for resident sessions, ignoring failed and evicting loads.
|
|
641
|
+
const sessions = await Promise.all(Array.from(this.sessions.values())
|
|
642
|
+
.filter((entry) => entry.state !== 'evicting')
|
|
643
|
+
.map((entry) => entry.promise.catch(() => null)));
|
|
420
644
|
// Filter out closed sessions — they do not contribute to activity
|
|
421
645
|
const openSessions = sessions.filter((s) => s !== null && s.state.status !== 'closed');
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
for (const metadata of metadataResults) {
|
|
425
|
-
if (metadata?.lastActivityAt) {
|
|
646
|
+
for (const metadata of openMetadata) {
|
|
647
|
+
if (metadata.lastActivityAt) {
|
|
426
648
|
if (lastActivityAt === null
|
|
427
649
|
|| metadata.lastActivityAt > lastActivityAt) {
|
|
428
650
|
lastActivityAt = metadata.lastActivityAt;
|
|
@@ -430,6 +652,7 @@ export class SessionManager {
|
|
|
430
652
|
}
|
|
431
653
|
}
|
|
432
654
|
const sessionStats = [];
|
|
655
|
+
const loadedById = new Map(openSessions.map((session) => [session.id, session]));
|
|
433
656
|
for (const session of openSessions) {
|
|
434
657
|
for (const [agentId, agentState] of session.state.agents) {
|
|
435
658
|
if (agentState.status === 'pending') {
|
|
@@ -443,15 +666,19 @@ export class SessionManager {
|
|
|
443
666
|
processingAgents++;
|
|
444
667
|
}
|
|
445
668
|
}
|
|
669
|
+
}
|
|
670
|
+
for (const metadata of openMetadata) {
|
|
671
|
+
const loaded = loadedById.get(metadata.sessionId);
|
|
446
672
|
sessionStats.push({
|
|
447
|
-
id:
|
|
448
|
-
presetId:
|
|
449
|
-
status:
|
|
450
|
-
metrics: selectSessionStats(
|
|
673
|
+
id: metadata.sessionId,
|
|
674
|
+
presetId: metadata.presetId,
|
|
675
|
+
status: loaded?.state.status ?? metadata.status,
|
|
676
|
+
metrics: loaded ? selectSessionStats(loaded.state) : statsFromMetadata(metadata),
|
|
451
677
|
});
|
|
452
678
|
}
|
|
453
679
|
return {
|
|
454
|
-
sessionCount:
|
|
680
|
+
sessionCount: openMetadata.length,
|
|
681
|
+
loadedSessionCount: openSessions.length,
|
|
455
682
|
pendingAgents,
|
|
456
683
|
processingAgents,
|
|
457
684
|
lastActivityAt,
|
|
@@ -462,31 +689,75 @@ export class SessionManager {
|
|
|
462
689
|
* Shutdown - clean up all sessions.
|
|
463
690
|
*/
|
|
464
691
|
async shutdown() {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
692
|
+
this.shuttingDown = true;
|
|
693
|
+
if (this.evictionSweepTimer)
|
|
694
|
+
clearInterval(this.evictionSweepTimer);
|
|
695
|
+
await Promise.all([...this.sessions].map(async ([sessionId, entry]) => {
|
|
696
|
+
try {
|
|
697
|
+
const session = await entry.promise;
|
|
698
|
+
await this.beginCacheEntryDisposal(sessionId, entry, session, 'shutdown');
|
|
470
699
|
}
|
|
471
|
-
|
|
700
|
+
catch (error) {
|
|
701
|
+
entry.listenerCleanup?.();
|
|
702
|
+
entry.listenerCleanup = undefined;
|
|
703
|
+
this.logger.error('Failed to dispose session during shutdown', error instanceof Error ? error : new Error(String(error)), { sessionId });
|
|
704
|
+
}
|
|
705
|
+
}));
|
|
472
706
|
this.sessions.clear();
|
|
473
|
-
for (const cleanup of this.sessionListenerCleanup.values()) {
|
|
474
|
-
cleanup();
|
|
475
|
-
}
|
|
476
|
-
this.sessionListenerCleanup.clear();
|
|
477
707
|
this.logger.info('SessionManager shutdown complete');
|
|
478
708
|
}
|
|
709
|
+
/** Narrow runtime-cache diagnostics for lifecycle tests and operational logs. */
|
|
710
|
+
getRuntimeCacheStats() {
|
|
711
|
+
return {
|
|
712
|
+
hits: this.cacheHits,
|
|
713
|
+
misses: this.cacheMisses,
|
|
714
|
+
evictions: this.cacheEvictions,
|
|
715
|
+
loadedSessionCount: this.sessions.size,
|
|
716
|
+
sessions: [...this.sessions].map(([id, entry]) => {
|
|
717
|
+
const activity = entry.activity.getSnapshot();
|
|
718
|
+
return {
|
|
719
|
+
id,
|
|
720
|
+
state: entry.state,
|
|
721
|
+
lastAccessAt: Math.max(entry.lastAccessAt, activity.lastActivityAt),
|
|
722
|
+
activeLeaseCount: activity.activeCount,
|
|
723
|
+
leaseReasons: activity.reasons,
|
|
724
|
+
};
|
|
725
|
+
}),
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Sessions whose runtime is already resident and ready.
|
|
730
|
+
*
|
|
731
|
+
* Deliberately does not load, and does not refresh `lastAccessAt` — a passive
|
|
732
|
+
* reader must not keep a runtime alive or resurrect an evicted one. Use this
|
|
733
|
+
* over `getSession()` for read-only sweeps across sessions.
|
|
734
|
+
*/
|
|
735
|
+
async listResidentSessions() {
|
|
736
|
+
const entries = [...this.sessions].filter(([, entry]) => entry.state === 'ready');
|
|
737
|
+
const sessions = await Promise.all(entries.map(async ([sessionId, entry]) => {
|
|
738
|
+
const session = await entry.promise.catch(() => null);
|
|
739
|
+
// Re-check: the entry can start evicting while we await the resolved promise.
|
|
740
|
+
if (!session || this.sessions.get(sessionId) !== entry || entry.state !== 'ready')
|
|
741
|
+
return null;
|
|
742
|
+
return session;
|
|
743
|
+
}));
|
|
744
|
+
return sessions.filter((session) => session !== null);
|
|
745
|
+
}
|
|
479
746
|
// ============================================================================
|
|
480
747
|
// Private methods
|
|
481
748
|
// ============================================================================
|
|
482
749
|
/**
|
|
483
|
-
* Build ConfiguredPlugin[] for a session.
|
|
750
|
+
* Build ConfiguredPlugin[] for a session, in hook order.
|
|
484
751
|
*
|
|
485
752
|
* Iterates all system-registered plugins. For each:
|
|
486
753
|
* 1. Check if preset has explicit SessionPluginConfig → use that config
|
|
487
754
|
* 2. If not, try auto-deriving infrastructure config (agents, uploads, services)
|
|
488
755
|
* 3. If no config at all → call .create() with no args (void config)
|
|
489
756
|
* 4. Check isSessionEnabled — skip plugin if not enabled
|
|
757
|
+
*
|
|
758
|
+
* The result is sorted by each plugin's declared `.order()` — the precedence
|
|
759
|
+
* between plugins that both want the same hook, since most agent hooks stop
|
|
760
|
+
* at the first non-null result.
|
|
490
761
|
*/
|
|
491
762
|
buildPlugins(preset) {
|
|
492
763
|
// Build a lookup from preset Sessionplugins
|
|
@@ -546,7 +817,8 @@ export class SessionManager {
|
|
|
546
817
|
}
|
|
547
818
|
}
|
|
548
819
|
}
|
|
549
|
-
|
|
820
|
+
// Stable, so plugins that declare no order keep their registration order.
|
|
821
|
+
return plugins.sort((a, b) => (a.order ?? DEFAULT_PLUGIN_ORDER) - (b.order ?? DEFAULT_PLUGIN_ORDER));
|
|
550
822
|
}
|
|
551
823
|
/**
|
|
552
824
|
* Build infrastructure-derived plugin configs from preset data.
|
|
@@ -569,7 +841,11 @@ export class SessionManager {
|
|
|
569
841
|
configs.set('uploads', {
|
|
570
842
|
dataFileStore: this.dataFileStore,
|
|
571
843
|
preprocessorRegistry: this.preprocessorRegistry,
|
|
844
|
+
archiveLimits: this.uploadArchiveLimits,
|
|
572
845
|
});
|
|
846
|
+
if (this.resourceArchiveLimits) {
|
|
847
|
+
configs.set('resources', { archiveLimits: this.resourceArchiveLimits });
|
|
848
|
+
}
|
|
573
849
|
// services plugin — collect services from all agent definitions
|
|
574
850
|
const allAgentConfigs = [preset.orchestrator, ...(preset.communicator ? [preset.communicator] : []), ...preset.agents];
|
|
575
851
|
const servicesByType = new Map();
|
|
@@ -592,15 +868,11 @@ export class SessionManager {
|
|
|
592
868
|
* which must remain immutable: running hooks would emit session_handler_* events
|
|
593
869
|
* to a sealed event log on every introspection / restart cycle.
|
|
594
870
|
*/
|
|
595
|
-
async createSessionInstance(store, preset, plugins, opts = {}) {
|
|
596
|
-
// Only register cache eviction listener for active sessions (not closed)
|
|
597
|
-
if (store.getState().status !== 'closed') {
|
|
598
|
-
this.registerSessionEventListener(store.sessionId, store);
|
|
599
|
-
}
|
|
871
|
+
async createSessionInstance(store, preset, plugins, entry, opts = {}) {
|
|
600
872
|
const sessionDir = this.getSessionDir(store.sessionId);
|
|
601
873
|
const sessionLogger = new TeeLogger([
|
|
602
874
|
this.logger.child({ sessionId: store.sessionId }),
|
|
603
|
-
|
|
875
|
+
createSessionLogger(this.platform, String(store.sessionId), join(sessionDir, 'session.log')),
|
|
604
876
|
]);
|
|
605
877
|
// Create session
|
|
606
878
|
const session = new Session({
|
|
@@ -616,20 +888,31 @@ export class SessionManager {
|
|
|
616
888
|
eventStore: this.eventStore,
|
|
617
889
|
llmLogger: this.llmLogger,
|
|
618
890
|
platform: this.platform,
|
|
891
|
+
runtimeActivity: entry.activity,
|
|
892
|
+
registerReopenedSession: (reopenedSession) => this.registerReopenedSession(reopenedSession, entry.activity),
|
|
619
893
|
});
|
|
894
|
+
// Only register cache eviction listener for active sessions (not closed)
|
|
895
|
+
if (store.getState().status !== 'closed') {
|
|
896
|
+
this.registerSessionEventListener(store.sessionId, store, session, entry);
|
|
897
|
+
}
|
|
620
898
|
// Ensure session and workspace directories exist before plugins run
|
|
621
899
|
await this.platform.fs.mkdir(sessionDir, { recursive: true });
|
|
622
900
|
const workspaceDir = store.getState().workspaceDir;
|
|
623
901
|
if (workspaceDir) {
|
|
624
902
|
await this.platform.fs.mkdir(workspaceDir, { recursive: true });
|
|
625
903
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
904
|
+
try {
|
|
905
|
+
// Safe for closed sessions — createContext is pure local setup, no event emit.
|
|
906
|
+
await session.initPluginContexts();
|
|
907
|
+
// Skipped for closed sessions to preserve event log immutability.
|
|
908
|
+
if (!opts.skipReadyHooks)
|
|
909
|
+
await session.callSessionReadyHooks();
|
|
910
|
+
}
|
|
911
|
+
catch (error) {
|
|
912
|
+
await session.dispose('evicted');
|
|
913
|
+
entry.listenerCleanup?.();
|
|
914
|
+
entry.listenerCleanup = undefined;
|
|
915
|
+
throw error;
|
|
633
916
|
}
|
|
634
917
|
return session;
|
|
635
918
|
}
|
|
@@ -653,20 +936,136 @@ export class SessionManager {
|
|
|
653
936
|
* Cleans up any previous listener for this sessionId (from a prior load)
|
|
654
937
|
* to prevent duplicate listeners firing on old stores.
|
|
655
938
|
*/
|
|
656
|
-
registerSessionEventListener(sessionId, store) {
|
|
657
|
-
|
|
658
|
-
if (prevCleanup)
|
|
659
|
-
prevCleanup();
|
|
939
|
+
registerSessionEventListener(sessionId, store, session, entry) {
|
|
940
|
+
entry.listenerCleanup?.();
|
|
660
941
|
const unsubscribe = store.onEvent((event) => {
|
|
661
|
-
if (event.type === 'session_closed'
|
|
662
|
-
this.sessions.
|
|
663
|
-
|
|
942
|
+
if (event.type === 'session_closed') {
|
|
943
|
+
if (this.sessions.get(sessionId) === entry)
|
|
944
|
+
this.beginCacheEntryDisposal(sessionId, entry, session, 'closed');
|
|
945
|
+
else
|
|
946
|
+
void session.dispose('closed');
|
|
947
|
+
}
|
|
948
|
+
else if (event.type === 'session_reopened') {
|
|
949
|
+
if (this.sessions.get(sessionId) === entry)
|
|
950
|
+
this.sessions.delete(sessionId);
|
|
951
|
+
unsubscribe();
|
|
952
|
+
entry.listenerCleanup = undefined;
|
|
664
953
|
}
|
|
665
954
|
});
|
|
666
|
-
|
|
955
|
+
entry.listenerCleanup = unsubscribe;
|
|
956
|
+
}
|
|
957
|
+
registerReopenedSession(session, activity) {
|
|
958
|
+
if (this.shuttingDown)
|
|
959
|
+
return Err(ValidationErrors.invalid('Session manager is shutting down'));
|
|
960
|
+
if (activity.getSnapshot().state !== 'ready')
|
|
961
|
+
return Ok(undefined);
|
|
962
|
+
if (this.sessions.has(session.id))
|
|
963
|
+
return Err(SessionErrors.alreadyExists(String(session.id)));
|
|
964
|
+
const deferred = Promise.withResolvers();
|
|
965
|
+
void deferred.promise.catch(() => { });
|
|
966
|
+
const entry = {
|
|
967
|
+
state: 'loading',
|
|
968
|
+
promise: deferred.promise,
|
|
969
|
+
activity,
|
|
970
|
+
lastAccessAt: performance.now(),
|
|
971
|
+
};
|
|
972
|
+
this.sessions.set(session.id, entry);
|
|
973
|
+
return Ok({
|
|
974
|
+
complete: async () => {
|
|
975
|
+
if (this.sessions.get(session.id) !== entry) {
|
|
976
|
+
throw new Error(`Reopened session lost cache ownership: ${session.id}`);
|
|
977
|
+
}
|
|
978
|
+
this.registerSessionEventListener(session.id, session.store, session, entry);
|
|
979
|
+
try {
|
|
980
|
+
await session.callSessionReadyHooks();
|
|
981
|
+
session.checkPendingAgents();
|
|
982
|
+
if (this.sessions.get(session.id) !== entry || entry.state !== 'loading' || activity.getSnapshot().state !== 'ready') {
|
|
983
|
+
throw new Error(`Reopened session became unavailable during ready hooks: ${session.id}`);
|
|
984
|
+
}
|
|
985
|
+
entry.state = 'ready';
|
|
986
|
+
entry.lastAccessAt = performance.now();
|
|
987
|
+
deferred.resolve(session);
|
|
988
|
+
}
|
|
989
|
+
catch (error) {
|
|
990
|
+
if (this.sessions.get(session.id) === entry)
|
|
991
|
+
this.sessions.delete(session.id);
|
|
992
|
+
entry.listenerCleanup?.();
|
|
993
|
+
entry.listenerCleanup = undefined;
|
|
994
|
+
deferred.reject(error);
|
|
995
|
+
await session.dispose('evicted');
|
|
996
|
+
throw error;
|
|
997
|
+
}
|
|
998
|
+
},
|
|
999
|
+
abort: (error) => {
|
|
1000
|
+
if (this.sessions.get(session.id) === entry)
|
|
1001
|
+
this.sessions.delete(session.id);
|
|
1002
|
+
entry.listenerCleanup?.();
|
|
1003
|
+
entry.listenerCleanup = undefined;
|
|
1004
|
+
deferred.reject(error);
|
|
1005
|
+
},
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
async evictIdleSessions() {
|
|
1009
|
+
if (this.sessionIdleTimeoutMs === 0)
|
|
1010
|
+
return;
|
|
1011
|
+
const now = performance.now();
|
|
1012
|
+
const disposals = [];
|
|
1013
|
+
for (const [sessionId, entry] of this.sessions) {
|
|
1014
|
+
if (entry.state !== 'ready')
|
|
1015
|
+
continue;
|
|
1016
|
+
const activity = entry.activity.getSnapshot();
|
|
1017
|
+
if (now - Math.max(entry.lastAccessAt, activity.lastActivityAt) < this.sessionIdleTimeoutMs)
|
|
1018
|
+
continue;
|
|
1019
|
+
if (!entry.activity.tryBeginUnload())
|
|
1020
|
+
continue;
|
|
1021
|
+
const session = await entry.promise;
|
|
1022
|
+
disposals.push(this.beginCacheEntryDisposal(sessionId, entry, session, 'idle'));
|
|
1023
|
+
}
|
|
1024
|
+
await Promise.all(disposals);
|
|
1025
|
+
}
|
|
1026
|
+
beginCacheEntryDisposal(sessionId, entry, session, reason) {
|
|
1027
|
+
if (entry.unloadPromise)
|
|
1028
|
+
return entry.unloadPromise;
|
|
1029
|
+
entry.state = 'evicting';
|
|
1030
|
+
entry.activity.beginForcedUnload();
|
|
1031
|
+
entry.unloadPromise = session.dispose(RUNTIME_DISPOSAL_CLOSE_REASON[reason])
|
|
1032
|
+
.catch((error) => {
|
|
1033
|
+
this.logger.error('Failed to dispose session runtime', error instanceof Error ? error : new Error(String(error)), { sessionId, reason });
|
|
1034
|
+
})
|
|
1035
|
+
.finally(() => {
|
|
1036
|
+
if (this.sessions.get(sessionId) === entry)
|
|
1037
|
+
this.sessions.delete(sessionId);
|
|
1038
|
+
entry.listenerCleanup?.();
|
|
1039
|
+
entry.listenerCleanup = undefined;
|
|
1040
|
+
if (reason === 'idle')
|
|
1041
|
+
this.cacheEvictions++;
|
|
1042
|
+
this.logger.debug('Session runtime evicted', { sessionId, reason });
|
|
1043
|
+
});
|
|
1044
|
+
return entry.unloadPromise;
|
|
667
1045
|
}
|
|
668
1046
|
getSessionDir(sessionId) {
|
|
669
1047
|
return join(this.basePath, 'sessions', String(sessionId));
|
|
670
1048
|
}
|
|
671
1049
|
}
|
|
1050
|
+
function statsFromMetadata(metadata) {
|
|
1051
|
+
return {
|
|
1052
|
+
totalTokens: metadata.metrics?.totalTokens ?? 0,
|
|
1053
|
+
promptTokens: metadata.metrics?.inputTokens ?? 0,
|
|
1054
|
+
completionTokens: metadata.metrics?.outputTokens ?? 0,
|
|
1055
|
+
cacheReadTokens: 0,
|
|
1056
|
+
cacheWriteTokens: 0,
|
|
1057
|
+
totalCost: metadata.metrics?.totalCost ?? 0,
|
|
1058
|
+
llmCalls: metadata.metrics?.totalLLMCalls ?? 0,
|
|
1059
|
+
llmErrors: 0,
|
|
1060
|
+
toolCalls: metadata.metrics?.totalToolCalls ?? 0,
|
|
1061
|
+
toolErrors: 0,
|
|
1062
|
+
userMessages: metadata.metrics?.totalMessages ?? 0,
|
|
1063
|
+
compactions: 0,
|
|
1064
|
+
agentCount: metadata.metrics?.totalAgents ?? 0,
|
|
1065
|
+
firstEventAt: metadata.createdAt,
|
|
1066
|
+
lastEventAt: metadata.lastActivityAt,
|
|
1067
|
+
byProvider: {},
|
|
1068
|
+
byAgent: {},
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
672
1071
|
//# sourceMappingURL=session-manager.js.map
|