@roj-ai/sdk 0.1.3 → 0.1.5
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.js +191 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/builtin-events.js +8 -0
- package/dist/builtin-events.js.map +1 -0
- package/dist/bun-platform/fs.js +39 -0
- package/dist/bun-platform/fs.js.map +1 -0
- package/dist/bun-platform/index.js +18 -0
- package/dist/bun-platform/index.js.map +1 -0
- package/dist/bun-platform/process.js +21 -0
- package/dist/bun-platform/process.js.map +1 -0
- package/dist/config.js +54 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.js +155 -0
- package/dist/config.test.js.map +1 -0
- package/dist/core/agent-loop.integration.test.js +414 -0
- package/dist/core/agent-loop.integration.test.js.map +1 -0
- package/dist/core/agents/agent-config.test.js +194 -0
- package/dist/core/agents/agent-config.test.js.map +1 -0
- package/dist/core/agents/agent-roles.js +25 -0
- package/dist/core/agents/agent-roles.js.map +1 -0
- package/dist/core/agents/agent-shutdown.test.js +180 -0
- package/dist/core/agents/agent-shutdown.test.js.map +1 -0
- package/dist/core/agents/agent.js +1205 -0
- package/dist/core/agents/agent.js.map +1 -0
- package/dist/core/agents/agent.test.js +313 -0
- package/dist/core/agents/agent.test.js.map +1 -0
- package/dist/core/agents/communicator.js +13 -0
- package/dist/core/agents/communicator.js.map +1 -0
- package/dist/core/agents/config.js +5 -0
- package/dist/core/agents/config.js.map +1 -0
- package/dist/core/agents/context.js +2 -0
- package/dist/core/agents/context.js.map +1 -0
- package/dist/core/agents/debounce.js +74 -0
- package/dist/core/agents/debounce.js.map +1 -0
- package/dist/core/agents/handler-events.test.js +115 -0
- package/dist/core/agents/handler-events.test.js.map +1 -0
- package/dist/core/agents/index.js +2 -0
- package/dist/core/agents/index.js.map +1 -0
- package/dist/core/agents/response-sanitizer.js +46 -0
- package/dist/core/agents/response-sanitizer.js.map +1 -0
- package/dist/core/agents/response-sanitizer.test.js +101 -0
- package/dist/core/agents/response-sanitizer.test.js.map +1 -0
- package/dist/core/agents/retry.js +105 -0
- package/dist/core/agents/retry.js.map +1 -0
- package/dist/core/agents/schema.js +39 -0
- package/dist/core/agents/schema.js.map +1 -0
- package/dist/core/agents/state.js +90 -0
- package/dist/core/agents/state.js.map +1 -0
- package/dist/core/context/state.js +23 -0
- package/dist/core/context/state.js.map +1 -0
- package/dist/core/errors.js +38 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/event-sourcing.integration.test.js +154 -0
- package/dist/core/event-sourcing.integration.test.js.map +1 -0
- package/dist/core/events/base-event-store.js +201 -0
- package/dist/core/events/base-event-store.js.map +1 -0
- package/dist/core/events/event-store.js +26 -0
- package/dist/core/events/event-store.js.map +1 -0
- package/dist/core/events/file.js +320 -0
- package/dist/core/events/file.js.map +1 -0
- package/dist/core/events/file.test.js +284 -0
- package/dist/core/events/file.test.js.map +1 -0
- package/dist/core/events/index.js +3 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/events/memory.js +101 -0
- package/dist/core/events/memory.js.map +1 -0
- package/dist/core/events/memory.test.js +502 -0
- package/dist/core/events/memory.test.js.map +1 -0
- package/dist/core/events/metadata-utils.js +107 -0
- package/dist/core/events/metadata-utils.js.map +1 -0
- package/dist/core/events/test-helpers.js +15 -0
- package/dist/core/events/test-helpers.js.map +1 -0
- package/dist/core/events/types.js +21 -0
- package/dist/core/events/types.js.map +1 -0
- package/dist/core/file-store/file-store.js +250 -0
- package/dist/core/file-store/file-store.js.map +1 -0
- package/dist/core/file-store/types.js +7 -0
- package/dist/core/file-store/types.js.map +1 -0
- package/dist/core/image/image-processor.js +106 -0
- package/dist/core/image/image-processor.js.map +1 -0
- package/dist/core/image/image-processor.test.js +171 -0
- package/dist/core/image/image-processor.test.js.map +1 -0
- package/dist/core/image/index.js +4 -0
- package/dist/core/image/index.js.map +1 -0
- package/dist/core/image/noop-resizer.js +6 -0
- package/dist/core/image/noop-resizer.js.map +1 -0
- package/dist/core/image/types.js +2 -0
- package/dist/core/image/types.js.map +1 -0
- package/dist/core/image/vips-resizer.js +100 -0
- package/dist/core/image/vips-resizer.js.map +1 -0
- package/dist/core/image/vips-resizer.test.js +324 -0
- package/dist/core/image/vips-resizer.test.js.map +1 -0
- package/dist/core/llm/anthropic.js +396 -0
- package/dist/core/llm/anthropic.js.map +1 -0
- package/dist/core/llm/anthropic.test.js +434 -0
- package/dist/core/llm/anthropic.test.js.map +1 -0
- package/dist/core/llm/cache-breakpoints.js +37 -0
- package/dist/core/llm/cache-breakpoints.js.map +1 -0
- package/dist/core/llm/cache-live.test.js +137 -0
- package/dist/core/llm/cache-live.test.js.map +1 -0
- package/dist/core/llm/index.js +9 -0
- package/dist/core/llm/index.js.map +1 -0
- package/dist/core/llm/llm-log-types.js +12 -0
- package/dist/core/llm/llm-log-types.js.map +1 -0
- package/dist/core/llm/logger.js +241 -0
- package/dist/core/llm/logger.js.map +1 -0
- package/dist/core/llm/logger.test.js +228 -0
- package/dist/core/llm/logger.test.js.map +1 -0
- package/dist/core/llm/logging-provider.js +49 -0
- package/dist/core/llm/logging-provider.js.map +1 -0
- package/dist/core/llm/middleware.js +114 -0
- package/dist/core/llm/middleware.js.map +1 -0
- package/dist/core/llm/mock.js +186 -0
- package/dist/core/llm/mock.js.map +1 -0
- package/dist/core/llm/mock.test.js +318 -0
- package/dist/core/llm/mock.test.js.map +1 -0
- package/dist/core/llm/openrouter-mapping.test.js +125 -0
- package/dist/core/llm/openrouter-mapping.test.js.map +1 -0
- package/dist/core/llm/openrouter.js +298 -0
- package/dist/core/llm/openrouter.js.map +1 -0
- package/dist/core/llm/openrouter.test.js +377 -0
- package/dist/core/llm/openrouter.test.js.map +1 -0
- package/dist/core/llm/provider-integration.test.js +350 -0
- package/dist/core/llm/provider-integration.test.js.map +1 -0
- package/dist/core/llm/provider.js +18 -0
- package/dist/core/llm/provider.js.map +1 -0
- package/dist/core/llm/routing-provider.js +52 -0
- package/dist/core/llm/routing-provider.js.map +1 -0
- package/dist/core/llm/routing-provider.test.js +94 -0
- package/dist/core/llm/routing-provider.test.js.map +1 -0
- package/dist/core/llm/schema.js +31 -0
- package/dist/core/llm/schema.js.map +1 -0
- package/dist/core/llm/snapshot-fetch.js +122 -0
- package/dist/core/llm/snapshot-fetch.js.map +1 -0
- package/dist/core/llm/snapshot-middleware.js +142 -0
- package/dist/core/llm/snapshot-middleware.js.map +1 -0
- package/dist/core/llm/snapshot-middleware.test.js +144 -0
- package/dist/core/llm/snapshot-middleware.test.js.map +1 -0
- package/dist/core/llm/state.js +48 -0
- package/dist/core/llm/state.js.map +1 -0
- package/dist/core/llm/tokens.js +40 -0
- package/dist/core/llm/tokens.js.map +1 -0
- package/dist/core/multi-agent.integration.test.js +298 -0
- package/dist/core/multi-agent.integration.test.js.map +1 -0
- package/dist/core/plugin-hooks.integration.test.js +344 -0
- package/dist/core/plugin-hooks.integration.test.js.map +1 -0
- package/dist/core/plugins/hook-types.js +5 -0
- package/dist/core/plugins/hook-types.js.map +1 -0
- package/dist/core/plugins/index.js +5 -0
- package/dist/core/plugins/index.js.map +1 -0
- package/dist/core/plugins/plugin-builder.js +321 -0
- package/dist/core/plugins/plugin-builder.js.map +1 -0
- package/dist/core/preset/config.js +54 -0
- package/dist/core/preset/config.js.map +1 -0
- package/dist/core/preset/index.js +6 -0
- package/dist/core/preset/index.js.map +1 -0
- package/dist/core/preset/preset-builder.js +63 -0
- package/dist/core/preset/preset-builder.js.map +1 -0
- package/dist/core/session-lifecycle.integration.test.js +159 -0
- package/dist/core/session-lifecycle.integration.test.js.map +1 -0
- package/dist/core/sessions/apply-event.js +41 -0
- package/dist/core/sessions/apply-event.js.map +1 -0
- package/dist/core/sessions/context.js +2 -0
- package/dist/core/sessions/context.js.map +1 -0
- package/dist/core/sessions/fork-utils.js +42 -0
- package/dist/core/sessions/fork-utils.js.map +1 -0
- package/dist/core/sessions/fork-utils.test.js +129 -0
- package/dist/core/sessions/fork-utils.test.js.map +1 -0
- package/dist/core/sessions/reducer.js +55 -0
- package/dist/core/sessions/reducer.js.map +1 -0
- package/dist/core/sessions/schema.js +66 -0
- package/dist/core/sessions/schema.js.map +1 -0
- package/dist/core/sessions/session-environment.js +2 -0
- package/dist/core/sessions/session-environment.js.map +1 -0
- package/dist/core/sessions/session-manager.js +650 -0
- package/dist/core/sessions/session-manager.js.map +1 -0
- package/dist/core/sessions/session-store.js +118 -0
- package/dist/core/sessions/session-store.js.map +1 -0
- package/dist/core/sessions/session.js +675 -0
- package/dist/core/sessions/session.js.map +1 -0
- package/dist/core/sessions/session.test.js +1095 -0
- package/dist/core/sessions/session.test.js.map +1 -0
- package/dist/core/sessions/state.js +377 -0
- package/dist/core/sessions/state.js.map +1 -0
- package/dist/core/system.js +66 -0
- package/dist/core/system.js.map +1 -0
- package/dist/core/tools/context.js +2 -0
- package/dist/core/tools/context.js.map +1 -0
- package/dist/core/tools/definition.js +4 -0
- package/dist/core/tools/definition.js.map +1 -0
- package/dist/core/tools/executor.js +82 -0
- package/dist/core/tools/executor.js.map +1 -0
- package/dist/core/tools/executor.test.js +143 -0
- package/dist/core/tools/executor.test.js.map +1 -0
- package/dist/core/tools/index.js +4 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/schema.js +20 -0
- package/dist/core/tools/schema.js.map +1 -0
- package/dist/core/tools/state.js +29 -0
- package/dist/core/tools/state.js.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/json/index.js +5 -0
- package/dist/lib/json/index.js.map +1 -0
- package/dist/lib/logger/console.js +147 -0
- package/dist/lib/logger/console.js.map +1 -0
- package/dist/lib/logger/console.test.js +258 -0
- package/dist/lib/logger/console.test.js.map +1 -0
- package/dist/lib/logger/file.js +54 -0
- package/dist/lib/logger/file.js.map +1 -0
- package/dist/lib/logger/index.js +4 -0
- package/dist/lib/logger/index.js.map +1 -0
- package/dist/lib/logger/logger.js +28 -0
- package/dist/lib/logger/logger.js.map +1 -0
- package/dist/lib/logger/ring-buffer.js +61 -0
- package/dist/lib/logger/ring-buffer.js.map +1 -0
- package/dist/lib/logger/tee.js +43 -0
- package/dist/lib/logger/tee.js.map +1 -0
- package/dist/lib/mime.js +22 -0
- package/dist/lib/mime.js.map +1 -0
- package/dist/lib/never.js +4 -0
- package/dist/lib/never.js.map +1 -0
- package/dist/lib/utils/hash.js +35 -0
- package/dist/lib/utils/hash.js.map +1 -0
- package/dist/lib/utils/result.js +21 -0
- package/dist/lib/utils/result.js.map +1 -0
- package/dist/platform/fs.js +8 -0
- package/dist/platform/fs.js.map +1 -0
- package/dist/platform/index.js +9 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/process.js +8 -0
- package/dist/platform/process.js.map +1 -0
- package/dist/plugins/agent-status/plugin.js +77 -0
- package/dist/plugins/agent-status/plugin.js.map +1 -0
- package/dist/plugins/agents/agents.integration.test.js +683 -0
- package/dist/plugins/agents/agents.integration.test.js.map +1 -0
- package/dist/plugins/agents/index.js +2 -0
- package/dist/plugins/agents/index.js.map +1 -0
- package/dist/plugins/agents/plugin.js +199 -0
- package/dist/plugins/agents/plugin.js.map +1 -0
- package/dist/plugins/context-compact/context-compact.integration.test.js +174 -0
- package/dist/plugins/context-compact/context-compact.integration.test.js.map +1 -0
- package/dist/plugins/context-compact/context-compactor.js +238 -0
- package/dist/plugins/context-compact/context-compactor.js.map +1 -0
- package/dist/plugins/context-compact/context-compactor.test.js +763 -0
- package/dist/plugins/context-compact/context-compactor.test.js.map +1 -0
- package/dist/plugins/context-compact/history-offloader.js +42 -0
- package/dist/plugins/context-compact/history-offloader.js.map +1 -0
- package/dist/plugins/context-compact/history-offloader.test.js +77 -0
- package/dist/plugins/context-compact/history-offloader.test.js.map +1 -0
- package/dist/plugins/context-compact/index.js +4 -0
- package/dist/plugins/context-compact/index.js.map +1 -0
- package/dist/plugins/context-compact/plugin.js +37 -0
- package/dist/plugins/context-compact/plugin.js.map +1 -0
- package/dist/plugins/filesystem/filesystem.integration.test.js +411 -0
- package/dist/plugins/filesystem/filesystem.integration.test.js.map +1 -0
- package/dist/plugins/filesystem/helpers.js +170 -0
- package/dist/plugins/filesystem/helpers.js.map +1 -0
- package/dist/plugins/filesystem/index.js +3 -0
- package/dist/plugins/filesystem/index.js.map +1 -0
- package/dist/plugins/filesystem/listing.js +247 -0
- package/dist/plugins/filesystem/listing.js.map +1 -0
- package/dist/plugins/filesystem/plugin.js +364 -0
- package/dist/plugins/filesystem/plugin.js.map +1 -0
- package/dist/plugins/filesystem/schema.js +2 -0
- package/dist/plugins/filesystem/schema.js.map +1 -0
- package/dist/plugins/git-status/index.js +2 -0
- package/dist/plugins/git-status/index.js.map +1 -0
- package/dist/plugins/git-status/plugin.js +144 -0
- package/dist/plugins/git-status/plugin.js.map +1 -0
- package/dist/plugins/limits-guard/config.js +5 -0
- package/dist/plugins/limits-guard/config.js.map +1 -0
- package/dist/plugins/limits-guard/index.js +3 -0
- package/dist/plugins/limits-guard/index.js.map +1 -0
- package/dist/plugins/limits-guard/limit-guard.js +125 -0
- package/dist/plugins/limits-guard/limit-guard.js.map +1 -0
- package/dist/plugins/limits-guard/limit-guard.test.js +121 -0
- package/dist/plugins/limits-guard/limit-guard.test.js.map +1 -0
- package/dist/plugins/limits-guard/limits-guard.integration.test.js +378 -0
- package/dist/plugins/limits-guard/limits-guard.integration.test.js.map +1 -0
- package/dist/plugins/limits-guard/plugin.js +240 -0
- package/dist/plugins/limits-guard/plugin.js.map +1 -0
- package/dist/plugins/llm-debug/index.js +2 -0
- package/dist/plugins/llm-debug/index.js.map +1 -0
- package/dist/plugins/llm-debug/llm-debug.integration.test.js +157 -0
- package/dist/plugins/llm-debug/llm-debug.integration.test.js.map +1 -0
- package/dist/plugins/llm-debug/plugin.js +148 -0
- package/dist/plugins/llm-debug/plugin.js.map +1 -0
- package/dist/plugins/logs/index.js +2 -0
- package/dist/plugins/logs/index.js.map +1 -0
- package/dist/plugins/logs/plugin.js +38 -0
- package/dist/plugins/logs/plugin.js.map +1 -0
- package/dist/plugins/mailbox/helpers.js +66 -0
- package/dist/plugins/mailbox/helpers.js.map +1 -0
- package/dist/plugins/mailbox/index.js +9 -0
- package/dist/plugins/mailbox/index.js.map +1 -0
- package/dist/plugins/mailbox/mailbox.integration.test.js +605 -0
- package/dist/plugins/mailbox/mailbox.integration.test.js.map +1 -0
- package/dist/plugins/mailbox/plugin.js +204 -0
- package/dist/plugins/mailbox/plugin.js.map +1 -0
- package/dist/plugins/mailbox/prompts.js +93 -0
- package/dist/plugins/mailbox/prompts.js.map +1 -0
- package/dist/plugins/mailbox/query.js +38 -0
- package/dist/plugins/mailbox/query.js.map +1 -0
- package/dist/plugins/mailbox/schema.js +32 -0
- package/dist/plugins/mailbox/schema.js.map +1 -0
- package/dist/plugins/mailbox/state.js +41 -0
- package/dist/plugins/mailbox/state.js.map +1 -0
- package/dist/plugins/resources/index.js +4 -0
- package/dist/plugins/resources/index.js.map +1 -0
- package/dist/plugins/resources/manifest.js +20 -0
- package/dist/plugins/resources/manifest.js.map +1 -0
- package/dist/plugins/resources/plugin.js +171 -0
- package/dist/plugins/resources/plugin.js.map +1 -0
- package/dist/plugins/resources/post-inject.js +32 -0
- package/dist/plugins/resources/post-inject.js.map +1 -0
- package/dist/plugins/resources/state.js +16 -0
- package/dist/plugins/resources/state.js.map +1 -0
- package/dist/plugins/result-eviction/index.js +2 -0
- package/dist/plugins/result-eviction/index.js.map +1 -0
- package/dist/plugins/result-eviction/plugin.js +43 -0
- package/dist/plugins/result-eviction/plugin.js.map +1 -0
- package/dist/plugins/result-eviction/result-eviction.integration.test.js +217 -0
- package/dist/plugins/result-eviction/result-eviction.integration.test.js.map +1 -0
- package/dist/plugins/services/plugin.js +453 -0
- package/dist/plugins/services/plugin.js.map +1 -0
- package/dist/plugins/services/port-pool.js +70 -0
- package/dist/plugins/services/port-pool.js.map +1 -0
- package/dist/plugins/services/prompt.js +40 -0
- package/dist/plugins/services/prompt.js.map +1 -0
- package/dist/plugins/services/schema.js +9 -0
- package/dist/plugins/services/schema.js.map +1 -0
- package/dist/plugins/services/service.js +470 -0
- package/dist/plugins/services/service.js.map +1 -0
- package/dist/plugins/services/services.integration.test.js +485 -0
- package/dist/plugins/services/services.integration.test.js.map +1 -0
- package/dist/plugins/session-lifecycle/index.js +2 -0
- package/dist/plugins/session-lifecycle/index.js.map +1 -0
- package/dist/plugins/session-lifecycle/plugin.js +273 -0
- package/dist/plugins/session-lifecycle/plugin.js.map +1 -0
- package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js +498 -0
- package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js.map +1 -0
- package/dist/plugins/session-state/plugin.js +159 -0
- package/dist/plugins/session-state/plugin.js.map +1 -0
- package/dist/plugins/session-stats/index.js +3 -0
- package/dist/plugins/session-stats/index.js.map +1 -0
- package/dist/plugins/session-stats/plugin.js +81 -0
- package/dist/plugins/session-stats/plugin.js.map +1 -0
- package/dist/plugins/shell/executor.js +339 -0
- package/dist/plugins/shell/executor.js.map +1 -0
- package/dist/plugins/shell/index.js +6 -0
- package/dist/plugins/shell/index.js.map +1 -0
- package/dist/plugins/shell/plugin.js +66 -0
- package/dist/plugins/shell/plugin.js.map +1 -0
- package/dist/plugins/shell/shell.integration.test.js +234 -0
- package/dist/plugins/shell/shell.integration.test.js.map +1 -0
- package/dist/plugins/shell/shell.test.js +236 -0
- package/dist/plugins/shell/shell.test.js.map +1 -0
- package/dist/plugins/skills/discovery.js +205 -0
- package/dist/plugins/skills/discovery.js.map +1 -0
- package/dist/plugins/skills/discovery.test.js +312 -0
- package/dist/plugins/skills/discovery.test.js.map +1 -0
- package/dist/plugins/skills/index.js +12 -0
- package/dist/plugins/skills/index.js.map +1 -0
- package/dist/plugins/skills/plugin.js +293 -0
- package/dist/plugins/skills/plugin.js.map +1 -0
- package/dist/plugins/skills/prompts.js +70 -0
- package/dist/plugins/skills/prompts.js.map +1 -0
- package/dist/plugins/skills/schema.js +18 -0
- package/dist/plugins/skills/schema.js.map +1 -0
- package/dist/plugins/skills/skills.integration.test.js +475 -0
- package/dist/plugins/skills/skills.integration.test.js.map +1 -0
- package/dist/plugins/snapshotting/index.js +3 -0
- package/dist/plugins/snapshotting/index.js.map +1 -0
- package/dist/plugins/snapshotting/jj-snapshotter.js +106 -0
- package/dist/plugins/snapshotting/jj-snapshotter.js.map +1 -0
- package/dist/plugins/snapshotting/plugin.js +28 -0
- package/dist/plugins/snapshotting/plugin.js.map +1 -0
- package/dist/plugins/snapshotting/snapshotter.js +2 -0
- package/dist/plugins/snapshotting/snapshotter.js.map +1 -0
- package/dist/plugins/todo/index.js +7 -0
- package/dist/plugins/todo/index.js.map +1 -0
- package/dist/plugins/todo/plugin.js +319 -0
- package/dist/plugins/todo/plugin.js.map +1 -0
- package/dist/plugins/todo/prompts.js +54 -0
- package/dist/plugins/todo/prompts.js.map +1 -0
- package/dist/plugins/todo/schema.js +18 -0
- package/dist/plugins/todo/schema.js.map +1 -0
- package/dist/plugins/todo/todo.integration.test.js +605 -0
- package/dist/plugins/todo/todo.integration.test.js.map +1 -0
- package/dist/plugins/uploads/index.js +8 -0
- package/dist/plugins/uploads/index.js.map +1 -0
- package/dist/plugins/uploads/plugin.js +346 -0
- package/dist/plugins/uploads/plugin.js.map +1 -0
- package/dist/plugins/uploads/preprocessor.js +44 -0
- package/dist/plugins/uploads/preprocessor.js.map +1 -0
- package/dist/plugins/uploads/preprocessors/image-classifier.js +127 -0
- package/dist/plugins/uploads/preprocessors/image-classifier.js.map +1 -0
- package/dist/plugins/uploads/preprocessors/index.js +7 -0
- package/dist/plugins/uploads/preprocessors/index.js.map +1 -0
- package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js +204 -0
- package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js.map +1 -0
- package/dist/plugins/uploads/preprocessors/zip-preprocessor.js +172 -0
- package/dist/plugins/uploads/preprocessors/zip-preprocessor.js.map +1 -0
- package/dist/plugins/uploads/schema.js +20 -0
- package/dist/plugins/uploads/schema.js.map +1 -0
- package/dist/plugins/uploads/state.js +22 -0
- package/dist/plugins/uploads/state.js.map +1 -0
- package/dist/plugins/uploads/uploads.integration.test.js +496 -0
- package/dist/plugins/uploads/uploads.integration.test.js.map +1 -0
- package/dist/plugins/user-chat/index.js +5 -0
- package/dist/plugins/user-chat/index.js.map +1 -0
- package/dist/plugins/user-chat/plugin.js +544 -0
- package/dist/plugins/user-chat/plugin.js.map +1 -0
- package/dist/plugins/user-chat/prompts.js +29 -0
- package/dist/plugins/user-chat/prompts.js.map +1 -0
- package/dist/plugins/user-chat/schema.js +46 -0
- package/dist/plugins/user-chat/schema.js.map +1 -0
- package/dist/plugins/user-chat/user-chat.integration.test.js +668 -0
- package/dist/plugins/user-chat/user-chat.integration.test.js.map +1 -0
- package/dist/plugins/workers/context.js +143 -0
- package/dist/plugins/workers/context.js.map +1 -0
- package/dist/plugins/workers/definition.js +30 -0
- package/dist/plugins/workers/definition.js.map +1 -0
- package/dist/plugins/workers/index.js +7 -0
- package/dist/plugins/workers/index.js.map +1 -0
- package/dist/plugins/workers/plugin.js +578 -0
- package/dist/plugins/workers/plugin.js.map +1 -0
- package/dist/plugins/workers/worker.js +18 -0
- package/dist/plugins/workers/worker.js.map +1 -0
- package/dist/plugins/workers/workers.integration.test.js +629 -0
- package/dist/plugins/workers/workers.integration.test.js.map +1 -0
- package/dist/prompts/base.js +239 -0
- package/dist/prompts/base.js.map +1 -0
- package/dist/prompts/builder.js +131 -0
- package/dist/prompts/builder.js.map +1 -0
- package/dist/prompts/index.js +20 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/macros.js +26 -0
- package/dist/prompts/macros.js.map +1 -0
- package/dist/prompts/macros.test.js +80 -0
- package/dist/prompts/macros.test.js.map +1 -0
- package/dist/testing/bootstrap-for-testing.js +28 -0
- package/dist/testing/bootstrap-for-testing.js.map +1 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/node-platform.js +65 -0
- package/dist/testing/node-platform.js.map +1 -0
- package/dist/testing/notification-collector.js +82 -0
- package/dist/testing/notification-collector.js.map +1 -0
- package/dist/testing/preset-helpers.js +37 -0
- package/dist/testing/preset-helpers.js.map +1 -0
- package/dist/testing/test-harness.js +226 -0
- package/dist/testing/test-harness.js.map +1 -0
- package/dist/testing/test-harness.test.js +51 -0
- package/dist/testing/test-harness.test.js.map +1 -0
- package/dist/testing/wait-helpers.js +64 -0
- package/dist/testing/wait-helpers.js.map +1 -0
- package/dist/transport/adapter/client-adapter.js +64 -0
- package/dist/transport/adapter/client-adapter.js.map +1 -0
- package/dist/transport/adapter/index.js +24 -0
- package/dist/transport/adapter/index.js.map +1 -0
- package/dist/transport/adapter/server-adapter.js +73 -0
- package/dist/transport/adapter/server-adapter.js.map +1 -0
- package/dist/transport/adapter/types.js +8 -0
- package/dist/transport/adapter/types.js.map +1 -0
- package/dist/transport/http/app.js +86 -0
- package/dist/transport/http/app.js.map +1 -0
- package/dist/transport/http/index.js +6 -0
- package/dist/transport/http/index.js.map +1 -0
- package/dist/transport/http/middleware/bearer-auth.js +33 -0
- package/dist/transport/http/middleware/bearer-auth.js.map +1 -0
- package/dist/transport/http/middleware/error-handler.js +56 -0
- package/dist/transport/http/middleware/error-handler.js.map +1 -0
- package/dist/transport/http/routes/files.js +237 -0
- package/dist/transport/http/routes/files.js.map +1 -0
- package/dist/transport/http/routes/resources.js +77 -0
- package/dist/transport/http/routes/resources.js.map +1 -0
- package/dist/transport/http/routes/rpc.integration.test.js +189 -0
- package/dist/transport/http/routes/rpc.integration.test.js.map +1 -0
- package/dist/transport/http/routes/rpc.js +110 -0
- package/dist/transport/http/routes/rpc.js.map +1 -0
- package/dist/transport/http/routes/rpc.test.js +316 -0
- package/dist/transport/http/routes/rpc.test.js.map +1 -0
- package/dist/transport/http/routes/upload.js +205 -0
- package/dist/transport/http/routes/upload.js.map +1 -0
- package/dist/transport/rpc/index.js +7 -0
- package/dist/transport/rpc/index.js.map +1 -0
- package/dist/transport/rpc/methods.js +8 -0
- package/dist/transport/rpc/methods.js.map +1 -0
- package/dist/user-config.js +14 -0
- package/dist/user-config.js.map +1 -0
- package/package.json +47 -57
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session - OOP wrapper for session management.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Factory for agents
|
|
6
|
+
* - User output callback
|
|
7
|
+
* - Plugin method aggregation
|
|
8
|
+
*/
|
|
9
|
+
import { COMMUNICATOR_ROLE, ORCHESTRATOR_ROLE } from '../../core/agents/agent-roles.js';
|
|
10
|
+
import { generateAgentId } from '../../core/agents/schema.js';
|
|
11
|
+
import { agentEvents, getChildren } from '../../core/agents/state.js';
|
|
12
|
+
import { AgentErrors, SessionErrors, ValidationErrors } from '../../core/errors.js';
|
|
13
|
+
import { withSessionId } from '../../core/events/test-helpers.js';
|
|
14
|
+
import { applyMiddleware } from '../../core/llm/middleware.js';
|
|
15
|
+
import { AGENT_CALLER, DEFAULT_CALLER, buildPluginDeps } from '../../core/plugins/plugin-builder.js';
|
|
16
|
+
import { getEntryAgentId, getNextAgentSeq, sessionEvents } from '../../core/sessions/state.js';
|
|
17
|
+
import { Err, Ok } from '../../lib/utils/result.js';
|
|
18
|
+
import { getNextMessageSeq, selectMailboxState } from '../../plugins/mailbox/query.js';
|
|
19
|
+
import { generateMessageId } from '../../plugins/mailbox/schema.js';
|
|
20
|
+
import { mailboxEvents } from '../../plugins/mailbox/state.js';
|
|
21
|
+
import { Agent } from '../agents/agent.js';
|
|
22
|
+
import { SessionFileStore } from '../file-store/file-store.js';
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Session
|
|
25
|
+
// ============================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Session manages agents and delegates everything else to plugins.
|
|
28
|
+
*/
|
|
29
|
+
export class Session {
|
|
30
|
+
id;
|
|
31
|
+
store;
|
|
32
|
+
preset;
|
|
33
|
+
llmProvider;
|
|
34
|
+
llmProviders;
|
|
35
|
+
toolExecutor;
|
|
36
|
+
logger;
|
|
37
|
+
onUserOutput;
|
|
38
|
+
sessionDir;
|
|
39
|
+
plugins;
|
|
40
|
+
eventStore;
|
|
41
|
+
llmLogger;
|
|
42
|
+
platform;
|
|
43
|
+
agents = new Map();
|
|
44
|
+
/** Cached plugin contexts created by plugin.createContext() */
|
|
45
|
+
pluginContexts = new Map();
|
|
46
|
+
constructor(deps) {
|
|
47
|
+
this.id = deps.store.sessionId;
|
|
48
|
+
this.store = deps.store;
|
|
49
|
+
this.preset = deps.preset;
|
|
50
|
+
this.llmProvider = deps.llmProvider;
|
|
51
|
+
this.llmProviders = deps.llmProviders ?? new Map();
|
|
52
|
+
this.toolExecutor = deps.toolExecutor;
|
|
53
|
+
this.logger = deps.logger;
|
|
54
|
+
this.onUserOutput = deps.onUserOutput;
|
|
55
|
+
this.sessionDir = deps.sessionDir;
|
|
56
|
+
this.plugins = deps.plugins;
|
|
57
|
+
this.eventStore = deps.eventStore;
|
|
58
|
+
this.llmLogger = deps.llmLogger;
|
|
59
|
+
this.platform = deps.platform;
|
|
60
|
+
// Initialize agents from state
|
|
61
|
+
this.initializeAgents();
|
|
62
|
+
// React to events for agent scheduling
|
|
63
|
+
this.store.onEvent((event) => this.handleStoreEvent(event));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the current session state.
|
|
67
|
+
*/
|
|
68
|
+
get state() {
|
|
69
|
+
return this.store.getState();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get the preset configuration for this session.
|
|
73
|
+
*/
|
|
74
|
+
getPreset() {
|
|
75
|
+
return this.preset;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get the entry agent ID (communicator if present, otherwise orchestrator).
|
|
79
|
+
*/
|
|
80
|
+
getEntryAgentId() {
|
|
81
|
+
return getEntryAgentId(this.state);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initialize plugin contexts.
|
|
85
|
+
* Must be called before session hooks or plugin methods that need pluginContext.
|
|
86
|
+
*/
|
|
87
|
+
async initPluginContexts() {
|
|
88
|
+
const sessionContext = this.buildSessionContext();
|
|
89
|
+
for (const plugin of this.plugins) {
|
|
90
|
+
if (plugin.createContext) {
|
|
91
|
+
const ctx = await plugin.createContext(sessionContext);
|
|
92
|
+
this.pluginContexts.set(plugin.name, ctx);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Call onSessionReady hooks for all plugins (with full context).
|
|
98
|
+
*
|
|
99
|
+
* Only errors are persisted as events — successful runs produce no event
|
|
100
|
+
* to keep the session log focused on state changes, not invocation noise.
|
|
101
|
+
*/
|
|
102
|
+
async callSessionReadyHooks() {
|
|
103
|
+
for (const plugin of this.plugins) {
|
|
104
|
+
if (plugin.sessionHooks?.onSessionReady) {
|
|
105
|
+
const startTime = Date.now();
|
|
106
|
+
try {
|
|
107
|
+
const ctx = this.buildSessionHookContext(plugin);
|
|
108
|
+
await plugin.sessionHooks.onSessionReady(ctx);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
await this.store.emit(withSessionId(this.id, sessionEvents.create('session_handler_completed', {
|
|
112
|
+
handlerName: 'onSessionReady',
|
|
113
|
+
pluginName: plugin.name,
|
|
114
|
+
durationMs: Date.now() - startTime,
|
|
115
|
+
error: err instanceof Error ? err.message : String(err),
|
|
116
|
+
})));
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Close the session.
|
|
124
|
+
* Emits session_closed event — hooks and agent shutdown are handled reactively by handleSessionClosed().
|
|
125
|
+
*/
|
|
126
|
+
async close() {
|
|
127
|
+
if (this.store.isClosed()) {
|
|
128
|
+
return Err(SessionErrors.closed(String(this.id)));
|
|
129
|
+
}
|
|
130
|
+
await this.store.emit(withSessionId(this.id, sessionEvents.create('session_closed', {})));
|
|
131
|
+
return Ok(undefined);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Reopen a closed session.
|
|
135
|
+
*/
|
|
136
|
+
async reopen() {
|
|
137
|
+
if (!this.store.isClosed()) {
|
|
138
|
+
return Err(ValidationErrors.invalid('Session is not closed'));
|
|
139
|
+
}
|
|
140
|
+
await this.store.emit(withSessionId(this.id, sessionEvents.create('session_reopened', {})));
|
|
141
|
+
return Ok(undefined);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get an agent by ID.
|
|
145
|
+
*/
|
|
146
|
+
getAgent(agentId) {
|
|
147
|
+
return this.agents.get(agentId) ?? null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get the entry agent (communicator or orchestrator).
|
|
151
|
+
*/
|
|
152
|
+
getEntryAgent() {
|
|
153
|
+
const entryId = getEntryAgentId(this.state);
|
|
154
|
+
if (!entryId)
|
|
155
|
+
return null;
|
|
156
|
+
return this.agents.get(entryId) ?? null;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Schedule agent processing (with debounce).
|
|
160
|
+
*/
|
|
161
|
+
scheduleAgent(agentId) {
|
|
162
|
+
const agent = this.agents.get(agentId);
|
|
163
|
+
if (agent) {
|
|
164
|
+
agent.scheduleProcessing();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Force process an agent (bypass debounce).
|
|
169
|
+
*/
|
|
170
|
+
async forceProcessAgent(agentId) {
|
|
171
|
+
const agent = this.agents.get(agentId);
|
|
172
|
+
if (agent) {
|
|
173
|
+
await agent.continue();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Resume a paused agent so it can continue processing.
|
|
178
|
+
*/
|
|
179
|
+
async resumeAgent(agentId) {
|
|
180
|
+
if (this.store.isClosed()) {
|
|
181
|
+
return Err(SessionErrors.closed(String(this.id)));
|
|
182
|
+
}
|
|
183
|
+
const agent = this.agents.get(agentId);
|
|
184
|
+
if (!agent) {
|
|
185
|
+
return Err(AgentErrors.notFound(String(agentId)));
|
|
186
|
+
}
|
|
187
|
+
const agentState = this.store.getAgentState(agentId);
|
|
188
|
+
if (!agentState || (agentState.status !== 'paused' && agentState.status !== 'errored')) {
|
|
189
|
+
return Err(ValidationErrors.invalid('Agent is not paused or errored'));
|
|
190
|
+
}
|
|
191
|
+
await this.store.emit(withSessionId(this.id, agentEvents.create('agent_resumed', {
|
|
192
|
+
agentId,
|
|
193
|
+
})));
|
|
194
|
+
agent.continue().catch((err) => {
|
|
195
|
+
this.logger.error('Unhandled error in agent.continue()', err instanceof Error ? err : undefined, { sessionId: this.id, agentId });
|
|
196
|
+
});
|
|
197
|
+
this.logger.info('Agent resumed', { sessionId: this.id, agentId });
|
|
198
|
+
return Ok(undefined);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Pause an agent manually via API.
|
|
202
|
+
*/
|
|
203
|
+
async pauseAgent(agentId, message) {
|
|
204
|
+
if (this.store.isClosed()) {
|
|
205
|
+
return Err(SessionErrors.closed(String(this.id)));
|
|
206
|
+
}
|
|
207
|
+
const agent = this.agents.get(agentId);
|
|
208
|
+
if (!agent) {
|
|
209
|
+
return Err(AgentErrors.notFound(String(agentId)));
|
|
210
|
+
}
|
|
211
|
+
const agentState = this.store.getAgentState(agentId);
|
|
212
|
+
if (!agentState || agentState.status === 'paused') {
|
|
213
|
+
return Err(ValidationErrors.invalid('Agent is already paused'));
|
|
214
|
+
}
|
|
215
|
+
await this.store.emit(withSessionId(this.id, agentEvents.create('agent_paused', {
|
|
216
|
+
agentId,
|
|
217
|
+
reason: 'manual',
|
|
218
|
+
message,
|
|
219
|
+
})));
|
|
220
|
+
this.logger.info('Agent paused', { sessionId: this.id, agentId });
|
|
221
|
+
return Ok(undefined);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Manually spawn an agent under a given parent.
|
|
225
|
+
*/
|
|
226
|
+
async spawnAgentManually(definitionName, parentId, message, typedInput) {
|
|
227
|
+
if (this.store.isClosed()) {
|
|
228
|
+
return Err(SessionErrors.closed(String(this.id)));
|
|
229
|
+
}
|
|
230
|
+
// Validate parent exists
|
|
231
|
+
if (!this.agents.has(parentId)) {
|
|
232
|
+
return Err(AgentErrors.notFound(String(parentId)));
|
|
233
|
+
}
|
|
234
|
+
// Validate definition exists in preset
|
|
235
|
+
const isOrchestrator = definitionName === ORCHESTRATOR_ROLE;
|
|
236
|
+
const isCommunicator = definitionName === COMMUNICATOR_ROLE && !!this.preset.communicator;
|
|
237
|
+
const isAgent = this.preset.agents.some((a) => a.name === definitionName);
|
|
238
|
+
if (!isOrchestrator && !isCommunicator && !isAgent) {
|
|
239
|
+
return Err(ValidationErrors.invalid(`Agent definition not found: ${definitionName}`));
|
|
240
|
+
}
|
|
241
|
+
// Validate parent is authorized to spawn this definition
|
|
242
|
+
const parentState = this.store.getAgentState(parentId);
|
|
243
|
+
if (parentState) {
|
|
244
|
+
const parentConfig = this.getAgentConfig(parentState.definitionName);
|
|
245
|
+
if (parentConfig.spawnableAgents.length > 0 && !parentConfig.spawnableAgents.includes(definitionName)) {
|
|
246
|
+
return Err(ValidationErrors.invalid(`Agent '${parentState.definitionName}' is not authorized to spawn '${definitionName}'`));
|
|
247
|
+
}
|
|
248
|
+
// Enforce max child agents per parent (default: 20)
|
|
249
|
+
const children = getChildren(this.state, parentId);
|
|
250
|
+
const maxChildren = 20;
|
|
251
|
+
if (children.length >= maxChildren) {
|
|
252
|
+
return Err(ValidationErrors.invalid(`Agent '${parentId}' has reached max child agent limit (${maxChildren})`));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const seq = getNextAgentSeq(this.state, definitionName);
|
|
256
|
+
const agentId = generateAgentId(definitionName, seq);
|
|
257
|
+
const now = Date.now();
|
|
258
|
+
const events = [
|
|
259
|
+
withSessionId(this.id, agentEvents.create('agent_spawned', {
|
|
260
|
+
agentId,
|
|
261
|
+
definitionName,
|
|
262
|
+
parentId,
|
|
263
|
+
...(typedInput !== undefined ? { typedInput } : {}),
|
|
264
|
+
})),
|
|
265
|
+
];
|
|
266
|
+
if (message) {
|
|
267
|
+
const messageId = generateMessageId(getNextMessageSeq(selectMailboxState(this.state)) + 1);
|
|
268
|
+
events.push(withSessionId(this.id, mailboxEvents.create('mailbox_message', {
|
|
269
|
+
toAgentId: agentId,
|
|
270
|
+
message: {
|
|
271
|
+
id: messageId,
|
|
272
|
+
from: parentId,
|
|
273
|
+
content: message,
|
|
274
|
+
timestamp: now,
|
|
275
|
+
consumed: false,
|
|
276
|
+
},
|
|
277
|
+
})));
|
|
278
|
+
}
|
|
279
|
+
await this.store.emitBatch(events);
|
|
280
|
+
this.logger.debug('Agent spawned manually', {
|
|
281
|
+
sessionId: this.id,
|
|
282
|
+
agentId,
|
|
283
|
+
definitionName,
|
|
284
|
+
parentId,
|
|
285
|
+
});
|
|
286
|
+
return Ok(agentId);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Shutdown the session - stop all agent processing.
|
|
290
|
+
*/
|
|
291
|
+
shutdown() {
|
|
292
|
+
for (const agent of this.agents.values()) {
|
|
293
|
+
try {
|
|
294
|
+
agent.shutdown();
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
// Suppress errors during shutdown
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Check if a session has any agents that need processing.
|
|
303
|
+
*/
|
|
304
|
+
checkPendingAgents() {
|
|
305
|
+
for (const agent of this.agents.values()) {
|
|
306
|
+
agent.continue().catch((err) => {
|
|
307
|
+
this.logger.error('Unhandled error in agent.continue()', err instanceof Error ? err : undefined, { sessionId: this.id, agentId: agent.id });
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Aggregate methods from all plugins.
|
|
313
|
+
* Returns a map of "pluginName.methodName" → { input, output, handler }.
|
|
314
|
+
*/
|
|
315
|
+
getPluginMethods() {
|
|
316
|
+
const methods = new Map();
|
|
317
|
+
for (const plugin of this.plugins) {
|
|
318
|
+
for (const [methodName, methodDef] of Object.entries(plugin.methods)) {
|
|
319
|
+
methods.set(`${plugin.name}.${methodName}`, methodDef);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return methods;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Call a plugin method with properly constructed MethodHandlerContext.
|
|
326
|
+
* The context includes pluginState, pluginConfig (bound in closure),
|
|
327
|
+
* pluginContext, and scheduleAgent.
|
|
328
|
+
*/
|
|
329
|
+
async callPluginMethod(method, input, agentId, caller) {
|
|
330
|
+
// Find the plugin and method by parsing "pluginName.methodName"
|
|
331
|
+
const dotIndex = method.indexOf('.');
|
|
332
|
+
if (dotIndex === -1) {
|
|
333
|
+
return Err(ValidationErrors.invalid(`Invalid method format: ${method}`));
|
|
334
|
+
}
|
|
335
|
+
const pluginName = method.slice(0, dotIndex);
|
|
336
|
+
const methodName = method.slice(dotIndex + 1);
|
|
337
|
+
const plugin = this.plugins.find((p) => p.name === pluginName);
|
|
338
|
+
if (!plugin) {
|
|
339
|
+
return Err(ValidationErrors.invalid(`Unknown plugin: ${pluginName}`));
|
|
340
|
+
}
|
|
341
|
+
const methodDef = plugin.methods[methodName];
|
|
342
|
+
if (!methodDef) {
|
|
343
|
+
return Err(ValidationErrors.invalid(`Unknown method: ${method}`));
|
|
344
|
+
}
|
|
345
|
+
// Validate input
|
|
346
|
+
const parsed = methodDef.input.safeParse(input);
|
|
347
|
+
if (!parsed.success) {
|
|
348
|
+
return Err(ValidationErrors.invalid(`Invalid input for ${method}: ${parsed.error.message}`));
|
|
349
|
+
}
|
|
350
|
+
// Build MethodHandlerContext with plugin state, context, scheduleAgent, notify, and deps
|
|
351
|
+
const sessionContext = this.buildSessionContext();
|
|
352
|
+
const pluginState = plugin.slice ? plugin.slice.select(this.store.getState()) : undefined;
|
|
353
|
+
const pluginContext = this.pluginContexts.get(pluginName);
|
|
354
|
+
const deps = this.buildPluginDeps(plugin);
|
|
355
|
+
const ctx = {
|
|
356
|
+
...sessionContext,
|
|
357
|
+
caller: caller ?? DEFAULT_CALLER,
|
|
358
|
+
logger: this.logger.child({ method, agentId }),
|
|
359
|
+
pluginConfig: undefined,
|
|
360
|
+
pluginContext,
|
|
361
|
+
pluginState,
|
|
362
|
+
scheduleAgent: (targetAgentId) => this.scheduleAgent(targetAgentId),
|
|
363
|
+
notify: this.createNotify(pluginName),
|
|
364
|
+
deps,
|
|
365
|
+
};
|
|
366
|
+
const result = await methodDef.handler(ctx, parsed.data);
|
|
367
|
+
return result;
|
|
368
|
+
}
|
|
369
|
+
// ============================================================================
|
|
370
|
+
// Private methods
|
|
371
|
+
// ============================================================================
|
|
372
|
+
/**
|
|
373
|
+
* Initialize agents from session state.
|
|
374
|
+
*/
|
|
375
|
+
initializeAgents() {
|
|
376
|
+
for (const [agentId, agentState] of this.state.agents) {
|
|
377
|
+
const agent = this.createAgent(agentState);
|
|
378
|
+
this.agents.set(agentId, agent);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Create an Agent instance from state.
|
|
383
|
+
*/
|
|
384
|
+
createAgent(agentState) {
|
|
385
|
+
const config = this.getAgentConfig(agentState.definitionName);
|
|
386
|
+
// Filter plugins by isEnabled for this specific agent
|
|
387
|
+
const agentPlugins = this.plugins.filter((plugin) => {
|
|
388
|
+
if (!plugin.isEnabled)
|
|
389
|
+
return true;
|
|
390
|
+
return plugin.isEnabled({
|
|
391
|
+
pluginConfig: undefined, // injected by plugin builder wrapper
|
|
392
|
+
pluginAgentConfig: config.plugins?.find(c => c.pluginName === plugin.name)?.config,
|
|
393
|
+
agentConfig: config,
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
const env = this.getSessionEnvironment();
|
|
397
|
+
const fileStore = new SessionFileStore(env.sessionDir, env.workspaceDir, env.sandboxed, this.platform.fs);
|
|
398
|
+
// Apply LLM middleware chain: preset-level → agent-level → base provider
|
|
399
|
+
const agentMiddleware = this.getAgentMiddleware(agentState.definitionName);
|
|
400
|
+
const middleware = [
|
|
401
|
+
...(this.preset.llmMiddleware ?? []),
|
|
402
|
+
...agentMiddleware,
|
|
403
|
+
];
|
|
404
|
+
const llmProvider = applyMiddleware(this.llmProvider, middleware);
|
|
405
|
+
return new Agent({
|
|
406
|
+
id: agentState.id,
|
|
407
|
+
sessionContext: {
|
|
408
|
+
sessionId: this.id,
|
|
409
|
+
sessionState: this.store.getState(),
|
|
410
|
+
sessionInput: undefined,
|
|
411
|
+
environment: env,
|
|
412
|
+
llm: this.llmProvider,
|
|
413
|
+
files: fileStore,
|
|
414
|
+
eventStore: this.eventStore,
|
|
415
|
+
llmLogger: this.llmLogger,
|
|
416
|
+
platform: this.platform,
|
|
417
|
+
logger: this.logger,
|
|
418
|
+
emitEvent: async (event) => {
|
|
419
|
+
await this.store.emit(withSessionId(this.id, event));
|
|
420
|
+
},
|
|
421
|
+
notify: (type, payload) => {
|
|
422
|
+
this.onUserOutput?.({ pluginName: '_agent', type, payload });
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
store: this.store,
|
|
426
|
+
llmProvider,
|
|
427
|
+
llmProviders: this.llmProviders,
|
|
428
|
+
toolExecutor: this.toolExecutor,
|
|
429
|
+
logger: this.logger.child({ agentId: agentState.id }),
|
|
430
|
+
config,
|
|
431
|
+
plugins: agentPlugins,
|
|
432
|
+
environment: env,
|
|
433
|
+
fileStore,
|
|
434
|
+
pluginContexts: this.pluginContexts,
|
|
435
|
+
sendNotification: (n) => this.onUserOutput?.(n),
|
|
436
|
+
pluginMethodCaller: async (depPluginName, methodName, input) => {
|
|
437
|
+
return await this.callPluginMethod(`${depPluginName}.${methodName}`, input, agentState.id, AGENT_CALLER);
|
|
438
|
+
},
|
|
439
|
+
schedule: () => this.scheduleAgent(agentState.id),
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Handle events emitted to the store — reactive scheduling.
|
|
444
|
+
*/
|
|
445
|
+
handleStoreEvent(event) {
|
|
446
|
+
switch (event.type) {
|
|
447
|
+
case 'agent_spawned': {
|
|
448
|
+
const spawned = event;
|
|
449
|
+
this.handleAgentSpawned(spawned.agentId);
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
case 'session_closed': {
|
|
453
|
+
this.handleSessionClosed().catch((err) => {
|
|
454
|
+
this.logger.error('Unhandled error in handleSessionClosed()', err instanceof Error ? err : undefined, { sessionId: this.id });
|
|
455
|
+
});
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Handle session_closed event — call close hooks and shutdown agents.
|
|
462
|
+
*
|
|
463
|
+
* Unlike onSessionReady (which re-throws), onSessionClose intentionally
|
|
464
|
+
* swallows per-plugin errors so that all plugins get a chance to clean up
|
|
465
|
+
* and agents are always shut down, even if one plugin's close hook fails.
|
|
466
|
+
*/
|
|
467
|
+
async handleSessionClosed() {
|
|
468
|
+
// Call onSessionClose for all plugins in REVERSE order (per-plugin isolation)
|
|
469
|
+
const reversedPlugins = [...this.plugins].reverse();
|
|
470
|
+
for (const plugin of reversedPlugins) {
|
|
471
|
+
if (plugin.sessionHooks?.onSessionClose) {
|
|
472
|
+
try {
|
|
473
|
+
const ctx = this.buildSessionHookContext(plugin);
|
|
474
|
+
await plugin.sessionHooks.onSessionClose(ctx);
|
|
475
|
+
}
|
|
476
|
+
catch (err) {
|
|
477
|
+
this.logger.error(`Session plugin '${plugin.name}' onSessionClose failed`, err instanceof Error ? err : new Error(String(err)), {
|
|
478
|
+
sessionId: this.id,
|
|
479
|
+
pluginName: plugin.name,
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Shutdown all agents
|
|
485
|
+
for (const agent of this.agents.values()) {
|
|
486
|
+
try {
|
|
487
|
+
agent.shutdown();
|
|
488
|
+
}
|
|
489
|
+
catch {
|
|
490
|
+
// Suppress errors during shutdown (e.g. AbortError from abort signal listeners)
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
// Clean up references to prevent memory leaks
|
|
494
|
+
this.agents.clear();
|
|
495
|
+
this.pluginContexts.clear();
|
|
496
|
+
this.store.clearListeners();
|
|
497
|
+
this.logger.info('Session closed', { sessionId: this.id });
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Handle newly spawned agent.
|
|
501
|
+
*/
|
|
502
|
+
handleAgentSpawned(agentId) {
|
|
503
|
+
// Guard: skip if agent already initialized (e.g., from initializeAgents)
|
|
504
|
+
if (this.agents.has(agentId))
|
|
505
|
+
return;
|
|
506
|
+
const agentState = this.store.getAgentState(agentId);
|
|
507
|
+
if (!agentState) {
|
|
508
|
+
this.logger.error('Spawned agent not found in state', undefined, {
|
|
509
|
+
sessionId: this.id,
|
|
510
|
+
agentId,
|
|
511
|
+
});
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
// Create and register the new agent
|
|
515
|
+
const agent = this.createAgent(agentState);
|
|
516
|
+
this.agents.set(agentId, agent);
|
|
517
|
+
// Schedule processing (with debounce) for the new agent
|
|
518
|
+
agent.scheduleProcessing();
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Handle user-facing output events.
|
|
522
|
+
*/
|
|
523
|
+
/**
|
|
524
|
+
* Create a notify function bound to a specific plugin name.
|
|
525
|
+
*/
|
|
526
|
+
createNotify(pluginName) {
|
|
527
|
+
return (type, payload) => {
|
|
528
|
+
this.onUserOutput?.({ pluginName, type, payload });
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Build deps object for a plugin — delegates method calls to callPluginMethod.
|
|
533
|
+
*/
|
|
534
|
+
buildPluginDeps(plugin) {
|
|
535
|
+
return buildPluginDeps(plugin.dependencyNames, this.plugins, async (depPluginName, methodName, input) => {
|
|
536
|
+
return await this.callPluginMethod(`${depPluginName}.${methodName}`, input);
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Build a SessionContext from current session state.
|
|
541
|
+
*/
|
|
542
|
+
buildSessionContext() {
|
|
543
|
+
const env = this.getSessionEnvironment();
|
|
544
|
+
const fileStore = new SessionFileStore(env.sessionDir, env.workspaceDir, env.sandboxed, this.platform.fs);
|
|
545
|
+
return {
|
|
546
|
+
sessionId: this.id,
|
|
547
|
+
sessionState: this.store.getState(),
|
|
548
|
+
sessionInput: undefined,
|
|
549
|
+
environment: env,
|
|
550
|
+
llm: this.llmProvider,
|
|
551
|
+
files: fileStore,
|
|
552
|
+
eventStore: this.eventStore,
|
|
553
|
+
llmLogger: this.llmLogger,
|
|
554
|
+
platform: this.platform,
|
|
555
|
+
logger: this.logger,
|
|
556
|
+
emitEvent: async (event) => {
|
|
557
|
+
await this.store.emit(withSessionId(this.id, event));
|
|
558
|
+
},
|
|
559
|
+
notify: (type, payload) => {
|
|
560
|
+
this.onUserOutput?.({ pluginName: '_session', type, payload });
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Build context for a session-level hook (onSessionReady / onSessionClose).
|
|
566
|
+
* Provides pluginConfig (via closure), pluginContext, pluginState, self, and session fields.
|
|
567
|
+
*/
|
|
568
|
+
buildSessionHookContext(plugin) {
|
|
569
|
+
const sessionContext = this.buildSessionContext();
|
|
570
|
+
const pluginState = plugin.slice ? plugin.slice.select(this.store.getState()) : undefined;
|
|
571
|
+
const pluginContext = this.pluginContexts.get(plugin.name);
|
|
572
|
+
// Build self — typed method callers (routed through callPluginMethod for proper context)
|
|
573
|
+
const self = {};
|
|
574
|
+
for (const [methodName] of Object.entries(plugin.methods)) {
|
|
575
|
+
self[methodName] = async (input) => {
|
|
576
|
+
const result = await this.callPluginMethod(`${plugin.name}.${methodName}`, input, undefined, AGENT_CALLER);
|
|
577
|
+
if (!result.ok) {
|
|
578
|
+
throw new Error(`Plugin method failed: ${plugin.name}.${methodName}: ${result.error.type}`);
|
|
579
|
+
}
|
|
580
|
+
return result.value;
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
const deps = this.buildPluginDeps(plugin);
|
|
584
|
+
return {
|
|
585
|
+
...sessionContext,
|
|
586
|
+
caller: AGENT_CALLER,
|
|
587
|
+
pluginConfig: undefined, // injected by plugin builder wrapper
|
|
588
|
+
pluginContext,
|
|
589
|
+
pluginState,
|
|
590
|
+
self,
|
|
591
|
+
scheduleAgent: (agentId) => this.scheduleAgent(agentId),
|
|
592
|
+
notify: this.createNotify(plugin.name),
|
|
593
|
+
deps,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Get session environment for tool context.
|
|
598
|
+
*/
|
|
599
|
+
getSessionEnvironment() {
|
|
600
|
+
return {
|
|
601
|
+
sessionDir: this.sessionDir,
|
|
602
|
+
workspaceDir: this.state.workspaceDir,
|
|
603
|
+
sandboxed: this.preset.sandboxed ?? false,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get LLM middleware from the agent/orchestrator/communicator definition.
|
|
608
|
+
*/
|
|
609
|
+
getAgentMiddleware(definitionName) {
|
|
610
|
+
if (definitionName === ORCHESTRATOR_ROLE)
|
|
611
|
+
return this.preset.orchestrator.llmMiddleware ?? [];
|
|
612
|
+
if (definitionName === COMMUNICATOR_ROLE)
|
|
613
|
+
return this.preset.communicator?.llmMiddleware ?? [];
|
|
614
|
+
return this.preset.agents.find(a => a.name === definitionName)?.llmMiddleware ?? [];
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Get agent config from preset definition.
|
|
618
|
+
* Tools are provided by plugins (Agent collects from plugins).
|
|
619
|
+
*/
|
|
620
|
+
getAgentConfig(definitionName) {
|
|
621
|
+
const withServicePluginConfig = (config) => {
|
|
622
|
+
const base = config.plugins ?? [];
|
|
623
|
+
if (!config.services || config.services.length === 0)
|
|
624
|
+
return base.length > 0 ? base : undefined;
|
|
625
|
+
// Merge services config into plugins array (if not already present)
|
|
626
|
+
if (base.some(c => c.pluginName === 'services'))
|
|
627
|
+
return base;
|
|
628
|
+
return [...base, { pluginName: 'services', config: { services: config.services.map(s => s.type) } }];
|
|
629
|
+
};
|
|
630
|
+
if (definitionName === ORCHESTRATOR_ROLE) {
|
|
631
|
+
const orch = this.preset.orchestrator;
|
|
632
|
+
return {
|
|
633
|
+
systemPrompt: orch.system,
|
|
634
|
+
model: orch.model,
|
|
635
|
+
spawnableAgents: orch.agents ?? [],
|
|
636
|
+
tools: orch.tools,
|
|
637
|
+
debounceMs: orch.debounceMs,
|
|
638
|
+
debounceCallback: orch.debounceCallback,
|
|
639
|
+
checkIntervalMs: orch.checkIntervalMs,
|
|
640
|
+
input: orch.input,
|
|
641
|
+
plugins: withServicePluginConfig(orch),
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
if (definitionName === COMMUNICATOR_ROLE && this.preset.communicator) {
|
|
645
|
+
const comm = this.preset.communicator;
|
|
646
|
+
return {
|
|
647
|
+
systemPrompt: comm.system,
|
|
648
|
+
model: comm.model,
|
|
649
|
+
spawnableAgents: comm.agents ?? [],
|
|
650
|
+
tools: comm.tools,
|
|
651
|
+
debounceMs: comm.debounceMs,
|
|
652
|
+
debounceCallback: comm.debounceCallback,
|
|
653
|
+
checkIntervalMs: comm.checkIntervalMs,
|
|
654
|
+
input: comm.input,
|
|
655
|
+
plugins: withServicePluginConfig(comm),
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
const agentDef = this.preset.agents.find((a) => a.name === definitionName);
|
|
659
|
+
if (!agentDef) {
|
|
660
|
+
throw new Error(`Agent definition not found: ${definitionName}`);
|
|
661
|
+
}
|
|
662
|
+
return {
|
|
663
|
+
systemPrompt: agentDef.system,
|
|
664
|
+
model: agentDef.model,
|
|
665
|
+
spawnableAgents: agentDef.agents ?? [],
|
|
666
|
+
tools: agentDef.tools,
|
|
667
|
+
debounceMs: agentDef.debounceMs,
|
|
668
|
+
debounceCallback: agentDef.debounceCallback,
|
|
669
|
+
checkIntervalMs: agentDef.checkIntervalMs,
|
|
670
|
+
input: agentDef.input,
|
|
671
|
+
plugins: withServicePluginConfig(agentDef),
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
//# sourceMappingURL=session.js.map
|