@roj-ai/sdk 0.1.3 → 0.1.4
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,605 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { AgentId } from '../../core/agents/schema.js';
|
|
3
|
+
import { MockLLMProvider } from '../../core/llm/mock.js';
|
|
4
|
+
import { ToolCallId } from '../../core/tools/schema.js';
|
|
5
|
+
import { createMultiAgentPreset, createTestPreset, TestHarness } from '../../testing/index.js';
|
|
6
|
+
import { getAgentMailbox, getAgentUnconsumedMailbox, mailboxEvents, selectMailboxState } from './index.js';
|
|
7
|
+
describe('mailbox plugin', () => {
|
|
8
|
+
// =========================================================================
|
|
9
|
+
// send_message tool
|
|
10
|
+
// =========================================================================
|
|
11
|
+
describe('send_message tool', () => {
|
|
12
|
+
it('send_message with to: parent → parent receives message in dequeue', async () => {
|
|
13
|
+
let orchestratorCalls = 0;
|
|
14
|
+
let workerCalls = 0;
|
|
15
|
+
let orchestratorSawWorkerMessage = false;
|
|
16
|
+
const harness = new TestHarness({
|
|
17
|
+
presets: [createMultiAgentPreset([
|
|
18
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
19
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
20
|
+
mockHandler: (request) => {
|
|
21
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
22
|
+
orchestratorCalls++;
|
|
23
|
+
if (orchestratorCalls === 1) {
|
|
24
|
+
return {
|
|
25
|
+
content: null,
|
|
26
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Do some work' } }],
|
|
27
|
+
finishReason: 'stop',
|
|
28
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const lastMsg = request.messages[request.messages.length - 1];
|
|
32
|
+
if (typeof lastMsg?.content === 'string' && lastMsg.content.includes('Hello from worker')) {
|
|
33
|
+
orchestratorSawWorkerMessage = true;
|
|
34
|
+
}
|
|
35
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
36
|
+
}
|
|
37
|
+
workerCalls++;
|
|
38
|
+
if (workerCalls === 1) {
|
|
39
|
+
return {
|
|
40
|
+
content: null,
|
|
41
|
+
toolCalls: [{ id: ToolCallId('tc2'), name: 'send_message', input: { to: 'parent', message: 'Hello from worker' } }],
|
|
42
|
+
finishReason: 'stop',
|
|
43
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const session = await harness.createSession('test');
|
|
50
|
+
await session.sendAndWaitForIdle('Start');
|
|
51
|
+
expect(orchestratorSawWorkerMessage).toBe(true);
|
|
52
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
53
|
+
const workerToParent = events.filter(e => e.message.content === 'Hello from worker');
|
|
54
|
+
expect(workerToParent).toHaveLength(1);
|
|
55
|
+
expect(workerToParent[0].toAgentId).toBe(session.getEntryAgentId());
|
|
56
|
+
await harness.shutdown();
|
|
57
|
+
});
|
|
58
|
+
it('send_message with to: childAgentId → child receives message in dequeue', async () => {
|
|
59
|
+
let orchestratorCalls = 0;
|
|
60
|
+
let workerSawExtraMessage = false;
|
|
61
|
+
const harness = new TestHarness({
|
|
62
|
+
presets: [createMultiAgentPreset([
|
|
63
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
64
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
65
|
+
mockHandler: (request) => {
|
|
66
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
67
|
+
orchestratorCalls++;
|
|
68
|
+
if (orchestratorCalls === 1) {
|
|
69
|
+
return {
|
|
70
|
+
content: null,
|
|
71
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Initial task' } }],
|
|
72
|
+
finishReason: 'stop',
|
|
73
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (orchestratorCalls === 2) {
|
|
77
|
+
return {
|
|
78
|
+
content: null,
|
|
79
|
+
toolCalls: [{ id: ToolCallId('tc2'), name: 'send_message', input: { to: 'worker_1', message: 'Extra task for you' } }],
|
|
80
|
+
finishReason: 'stop',
|
|
81
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
85
|
+
}
|
|
86
|
+
if (request.messages.some(m => typeof m.content === 'string' && m.content.includes('Extra task for you'))) {
|
|
87
|
+
workerSawExtraMessage = true;
|
|
88
|
+
}
|
|
89
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
const session = await harness.createSession('test');
|
|
93
|
+
await session.sendAndWaitForIdle('Start');
|
|
94
|
+
expect(workerSawExtraMessage).toBe(true);
|
|
95
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
96
|
+
const orchToWorker = events.filter(e => e.message.content === 'Extra task for you');
|
|
97
|
+
expect(orchToWorker).toHaveLength(1);
|
|
98
|
+
expect(orchToWorker[0].toAgentId).toBe(AgentId('worker_1'));
|
|
99
|
+
await harness.shutdown();
|
|
100
|
+
});
|
|
101
|
+
it('send_message to invalid target → tool returns error with allowed agents', async () => {
|
|
102
|
+
let orchestratorCalls = 0;
|
|
103
|
+
let workerCalls = 0;
|
|
104
|
+
let workerReceivedErrorAboutTarget = false;
|
|
105
|
+
const harness = new TestHarness({
|
|
106
|
+
presets: [createMultiAgentPreset([
|
|
107
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
108
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
109
|
+
mockHandler: (request) => {
|
|
110
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
111
|
+
orchestratorCalls++;
|
|
112
|
+
if (orchestratorCalls === 1) {
|
|
113
|
+
return {
|
|
114
|
+
content: null,
|
|
115
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Do work' } }],
|
|
116
|
+
finishReason: 'stop',
|
|
117
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
121
|
+
}
|
|
122
|
+
workerCalls++;
|
|
123
|
+
if (workerCalls === 1) {
|
|
124
|
+
return {
|
|
125
|
+
content: null,
|
|
126
|
+
toolCalls: [{ id: ToolCallId('tc2'), name: 'send_message', input: { to: 'nonexistent_agent', message: 'Should fail' } }],
|
|
127
|
+
finishReason: 'stop',
|
|
128
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// Second call: verify the tool result contains the error about invalid target
|
|
132
|
+
const toolMessages = request.messages.filter(m => m.role === 'tool');
|
|
133
|
+
if (toolMessages.some(m => typeof m.content === 'string' && m.content.includes('Cannot send message'))) {
|
|
134
|
+
workerReceivedErrorAboutTarget = true;
|
|
135
|
+
}
|
|
136
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
const session = await harness.createSession('test');
|
|
140
|
+
await session.sendAndWaitForIdle('Start');
|
|
141
|
+
// No mailbox_message for invalid target
|
|
142
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
143
|
+
const invalidMessages = events.filter(e => e.message.content === 'Should fail');
|
|
144
|
+
expect(invalidMessages).toHaveLength(0);
|
|
145
|
+
// Worker was called exactly twice (tool call + error result)
|
|
146
|
+
expect(workerCalls).toBe(2);
|
|
147
|
+
// Worker received error message about invalid target with allowed agents
|
|
148
|
+
expect(workerReceivedErrorAboutTarget).toBe(true);
|
|
149
|
+
await harness.shutdown();
|
|
150
|
+
});
|
|
151
|
+
it('mailbox_message event emitted with correct from/to/content', async () => {
|
|
152
|
+
let orchestratorCalls = 0;
|
|
153
|
+
let workerCalls = 0;
|
|
154
|
+
const harness = new TestHarness({
|
|
155
|
+
presets: [createMultiAgentPreset([
|
|
156
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
157
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
158
|
+
mockHandler: (request) => {
|
|
159
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
160
|
+
orchestratorCalls++;
|
|
161
|
+
if (orchestratorCalls === 1) {
|
|
162
|
+
return {
|
|
163
|
+
content: null,
|
|
164
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Task content' } }],
|
|
165
|
+
finishReason: 'stop',
|
|
166
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
170
|
+
}
|
|
171
|
+
workerCalls++;
|
|
172
|
+
if (workerCalls === 1) {
|
|
173
|
+
return {
|
|
174
|
+
content: null,
|
|
175
|
+
toolCalls: [{ id: ToolCallId('tc2'), name: 'send_message', input: { to: 'parent', message: 'Result payload' } }],
|
|
176
|
+
finishReason: 'stop',
|
|
177
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
const session = await harness.createSession('test');
|
|
184
|
+
await session.sendAndWaitForIdle('Start');
|
|
185
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
186
|
+
const workerMessage = events.find(e => e.message.content === 'Result payload');
|
|
187
|
+
expect(workerMessage).toBeDefined();
|
|
188
|
+
expect(workerMessage.toAgentId).toBe(session.getEntryAgentId());
|
|
189
|
+
expect(workerMessage.message.from).toBe(AgentId('worker_1'));
|
|
190
|
+
expect(workerMessage.message.consumed).toBe(false);
|
|
191
|
+
expect(workerMessage.message.timestamp).toBeGreaterThan(0);
|
|
192
|
+
expect(workerMessage.message.id).toBeDefined();
|
|
193
|
+
await harness.shutdown();
|
|
194
|
+
});
|
|
195
|
+
it('idle agent re-scheduled when message sent via direct mailbox.send', async () => {
|
|
196
|
+
let orchestratorCalls = 0;
|
|
197
|
+
let workerCalls = 0;
|
|
198
|
+
let workerSawFollowUp = false;
|
|
199
|
+
const harness = new TestHarness({
|
|
200
|
+
presets: [createMultiAgentPreset([
|
|
201
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
202
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
203
|
+
mockHandler: (request) => {
|
|
204
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
205
|
+
orchestratorCalls++;
|
|
206
|
+
if (orchestratorCalls === 1) {
|
|
207
|
+
return {
|
|
208
|
+
content: null,
|
|
209
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Initial work' } }],
|
|
210
|
+
finishReason: 'stop',
|
|
211
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
215
|
+
}
|
|
216
|
+
workerCalls++;
|
|
217
|
+
const lastMsg = request.messages[request.messages.length - 1];
|
|
218
|
+
if (typeof lastMsg?.content === 'string' && lastMsg.content.includes('Follow-up task')) {
|
|
219
|
+
workerSawFollowUp = true;
|
|
220
|
+
}
|
|
221
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
const session = await harness.createSession('test');
|
|
225
|
+
await session.sendAndWaitForIdle('Start');
|
|
226
|
+
// Worker processed initial message and became idle
|
|
227
|
+
expect(workerCalls).toBe(1);
|
|
228
|
+
// Send a follow-up message directly — should re-schedule the idle worker
|
|
229
|
+
const result = await session.callPluginMethod('mailbox.send', {
|
|
230
|
+
fromAgentId: String(session.getEntryAgentId()),
|
|
231
|
+
toAgentId: 'worker_1',
|
|
232
|
+
content: 'Follow-up task',
|
|
233
|
+
});
|
|
234
|
+
expect(result.ok).toBe(true);
|
|
235
|
+
await session.waitForIdle();
|
|
236
|
+
// Worker was re-scheduled and processed the new message
|
|
237
|
+
expect(workerCalls).toBe(2);
|
|
238
|
+
expect(workerSawFollowUp).toBe(true);
|
|
239
|
+
await harness.shutdown();
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
// =========================================================================
|
|
243
|
+
// dequeue
|
|
244
|
+
// =========================================================================
|
|
245
|
+
describe('dequeue', () => {
|
|
246
|
+
it('unconsumed messages delivered to agent as LLM user message before inference', async () => {
|
|
247
|
+
let orchestratorCalls = 0;
|
|
248
|
+
const harness = new TestHarness({
|
|
249
|
+
presets: [createMultiAgentPreset([
|
|
250
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
251
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
252
|
+
mockHandler: (request) => {
|
|
253
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
254
|
+
orchestratorCalls++;
|
|
255
|
+
if (orchestratorCalls === 1) {
|
|
256
|
+
return {
|
|
257
|
+
content: null,
|
|
258
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Process this data' } }],
|
|
259
|
+
finishReason: 'stop',
|
|
260
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
264
|
+
}
|
|
265
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
const session = await harness.createSession('test');
|
|
269
|
+
await session.sendAndWaitForIdle('Start');
|
|
270
|
+
// Find the worker's LLM request
|
|
271
|
+
const calls = harness.llmProvider.getCallHistory();
|
|
272
|
+
const workerCall = calls.find(c => c.systemPrompt.includes('Worker'));
|
|
273
|
+
expect(workerCall).toBeDefined();
|
|
274
|
+
// The mailbox message should be in the request as a user message
|
|
275
|
+
const userMessages = workerCall.messages.filter(m => m.role === 'user');
|
|
276
|
+
expect(userMessages.length).toBeGreaterThanOrEqual(1);
|
|
277
|
+
// The message content should contain the task (formatted as XML by formatMailboxForLLM)
|
|
278
|
+
const lastUserMsg = userMessages[userMessages.length - 1];
|
|
279
|
+
const content = typeof lastUserMsg.content === 'string' ? lastUserMsg.content : '';
|
|
280
|
+
expect(content).toContain('Process this data');
|
|
281
|
+
expect(content).toContain('<message');
|
|
282
|
+
await harness.shutdown();
|
|
283
|
+
});
|
|
284
|
+
it('messages marked as consumed after delivery (mailbox_consumed event)', async () => {
|
|
285
|
+
let orchestratorCalls = 0;
|
|
286
|
+
const harness = new TestHarness({
|
|
287
|
+
presets: [createMultiAgentPreset([
|
|
288
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
289
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
290
|
+
mockHandler: (request) => {
|
|
291
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
292
|
+
orchestratorCalls++;
|
|
293
|
+
if (orchestratorCalls === 1) {
|
|
294
|
+
return {
|
|
295
|
+
content: null,
|
|
296
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Task for worker' } }],
|
|
297
|
+
finishReason: 'stop',
|
|
298
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
302
|
+
}
|
|
303
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
const session = await harness.createSession('test');
|
|
307
|
+
await session.sendAndWaitForIdle('Start');
|
|
308
|
+
// mailbox_consumed event emitted
|
|
309
|
+
const consumedEvents = await session.getEventsByType(mailboxEvents, 'mailbox_consumed');
|
|
310
|
+
const workerConsumed = consumedEvents.filter(e => e.agentId === AgentId('worker_1'));
|
|
311
|
+
expect(workerConsumed).toHaveLength(1);
|
|
312
|
+
// All worker messages should be consumed in state
|
|
313
|
+
const mailboxState = selectMailboxState(session.state);
|
|
314
|
+
const unconsumed = getAgentUnconsumedMailbox(mailboxState, AgentId('worker_1'));
|
|
315
|
+
expect(unconsumed).toHaveLength(0);
|
|
316
|
+
await harness.shutdown();
|
|
317
|
+
});
|
|
318
|
+
it('message ordering preserved — multiple messages delivered in sequence', async () => {
|
|
319
|
+
let orchestratorCalls = 0;
|
|
320
|
+
const harness = new TestHarness({
|
|
321
|
+
presets: [createMultiAgentPreset([
|
|
322
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
323
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
324
|
+
mockHandler: (request) => {
|
|
325
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
326
|
+
orchestratorCalls++;
|
|
327
|
+
if (orchestratorCalls === 1) {
|
|
328
|
+
return {
|
|
329
|
+
content: null,
|
|
330
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'First message' } }],
|
|
331
|
+
finishReason: 'stop',
|
|
332
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
if (orchestratorCalls === 2) {
|
|
336
|
+
return {
|
|
337
|
+
content: null,
|
|
338
|
+
toolCalls: [
|
|
339
|
+
{ id: ToolCallId('tc2'), name: 'send_message', input: { to: 'worker_1', message: 'Second message' } },
|
|
340
|
+
{ id: ToolCallId('tc3'), name: 'send_message', input: { to: 'worker_1', message: 'Third message' } },
|
|
341
|
+
],
|
|
342
|
+
finishReason: 'stop',
|
|
343
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
347
|
+
}
|
|
348
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
const session = await harness.createSession('test');
|
|
352
|
+
await session.sendAndWaitForIdle('Start');
|
|
353
|
+
// Check message order in state
|
|
354
|
+
const mailboxState = selectMailboxState(session.state);
|
|
355
|
+
const allMessages = getAgentMailbox(mailboxState, AgentId('worker_1'));
|
|
356
|
+
expect(allMessages).toHaveLength(3);
|
|
357
|
+
const contents = allMessages.map(m => m.content);
|
|
358
|
+
expect(contents[0]).toBe('First message');
|
|
359
|
+
expect(contents[1]).toBe('Second message');
|
|
360
|
+
expect(contents[2]).toBe('Third message');
|
|
361
|
+
await harness.shutdown();
|
|
362
|
+
});
|
|
363
|
+
it('messages from different senders all delivered', async () => {
|
|
364
|
+
let orchestratorCalls = 0;
|
|
365
|
+
let worker1Calls = 0;
|
|
366
|
+
let subworkerCalls = 0;
|
|
367
|
+
const harness = new TestHarness({
|
|
368
|
+
presets: [createMultiAgentPreset([
|
|
369
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: ['subworker'] },
|
|
370
|
+
{ name: 'subworker', system: 'Subworker agent.', tools: [], agents: [] },
|
|
371
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
372
|
+
mockHandler: (request) => {
|
|
373
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
374
|
+
orchestratorCalls++;
|
|
375
|
+
if (orchestratorCalls === 1) {
|
|
376
|
+
return {
|
|
377
|
+
content: null,
|
|
378
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Go' } }],
|
|
379
|
+
finishReason: 'stop',
|
|
380
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
384
|
+
}
|
|
385
|
+
if (request.systemPrompt.includes('Worker agent')) {
|
|
386
|
+
worker1Calls++;
|
|
387
|
+
if (worker1Calls === 1) {
|
|
388
|
+
// Worker spawns subworker
|
|
389
|
+
return {
|
|
390
|
+
content: null,
|
|
391
|
+
toolCalls: [{ id: ToolCallId('tc2'), name: 'start_subworker', input: { message: 'Subtask' } }],
|
|
392
|
+
finishReason: 'stop',
|
|
393
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
397
|
+
}
|
|
398
|
+
// Subworker
|
|
399
|
+
subworkerCalls++;
|
|
400
|
+
if (subworkerCalls === 1) {
|
|
401
|
+
return {
|
|
402
|
+
content: null,
|
|
403
|
+
toolCalls: [{ id: ToolCallId('tc3'), name: 'send_message', input: { to: 'parent', message: 'From subworker' } }],
|
|
404
|
+
finishReason: 'stop',
|
|
405
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
return { content: 'Subworker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
409
|
+
},
|
|
410
|
+
});
|
|
411
|
+
const session = await harness.createSession('test');
|
|
412
|
+
await session.sendAndWaitForIdle('Start', { timeoutMs: 10000 });
|
|
413
|
+
// Worker should have messages from both orchestrator (initial) and subworker
|
|
414
|
+
const mailboxState = selectMailboxState(session.state);
|
|
415
|
+
const workerMailbox = getAgentMailbox(mailboxState, AgentId('worker_1'));
|
|
416
|
+
const fromOrchestrator = workerMailbox.filter(m => m.from === session.getEntryAgentId());
|
|
417
|
+
const fromSubworker = workerMailbox.filter(m => m.from === AgentId('subworker_1'));
|
|
418
|
+
expect(fromOrchestrator).toHaveLength(1);
|
|
419
|
+
expect(fromSubworker).toHaveLength(1);
|
|
420
|
+
await harness.shutdown();
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
// =========================================================================
|
|
424
|
+
// onComplete hook
|
|
425
|
+
// =========================================================================
|
|
426
|
+
describe('onComplete hook', () => {
|
|
427
|
+
it('agent with sendCompletionMessage: true → parent receives "Task completed." on agent completion', async () => {
|
|
428
|
+
let orchestratorCalls = 0;
|
|
429
|
+
const harness = new TestHarness({
|
|
430
|
+
presets: [createMultiAgentPreset([
|
|
431
|
+
{
|
|
432
|
+
name: 'worker',
|
|
433
|
+
system: 'Worker agent.',
|
|
434
|
+
tools: [],
|
|
435
|
+
agents: [],
|
|
436
|
+
plugins: [{ pluginName: 'mailbox', config: { sendCompletionMessage: true } }],
|
|
437
|
+
},
|
|
438
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
439
|
+
mockHandler: (request) => {
|
|
440
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
441
|
+
orchestratorCalls++;
|
|
442
|
+
if (orchestratorCalls === 1) {
|
|
443
|
+
return {
|
|
444
|
+
content: null,
|
|
445
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Do work' } }],
|
|
446
|
+
finishReason: 'stop',
|
|
447
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
451
|
+
}
|
|
452
|
+
// Worker responds with content only → completes → onComplete fires
|
|
453
|
+
return { content: 'Work finished', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
const session = await harness.createSession('test');
|
|
457
|
+
await session.sendAndWaitForIdle('Start');
|
|
458
|
+
// Check that "Task completed." was sent to parent
|
|
459
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
460
|
+
const completionMessages = events.filter(e => e.message.content === 'Task completed.');
|
|
461
|
+
expect(completionMessages).toHaveLength(1);
|
|
462
|
+
expect(completionMessages[0].toAgentId).toBe(session.getEntryAgentId());
|
|
463
|
+
expect(completionMessages[0].message.from).toBe(AgentId('worker_1'));
|
|
464
|
+
await harness.shutdown();
|
|
465
|
+
});
|
|
466
|
+
it('agent with sendCompletionMessage: false → no completion message', async () => {
|
|
467
|
+
let orchestratorCalls = 0;
|
|
468
|
+
const harness = new TestHarness({
|
|
469
|
+
presets: [createMultiAgentPreset([
|
|
470
|
+
{
|
|
471
|
+
name: 'worker',
|
|
472
|
+
system: 'Worker agent.',
|
|
473
|
+
tools: [],
|
|
474
|
+
agents: [],
|
|
475
|
+
// No sendCompletionMessage config
|
|
476
|
+
},
|
|
477
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
478
|
+
mockHandler: (request) => {
|
|
479
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
480
|
+
orchestratorCalls++;
|
|
481
|
+
if (orchestratorCalls === 1) {
|
|
482
|
+
return {
|
|
483
|
+
content: null,
|
|
484
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Do work' } }],
|
|
485
|
+
finishReason: 'stop',
|
|
486
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
490
|
+
}
|
|
491
|
+
return { content: 'Work finished', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
const session = await harness.createSession('test');
|
|
495
|
+
await session.sendAndWaitForIdle('Start');
|
|
496
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
497
|
+
const completionMessages = events.filter(e => e.message.content === 'Task completed.');
|
|
498
|
+
expect(completionMessages).toHaveLength(0);
|
|
499
|
+
await harness.shutdown();
|
|
500
|
+
});
|
|
501
|
+
it('agent without parent → no completion message even with flag true', async () => {
|
|
502
|
+
const harness = new TestHarness({
|
|
503
|
+
presets: [createTestPreset({
|
|
504
|
+
orchestratorPlugins: [
|
|
505
|
+
{ pluginName: 'mailbox', config: { sendCompletionMessage: true } },
|
|
506
|
+
],
|
|
507
|
+
})],
|
|
508
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Done', toolCalls: [] }),
|
|
509
|
+
});
|
|
510
|
+
const session = await harness.createSession('test');
|
|
511
|
+
await session.sendAndWaitForIdle('Test');
|
|
512
|
+
// Orchestrator has no parent → no completion message
|
|
513
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
514
|
+
const completionMessages = events.filter(e => e.message.content === 'Task completed.');
|
|
515
|
+
expect(completionMessages).toHaveLength(0);
|
|
516
|
+
await harness.shutdown();
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
// =========================================================================
|
|
520
|
+
// send method (direct)
|
|
521
|
+
// =========================================================================
|
|
522
|
+
describe('send method (direct)', () => {
|
|
523
|
+
it('mailbox.send between valid agents → message delivered', async () => {
|
|
524
|
+
let orchestratorCalls = 0;
|
|
525
|
+
const harness = new TestHarness({
|
|
526
|
+
presets: [createMultiAgentPreset([
|
|
527
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
528
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
529
|
+
mockHandler: (request) => {
|
|
530
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
531
|
+
orchestratorCalls++;
|
|
532
|
+
if (orchestratorCalls === 1) {
|
|
533
|
+
return {
|
|
534
|
+
content: null,
|
|
535
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Init' } }],
|
|
536
|
+
finishReason: 'stop',
|
|
537
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
541
|
+
}
|
|
542
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
const session = await harness.createSession('test');
|
|
546
|
+
await session.sendAndWaitForIdle('Start');
|
|
547
|
+
const orchestratorId = session.getEntryAgentId();
|
|
548
|
+
// Send via direct method
|
|
549
|
+
const result = await session.callPluginMethod('mailbox.send', {
|
|
550
|
+
fromAgentId: String(orchestratorId),
|
|
551
|
+
toAgentId: 'worker_1',
|
|
552
|
+
content: 'Direct hello',
|
|
553
|
+
});
|
|
554
|
+
expect(result.ok).toBe(true);
|
|
555
|
+
// Event emitted
|
|
556
|
+
const events = await session.getEventsByType(mailboxEvents, 'mailbox_message');
|
|
557
|
+
const directMsg = events.find(e => e.message.content === 'Direct hello');
|
|
558
|
+
expect(directMsg).toBeDefined();
|
|
559
|
+
expect(directMsg.toAgentId).toBe(AgentId('worker_1'));
|
|
560
|
+
expect(directMsg.message.from).toBe(orchestratorId);
|
|
561
|
+
await harness.shutdown();
|
|
562
|
+
});
|
|
563
|
+
it('mailbox.send between non-related agents → error', async () => {
|
|
564
|
+
let orchestratorCalls = 0;
|
|
565
|
+
const harness = new TestHarness({
|
|
566
|
+
presets: [createMultiAgentPreset([
|
|
567
|
+
{ name: 'worker', system: 'Worker agent.', tools: [], agents: [] },
|
|
568
|
+
], { orchestratorSystem: 'Orchestrator agent.' })],
|
|
569
|
+
mockHandler: (request) => {
|
|
570
|
+
if (request.systemPrompt.includes('Orchestrator')) {
|
|
571
|
+
orchestratorCalls++;
|
|
572
|
+
if (orchestratorCalls === 1) {
|
|
573
|
+
// Spawn two workers
|
|
574
|
+
return {
|
|
575
|
+
content: null,
|
|
576
|
+
toolCalls: [
|
|
577
|
+
{ id: ToolCallId('tc1'), name: 'start_worker', input: { message: 'Task 1' } },
|
|
578
|
+
{ id: ToolCallId('tc2'), name: 'start_worker', input: { message: 'Task 2' } },
|
|
579
|
+
],
|
|
580
|
+
finishReason: 'stop',
|
|
581
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
return { content: 'Done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
585
|
+
}
|
|
586
|
+
return { content: 'Worker done', toolCalls: [], finishReason: 'stop', metrics: MockLLMProvider.defaultMetrics() };
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
const session = await harness.createSession('test');
|
|
590
|
+
await session.sendAndWaitForIdle('Start');
|
|
591
|
+
// Try to send between siblings (worker_1 → worker_2)
|
|
592
|
+
const result = await session.callPluginMethod('mailbox.send', {
|
|
593
|
+
fromAgentId: 'worker_1',
|
|
594
|
+
toAgentId: 'worker_2',
|
|
595
|
+
content: 'Should fail',
|
|
596
|
+
});
|
|
597
|
+
expect(result.ok).toBe(false);
|
|
598
|
+
if (!result.ok) {
|
|
599
|
+
expect(result.error.message).toContain('Cannot send message');
|
|
600
|
+
}
|
|
601
|
+
await harness.shutdown();
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
//# sourceMappingURL=mailbox.integration.test.js.map
|