@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,668 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { MockLLMProvider } from '../../core/llm/mock.js';
|
|
3
|
+
import { selectPluginState } from '../../core/sessions/reducer.js';
|
|
4
|
+
import { ToolCallId } from '../../core/tools/schema.js';
|
|
5
|
+
import { createTestPreset, TestHarness } from '../../testing/index.js';
|
|
6
|
+
import { userChatEvents, userChatPlugin } from './index.js';
|
|
7
|
+
describe('user-chat plugin', () => {
|
|
8
|
+
// =========================================================================
|
|
9
|
+
// sendMessage flow
|
|
10
|
+
// =========================================================================
|
|
11
|
+
describe('sendMessage flow', () => {
|
|
12
|
+
it('sendMessage → agent scheduled → LLM called with user message content', async () => {
|
|
13
|
+
const harness = new TestHarness({
|
|
14
|
+
presets: [createTestPreset()],
|
|
15
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
16
|
+
});
|
|
17
|
+
const session = await harness.createSession('test');
|
|
18
|
+
await session.sendAndWaitForIdle('Hello world');
|
|
19
|
+
const lastRequest = harness.llmProvider.getLastRequest();
|
|
20
|
+
expect(lastRequest).toBeDefined();
|
|
21
|
+
const lastMessage = lastRequest.messages[lastRequest.messages.length - 1];
|
|
22
|
+
expect(lastMessage.content).toContain('Hello world');
|
|
23
|
+
await harness.shutdown();
|
|
24
|
+
});
|
|
25
|
+
it('sendMessage → user_chat_message_received event emitted', async () => {
|
|
26
|
+
const harness = new TestHarness({
|
|
27
|
+
presets: [createTestPreset()],
|
|
28
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
29
|
+
});
|
|
30
|
+
const session = await harness.createSession('test');
|
|
31
|
+
await session.sendAndWaitForIdle('Test message');
|
|
32
|
+
const events = await session.getEventsByType('user_chat_message_received');
|
|
33
|
+
expect(events).toHaveLength(1);
|
|
34
|
+
expect(events[0]).toMatchObject({
|
|
35
|
+
type: 'user_chat_message_received',
|
|
36
|
+
content: 'Test message',
|
|
37
|
+
});
|
|
38
|
+
await harness.shutdown();
|
|
39
|
+
});
|
|
40
|
+
it('sendMessage to specific agent (non-entry) via sendMessageToAgent', async () => {
|
|
41
|
+
const harness = new TestHarness({
|
|
42
|
+
presets: [createTestPreset()],
|
|
43
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
44
|
+
});
|
|
45
|
+
const session = await harness.createSession('test');
|
|
46
|
+
const entryAgentId = session.getEntryAgentId();
|
|
47
|
+
await session.sendMessageToAgent(entryAgentId, 'Direct message');
|
|
48
|
+
await session.waitForIdle();
|
|
49
|
+
const events = await session.getEventsByType('user_chat_message_received');
|
|
50
|
+
expect(events).toHaveLength(1);
|
|
51
|
+
expect(events[0]).toMatchObject({
|
|
52
|
+
agentId: entryAgentId,
|
|
53
|
+
content: 'Direct message',
|
|
54
|
+
});
|
|
55
|
+
await harness.shutdown();
|
|
56
|
+
});
|
|
57
|
+
it('multiple sendMessage calls → all messages appear in conversation history in order', async () => {
|
|
58
|
+
const harness = new TestHarness({
|
|
59
|
+
presets: [createTestPreset()],
|
|
60
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
61
|
+
});
|
|
62
|
+
const session = await harness.createSession('test');
|
|
63
|
+
await session.sendAndWaitForIdle('First message');
|
|
64
|
+
await session.sendAndWaitForIdle('Second message');
|
|
65
|
+
const events = await session.getEventsByType('user_chat_message_received');
|
|
66
|
+
expect(events).toHaveLength(2);
|
|
67
|
+
expect(events[0]).toMatchObject({ content: 'First message' });
|
|
68
|
+
expect(events[1]).toMatchObject({ content: 'Second message' });
|
|
69
|
+
await harness.shutdown();
|
|
70
|
+
});
|
|
71
|
+
it('sendMessage → pending inbound message created and marked consumed after inference', async () => {
|
|
72
|
+
const harness = new TestHarness({
|
|
73
|
+
presets: [createTestPreset()],
|
|
74
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
75
|
+
});
|
|
76
|
+
const session = await harness.createSession('test');
|
|
77
|
+
await session.sendAndWaitForIdle('Test');
|
|
78
|
+
// Check consumed event was emitted
|
|
79
|
+
const consumedEvents = await session.getEventsByType('user_chat_messages_consumed');
|
|
80
|
+
expect(consumedEvents.length).toBeGreaterThanOrEqual(1);
|
|
81
|
+
// After consumption, pending messages should be marked consumed in state
|
|
82
|
+
const pendingInbound = selectPluginState(session.state, 'messages')?.pendingInbound ?? [];
|
|
83
|
+
const unconsumed = pendingInbound.filter((m) => !m.consumed);
|
|
84
|
+
expect(unconsumed).toHaveLength(0);
|
|
85
|
+
await harness.shutdown();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
// =========================================================================
|
|
89
|
+
// tell_user tool
|
|
90
|
+
// =========================================================================
|
|
91
|
+
describe('tell_user tool', () => {
|
|
92
|
+
it('agent calls tell_user → agentMessage notification emitted', async () => {
|
|
93
|
+
const harness = new TestHarness({
|
|
94
|
+
presets: [createTestPreset()],
|
|
95
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
96
|
+
{
|
|
97
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'Hello user!' } }],
|
|
98
|
+
},
|
|
99
|
+
{ content: 'Done', toolCalls: [] },
|
|
100
|
+
]),
|
|
101
|
+
});
|
|
102
|
+
const session = await harness.createSession('test');
|
|
103
|
+
await session.sendAndWaitForIdle('Hi');
|
|
104
|
+
const messages = harness.notifications.getAgentMessages();
|
|
105
|
+
expect(messages).toHaveLength(1);
|
|
106
|
+
expect(messages[0].content).toBe('Hello user!');
|
|
107
|
+
await harness.shutdown();
|
|
108
|
+
});
|
|
109
|
+
it('tell_user with format: text → notification has text format', async () => {
|
|
110
|
+
const harness = new TestHarness({
|
|
111
|
+
presets: [createTestPreset()],
|
|
112
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
113
|
+
{
|
|
114
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'Plain text', format: 'text' } }],
|
|
115
|
+
},
|
|
116
|
+
{ content: 'Done', toolCalls: [] },
|
|
117
|
+
]),
|
|
118
|
+
});
|
|
119
|
+
const session = await harness.createSession('test');
|
|
120
|
+
await session.sendAndWaitForIdle('Hi');
|
|
121
|
+
const messages = harness.notifications.getAgentMessages();
|
|
122
|
+
expect(messages).toHaveLength(1);
|
|
123
|
+
expect(messages[0].format).toBe('text');
|
|
124
|
+
await harness.shutdown();
|
|
125
|
+
});
|
|
126
|
+
it('tell_user with format: markdown → notification has markdown format', async () => {
|
|
127
|
+
const harness = new TestHarness({
|
|
128
|
+
presets: [createTestPreset()],
|
|
129
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
130
|
+
{
|
|
131
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: '**Bold**', format: 'markdown' } }],
|
|
132
|
+
},
|
|
133
|
+
{ content: 'Done', toolCalls: [] },
|
|
134
|
+
]),
|
|
135
|
+
});
|
|
136
|
+
const session = await harness.createSession('test');
|
|
137
|
+
await session.sendAndWaitForIdle('Hi');
|
|
138
|
+
const messages = harness.notifications.getAgentMessages();
|
|
139
|
+
expect(messages).toHaveLength(1);
|
|
140
|
+
expect(messages[0].format).toBe('markdown');
|
|
141
|
+
await harness.shutdown();
|
|
142
|
+
});
|
|
143
|
+
it('tell_user → user_message_sent event emitted with correct content', async () => {
|
|
144
|
+
const harness = new TestHarness({
|
|
145
|
+
presets: [createTestPreset()],
|
|
146
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
147
|
+
{
|
|
148
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'Event test' } }],
|
|
149
|
+
},
|
|
150
|
+
{ content: 'Done', toolCalls: [] },
|
|
151
|
+
]),
|
|
152
|
+
});
|
|
153
|
+
const session = await harness.createSession('test');
|
|
154
|
+
await session.sendAndWaitForIdle('Hi');
|
|
155
|
+
const events = await session.getEventsByType('user_message_sent');
|
|
156
|
+
expect(events).toHaveLength(1);
|
|
157
|
+
expect(events[0]).toMatchObject({
|
|
158
|
+
type: 'user_message_sent',
|
|
159
|
+
message: 'Event test',
|
|
160
|
+
});
|
|
161
|
+
await harness.shutdown();
|
|
162
|
+
});
|
|
163
|
+
it('tell_user → message appears in getMessages result', async () => {
|
|
164
|
+
const harness = new TestHarness({
|
|
165
|
+
presets: [createTestPreset()],
|
|
166
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
167
|
+
{
|
|
168
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'Stored msg' } }],
|
|
169
|
+
},
|
|
170
|
+
{ content: 'Done', toolCalls: [] },
|
|
171
|
+
]),
|
|
172
|
+
});
|
|
173
|
+
const session = await harness.createSession('test');
|
|
174
|
+
await session.sendAndWaitForIdle('Hi');
|
|
175
|
+
const chatMessages = selectPluginState(session.state, 'messages')?.messages ?? [];
|
|
176
|
+
const agentMessages = chatMessages.filter((m) => m.type === 'agent_message');
|
|
177
|
+
expect(agentMessages).toHaveLength(1);
|
|
178
|
+
expect(agentMessages[0]).toMatchObject({
|
|
179
|
+
type: 'agent_message',
|
|
180
|
+
content: 'Stored msg',
|
|
181
|
+
});
|
|
182
|
+
await harness.shutdown();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
// =========================================================================
|
|
186
|
+
// ask_user tool
|
|
187
|
+
// =========================================================================
|
|
188
|
+
describe('ask_user tool', () => {
|
|
189
|
+
it('agent calls ask_user (text input) → askUser notification emitted with question', async () => {
|
|
190
|
+
const harness = new TestHarness({
|
|
191
|
+
presets: [createTestPreset()],
|
|
192
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
193
|
+
{
|
|
194
|
+
toolCalls: [{
|
|
195
|
+
id: ToolCallId('tc1'),
|
|
196
|
+
name: 'ask_user',
|
|
197
|
+
input: { question: 'What is your name?', inputType: 'text' },
|
|
198
|
+
}],
|
|
199
|
+
},
|
|
200
|
+
{ content: 'Done', toolCalls: [] },
|
|
201
|
+
]),
|
|
202
|
+
});
|
|
203
|
+
const session = await harness.createSession('test');
|
|
204
|
+
await session.sendAndWaitForIdle('Hi');
|
|
205
|
+
const askNotifications = harness.notifications.getByType('user-chat', 'askUser');
|
|
206
|
+
expect(askNotifications).toHaveLength(1);
|
|
207
|
+
expect(askNotifications[0].payload).toMatchObject({
|
|
208
|
+
question: 'What is your name?',
|
|
209
|
+
inputType: { type: 'text' },
|
|
210
|
+
});
|
|
211
|
+
await harness.shutdown();
|
|
212
|
+
});
|
|
213
|
+
it('ask_user → user_question_asked event emitted', async () => {
|
|
214
|
+
const harness = new TestHarness({
|
|
215
|
+
presets: [createTestPreset()],
|
|
216
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
217
|
+
{
|
|
218
|
+
toolCalls: [{
|
|
219
|
+
id: ToolCallId('tc1'),
|
|
220
|
+
name: 'ask_user',
|
|
221
|
+
input: { question: 'Confirm?', inputType: 'confirm' },
|
|
222
|
+
}],
|
|
223
|
+
},
|
|
224
|
+
{ content: 'Done', toolCalls: [] },
|
|
225
|
+
]),
|
|
226
|
+
});
|
|
227
|
+
const session = await harness.createSession('test');
|
|
228
|
+
await session.sendAndWaitForIdle('Hi');
|
|
229
|
+
const events = await session.getEventsByType('user_question_asked');
|
|
230
|
+
expect(events).toHaveLength(1);
|
|
231
|
+
expect(events[0]).toMatchObject({
|
|
232
|
+
type: 'user_question_asked',
|
|
233
|
+
question: 'Confirm?',
|
|
234
|
+
});
|
|
235
|
+
await harness.shutdown();
|
|
236
|
+
});
|
|
237
|
+
it('ask_user with single_choice → notification contains options', async () => {
|
|
238
|
+
const harness = new TestHarness({
|
|
239
|
+
presets: [createTestPreset()],
|
|
240
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
241
|
+
{
|
|
242
|
+
toolCalls: [{
|
|
243
|
+
id: ToolCallId('tc1'),
|
|
244
|
+
name: 'ask_user',
|
|
245
|
+
input: {
|
|
246
|
+
question: 'Pick one',
|
|
247
|
+
inputType: 'single_choice',
|
|
248
|
+
options: [
|
|
249
|
+
{ value: 'a', label: 'Option A' },
|
|
250
|
+
{ value: 'b', label: 'Option B' },
|
|
251
|
+
],
|
|
252
|
+
},
|
|
253
|
+
}],
|
|
254
|
+
},
|
|
255
|
+
{ content: 'Done', toolCalls: [] },
|
|
256
|
+
]),
|
|
257
|
+
});
|
|
258
|
+
const session = await harness.createSession('test');
|
|
259
|
+
await session.sendAndWaitForIdle('Hi');
|
|
260
|
+
const askNotifications = harness.notifications.getByType('user-chat', 'askUser');
|
|
261
|
+
expect(askNotifications).toHaveLength(1);
|
|
262
|
+
expect(askNotifications[0].payload).toMatchObject({
|
|
263
|
+
inputType: {
|
|
264
|
+
type: 'single_choice',
|
|
265
|
+
options: [
|
|
266
|
+
{ value: 'a', label: 'Option A' },
|
|
267
|
+
{ value: 'b', label: 'Option B' },
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
await harness.shutdown();
|
|
272
|
+
});
|
|
273
|
+
it('ask_user with multi_choice → notification contains options', async () => {
|
|
274
|
+
const harness = new TestHarness({
|
|
275
|
+
presets: [createTestPreset()],
|
|
276
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
277
|
+
{
|
|
278
|
+
toolCalls: [{
|
|
279
|
+
id: ToolCallId('tc1'),
|
|
280
|
+
name: 'ask_user',
|
|
281
|
+
input: {
|
|
282
|
+
question: 'Pick multiple',
|
|
283
|
+
inputType: 'multi_choice',
|
|
284
|
+
options: [
|
|
285
|
+
{ value: 'x', label: 'X' },
|
|
286
|
+
{ value: 'y', label: 'Y' },
|
|
287
|
+
],
|
|
288
|
+
},
|
|
289
|
+
}],
|
|
290
|
+
},
|
|
291
|
+
{ content: 'Done', toolCalls: [] },
|
|
292
|
+
]),
|
|
293
|
+
});
|
|
294
|
+
const session = await harness.createSession('test');
|
|
295
|
+
await session.sendAndWaitForIdle('Hi');
|
|
296
|
+
const askNotifications = harness.notifications.getByType('user-chat', 'askUser');
|
|
297
|
+
expect(askNotifications).toHaveLength(1);
|
|
298
|
+
expect(askNotifications[0].payload).toMatchObject({
|
|
299
|
+
inputType: {
|
|
300
|
+
type: 'multi_choice',
|
|
301
|
+
options: [
|
|
302
|
+
{ value: 'x', label: 'X' },
|
|
303
|
+
{ value: 'y', label: 'Y' },
|
|
304
|
+
],
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
await harness.shutdown();
|
|
308
|
+
});
|
|
309
|
+
it('ask_user with confirm → notification has confirm type', async () => {
|
|
310
|
+
const harness = new TestHarness({
|
|
311
|
+
presets: [createTestPreset()],
|
|
312
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
313
|
+
{
|
|
314
|
+
toolCalls: [{
|
|
315
|
+
id: ToolCallId('tc1'),
|
|
316
|
+
name: 'ask_user',
|
|
317
|
+
input: { question: 'Are you sure?', inputType: 'confirm' },
|
|
318
|
+
}],
|
|
319
|
+
},
|
|
320
|
+
{ content: 'Done', toolCalls: [] },
|
|
321
|
+
]),
|
|
322
|
+
});
|
|
323
|
+
const session = await harness.createSession('test');
|
|
324
|
+
await session.sendAndWaitForIdle('Hi');
|
|
325
|
+
const askNotifications = harness.notifications.getByType('user-chat', 'askUser');
|
|
326
|
+
expect(askNotifications).toHaveLength(1);
|
|
327
|
+
expect(askNotifications[0].payload).toMatchObject({
|
|
328
|
+
inputType: { type: 'confirm' },
|
|
329
|
+
});
|
|
330
|
+
await harness.shutdown();
|
|
331
|
+
});
|
|
332
|
+
it('ask_user with rating → notification has min/max', async () => {
|
|
333
|
+
const harness = new TestHarness({
|
|
334
|
+
presets: [createTestPreset()],
|
|
335
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
336
|
+
{
|
|
337
|
+
toolCalls: [{
|
|
338
|
+
id: ToolCallId('tc1'),
|
|
339
|
+
name: 'ask_user',
|
|
340
|
+
input: { question: 'Rate this', inputType: 'rating', min: 1, max: 10 },
|
|
341
|
+
}],
|
|
342
|
+
},
|
|
343
|
+
{ content: 'Done', toolCalls: [] },
|
|
344
|
+
]),
|
|
345
|
+
});
|
|
346
|
+
const session = await harness.createSession('test');
|
|
347
|
+
await session.sendAndWaitForIdle('Hi');
|
|
348
|
+
const askNotifications = harness.notifications.getByType('user-chat', 'askUser');
|
|
349
|
+
expect(askNotifications).toHaveLength(1);
|
|
350
|
+
expect(askNotifications[0].payload).toMatchObject({
|
|
351
|
+
inputType: { type: 'rating', min: 1, max: 10 },
|
|
352
|
+
});
|
|
353
|
+
await harness.shutdown();
|
|
354
|
+
});
|
|
355
|
+
it('answerQuestion → answer delivered → agent sees answer in next inference', async () => {
|
|
356
|
+
let inferenceCount = 0;
|
|
357
|
+
const harness = new TestHarness({
|
|
358
|
+
presets: [createTestPreset()],
|
|
359
|
+
mockHandler: (request) => {
|
|
360
|
+
inferenceCount++;
|
|
361
|
+
if (inferenceCount === 1) {
|
|
362
|
+
return {
|
|
363
|
+
content: null,
|
|
364
|
+
toolCalls: [{
|
|
365
|
+
id: ToolCallId('tc1'),
|
|
366
|
+
name: 'ask_user',
|
|
367
|
+
input: { question: 'Your name?', inputType: 'text' },
|
|
368
|
+
}],
|
|
369
|
+
finishReason: 'stop',
|
|
370
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
if (inferenceCount === 2) {
|
|
374
|
+
// After tool result — agent finishes this cycle
|
|
375
|
+
return {
|
|
376
|
+
content: 'Waiting for answer',
|
|
377
|
+
toolCalls: [],
|
|
378
|
+
finishReason: 'stop',
|
|
379
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
// After answer arrives — check the LLM sees it
|
|
383
|
+
const lastMessage = request.messages[request.messages.length - 1];
|
|
384
|
+
const content = typeof lastMessage.content === 'string' ? lastMessage.content : '';
|
|
385
|
+
return {
|
|
386
|
+
content: `Got: ${content}`,
|
|
387
|
+
toolCalls: [],
|
|
388
|
+
finishReason: 'stop',
|
|
389
|
+
metrics: MockLLMProvider.defaultMetrics(),
|
|
390
|
+
};
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
const session = await harness.createSession('test');
|
|
394
|
+
await session.sendAndWaitForIdle('Hi');
|
|
395
|
+
// Find the question event to get the questionId
|
|
396
|
+
const questionEvents = await session.getEventsByType(userChatEvents, 'user_question_asked');
|
|
397
|
+
expect(questionEvents).toHaveLength(1);
|
|
398
|
+
const questionId = questionEvents[0].messageId;
|
|
399
|
+
const entryAgentId = session.getEntryAgentId();
|
|
400
|
+
// Answer the question via the new helper
|
|
401
|
+
await session.answerQuestion(entryAgentId, questionId, 'John');
|
|
402
|
+
await session.waitForIdle();
|
|
403
|
+
// Verify the answer event was emitted
|
|
404
|
+
const answerEvents = await session.getEventsByType('user_chat_answer_received');
|
|
405
|
+
expect(answerEvents).toHaveLength(1);
|
|
406
|
+
expect(answerEvents[0]).toMatchObject({
|
|
407
|
+
answerValue: 'John',
|
|
408
|
+
});
|
|
409
|
+
// Verify LLM saw the answer (inference count should be > 2)
|
|
410
|
+
expect(inferenceCount).toBeGreaterThan(2);
|
|
411
|
+
await harness.shutdown();
|
|
412
|
+
});
|
|
413
|
+
it('answerQuestion → user_chat_answer_received event emitted', async () => {
|
|
414
|
+
const harness = new TestHarness({
|
|
415
|
+
presets: [createTestPreset()],
|
|
416
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
417
|
+
{
|
|
418
|
+
toolCalls: [{
|
|
419
|
+
id: ToolCallId('tc1'),
|
|
420
|
+
name: 'ask_user',
|
|
421
|
+
input: { question: 'Color?', inputType: 'text' },
|
|
422
|
+
}],
|
|
423
|
+
},
|
|
424
|
+
{ content: 'Waiting', toolCalls: [] },
|
|
425
|
+
{ content: 'Got it', toolCalls: [] },
|
|
426
|
+
]),
|
|
427
|
+
});
|
|
428
|
+
const session = await harness.createSession('test');
|
|
429
|
+
await session.sendAndWaitForIdle('Hi');
|
|
430
|
+
const questionEvents = await session.getEventsByType(userChatEvents, 'user_question_asked');
|
|
431
|
+
const questionId = questionEvents[0].messageId;
|
|
432
|
+
const entryAgentId = session.getEntryAgentId();
|
|
433
|
+
await session.answerQuestion(entryAgentId, questionId, 'Blue');
|
|
434
|
+
await session.waitForIdle();
|
|
435
|
+
const answerEvents = await session.getEventsByType('user_chat_answer_received');
|
|
436
|
+
expect(answerEvents).toHaveLength(1);
|
|
437
|
+
expect(answerEvents[0]).toMatchObject({
|
|
438
|
+
type: 'user_chat_answer_received',
|
|
439
|
+
answerValue: 'Blue',
|
|
440
|
+
questionId,
|
|
441
|
+
});
|
|
442
|
+
await harness.shutdown();
|
|
443
|
+
});
|
|
444
|
+
it('answerQuestion → question marked as answered in getMessages', async () => {
|
|
445
|
+
const harness = new TestHarness({
|
|
446
|
+
presets: [createTestPreset()],
|
|
447
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
448
|
+
{
|
|
449
|
+
toolCalls: [{
|
|
450
|
+
id: ToolCallId('tc1'),
|
|
451
|
+
name: 'ask_user',
|
|
452
|
+
input: { question: 'Ready?', inputType: 'confirm' },
|
|
453
|
+
}],
|
|
454
|
+
},
|
|
455
|
+
{ content: 'Waiting', toolCalls: [] },
|
|
456
|
+
{ content: 'Great', toolCalls: [] },
|
|
457
|
+
]),
|
|
458
|
+
});
|
|
459
|
+
const session = await harness.createSession('test');
|
|
460
|
+
await session.sendAndWaitForIdle('Hi');
|
|
461
|
+
const questionEvents = await session.getEventsByType(userChatEvents, 'user_question_asked');
|
|
462
|
+
const questionId = questionEvents[0].messageId;
|
|
463
|
+
const entryAgentId = session.getEntryAgentId();
|
|
464
|
+
await session.answerQuestion(entryAgentId, questionId, true);
|
|
465
|
+
await session.waitForIdle();
|
|
466
|
+
// Check messages state
|
|
467
|
+
const chatMessages = selectPluginState(session.state, 'messages')?.messages ?? [];
|
|
468
|
+
const askMessages = chatMessages.filter((m) => m.type === 'ask_user');
|
|
469
|
+
expect(askMessages).toHaveLength(1);
|
|
470
|
+
expect(askMessages[0]).toMatchObject({
|
|
471
|
+
type: 'ask_user',
|
|
472
|
+
answered: true,
|
|
473
|
+
answer: true,
|
|
474
|
+
});
|
|
475
|
+
await harness.shutdown();
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
// =========================================================================
|
|
479
|
+
// XML mode
|
|
480
|
+
// =========================================================================
|
|
481
|
+
describe('XML mode', () => {
|
|
482
|
+
it('agent with userCommunication: xml → <user> tags parsed from response → notification emitted', async () => {
|
|
483
|
+
const harness = new TestHarness({
|
|
484
|
+
presets: [createTestPreset({
|
|
485
|
+
orchestratorPlugins: [
|
|
486
|
+
userChatPlugin.configureAgent({ enabled: true, userCommunication: 'xml' }),
|
|
487
|
+
],
|
|
488
|
+
})],
|
|
489
|
+
llmProvider: MockLLMProvider.withFixedResponse({
|
|
490
|
+
content: 'Thinking... <user>Hello from XML!</user> Done.',
|
|
491
|
+
toolCalls: [],
|
|
492
|
+
}),
|
|
493
|
+
});
|
|
494
|
+
const session = await harness.createSession('test');
|
|
495
|
+
await session.sendAndWaitForIdle('Hi');
|
|
496
|
+
const messages = harness.notifications.getAgentMessages();
|
|
497
|
+
expect(messages).toHaveLength(1);
|
|
498
|
+
expect(messages[0].content).toBe('Hello from XML!');
|
|
499
|
+
await harness.shutdown();
|
|
500
|
+
});
|
|
501
|
+
it('<user> tags stripped from response content after parsing', async () => {
|
|
502
|
+
const harness = new TestHarness({
|
|
503
|
+
presets: [createTestPreset({
|
|
504
|
+
orchestratorPlugins: [
|
|
505
|
+
userChatPlugin.configureAgent({ enabled: true, userCommunication: 'xml' }),
|
|
506
|
+
],
|
|
507
|
+
})],
|
|
508
|
+
llmProvider: MockLLMProvider.withFixedResponse({
|
|
509
|
+
content: 'Before <user>Message</user> After',
|
|
510
|
+
toolCalls: [],
|
|
511
|
+
}),
|
|
512
|
+
});
|
|
513
|
+
const session = await harness.createSession('test');
|
|
514
|
+
await session.sendAndWaitForIdle('Hi');
|
|
515
|
+
// The user_message_sent event should have the extracted message
|
|
516
|
+
const events = await session.getEventsByType('user_message_sent');
|
|
517
|
+
expect(events).toHaveLength(1);
|
|
518
|
+
expect(events[0]).toMatchObject({ message: 'Message' });
|
|
519
|
+
await harness.shutdown();
|
|
520
|
+
});
|
|
521
|
+
it('agent with userCommunication: both → both tools and <user> tags work', async () => {
|
|
522
|
+
const harness = new TestHarness({
|
|
523
|
+
presets: [createTestPreset({
|
|
524
|
+
orchestratorPlugins: [
|
|
525
|
+
userChatPlugin.configureAgent({ enabled: true, userCommunication: 'both' }),
|
|
526
|
+
],
|
|
527
|
+
})],
|
|
528
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
529
|
+
{
|
|
530
|
+
content: 'Thinking... <user>XML message!</user> Done.',
|
|
531
|
+
toolCalls: [{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'Tool message!' } }],
|
|
532
|
+
},
|
|
533
|
+
{ content: 'Finished', toolCalls: [] },
|
|
534
|
+
]),
|
|
535
|
+
});
|
|
536
|
+
const session = await harness.createSession('test');
|
|
537
|
+
await session.sendAndWaitForIdle('Hi');
|
|
538
|
+
const messages = harness.notifications.getAgentMessages();
|
|
539
|
+
expect(messages).toHaveLength(2);
|
|
540
|
+
const contents = messages.map((m) => m.content);
|
|
541
|
+
expect(contents).toContain('Tool message!');
|
|
542
|
+
expect(contents).toContain('XML message!');
|
|
543
|
+
await harness.shutdown();
|
|
544
|
+
});
|
|
545
|
+
it('agent with userCommunication: tool (default) → <user> tags ignored', async () => {
|
|
546
|
+
const harness = new TestHarness({
|
|
547
|
+
presets: [createTestPreset()],
|
|
548
|
+
llmProvider: MockLLMProvider.withFixedResponse({
|
|
549
|
+
content: 'Response with <user>Should not be parsed</user> content',
|
|
550
|
+
toolCalls: [],
|
|
551
|
+
}),
|
|
552
|
+
});
|
|
553
|
+
const session = await harness.createSession('test');
|
|
554
|
+
await session.sendAndWaitForIdle('Hi');
|
|
555
|
+
const messages = harness.notifications.getAgentMessages();
|
|
556
|
+
expect(messages).toHaveLength(0);
|
|
557
|
+
await harness.shutdown();
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
// =========================================================================
|
|
561
|
+
// getMessages
|
|
562
|
+
// =========================================================================
|
|
563
|
+
describe('getMessages', () => {
|
|
564
|
+
it('getMessages returns all chat messages (user + agent + ask_user) in order', async () => {
|
|
565
|
+
const harness = new TestHarness({
|
|
566
|
+
presets: [createTestPreset()],
|
|
567
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
568
|
+
{
|
|
569
|
+
toolCalls: [
|
|
570
|
+
{ id: ToolCallId('tc1'), name: 'tell_user', input: { message: 'Hello!' } },
|
|
571
|
+
{ id: ToolCallId('tc2'), name: 'ask_user', input: { question: 'Name?', inputType: 'text' } },
|
|
572
|
+
],
|
|
573
|
+
},
|
|
574
|
+
{ content: 'Done', toolCalls: [] },
|
|
575
|
+
]),
|
|
576
|
+
});
|
|
577
|
+
const session = await harness.createSession('test');
|
|
578
|
+
await session.sendAndWaitForIdle('Hi');
|
|
579
|
+
const chatMessages = selectPluginState(session.state, 'messages')?.messages ?? [];
|
|
580
|
+
// Should have: user_message (from sendMessage), agent_message (from tell_user), ask_user (from ask_user)
|
|
581
|
+
expect(chatMessages.length).toBeGreaterThanOrEqual(3);
|
|
582
|
+
const types = chatMessages.map((m) => m.type);
|
|
583
|
+
expect(types).toContain('user_message');
|
|
584
|
+
expect(types).toContain('agent_message');
|
|
585
|
+
expect(types).toContain('ask_user');
|
|
586
|
+
await harness.shutdown();
|
|
587
|
+
});
|
|
588
|
+
it('getMessages reflects answered questions', async () => {
|
|
589
|
+
const harness = new TestHarness({
|
|
590
|
+
presets: [createTestPreset()],
|
|
591
|
+
llmProvider: MockLLMProvider.withSequence([
|
|
592
|
+
{
|
|
593
|
+
toolCalls: [{
|
|
594
|
+
id: ToolCallId('tc1'),
|
|
595
|
+
name: 'ask_user',
|
|
596
|
+
input: { question: 'Favorite color?', inputType: 'text' },
|
|
597
|
+
}],
|
|
598
|
+
},
|
|
599
|
+
{ content: 'Waiting', toolCalls: [] },
|
|
600
|
+
{ content: 'Got it', toolCalls: [] },
|
|
601
|
+
]),
|
|
602
|
+
});
|
|
603
|
+
const session = await harness.createSession('test');
|
|
604
|
+
await session.sendAndWaitForIdle('Hi');
|
|
605
|
+
// Before answering — question should be unanswered
|
|
606
|
+
const beforeMessages = selectPluginState(session.state, 'messages')?.messages ?? [];
|
|
607
|
+
const beforeAsk = beforeMessages.filter((m) => m.type === 'ask_user');
|
|
608
|
+
expect(beforeAsk).toHaveLength(1);
|
|
609
|
+
expect(beforeAsk[0]).toMatchObject({ answered: false });
|
|
610
|
+
expect(beforeAsk[0]).not.toHaveProperty('answer');
|
|
611
|
+
// Answer the question
|
|
612
|
+
const questionEvents = await session.getEventsByType(userChatEvents, 'user_question_asked');
|
|
613
|
+
const questionId = questionEvents[0].messageId;
|
|
614
|
+
const entryAgentId = session.getEntryAgentId();
|
|
615
|
+
await session.answerQuestion(entryAgentId, questionId, 'Blue');
|
|
616
|
+
await session.waitForIdle();
|
|
617
|
+
// After answering — question should be marked as answered with answer value
|
|
618
|
+
const afterMessages = selectPluginState(session.state, 'messages')?.messages ?? [];
|
|
619
|
+
const afterAsk = afterMessages.filter((m) => m.type === 'ask_user');
|
|
620
|
+
expect(afterAsk).toHaveLength(1);
|
|
621
|
+
expect(afterAsk[0]).toMatchObject({
|
|
622
|
+
answered: true,
|
|
623
|
+
answer: 'Blue',
|
|
624
|
+
});
|
|
625
|
+
await harness.shutdown();
|
|
626
|
+
});
|
|
627
|
+
});
|
|
628
|
+
// =========================================================================
|
|
629
|
+
// disabled
|
|
630
|
+
// =========================================================================
|
|
631
|
+
describe('disabled', () => {
|
|
632
|
+
it('plugin enabled: false → no tools provided to agent', async () => {
|
|
633
|
+
const harness = new TestHarness({
|
|
634
|
+
presets: [createTestPreset({
|
|
635
|
+
plugins: [
|
|
636
|
+
userChatPlugin.configure({ enabled: false }),
|
|
637
|
+
],
|
|
638
|
+
})],
|
|
639
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
640
|
+
});
|
|
641
|
+
const session = await harness.createSession('test');
|
|
642
|
+
await session.sendAndWaitForIdle('Hi');
|
|
643
|
+
const lastRequest = harness.llmProvider.getLastRequest();
|
|
644
|
+
const toolNames = lastRequest?.tools?.map((t) => t.name) ?? [];
|
|
645
|
+
expect(toolNames).not.toContain('tell_user');
|
|
646
|
+
expect(toolNames).not.toContain('ask_user');
|
|
647
|
+
await harness.shutdown();
|
|
648
|
+
});
|
|
649
|
+
it('agent enabled: false → no user-chat tools provided to that agent', async () => {
|
|
650
|
+
const harness = new TestHarness({
|
|
651
|
+
presets: [createTestPreset({
|
|
652
|
+
orchestratorPlugins: [
|
|
653
|
+
userChatPlugin.configureAgent({ enabled: false }),
|
|
654
|
+
],
|
|
655
|
+
})],
|
|
656
|
+
llmProvider: MockLLMProvider.withFixedResponse({ content: 'Ok', toolCalls: [] }),
|
|
657
|
+
});
|
|
658
|
+
const session = await harness.createSession('test');
|
|
659
|
+
await session.sendAndWaitForIdle('Hi');
|
|
660
|
+
const lastRequest = harness.llmProvider.getLastRequest();
|
|
661
|
+
const toolNames = lastRequest?.tools?.map((t) => t.name) ?? [];
|
|
662
|
+
expect(toolNames).not.toContain('tell_user');
|
|
663
|
+
expect(toolNames).not.toContain('ask_user');
|
|
664
|
+
await harness.shutdown();
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
});
|
|
668
|
+
//# sourceMappingURL=user-chat.integration.test.js.map
|