@animalabs/agent-framework 0.22.2 → 0.22.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/README.md +3 -1
- package/dist/src/agent.d.ts +77 -12
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +143 -41
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/mcp-server-core.js +1 -1
- package/dist/src/api/mcp-server-core.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +5 -1
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/api/types.d.ts +1 -1
- package/dist/src/api/types.d.ts.map +1 -1
- package/dist/src/branch-names.d.ts +14 -0
- package/dist/src/branch-names.d.ts.map +1 -0
- package/dist/src/branch-names.js +22 -0
- package/dist/src/branch-names.js.map +1 -0
- package/dist/src/closest-names.d.ts +28 -0
- package/dist/src/closest-names.d.ts.map +1 -0
- package/dist/src/closest-names.js +98 -0
- package/dist/src/closest-names.js.map +1 -0
- package/dist/src/code-execution/py-runner.d.ts +16 -5
- package/dist/src/code-execution/py-runner.d.ts.map +1 -1
- package/dist/src/code-execution/py-runner.js +186 -74
- package/dist/src/code-execution/py-runner.js.map +1 -1
- package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
- package/dist/src/code-execution/runtime-py.js +49 -3
- package/dist/src/code-execution/runtime-py.js.map +1 -1
- package/dist/src/code-execution/tool-definition.d.ts +12 -1
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +21 -3
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/config-checks.d.ts +28 -0
- package/dist/src/config-checks.d.ts.map +1 -0
- package/dist/src/config-checks.js +52 -0
- package/dist/src/config-checks.js.map +1 -0
- package/dist/src/deadline-timer.d.ts +21 -0
- package/dist/src/deadline-timer.d.ts.map +1 -0
- package/dist/src/deadline-timer.js +43 -0
- package/dist/src/deadline-timer.js.map +1 -0
- package/dist/src/error-message.d.ts +30 -0
- package/dist/src/error-message.d.ts.map +1 -0
- package/dist/src/error-message.js +50 -0
- package/dist/src/error-message.js.map +1 -0
- package/dist/src/framework.d.ts +828 -88
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +5011 -1326
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +8 -0
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +27 -3
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +144 -6
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +424 -263
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.js +91 -30
- package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +19 -3
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +23 -8
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts +20 -0
- package/dist/src/mcpl/convert-block.d.ts.map +1 -0
- package/dist/src/mcpl/convert-block.js +89 -0
- package/dist/src/mcpl/convert-block.js.map +1 -0
- package/dist/src/mcpl/errors.d.ts +13 -0
- package/dist/src/mcpl/errors.d.ts.map +1 -1
- package/dist/src/mcpl/errors.js +28 -0
- package/dist/src/mcpl/errors.js.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.js +83 -72
- package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +114 -0
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
- package/dist/src/mcpl/inbound-source.js +83 -0
- package/dist/src/mcpl/inbound-source.js.map +1 -0
- package/dist/src/mcpl/index.d.ts +3 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -1
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts +15 -11
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.js +153 -84
- package/dist/src/mcpl/inference-router.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +33 -11
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +52 -20
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +16 -9
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +18 -83
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +72 -30
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +47 -12
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js +74 -21
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +89 -10
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +405 -129
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/server-registry.d.ts +10 -1
- package/dist/src/mcpl/server-registry.d.ts.map +1 -1
- package/dist/src/mcpl/server-registry.js +14 -3
- package/dist/src/mcpl/server-registry.js.map +1 -1
- package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
- package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
- package/dist/src/mcpl/skip-reply-wake.js +55 -0
- package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
- package/dist/src/mcpl/transport.d.ts +51 -2
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +114 -20
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +14 -3
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/mcpl/visible-content.d.ts +15 -0
- package/dist/src/mcpl/visible-content.d.ts.map +1 -1
- package/dist/src/mcpl/visible-content.js +25 -0
- package/dist/src/mcpl/visible-content.js.map +1 -1
- package/dist/src/module-registry.d.ts +19 -1
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +54 -25
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/api/index.js +1 -1
- package/dist/src/modules/api/index.js.map +1 -1
- package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
- package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
- package/dist/src/modules/discord/discord-js-client.js +25 -9
- package/dist/src/modules/discord/discord-js-client.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts +29 -3
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +379 -143
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/discord/types.d.ts +14 -1
- package/dist/src/modules/discord/types.d.ts.map +1 -1
- package/dist/src/modules/health/index.d.ts.map +1 -1
- package/dist/src/modules/health/index.js +2 -1
- package/dist/src/modules/health/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts +3 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +359 -127
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +28 -1
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +177 -32
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/unknown-tool.d.ts +10 -0
- package/dist/src/modules/unknown-tool.d.ts.map +1 -0
- package/dist/src/modules/unknown-tool.js +17 -0
- package/dist/src/modules/unknown-tool.js.map +1 -0
- package/dist/src/modules/workspace/disk-agreement.d.ts +32 -2
- package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +30 -2
- package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
- package/dist/src/modules/workspace/effects.d.ts +64 -6
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +291 -44
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +119 -23
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +793 -247
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +75 -8
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +174 -14
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts +58 -7
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +521 -56
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +18 -4
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/modules/workspace/watcher.d.ts +7 -2
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
- package/dist/src/modules/workspace/watcher.js +28 -4
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/prose-drafts.d.ts +240 -0
- package/dist/src/prose-drafts.d.ts.map +1 -0
- package/dist/src/prose-drafts.js +362 -0
- package/dist/src/prose-drafts.js.map +1 -0
- package/dist/src/prose-segments.d.ts +21 -2
- package/dist/src/prose-segments.d.ts.map +1 -1
- package/dist/src/prose-segments.js +46 -9
- package/dist/src/prose-segments.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts +1 -0
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +3 -1
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/safe-slice.d.ts +5 -1
- package/dist/src/safe-slice.d.ts.map +1 -1
- package/dist/src/safe-slice.js +9 -1
- package/dist/src/safe-slice.js.map +1 -1
- package/dist/src/thinking-token-stamp.d.ts +12 -0
- package/dist/src/thinking-token-stamp.d.ts.map +1 -1
- package/dist/src/thinking-token-stamp.js +34 -3
- package/dist/src/thinking-token-stamp.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts +87 -19
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js +135 -32
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-presentation.d.ts +9 -0
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +257 -60
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +7 -10
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +32 -3
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +106 -19
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +25 -1
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +260 -65
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/types/agent.d.ts +17 -5
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +17 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +21 -5
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/inference-log.d.ts +1 -1
- package/dist/src/types/inference-log.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +23 -4
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +95 -6
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts +5 -0
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.js +35 -8
- package/dist/src/usage/usage-tracker.js.map +1 -1
- package/package.json +6 -4
- package/src/agent.ts +169 -41
- package/src/api/mcp-server-core.ts +1 -1
- package/src/api/server.ts +4 -1
- package/src/api/types.ts +1 -1
- package/src/branch-names.ts +19 -0
- package/src/closest-names.ts +94 -0
- package/src/code-execution/py-runner.ts +200 -76
- package/src/code-execution/runtime-py.ts +49 -3
- package/src/code-execution/tool-definition.ts +28 -4
- package/src/config-checks.ts +48 -0
- package/src/deadline-timer.ts +44 -0
- package/src/error-message.ts +48 -0
- package/src/framework.ts +5352 -1388
- package/src/gate/event-gate.ts +28 -3
- package/src/index.ts +11 -2
- package/src/mcpl/channel-registry.ts +517 -286
- package/src/mcpl/checkpoint-manager.ts +104 -29
- package/src/mcpl/conversation-router.ts +28 -8
- package/src/mcpl/convert-block.ts +97 -0
- package/src/mcpl/errors.ts +28 -0
- package/src/mcpl/hook-orchestrator.ts +84 -77
- package/src/mcpl/inbound-source.ts +156 -0
- package/src/mcpl/index.ts +10 -1
- package/src/mcpl/inference-router.ts +174 -99
- package/src/mcpl/push-coalescer.ts +60 -24
- package/src/mcpl/push-handler.ts +20 -90
- package/src/mcpl/reference-fetcher.ts +71 -26
- package/src/mcpl/references.ts +81 -22
- package/src/mcpl/server-connection.ts +427 -132
- package/src/mcpl/server-registry.ts +15 -4
- package/src/mcpl/skip-reply-wake.ts +73 -0
- package/src/mcpl/transport.ts +120 -18
- package/src/mcpl/types.ts +14 -3
- package/src/mcpl/visible-content.ts +27 -0
- package/src/module-registry.ts +58 -23
- package/src/modules/api/index.ts +1 -1
- package/src/modules/discord/discord-js-client.ts +26 -10
- package/src/modules/discord/index.ts +391 -158
- package/src/modules/discord/types.ts +15 -2
- package/src/modules/health/index.ts +2 -1
- package/src/modules/history/index.ts +410 -120
- package/src/modules/history/semantic.ts +189 -32
- package/src/modules/unknown-tool.ts +16 -0
- package/src/modules/workspace/disk-agreement.ts +51 -3
- package/src/modules/workspace/effects.ts +279 -35
- package/src/modules/workspace/index.ts +810 -260
- package/src/modules/workspace/observe.ts +194 -20
- package/src/modules/workspace/reconcile.ts +619 -64
- package/src/modules/workspace/types.ts +18 -4
- package/src/modules/workspace/watcher.ts +27 -4
- package/src/prose-drafts.ts +481 -0
- package/src/prose-segments.ts +51 -8
- package/src/recovery/offline-branch.ts +4 -1
- package/src/safe-slice.ts +9 -1
- package/src/thinking-token-stamp.ts +34 -3
- package/src/tool-image-ledger.ts +153 -34
- package/src/tool-presentation.ts +224 -40
- package/src/tool-result-guard.ts +7 -8
- package/src/tool-result-history.ts +124 -20
- package/src/tune-out/coordinator.ts +259 -65
- package/src/types/agent.ts +17 -7
- package/src/types/events.ts +17 -0
- package/src/types/framework.ts +21 -5
- package/src/types/inference-log.ts +1 -1
- package/src/types/module.ts +24 -4
- package/src/types/trace.ts +101 -6
- package/src/usage/usage-tracker.ts +32 -8
- package/dist/test/activation-request-sanitize.test.d.ts +0 -2
- package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
- package/dist/test/activation-request-sanitize.test.js +0 -89
- package/dist/test/activation-request-sanitize.test.js.map +0 -1
- package/dist/test/agent-cache-ttl.test.d.ts +0 -2
- package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
- package/dist/test/agent-cache-ttl.test.js +0 -41
- package/dist/test/agent-cache-ttl.test.js.map +0 -1
- package/dist/test/agent-runtime-settings.test.d.ts +0 -2
- package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
- package/dist/test/agent-runtime-settings.test.js +0 -1598
- package/dist/test/agent-runtime-settings.test.js.map +0 -1
- package/dist/test/api-admin-gate.test.d.ts +0 -2
- package/dist/test/api-admin-gate.test.d.ts.map +0 -1
- package/dist/test/api-admin-gate.test.js +0 -116
- package/dist/test/api-admin-gate.test.js.map +0 -1
- package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
- package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
- package/dist/test/assistant-persist-refusal.test.js +0 -63
- package/dist/test/assistant-persist-refusal.test.js.map +0 -1
- package/dist/test/batched-wake-locus.test.d.ts +0 -2
- package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
- package/dist/test/batched-wake-locus.test.js +0 -166
- package/dist/test/batched-wake-locus.test.js.map +0 -1
- package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
- package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
- package/dist/test/busy-agent-scheduler.test.js +0 -92
- package/dist/test/busy-agent-scheduler.test.js.map +0 -1
- package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
- package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
- package/dist/test/channel-incoming-targeting.test.js +0 -81
- package/dist/test/channel-incoming-targeting.test.js.map +0 -1
- package/dist/test/channel-label-history.test.d.ts +0 -2
- package/dist/test/channel-label-history.test.d.ts.map +0 -1
- package/dist/test/channel-label-history.test.js +0 -424
- package/dist/test/channel-label-history.test.js.map +0 -1
- package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
- package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
- package/dist/test/channel-lifecycle-provenance.test.js +0 -47
- package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
- package/dist/test/channel-registry-routing.test.d.ts +0 -2
- package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
- package/dist/test/channel-registry-routing.test.js +0 -446
- package/dist/test/channel-registry-routing.test.js.map +0 -1
- package/dist/test/channel-registry-typing.test.d.ts +0 -2
- package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
- package/dist/test/channel-registry-typing.test.js +0 -91
- package/dist/test/channel-registry-typing.test.js.map +0 -1
- package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
- package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
- package/dist/test/channels-changed-respond-first.test.js +0 -74
- package/dist/test/channels-changed-respond-first.test.js.map +0 -1
- package/dist/test/checkpoint-attribution.test.d.ts +0 -2
- package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
- package/dist/test/checkpoint-attribution.test.js +0 -200
- package/dist/test/checkpoint-attribution.test.js.map +0 -1
- package/dist/test/code-execution.test.d.ts +0 -11
- package/dist/test/code-execution.test.d.ts.map +0 -1
- package/dist/test/code-execution.test.js +0 -1272
- package/dist/test/code-execution.test.js.map +0 -1
- package/dist/test/component-defaults.test.d.ts +0 -2
- package/dist/test/component-defaults.test.d.ts.map +0 -1
- package/dist/test/component-defaults.test.js +0 -54
- package/dist/test/component-defaults.test.js.map +0 -1
- package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
- package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
- package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
- package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
- package/dist/test/conversation-router.test.d.ts +0 -2
- package/dist/test/conversation-router.test.d.ts.map +0 -1
- package/dist/test/conversation-router.test.js +0 -174
- package/dist/test/conversation-router.test.js.map +0 -1
- package/dist/test/conversation-routing.test.d.ts +0 -7
- package/dist/test/conversation-routing.test.d.ts.map +0 -1
- package/dist/test/conversation-routing.test.js +0 -621
- package/dist/test/conversation-routing.test.js.map +0 -1
- package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
- package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
- package/dist/test/deferred-wake-integrity.test.js +0 -320
- package/dist/test/deferred-wake-integrity.test.js.map +0 -1
- package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
- package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
- package/dist/test/discord-awareness-outbox.test.js +0 -371
- package/dist/test/discord-awareness-outbox.test.js.map +0 -1
- package/dist/test/discord-history-delete-window.test.d.ts +0 -2
- package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
- package/dist/test/discord-history-delete-window.test.js +0 -81
- package/dist/test/discord-history-delete-window.test.js.map +0 -1
- package/dist/test/discord-history-sync.test.d.ts +0 -2
- package/dist/test/discord-history-sync.test.d.ts.map +0 -1
- package/dist/test/discord-history-sync.test.js +0 -56
- package/dist/test/discord-history-sync.test.js.map +0 -1
- package/dist/test/discord-typing-keepalive.test.d.ts +0 -2
- package/dist/test/discord-typing-keepalive.test.d.ts.map +0 -1
- package/dist/test/discord-typing-keepalive.test.js +0 -77
- package/dist/test/discord-typing-keepalive.test.js.map +0 -1
- package/dist/test/ephemeral-settle.test.d.ts +0 -2
- package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
- package/dist/test/ephemeral-settle.test.js +0 -354
- package/dist/test/ephemeral-settle.test.js.map +0 -1
- package/dist/test/event-gate-passthrough.test.d.ts +0 -15
- package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
- package/dist/test/event-gate-passthrough.test.js +0 -289
- package/dist/test/event-gate-passthrough.test.js.map +0 -1
- package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
- package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
- package/dist/test/event-gate-policy-mutation.test.js +0 -137
- package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
- package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
- package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
- package/dist/test/event-gate-rate-limit.test.js +0 -627
- package/dist/test/event-gate-rate-limit.test.js.map +0 -1
- package/dist/test/event-gate-script.test.d.ts +0 -2
- package/dist/test/event-gate-script.test.d.ts.map +0 -1
- package/dist/test/event-gate-script.test.js +0 -95
- package/dist/test/event-gate-script.test.js.map +0 -1
- package/dist/test/event-gate-selfwake.test.d.ts +0 -15
- package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
- package/dist/test/event-gate-selfwake.test.js +0 -125
- package/dist/test/event-gate-selfwake.test.js.map +0 -1
- package/dist/test/event-gate-tags.test.d.ts +0 -2
- package/dist/test/event-gate-tags.test.d.ts.map +0 -1
- package/dist/test/event-gate-tags.test.js +0 -76
- package/dist/test/event-gate-tags.test.js.map +0 -1
- package/dist/test/event-gate.test.d.ts +0 -2
- package/dist/test/event-gate.test.d.ts.map +0 -1
- package/dist/test/event-gate.test.js +0 -919
- package/dist/test/event-gate.test.js.map +0 -1
- package/dist/test/explicit-prose-routing.test.d.ts +0 -11
- package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
- package/dist/test/explicit-prose-routing.test.js +0 -1715
- package/dist/test/explicit-prose-routing.test.js.map +0 -1
- package/dist/test/framework.test.d.ts +0 -5
- package/dist/test/framework.test.d.ts.map +0 -1
- package/dist/test/framework.test.js +0 -1048
- package/dist/test/framework.test.js.map +0 -1
- package/dist/test/gather-context-timeout.test.d.ts +0 -2
- package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
- package/dist/test/gather-context-timeout.test.js +0 -120
- package/dist/test/gather-context-timeout.test.js.map +0 -1
- package/dist/test/health-snapshot.test.d.ts +0 -2
- package/dist/test/health-snapshot.test.d.ts.map +0 -1
- package/dist/test/health-snapshot.test.js +0 -74
- package/dist/test/health-snapshot.test.js.map +0 -1
- package/dist/test/helpers/coalescing-fixture.d.ts +0 -74
- package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
- package/dist/test/helpers/coalescing-fixture.js +0 -152
- package/dist/test/helpers/coalescing-fixture.js.map +0 -1
- package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
- package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
- package/dist/test/helpers/coalescing-kill-child.js +0 -24
- package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
- package/dist/test/helpers/mock-membrane.d.ts +0 -53
- package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
- package/dist/test/helpers/mock-membrane.js +0 -168
- package/dist/test/helpers/mock-membrane.js.map +0 -1
- package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
- package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
- package/dist/test/helpers/pytc-stop-rows.js +0 -143
- package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
- package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
- package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
- package/dist/test/helpers/quiesce-crash-child.js +0 -156
- package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
- package/dist/test/hide-then-turn.test.d.ts +0 -2
- package/dist/test/hide-then-turn.test.d.ts.map +0 -1
- package/dist/test/hide-then-turn.test.js +0 -101
- package/dist/test/hide-then-turn.test.js.map +0 -1
- package/dist/test/history-module-overview.test.d.ts +0 -2
- package/dist/test/history-module-overview.test.d.ts.map +0 -1
- package/dist/test/history-module-overview.test.js +0 -711
- package/dist/test/history-module-overview.test.js.map +0 -1
- package/dist/test/history-module-realstore.test.d.ts +0 -2
- package/dist/test/history-module-realstore.test.d.ts.map +0 -1
- package/dist/test/history-module-realstore.test.js +0 -363
- package/dist/test/history-module-realstore.test.js.map +0 -1
- package/dist/test/history-module-semantic.test.d.ts +0 -2
- package/dist/test/history-module-semantic.test.d.ts.map +0 -1
- package/dist/test/history-module-semantic.test.js +0 -213
- package/dist/test/history-module-semantic.test.js.map +0 -1
- package/dist/test/history-module-ux.test.d.ts +0 -2
- package/dist/test/history-module-ux.test.d.ts.map +0 -1
- package/dist/test/history-module-ux.test.js +0 -304
- package/dist/test/history-module-ux.test.js.map +0 -1
- package/dist/test/history-module.test.d.ts +0 -2
- package/dist/test/history-module.test.d.ts.map +0 -1
- package/dist/test/history-module.test.js +0 -619
- package/dist/test/history-module.test.js.map +0 -1
- package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
- package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
- package/dist/test/history-semantic-review-findings.test.js +0 -338
- package/dist/test/history-semantic-review-findings.test.js.map +0 -1
- package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
- package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
- package/dist/test/history-semantic-sync-converges.test.js +0 -109
- package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
- package/dist/test/host-quiesce.test.d.ts +0 -2
- package/dist/test/host-quiesce.test.d.ts.map +0 -1
- package/dist/test/host-quiesce.test.js +0 -988
- package/dist/test/host-quiesce.test.js.map +0 -1
- package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
- package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
- package/dist/test/inference-exhaustion-rewind.test.js +0 -387
- package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
- package/dist/test/inference-failure-bounds.test.d.ts +0 -2
- package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
- package/dist/test/inference-failure-bounds.test.js +0 -1202
- package/dist/test/inference-failure-bounds.test.js.map +0 -1
- package/dist/test/inference-failure-observability.test.d.ts +0 -2
- package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
- package/dist/test/inference-failure-observability.test.js +0 -84
- package/dist/test/inference-failure-observability.test.js.map +0 -1
- package/dist/test/journal-tool.test.d.ts +0 -2
- package/dist/test/journal-tool.test.d.ts.map +0 -1
- package/dist/test/journal-tool.test.js +0 -33
- package/dist/test/journal-tool.test.js.map +0 -1
- package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
- package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
- package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
- package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
- package/dist/test/kv-unified-wiring.test.d.ts +0 -2
- package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
- package/dist/test/kv-unified-wiring.test.js +0 -95
- package/dist/test/kv-unified-wiring.test.js.map +0 -1
- package/dist/test/late-events-after-stop.test.d.ts +0 -2
- package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
- package/dist/test/late-events-after-stop.test.js +0 -122
- package/dist/test/late-events-after-stop.test.js.map +0 -1
- package/dist/test/liveness-watchdog.test.d.ts +0 -2
- package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
- package/dist/test/liveness-watchdog.test.js +0 -94
- package/dist/test/liveness-watchdog.test.js.map +0 -1
- package/dist/test/machine-close-provenance.test.d.ts +0 -2
- package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
- package/dist/test/machine-close-provenance.test.js +0 -116
- package/dist/test/machine-close-provenance.test.js.map +0 -1
- package/dist/test/maintenance-timer.test.d.ts +0 -2
- package/dist/test/maintenance-timer.test.d.ts.map +0 -1
- package/dist/test/maintenance-timer.test.js +0 -1827
- package/dist/test/maintenance-timer.test.js.map +0 -1
- package/dist/test/mcp-server-bin.test.d.ts +0 -2
- package/dist/test/mcp-server-bin.test.d.ts.map +0 -1
- package/dist/test/mcp-server-bin.test.js +0 -142
- package/dist/test/mcp-server-bin.test.js.map +0 -1
- package/dist/test/mcpl-access-provider.test.d.ts +0 -2
- package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
- package/dist/test/mcpl-access-provider.test.js +0 -20
- package/dist/test/mcpl-access-provider.test.js.map +0 -1
- package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
- package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
- package/dist/test/mcpl-awareness-barrier.test.js +0 -769
- package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
- package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
- package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
- package/dist/test/mcpl-capability-grant.test.js +0 -111
- package/dist/test/mcpl-capability-grant.test.js.map +0 -1
- package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
- package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
- package/dist/test/mcpl-capability-scoping.test.js +0 -266
- package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
- package/dist/test/mcpl-child-env.test.d.ts +0 -2
- package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
- package/dist/test/mcpl-child-env.test.js +0 -158
- package/dist/test/mcpl-child-env.test.js.map +0 -1
- package/dist/test/mcpl-coalesced-content-parity.test.d.ts +0 -2
- package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +0 -1
- package/dist/test/mcpl-coalesced-content-parity.test.js +0 -532
- package/dist/test/mcpl-coalesced-content-parity.test.js.map +0 -1
- package/dist/test/mcpl-coalescing.test.d.ts +0 -2
- package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
- package/dist/test/mcpl-coalescing.test.js +0 -1125
- package/dist/test/mcpl-coalescing.test.js.map +0 -1
- package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
- package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
- package/dist/test/mcpl-config-diagnostics.test.js +0 -452
- package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
- package/dist/test/mcpl-empty-content.test.d.ts +0 -2
- package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
- package/dist/test/mcpl-empty-content.test.js +0 -368
- package/dist/test/mcpl-empty-content.test.js.map +0 -1
- package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
- package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
- package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
- package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
- package/dist/test/mcpl-list-status.test.d.ts +0 -2
- package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
- package/dist/test/mcpl-list-status.test.js +0 -82
- package/dist/test/mcpl-list-status.test.js.map +0 -1
- package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
- package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
- package/dist/test/mcpl-manifest-changed.test.js +0 -178
- package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
- package/dist/test/mcpl-push-convert.test.d.ts +0 -2
- package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
- package/dist/test/mcpl-push-convert.test.js +0 -42
- package/dist/test/mcpl-push-convert.test.js.map +0 -1
- package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
- package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
- package/dist/test/mcpl-reconnect-events.test.js +0 -144
- package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
- package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
- package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
- package/dist/test/mcpl-reconnect-reregistration.test.js +0 -238
- package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
- package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
- package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
- package/dist/test/mcpl-reference-fetcher.test.js +0 -427
- package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
- package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
- package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
- package/dist/test/mcpl-reference-fields.test.js +0 -149
- package/dist/test/mcpl-reference-fields.test.js.map +0 -1
- package/dist/test/mcpl-rejection-log-lines.test.d.ts +0 -2
- package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +0 -1
- package/dist/test/mcpl-rejection-log-lines.test.js +0 -349
- package/dist/test/mcpl-rejection-log-lines.test.js.map +0 -1
- package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
- package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
- package/dist/test/mcpl-request-timeout.test.js +0 -138
- package/dist/test/mcpl-request-timeout.test.js.map +0 -1
- package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
- package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
- package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
- package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
- package/dist/test/mcpl-stderr-tail.test.d.ts +0 -2
- package/dist/test/mcpl-stderr-tail.test.d.ts.map +0 -1
- package/dist/test/mcpl-stderr-tail.test.js +0 -210
- package/dist/test/mcpl-stderr-tail.test.js.map +0 -1
- package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
- package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-class-listing.test.js +0 -147
- package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
- package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
- package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-classes.test.js +0 -80
- package/dist/test/mcpl-tool-classes.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
- package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
- package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
- package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
- package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
- package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
- package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
- package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
- package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
- package/dist/test/mcpl-transport-close.test.d.ts +0 -2
- package/dist/test/mcpl-transport-close.test.d.ts.map +0 -1
- package/dist/test/mcpl-transport-close.test.js +0 -373
- package/dist/test/mcpl-transport-close.test.js.map +0 -1
- package/dist/test/mcpl-transport-spawn.test.d.ts +0 -2
- package/dist/test/mcpl-transport-spawn.test.d.ts.map +0 -1
- package/dist/test/mcpl-transport-spawn.test.js +0 -58
- package/dist/test/mcpl-transport-spawn.test.js.map +0 -1
- package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
- package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
- package/dist/test/mcpl-ws-transport.test.js +0 -259
- package/dist/test/mcpl-ws-transport.test.js.map +0 -1
- package/dist/test/module-context-integration.test.d.ts +0 -18
- package/dist/test/module-context-integration.test.d.ts.map +0 -1
- package/dist/test/module-context-integration.test.js +0 -181
- package/dist/test/module-context-integration.test.js.map +0 -1
- package/dist/test/offline-recovery-branch.test.d.ts +0 -2
- package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
- package/dist/test/offline-recovery-branch.test.js +0 -570
- package/dist/test/offline-recovery-branch.test.js.map +0 -1
- package/dist/test/operator-surgery.test.d.ts +0 -2
- package/dist/test/operator-surgery.test.d.ts.map +0 -1
- package/dist/test/operator-surgery.test.js +0 -595
- package/dist/test/operator-surgery.test.js.map +0 -1
- package/dist/test/ops-alert.test.d.ts +0 -2
- package/dist/test/ops-alert.test.d.ts.map +0 -1
- package/dist/test/ops-alert.test.js +0 -153
- package/dist/test/ops-alert.test.js.map +0 -1
- package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
- package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
- package/dist/test/overbudget-drain-breaker.test.js +0 -198
- package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
- package/dist/test/pack-installs-alone.test.d.ts +0 -2
- package/dist/test/pack-installs-alone.test.d.ts.map +0 -1
- package/dist/test/pack-installs-alone.test.js +0 -284
- package/dist/test/pack-installs-alone.test.js.map +0 -1
- package/dist/test/per-agent-delivery.test.d.ts +0 -2
- package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
- package/dist/test/per-agent-delivery.test.js +0 -108
- package/dist/test/per-agent-delivery.test.js.map +0 -1
- package/dist/test/physical-window-restart.test.d.ts +0 -16
- package/dist/test/physical-window-restart.test.d.ts.map +0 -1
- package/dist/test/physical-window-restart.test.js +0 -487
- package/dist/test/physical-window-restart.test.js.map +0 -1
- package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
- package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
- package/dist/test/placed-reaction-baseline.test.js +0 -312
- package/dist/test/placed-reaction-baseline.test.js.map +0 -1
- package/dist/test/present-while-acting.test.d.ts +0 -19
- package/dist/test/present-while-acting.test.d.ts.map +0 -1
- package/dist/test/present-while-acting.test.js +0 -1649
- package/dist/test/present-while-acting.test.js.map +0 -1
- package/dist/test/prose-segments.test.d.ts +0 -2
- package/dist/test/prose-segments.test.d.ts.map +0 -1
- package/dist/test/prose-segments.test.js +0 -52
- package/dist/test/prose-segments.test.js.map +0 -1
- package/dist/test/prose-stream-router.test.d.ts +0 -2
- package/dist/test/prose-stream-router.test.d.ts.map +0 -1
- package/dist/test/prose-stream-router.test.js +0 -171
- package/dist/test/prose-stream-router.test.js.map +0 -1
- package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
- package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
- package/dist/test/provider-acceleration-cooldown.test.js +0 -435
- package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
- package/dist/test/provider-waits.test.d.ts +0 -2
- package/dist/test/provider-waits.test.d.ts.map +0 -1
- package/dist/test/provider-waits.test.js +0 -2259
- package/dist/test/provider-waits.test.js.map +0 -1
- package/dist/test/puppet-tool-call.test.d.ts +0 -2
- package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
- package/dist/test/puppet-tool-call.test.js +0 -226
- package/dist/test/puppet-tool-call.test.js.map +0 -1
- package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
- package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
- package/dist/test/puppet-turn-reservation.test.js +0 -139
- package/dist/test/puppet-turn-reservation.test.js.map +0 -1
- package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
- package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
- package/dist/test/reaction-baseline-platform.test.js +0 -124
- package/dist/test/reaction-baseline-platform.test.js.map +0 -1
- package/dist/test/record-journal.test.d.ts +0 -6
- package/dist/test/record-journal.test.d.ts.map +0 -1
- package/dist/test/record-journal.test.js +0 -269
- package/dist/test/record-journal.test.js.map +0 -1
- package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
- package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
- package/dist/test/refusal-reaction-baseline.test.js +0 -81
- package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
- package/dist/test/refusal-rewind.test.d.ts +0 -2
- package/dist/test/refusal-rewind.test.d.ts.map +0 -1
- package/dist/test/refusal-rewind.test.js +0 -117
- package/dist/test/refusal-rewind.test.js.map +0 -1
- package/dist/test/refusal-single-call.test.d.ts +0 -2
- package/dist/test/refusal-single-call.test.d.ts.map +0 -1
- package/dist/test/refusal-single-call.test.js +0 -177
- package/dist/test/refusal-single-call.test.js.map +0 -1
- package/dist/test/release-bump.test.d.ts +0 -2
- package/dist/test/release-bump.test.d.ts.map +0 -1
- package/dist/test/release-bump.test.js +0 -248
- package/dist/test/release-bump.test.js.map +0 -1
- package/dist/test/release-changelog.test.d.ts +0 -2
- package/dist/test/release-changelog.test.d.ts.map +0 -1
- package/dist/test/release-changelog.test.js +0 -159
- package/dist/test/release-changelog.test.js.map +0 -1
- package/dist/test/release-holds.test.d.ts +0 -2
- package/dist/test/release-holds.test.d.ts.map +0 -1
- package/dist/test/release-holds.test.js +0 -456
- package/dist/test/release-holds.test.js.map +0 -1
- package/dist/test/same-round-think-policy.test.d.ts +0 -2
- package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
- package/dist/test/same-round-think-policy.test.js +0 -853
- package/dist/test/same-round-think-policy.test.js.map +0 -1
- package/dist/test/save-recent-image.test.d.ts +0 -26
- package/dist/test/save-recent-image.test.d.ts.map +0 -1
- package/dist/test/save-recent-image.test.js +0 -974
- package/dist/test/save-recent-image.test.js.map +0 -1
- package/dist/test/shutdown-errors.test.d.ts +0 -2
- package/dist/test/shutdown-errors.test.d.ts.map +0 -1
- package/dist/test/shutdown-errors.test.js +0 -662
- package/dist/test/shutdown-errors.test.js.map +0 -1
- package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
- package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
- package/dist/test/silent-heartbeat-rows.test.js +0 -451
- package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
- package/dist/test/silent-heartbeat.test.d.ts +0 -2
- package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
- package/dist/test/silent-heartbeat.test.js +0 -165
- package/dist/test/silent-heartbeat.test.js.map +0 -1
- package/dist/test/state-scaling-e2e.test.d.ts +0 -22
- package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
- package/dist/test/state-scaling-e2e.test.js +0 -206
- package/dist/test/state-scaling-e2e.test.js.map +0 -1
- package/dist/test/state-scaling.test.d.ts +0 -12
- package/dist/test/state-scaling.test.d.ts.map +0 -1
- package/dist/test/state-scaling.test.js +0 -251
- package/dist/test/state-scaling.test.js.map +0 -1
- package/dist/test/stop-with-host-operations.test.d.ts +0 -20
- package/dist/test/stop-with-host-operations.test.d.ts.map +0 -1
- package/dist/test/stop-with-host-operations.test.js +0 -1174
- package/dist/test/stop-with-host-operations.test.js.map +0 -1
- package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
- package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
- package/dist/test/stop-with-work-in-flight.test.js +0 -784
- package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
- package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
- package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
- package/dist/test/surgery-marks-receipt.test.js +0 -540
- package/dist/test/surgery-marks-receipt.test.js.map +0 -1
- package/dist/test/thinking-token-stamp.test.d.ts +0 -12
- package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
- package/dist/test/thinking-token-stamp.test.js +0 -129
- package/dist/test/thinking-token-stamp.test.js.map +0 -1
- package/dist/test/timezone.test.d.ts +0 -2
- package/dist/test/timezone.test.d.ts.map +0 -1
- package/dist/test/timezone.test.js +0 -18
- package/dist/test/timezone.test.js.map +0 -1
- package/dist/test/tool-batch-hook.test.d.ts +0 -8
- package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
- package/dist/test/tool-batch-hook.test.js +0 -275
- package/dist/test/tool-batch-hook.test.js.map +0 -1
- package/dist/test/tool-policy.test.d.ts +0 -2
- package/dist/test/tool-policy.test.d.ts.map +0 -1
- package/dist/test/tool-policy.test.js +0 -51
- package/dist/test/tool-policy.test.js.map +0 -1
- package/dist/test/tool-presentation.test.d.ts +0 -2
- package/dist/test/tool-presentation.test.d.ts.map +0 -1
- package/dist/test/tool-presentation.test.js +0 -268
- package/dist/test/tool-presentation.test.js.map +0 -1
- package/dist/test/tool-result-content.test.d.ts +0 -2
- package/dist/test/tool-result-content.test.d.ts.map +0 -1
- package/dist/test/tool-result-content.test.js +0 -37
- package/dist/test/tool-result-content.test.js.map +0 -1
- package/dist/test/tool-result-guard.test.d.ts +0 -2
- package/dist/test/tool-result-guard.test.d.ts.map +0 -1
- package/dist/test/tool-result-guard.test.js +0 -3729
- package/dist/test/tool-result-guard.test.js.map +0 -1
- package/dist/test/tool-result-history.test.d.ts +0 -7
- package/dist/test/tool-result-history.test.d.ts.map +0 -1
- package/dist/test/tool-result-history.test.js +0 -156
- package/dist/test/tool-result-history.test.js.map +0 -1
- package/dist/test/tool-result-spill.test.d.ts +0 -13
- package/dist/test/tool-result-spill.test.d.ts.map +0 -1
- package/dist/test/tool-result-spill.test.js +0 -586
- package/dist/test/tool-result-spill.test.js.map +0 -1
- package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
- package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
- package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
- package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
- package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
- package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
- package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
- package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
- package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
- package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
- package/dist/test/tools-observe-parser-conformance.test.js +0 -129
- package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
- package/dist/test/trunk-channel-routing.test.d.ts +0 -19
- package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
- package/dist/test/trunk-channel-routing.test.js +0 -652
- package/dist/test/trunk-channel-routing.test.js.map +0 -1
- package/dist/test/tune-out-e2e.test.d.ts +0 -2
- package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
- package/dist/test/tune-out-e2e.test.js +0 -142
- package/dist/test/tune-out-e2e.test.js.map +0 -1
- package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
- package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
- package/dist/test/tune-out-gate-composition.test.js +0 -221
- package/dist/test/tune-out-gate-composition.test.js.map +0 -1
- package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
- package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
- package/dist/test/tune-out-lifecycle.test.js +0 -121
- package/dist/test/tune-out-lifecycle.test.js.map +0 -1
- package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
- package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
- package/dist/test/turn-trigger-provenance.test.js +0 -137
- package/dist/test/turn-trigger-provenance.test.js.map +0 -1
- package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
- package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
- package/dist/test/unconvertible-tool-result.test.js +0 -358
- package/dist/test/unconvertible-tool-result.test.js.map +0 -1
- package/dist/test/unsent-compiles.test.d.ts +0 -2
- package/dist/test/unsent-compiles.test.d.ts.map +0 -1
- package/dist/test/unsent-compiles.test.js +0 -139
- package/dist/test/unsent-compiles.test.js.map +0 -1
- package/dist/test/usage-accounting.test.d.ts +0 -2
- package/dist/test/usage-accounting.test.d.ts.map +0 -1
- package/dist/test/usage-accounting.test.js +0 -13
- package/dist/test/usage-accounting.test.js.map +0 -1
- package/dist/test/usage-tracker.test.d.ts +0 -2
- package/dist/test/usage-tracker.test.d.ts.map +0 -1
- package/dist/test/usage-tracker.test.js +0 -129
- package/dist/test/usage-tracker.test.js.map +0 -1
- package/dist/test/utils-surface.test.d.ts +0 -2
- package/dist/test/utils-surface.test.d.ts.map +0 -1
- package/dist/test/utils-surface.test.js +0 -145
- package/dist/test/utils-surface.test.js.map +0 -1
- package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
- package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
- package/dist/test/workspace-branch-continuation.test.js +0 -183
- package/dist/test/workspace-branch-continuation.test.js.map +0 -1
- package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
- package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
- package/dist/test/workspace-materialize-freshness.test.js +0 -252
- package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
- package/dist/test/workspace-path-containment.test.d.ts +0 -19
- package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
- package/dist/test/workspace-path-containment.test.js +0 -91
- package/dist/test/workspace-path-containment.test.js.map +0 -1
- package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
- package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
- package/dist/test/workspace-read-file-from-disk.test.js +0 -174
- package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
- package/dist/test/workspace-read-image.test.d.ts +0 -2
- package/dist/test/workspace-read-image.test.d.ts.map +0 -1
- package/dist/test/workspace-read-image.test.js +0 -597
- package/dist/test/workspace-read-image.test.js.map +0 -1
- package/dist/test/workspace-read-text.test.d.ts +0 -2
- package/dist/test/workspace-read-text.test.d.ts.map +0 -1
- package/dist/test/workspace-read-text.test.js +0 -101
- package/dist/test/workspace-read-text.test.js.map +0 -1
- package/dist/test/workspace-restore-order.test.d.ts +0 -16
- package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
- package/dist/test/workspace-restore-order.test.js +0 -140
- package/dist/test/workspace-restore-order.test.js.map +0 -1
- package/dist/test/workspace-three-way.test.d.ts +0 -12
- package/dist/test/workspace-three-way.test.d.ts.map +0 -1
- package/dist/test/workspace-three-way.test.js +0 -4094
- package/dist/test/workspace-three-way.test.js.map +0 -1
- package/dist/test/workspace-watcher.test.d.ts +0 -2
- package/dist/test/workspace-watcher.test.d.ts.map +0 -1
- package/dist/test/workspace-watcher.test.js +0 -281
- package/dist/test/workspace-watcher.test.js.map +0 -1
- package/dist/test/xml-round-persist.test.d.ts +0 -19
- package/dist/test/xml-round-persist.test.d.ts.map +0 -1
- package/dist/test/xml-round-persist.test.js +0 -235
- package/dist/test/xml-round-persist.test.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -1,621 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration tests for per-channel conversation routing: incoming MCPL
|
|
3
|
-
* channel messages spawn/route to fork agents instead of the primary
|
|
4
|
-
* conversation when FrameworkConfig.conversations is set.
|
|
5
|
-
*/
|
|
6
|
-
import { describe, it, beforeEach, afterEach, mock } from 'node:test';
|
|
7
|
-
import assert from 'node:assert/strict';
|
|
8
|
-
import { tmpdir } from 'node:os';
|
|
9
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
10
|
-
import { join } from 'node:path';
|
|
11
|
-
import { AgentFramework } from '../src/index.js';
|
|
12
|
-
import { Membrane, OpenAIResponsesAPIAdapter, OpenAIResponsesFormatter } from '@animalabs/membrane';
|
|
13
|
-
import { MockMembrane, createMockResponse } from './helpers/mock-membrane.js';
|
|
14
|
-
function incomingEvent(overrides) {
|
|
15
|
-
return {
|
|
16
|
-
type: 'mcpl:channel-incoming',
|
|
17
|
-
serverId: 'srv',
|
|
18
|
-
channelId: overrides.channelId,
|
|
19
|
-
messageId: overrides.messageId ?? `m-${Math.random().toString(36).slice(2)}`,
|
|
20
|
-
author: { id: 'U1', name: 'alice' },
|
|
21
|
-
content: [{ type: 'text', text: overrides.text }],
|
|
22
|
-
timestamp: new Date().toISOString(),
|
|
23
|
-
metadata: {
|
|
24
|
-
mentioned: overrides.mentioned ?? false,
|
|
25
|
-
...(overrides.channelType ? { channel_type: overrides.channelType } : {}),
|
|
26
|
-
},
|
|
27
|
-
triggerInference: true,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
describe('Conversation routing', () => {
|
|
31
|
-
let tempDir;
|
|
32
|
-
let membrane;
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
tempDir = mkdtempSync(join(tmpdir(), 'conv-routing-test-'));
|
|
35
|
-
membrane = new MockMembrane();
|
|
36
|
-
});
|
|
37
|
-
afterEach(() => {
|
|
38
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
39
|
-
});
|
|
40
|
-
async function makeFramework(conversations = {}, storeFile = 'test.chronicle') {
|
|
41
|
-
return AgentFramework.create({
|
|
42
|
-
storePath: join(tempDir, storeFile),
|
|
43
|
-
membrane: membrane.asMembrane(),
|
|
44
|
-
agents: [
|
|
45
|
-
{ name: 'trunk', model: 'test-model', systemPrompt: 'You are the trunk.' },
|
|
46
|
-
],
|
|
47
|
-
modules: [],
|
|
48
|
-
conversations: { templateAgent: 'trunk', ...conversations },
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/** Make a binding look idle past the TTL and re-arm the sweep throttle —
|
|
52
|
-
* deterministic expiry instead of racing a 1ms TTL against the wall clock. */
|
|
53
|
-
function forceExpiry(framework, channelId, idleTtlMs) {
|
|
54
|
-
const binding = framework.getConversationRouter().getBinding(channelId);
|
|
55
|
-
assert.ok(binding, `binding for ${channelId} should exist before forcing expiry`);
|
|
56
|
-
binding.lastActivity = Date.now() - idleTtlMs - 1_000;
|
|
57
|
-
framework.lastConversationSweep = 0;
|
|
58
|
-
}
|
|
59
|
-
it('rejects an unknown template agent at creation', async () => {
|
|
60
|
-
await assert.rejects(() => AgentFramework.create({
|
|
61
|
-
storePath: join(tempDir, 'test.chronicle'),
|
|
62
|
-
membrane: membrane.asMembrane(),
|
|
63
|
-
agents: [{ name: 'trunk', model: 'test-model', systemPrompt: 'x' }],
|
|
64
|
-
modules: [],
|
|
65
|
-
conversations: { templateAgent: 'nope' },
|
|
66
|
-
}), /templateAgent "nope"/);
|
|
67
|
-
});
|
|
68
|
-
// Deprecation (agent-framework#235): behavior unchanged, one stderr line.
|
|
69
|
-
function deprecationWarnings(warn) {
|
|
70
|
-
return warn.mock.calls
|
|
71
|
-
.map((c) => String(c.arguments[0]))
|
|
72
|
-
.filter((line) => line.startsWith('[deprecated]') && line.includes('conversation routing'));
|
|
73
|
-
}
|
|
74
|
-
it('configured: logs one [deprecated] line per framework and still routes', async () => {
|
|
75
|
-
const warn = mock.method(console, 'warn', () => { });
|
|
76
|
-
let framework;
|
|
77
|
-
try {
|
|
78
|
-
framework = await makeFramework();
|
|
79
|
-
assert.equal(deprecationWarnings(warn).length, 1, 'warned once at creation');
|
|
80
|
-
assert.match(deprecationWarnings(warn)[0], /agent-framework#235/);
|
|
81
|
-
// Routing is unchanged: a DM and a channel mention each spawn a fork.
|
|
82
|
-
// (One queued response per stream: MockMembrane hands a stream every
|
|
83
|
-
// response still queued.)
|
|
84
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Hi alice!' }]));
|
|
85
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:D1', text: 'hello there', channelType: 'im' }));
|
|
86
|
-
await framework.runUntilIdle();
|
|
87
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'On it.' }]));
|
|
88
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'bot, help', mentioned: true }));
|
|
89
|
-
await framework.runUntilIdle();
|
|
90
|
-
assert.ok(framework.getAgent('conversation-slack-D1-g1'), 'DM fork spawned');
|
|
91
|
-
assert.ok(framework.getAgent('conversation-slack-C1-g1'), 'channel-mention fork spawned');
|
|
92
|
-
assert.equal(membrane.calls.length, 2, 'both forks ran inference');
|
|
93
|
-
assert.equal(deprecationWarnings(warn).length, 1, 'spawning forks does not warn again');
|
|
94
|
-
}
|
|
95
|
-
finally {
|
|
96
|
-
warn.mock.restore();
|
|
97
|
-
await framework?.stop();
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
it('not configured: no [deprecated] line', async () => {
|
|
101
|
-
const warn = mock.method(console, 'warn', () => { });
|
|
102
|
-
let framework;
|
|
103
|
-
try {
|
|
104
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Hi alice!' }]));
|
|
105
|
-
framework = await AgentFramework.create({
|
|
106
|
-
storePath: join(tempDir, 'test.chronicle'),
|
|
107
|
-
membrane: membrane.asMembrane(),
|
|
108
|
-
agents: [{ name: 'trunk', model: 'test-model', systemPrompt: 'You are the trunk.' }],
|
|
109
|
-
modules: [],
|
|
110
|
-
});
|
|
111
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:D1', text: 'hello there', channelType: 'im' }));
|
|
112
|
-
await framework.runUntilIdle();
|
|
113
|
-
assert.equal(framework.getConversationRouter(), null);
|
|
114
|
-
assert.deepEqual(deprecationWarnings(warn), []);
|
|
115
|
-
}
|
|
116
|
-
finally {
|
|
117
|
-
warn.mock.restore();
|
|
118
|
-
await framework?.stop();
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
it('DM message spawns a fork, routes the message there, and triggers inference', async () => {
|
|
122
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Hi alice!' }]));
|
|
123
|
-
const framework = await makeFramework();
|
|
124
|
-
framework.pushEvent(incomingEvent({
|
|
125
|
-
channelId: 'slack:D1', text: 'hello there', channelType: 'im',
|
|
126
|
-
}));
|
|
127
|
-
await framework.runUntilIdle();
|
|
128
|
-
const fork = framework.getAgent('conversation-slack-D1-g1');
|
|
129
|
-
assert.ok(fork, 'fork agent should exist');
|
|
130
|
-
// Message landed in the fork's context, not the trunk's.
|
|
131
|
-
const { messages: forkMessages } = await fork.getContextManager().compile();
|
|
132
|
-
assert.ok(forkMessages.some((m) => JSON.stringify(m.content).includes('hello there')), 'fork context should contain the incoming message');
|
|
133
|
-
const trunk = framework.getAgent('trunk');
|
|
134
|
-
const { messages: trunkMessages } = await trunk.getContextManager().compile();
|
|
135
|
-
assert.ok(!trunkMessages.some((m) => JSON.stringify(m.content).includes('hello there')), 'trunk context must not receive routed messages');
|
|
136
|
-
// Inference ran for the fork.
|
|
137
|
-
assert.ok(membrane.calls.length >= 1, 'inference should have been triggered');
|
|
138
|
-
// Binding is live.
|
|
139
|
-
const router = framework.getConversationRouter();
|
|
140
|
-
assert.equal(router.getBinding('slack:D1')?.agentName, 'conversation-slack-D1-g1');
|
|
141
|
-
await framework.stop();
|
|
142
|
-
});
|
|
143
|
-
it('channel message without mention is dropped; mention spawns', async () => {
|
|
144
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'On it.' }]));
|
|
145
|
-
const framework = await makeFramework();
|
|
146
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'just chatting' }));
|
|
147
|
-
await framework.runUntilIdle();
|
|
148
|
-
assert.equal(framework.getAgent('conversation-slack-C1-g1'), null, 'no fork without mention');
|
|
149
|
-
assert.equal(membrane.calls.length, 0, 'no inference for unrouted messages');
|
|
150
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'bot, help', mentioned: true }));
|
|
151
|
-
await framework.runUntilIdle();
|
|
152
|
-
assert.ok(framework.getAgent('conversation-slack-C1-g1'), 'mention spawns fork');
|
|
153
|
-
await framework.stop();
|
|
154
|
-
});
|
|
155
|
-
it('non-mention on a bound channel lands in context without triggering', async () => {
|
|
156
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ack' }]));
|
|
157
|
-
const framework = await makeFramework();
|
|
158
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'first', mentioned: true }));
|
|
159
|
-
await framework.runUntilIdle();
|
|
160
|
-
const callsAfterSpawn = membrane.calls.length;
|
|
161
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C1', text: 'ambient detail' }));
|
|
162
|
-
await framework.runUntilIdle();
|
|
163
|
-
const fork = framework.getAgent('conversation-slack-C1-g1');
|
|
164
|
-
const { messages } = await fork.getContextManager().compile();
|
|
165
|
-
assert.ok(messages.some((m) => JSON.stringify(m.content).includes('ambient detail')), 'ambient message should land in fork context');
|
|
166
|
-
assert.equal(membrane.calls.length, callsAfterSpawn, 'ambient message must not trigger inference');
|
|
167
|
-
await framework.stop();
|
|
168
|
-
});
|
|
169
|
-
/** Spawn the fork for `slack:D3`, and return what its namespace was seeded
|
|
170
|
-
* with and the `[conversation]` lines the spawn logged. */
|
|
171
|
-
async function seedOf(framework) {
|
|
172
|
-
const log = mock.method(console, 'log', () => { });
|
|
173
|
-
let lines;
|
|
174
|
-
try {
|
|
175
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:D3', text: 'hi', channelType: 'im' }));
|
|
176
|
-
await framework.runUntilIdle();
|
|
177
|
-
lines = log.mock.calls.map((c) => String(c.arguments[0])).filter((line) => line.startsWith('[conversation]'));
|
|
178
|
-
}
|
|
179
|
-
finally {
|
|
180
|
-
log.mock.restore();
|
|
181
|
-
}
|
|
182
|
-
const seeded = framework.getAgent('conversation-slack-D3-g1').getContextManager().getAllMessages();
|
|
183
|
-
return { seeded, lines };
|
|
184
|
-
}
|
|
185
|
-
/** The line a spawn logs for a seed that left something out. */
|
|
186
|
-
function seedLine(thinking, calls, results) {
|
|
187
|
-
return `[conversation] conversation-slack-D3-g1: seeded from trunk without ${thinking} thinking block(s), ` +
|
|
188
|
-
`${calls} unanswered tool call(s) and ${results} orphaned tool result(s)`;
|
|
189
|
-
}
|
|
190
|
-
it('fork inherits the template context, and a seed that leaves nothing out logs nothing', async () => {
|
|
191
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
|
|
192
|
-
const framework = await makeFramework();
|
|
193
|
-
// Seed the trunk (primary agent) with handbook-like content.
|
|
194
|
-
framework.getAgent('trunk').getContextManager().addMessage('user', [
|
|
195
|
-
{ type: 'text', text: 'HANDBOOK: always check the logs first.' },
|
|
196
|
-
]);
|
|
197
|
-
const { seeded, lines } = await seedOf(framework);
|
|
198
|
-
assert.ok(seeded.some((m) => JSON.stringify(m.content).includes('HANDBOOK')), 'fork should inherit trunk context');
|
|
199
|
-
assert.deepEqual(lines, [], 'a seed with nothing left out logs no line');
|
|
200
|
-
await framework.stop();
|
|
201
|
-
});
|
|
202
|
-
it("a fork's seed is a dry run, and carries none of the template's thinking", async () => {
|
|
203
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
|
|
204
|
-
const framework = await makeFramework();
|
|
205
|
-
const trunk = framework.getAgent('trunk').getContextManager();
|
|
206
|
-
trunk.addMessage('user', [{ type: 'text', text: 'HANDBOOK: always check the logs first.' }]);
|
|
207
|
-
trunk.addMessage('trunk', [
|
|
208
|
-
{ type: 'thinking', thinking: 'minted under the trunk\'s prefix', signature: 'sig-trunk' },
|
|
209
|
-
{ type: 'text', text: 'Checked the logs.' },
|
|
210
|
-
]);
|
|
211
|
-
trunk.addMessage('trunk', [{ type: 'redacted_thinking', data: 'opaque' }]);
|
|
212
|
-
// Every compile on any context manager during the spawn, by instance.
|
|
213
|
-
const proto = trunk.constructor.prototype;
|
|
214
|
-
const original = proto.compile;
|
|
215
|
-
const compiles = [];
|
|
216
|
-
proto.compile = function (...args) {
|
|
217
|
-
compiles.push({ cm: this, dry: args[2]?.dryRun === true });
|
|
218
|
-
return original.apply(this, args);
|
|
219
|
-
};
|
|
220
|
-
let seed;
|
|
221
|
-
try {
|
|
222
|
-
seed = await seedOf(framework);
|
|
223
|
-
}
|
|
224
|
-
finally {
|
|
225
|
-
proto.compile = original;
|
|
226
|
-
}
|
|
227
|
-
const { seeded, lines } = seed;
|
|
228
|
-
const fork = framework.getAgent('conversation-slack-D3-g1').getContextManager();
|
|
229
|
-
const onTrunk = compiles.filter((c) => c.cm === trunk);
|
|
230
|
-
assert.ok(onTrunk.length >= 1, 'the seed compiled the template');
|
|
231
|
-
assert.ok(onTrunk.every((c) => c.dry), "the template's compiles during the spawn are dry runs");
|
|
232
|
-
assert.equal(compiles.find((c) => c.cm === fork)?.dry, true, "the new namespace's emptiness check is a dry run");
|
|
233
|
-
const types = seeded.flatMap((m) => m.content.map((b) => b.type));
|
|
234
|
-
assert.ok(!types.includes('thinking') && !types.includes('redacted_thinking'), `no thinking in the seed: ${types}`);
|
|
235
|
-
const texts = seeded.map((m) => JSON.stringify(m.content));
|
|
236
|
-
assert.ok(texts.some((t) => t.includes('HANDBOOK')) && texts.some((t) => t.includes('Checked the logs.')));
|
|
237
|
-
assert.ok(seeded.some((m) => m.participant === 'conversation-slack-D3-g1'
|
|
238
|
-
&& JSON.stringify(m.content).includes('Checked the logs.')), "the reply keeps its text, under the fork's name");
|
|
239
|
-
assert.ok(seeded.every((m) => m.content.length > 0), 'the thinking-only message is left out, not stored empty');
|
|
240
|
-
assert.deepEqual(lines, [seedLine(2, 0, 0)], 'one line counts what the seed left out');
|
|
241
|
-
await framework.stop();
|
|
242
|
-
});
|
|
243
|
-
it("a seed that ends on a completed tool round keeps the round, without its thinking", async () => {
|
|
244
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
|
|
245
|
-
const framework = await makeFramework();
|
|
246
|
-
const trunk = framework.getAgent('trunk').getContextManager();
|
|
247
|
-
trunk.addMessage('user', [{ type: 'text', text: 'check the logs' }]);
|
|
248
|
-
trunk.addMessage('trunk', [
|
|
249
|
-
{ type: 'thinking', thinking: 'the logs first', signature: 'sig-round' },
|
|
250
|
-
{ type: 'tool_use', id: 'toolu_logs', name: 'read_logs', input: {} },
|
|
251
|
-
]);
|
|
252
|
-
trunk.addMessage('user', [{ type: 'tool_result', toolUseId: 'toolu_logs', content: 'all quiet' }]);
|
|
253
|
-
const { seeded, lines } = await seedOf(framework);
|
|
254
|
-
const contents = seeded.map((m) => m.content);
|
|
255
|
-
const round = contents.findIndex((c) => c.some((b) => b.type === 'tool_use'));
|
|
256
|
-
assert.ok(round >= 0, 'the round is in the seed');
|
|
257
|
-
assert.deepEqual(contents[round].map((b) => b.type), ['tool_use'], 'its call stays, its thinking goes');
|
|
258
|
-
assert.equal(seeded[round].participant, 'conversation-slack-D3-g1');
|
|
259
|
-
assert.deepEqual(contents[round + 1].map((b) => b.type), ['tool_result'], 'its result follows it');
|
|
260
|
-
assert.deepEqual(lines, [seedLine(1, 0, 0)]);
|
|
261
|
-
await framework.stop();
|
|
262
|
-
});
|
|
263
|
-
it("a seed's unanswered call gives way to a placeholder, and the seed ends on neither it nor a thinking-only row", async () => {
|
|
264
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
|
|
265
|
-
const framework = await makeFramework();
|
|
266
|
-
const trunk = framework.getAgent('trunk').getContextManager();
|
|
267
|
-
trunk.addMessage('user', [{ type: 'text', text: 'check the logs' }]);
|
|
268
|
-
trunk.addMessage('trunk', [{ type: 'text', text: 'Looking.' }]);
|
|
269
|
-
// A tool round's assistant row, stored before its results (the spawn can
|
|
270
|
-
// land between the two when the coalescer spawns outside the event loop),
|
|
271
|
-
// and a thinking-only row after it.
|
|
272
|
-
trunk.addMessage('trunk', [
|
|
273
|
-
{ type: 'thinking', thinking: 'mid-round', signature: 'sig-mid' },
|
|
274
|
-
{ type: 'tool_use', id: 'toolu_pending', name: 'read_logs', input: {} },
|
|
275
|
-
]);
|
|
276
|
-
trunk.addMessage('trunk', [{ type: 'thinking', thinking: 'still thinking', signature: 'sig-after' }]);
|
|
277
|
-
const { seeded, lines } = await seedOf(framework);
|
|
278
|
-
const types = seeded.flatMap((m) => m.content.map((b) => b.type));
|
|
279
|
-
assert.ok(!types.includes('tool_use') && !types.includes('thinking'), `no unanswered call or thinking in the seed: ${types}`);
|
|
280
|
-
// The seed is everything before the fork's own first message ('hi').
|
|
281
|
-
const firstOwn = seeded.findIndex((m) => JSON.stringify(m.content).includes('"hi"'));
|
|
282
|
-
assert.ok(firstOwn > 1, 'the incoming message follows the seed');
|
|
283
|
-
// The thinking goes first, so the round's row holds only its unanswered
|
|
284
|
-
// call, which the pairing pass replaces with its placeholder.
|
|
285
|
-
const last = seeded[firstOwn - 1];
|
|
286
|
-
assert.deepEqual(last.content.map((b) => b.type), ['text']);
|
|
287
|
-
assert.ok(JSON.stringify(last.content).includes('[tool call omitted]'), `the seed ends on the placeholder: ${JSON.stringify(last.content)}`);
|
|
288
|
-
assert.equal(last.participant, 'conversation-slack-D3-g1');
|
|
289
|
-
assert.ok(JSON.stringify(seeded[firstOwn - 2].content).includes('Looking.'), 'the exchange before the round stays');
|
|
290
|
-
assert.deepEqual(lines, [seedLine(2, 1, 0)]);
|
|
291
|
-
await framework.stop();
|
|
292
|
-
});
|
|
293
|
-
it("a seed keeps a partly answered round's answered call and drops the other, drops an orphaned result and a trailing unanswered call, and keeps the text beside each", async () => {
|
|
294
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
|
|
295
|
-
const framework = await makeFramework();
|
|
296
|
-
const trunk = framework.getAgent('trunk').getContextManager();
|
|
297
|
-
// A result whose call isn't in the history (as where a window starts
|
|
298
|
-
// after the call), beside the user's text.
|
|
299
|
-
trunk.addMessage('user', [
|
|
300
|
-
{ type: 'tool_result', toolUseId: 'toolu_gone', content: 'stale' },
|
|
301
|
-
{ type: 'text', text: 'check both' },
|
|
302
|
-
]);
|
|
303
|
-
// A parallel round with one of its two calls answered.
|
|
304
|
-
trunk.addMessage('trunk', [
|
|
305
|
-
{ type: 'text', text: 'Checking both.' },
|
|
306
|
-
{ type: 'tool_use', id: 'toolu_a', name: 'read_logs', input: {} },
|
|
307
|
-
{ type: 'tool_use', id: 'toolu_b', name: 'read_config', input: {} },
|
|
308
|
-
]);
|
|
309
|
-
trunk.addMessage('user', [{ type: 'tool_result', toolUseId: 'toolu_a', content: 'all quiet' }]);
|
|
310
|
-
// The next round's row, stored before its result: thinking, text and a call.
|
|
311
|
-
trunk.addMessage('trunk', [
|
|
312
|
-
{ type: 'thinking', thinking: 'the config next', signature: 'sig-next' },
|
|
313
|
-
{ type: 'text', text: 'And the config.' },
|
|
314
|
-
{ type: 'tool_use', id: 'toolu_c', name: 'read_config', input: {} },
|
|
315
|
-
]);
|
|
316
|
-
const { seeded, lines } = await seedOf(framework);
|
|
317
|
-
const blocks = seeded.flatMap((m) => m.content);
|
|
318
|
-
assert.deepEqual(blocks.filter((b) => b.type === 'tool_use').map((b) => b.id), ['toolu_a'], 'the answered call stays, the unanswered ones go');
|
|
319
|
-
assert.deepEqual(blocks.filter((b) => b.type === 'tool_result').map((b) => b.toolUseId), ['toolu_a'], 'its result stays, the orphaned one goes');
|
|
320
|
-
const round = seeded.find((m) => m.content.some((b) => b.type === 'tool_use'));
|
|
321
|
-
assert.deepEqual(round.content.map((b) => b.type), ['text', 'tool_use'], "the round's text stays beside its answered call");
|
|
322
|
-
assert.ok(seeded.some((m) => JSON.stringify(m.content).includes('check both')), "the user's text stays beside the orphaned result");
|
|
323
|
-
const trailing = seeded.find((m) => JSON.stringify(m.content).includes('And the config.'));
|
|
324
|
-
assert.deepEqual(trailing.content.map((b) => b.type), ['text'], "the trailing row keeps its text, without its thinking or its unanswered call");
|
|
325
|
-
assert.deepEqual(lines, [seedLine(1, 2, 1)]);
|
|
326
|
-
await framework.stop();
|
|
327
|
-
});
|
|
328
|
-
/** A Responses reply as membrane stores it: `output` through membrane's own
|
|
329
|
-
* Responses adapter and its conversion to content blocks, with the HTTP
|
|
330
|
-
* call stubbed. */
|
|
331
|
-
async function storedResponsesReply(output) {
|
|
332
|
-
const completed = {
|
|
333
|
-
type: 'response.completed',
|
|
334
|
-
response: { id: 'resp_seed', status: 'completed', output, usage: { input_tokens: 1, output_tokens: 1 } },
|
|
335
|
-
};
|
|
336
|
-
const realFetch = globalThis.fetch;
|
|
337
|
-
globalThis.fetch = (async () => new Response(`data: ${JSON.stringify(completed)}\n\n`, {
|
|
338
|
-
status: 200,
|
|
339
|
-
headers: { 'content-type': 'text/event-stream' },
|
|
340
|
-
}));
|
|
341
|
-
try {
|
|
342
|
-
const responses = new Membrane(new OpenAIResponsesAPIAdapter({ apiKey: 'test' }), {
|
|
343
|
-
formatter: new OpenAIResponsesFormatter(),
|
|
344
|
-
});
|
|
345
|
-
const response = await responses.stream({
|
|
346
|
-
messages: [{ participant: 'user', content: [{ type: 'text', text: 'what changed?' }] }],
|
|
347
|
-
config: { model: 'gpt-test', maxTokens: 100 },
|
|
348
|
-
tools: [{ name: 'read_config', description: 'Read the config.', inputSchema: { type: 'object', properties: {} } }],
|
|
349
|
-
});
|
|
350
|
-
return response.content;
|
|
351
|
-
}
|
|
352
|
-
finally {
|
|
353
|
-
globalThis.fetch = realFetch;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
it("a Responses seed replays no item paired with the reasoning it left out; opaque carriers stay whole", async () => {
|
|
357
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'ok' }]));
|
|
358
|
-
const framework = await makeFramework();
|
|
359
|
-
const trunk = framework.getAgent('trunk').getContextManager();
|
|
360
|
-
trunk.addMessage('user', [{ type: 'text', text: 'what changed?' }]);
|
|
361
|
-
// A reply holding a compaction, a reasoning item, a hosted web search, a
|
|
362
|
-
// message and a function call, as membrane stores it.
|
|
363
|
-
trunk.addMessage('trunk', await storedResponsesReply([
|
|
364
|
-
{ type: 'compaction', id: 'cmp_1', encrypted_content: 'earlier history' },
|
|
365
|
-
{ type: 'reasoning', id: 'rs_1', encrypted_content: 'enc', summary: [] },
|
|
366
|
-
{ type: 'web_search_call', id: 'ws_1', status: 'completed', action: { type: 'search', query: 'config' } },
|
|
367
|
-
{ type: 'message', id: 'msg_1', role: 'assistant', status: 'completed', content: [{ type: 'output_text', text: 'The config.' }] },
|
|
368
|
-
{ type: 'function_call', id: 'fc_1', call_id: 'call_1', name: 'read_config', arguments: '{}', status: 'completed' },
|
|
369
|
-
]));
|
|
370
|
-
trunk.addMessage('user', [{ type: 'tool_result', toolUseId: 'call_1', content: 'ok' }]);
|
|
371
|
-
// A reply with no reasoning item: nothing it was paired with is left out,
|
|
372
|
-
// so it replays as it was.
|
|
373
|
-
trunk.addMessage('trunk', await storedResponsesReply([
|
|
374
|
-
{ type: 'message', id: 'msg_2', role: 'assistant', status: 'completed', content: [{ type: 'output_text', text: 'Read it.' }] },
|
|
375
|
-
]));
|
|
376
|
-
// An Anthropic reply in the same history: its thinking carries no raw item.
|
|
377
|
-
trunk.addMessage('trunk', [
|
|
378
|
-
{ type: 'thinking', thinking: 'plain', signature: 'sig-plain' },
|
|
379
|
-
{ type: 'text', text: 'Done.' },
|
|
380
|
-
]);
|
|
381
|
-
const { seeded } = await seedOf(framework);
|
|
382
|
-
const items = new OpenAIResponsesFormatter().buildMessages(seeded.map((m) => ({ participant: m.participant, content: m.content })), { participantMode: 'simple', assistantParticipant: 'conversation-slack-D3-g1', humanParticipant: 'user', systemPrompt: 'fork' }).messages;
|
|
383
|
-
const ids = items.map((item) => item.id).filter((id) => id !== undefined);
|
|
384
|
-
assert.deepEqual(ids, ['cmp_1', 'ws_1', 'msg_2'], `only the opaque carriers and the unpaired reply replay by id: ${JSON.stringify(items)}`);
|
|
385
|
-
assert.ok(!items.some((item) => item.type === 'reasoning'), 'the reasoning item is left out');
|
|
386
|
-
assert.ok(items.some((item) => item.type === 'function_call' && item.call_id === 'call_1'), 'the call renders from its fields');
|
|
387
|
-
assert.ok(items.some((item) => item.type === 'message' && JSON.stringify(item.content).includes('The config.')), 'the text renders from its fields');
|
|
388
|
-
const plain = seeded.find((m) => JSON.stringify(m.content).includes('Done.'));
|
|
389
|
-
assert.deepEqual(plain.content.map((b) => b.type), ['text'], "an Anthropic reply loses only its thinking");
|
|
390
|
-
await framework.stop();
|
|
391
|
-
});
|
|
392
|
-
it("a fork whose namespace already holds history isn't seeded again", async () => {
|
|
393
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'noted' }]));
|
|
394
|
-
const fw1 = await makeFramework({}, 'reseed.chronicle');
|
|
395
|
-
fw1.getAgent('trunk').getContextManager().addMessage('user', [
|
|
396
|
-
{ type: 'text', text: 'HANDBOOK-V1: always check the logs first.' },
|
|
397
|
-
]);
|
|
398
|
-
fw1.pushEvent(incomingEvent({ channelId: 'slack:D8', text: 'case one', channelType: 'im' }));
|
|
399
|
-
await fw1.runUntilIdle();
|
|
400
|
-
assert.ok(fw1.getAgent('conversation-slack-D8-g1'), 'first engagement spawns g1');
|
|
401
|
-
await fw1.stop();
|
|
402
|
-
// Restart with the generation counters lost, so the next engagement
|
|
403
|
-
// proposes g1 again, and its namespace already holds g1's history.
|
|
404
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'again' }]));
|
|
405
|
-
const fw2 = await makeFramework({}, 'reseed.chronicle');
|
|
406
|
-
fw2.getConversationRouter().generations.clear();
|
|
407
|
-
fw2.pushEvent(incomingEvent({ channelId: 'slack:D8', text: 'case two', channelType: 'im' }));
|
|
408
|
-
await fw2.runUntilIdle();
|
|
409
|
-
const g1 = fw2.getAgent('conversation-slack-D8-g1');
|
|
410
|
-
assert.ok(g1, 'the lost counters propose g1 again');
|
|
411
|
-
const contents = g1.getContextManager().getAllMessages().map((m) => JSON.stringify(m.content));
|
|
412
|
-
assert.equal(contents.filter((c) => c.includes('HANDBOOK-V1')).length, 1, 'no second template copy on its history');
|
|
413
|
-
assert.ok(contents.some((c) => c.includes('case one')), 'its own history stays');
|
|
414
|
-
await fw2.stop();
|
|
415
|
-
});
|
|
416
|
-
// Exercise the delivery boundary without scheduling inference. The same
|
|
417
|
-
// handler receives ordinary channel traffic and coalesced fixed-audience notices.
|
|
418
|
-
async function deliver(framework, channelId, text, deliverTo) {
|
|
419
|
-
const internals = framework;
|
|
420
|
-
return internals.handleMcplChannelIncoming({
|
|
421
|
-
...incomingEvent({ channelId, text, mentioned: true }),
|
|
422
|
-
triggerInference: false,
|
|
423
|
-
...(deliverTo ? { deliverTo } : {}),
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
it('successful ambient delivery refreshes the bound fork idle clock', async () => {
|
|
427
|
-
const framework = await makeFramework();
|
|
428
|
-
try {
|
|
429
|
-
await deliver(framework, 'slack:C1', 'first');
|
|
430
|
-
const router = framework.getConversationRouter();
|
|
431
|
-
const binding = router.getBinding('slack:C1');
|
|
432
|
-
binding.lastActivity = 1;
|
|
433
|
-
const before = Date.now();
|
|
434
|
-
framework.pushEvent({
|
|
435
|
-
...incomingEvent({ channelId: 'slack:C1', text: 'ambient detail' }),
|
|
436
|
-
triggerInference: false,
|
|
437
|
-
});
|
|
438
|
-
await framework.runUntilIdle();
|
|
439
|
-
assert.ok(binding.lastActivity >= before, 'successful delivery records activity');
|
|
440
|
-
assert.equal(membrane.calls.length, 0, 'ambient delivery needs no inference');
|
|
441
|
-
assert.deepEqual(router.expired(before), []);
|
|
442
|
-
}
|
|
443
|
-
finally {
|
|
444
|
-
await framework.stop();
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
it('failed delivery leaves the bound fork idle clock unchanged', async () => {
|
|
448
|
-
const framework = await makeFramework();
|
|
449
|
-
try {
|
|
450
|
-
await deliver(framework, 'slack:C1', 'first');
|
|
451
|
-
const router = framework.getConversationRouter();
|
|
452
|
-
const binding = router.getBinding('slack:C1');
|
|
453
|
-
binding.lastActivity = 1;
|
|
454
|
-
const context = framework.getAgent(binding.agentName).getContextManager();
|
|
455
|
-
const addMessage = context.addMessage;
|
|
456
|
-
context.addMessage = () => { throw new Error('injected context write failure'); };
|
|
457
|
-
try {
|
|
458
|
-
await assert.rejects(deliver(framework, 'slack:C1', 'lost'), /injected context write failure/);
|
|
459
|
-
assert.equal(binding.lastActivity, 1, 'a routing decision is not delivered activity');
|
|
460
|
-
}
|
|
461
|
-
finally {
|
|
462
|
-
context.addMessage = addMessage;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
finally {
|
|
466
|
-
await framework.stop();
|
|
467
|
-
}
|
|
468
|
-
});
|
|
469
|
-
it('fixed-audience coalesced delivery refreshes the current fork idle clock', async () => {
|
|
470
|
-
const framework = await makeFramework();
|
|
471
|
-
try {
|
|
472
|
-
await deliver(framework, 'slack:C1', 'first');
|
|
473
|
-
const router = framework.getConversationRouter();
|
|
474
|
-
const binding = router.getBinding('slack:C1');
|
|
475
|
-
binding.lastActivity = 1;
|
|
476
|
-
const before = Date.now();
|
|
477
|
-
await deliver(framework, 'slack:C1', 'updated detail', binding.agentName);
|
|
478
|
-
assert.ok(binding.lastActivity >= before, 'delivery bypassing fresh routing still records activity');
|
|
479
|
-
const { messages } = await framework.getAgent(binding.agentName).getContextManager().compile();
|
|
480
|
-
assert.ok(JSON.stringify(messages).includes('updated detail'));
|
|
481
|
-
}
|
|
482
|
-
finally {
|
|
483
|
-
await framework.stop();
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
it('delivery to an older fork does not refresh a newer binding on the same channel', async () => {
|
|
487
|
-
const framework = await makeFramework();
|
|
488
|
-
try {
|
|
489
|
-
await deliver(framework, 'slack:C1', 'first');
|
|
490
|
-
const router = framework.getConversationRouter();
|
|
491
|
-
const oldName = router.getBinding('slack:C1').agentName;
|
|
492
|
-
router.unbind('slack:C1');
|
|
493
|
-
await deliver(framework, 'slack:C1', 'new engagement');
|
|
494
|
-
const binding = router.getBinding('slack:C1');
|
|
495
|
-
binding.lastActivity = 1;
|
|
496
|
-
await deliver(framework, 'slack:C1', 'old engagement correction', oldName);
|
|
497
|
-
assert.equal(binding.lastActivity, 1, 'the correction belongs to the old engagement');
|
|
498
|
-
const { messages } = await framework.getAgent(oldName).getContextManager().compile();
|
|
499
|
-
assert.ok(JSON.stringify(messages).includes('old engagement correction'));
|
|
500
|
-
}
|
|
501
|
-
finally {
|
|
502
|
-
await framework.stop();
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
it('idle TTL runs a closure turn, unbinds, disposes the fork, and the next message spawns g2', async () => {
|
|
506
|
-
const IDLE_TTL_MS = 60_000;
|
|
507
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hello!' }]));
|
|
508
|
-
const framework = await makeFramework({ idleTtlMs: IDLE_TTL_MS });
|
|
509
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:D3', text: 'hi', channelType: 'im' }));
|
|
510
|
-
await framework.runUntilIdle();
|
|
511
|
-
const router = framework.getConversationRouter();
|
|
512
|
-
assert.ok(router.getBinding('slack:D3'), 'spawn should leave a live binding');
|
|
513
|
-
const g1 = framework.getAgent('conversation-slack-D3-g1');
|
|
514
|
-
assert.ok(g1, 'g1 fork should exist after spawn');
|
|
515
|
-
// Force expiry deterministically and provide the closure-turn response.
|
|
516
|
-
forceExpiry(framework, 'slack:D3', IDLE_TTL_MS);
|
|
517
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'Final report posted.' }]));
|
|
518
|
-
// Nudge the loop so the sweep runs.
|
|
519
|
-
framework.pushEvent({ type: 'external-message', source: 'test', content: 'tick', metadata: {} });
|
|
520
|
-
await framework.runUntilIdle();
|
|
521
|
-
assert.equal(router.getBinding('slack:D3'), undefined, 'binding should be gone after TTL');
|
|
522
|
-
const { messages } = await g1.getContextManager().compile();
|
|
523
|
-
assert.ok(messages.some((m) => JSON.stringify(m.content).includes('engagement is closing')), 'closure prompt should be in the fork context');
|
|
524
|
-
assert.equal(framework.getAgent('conversation-slack-D3-g1'), null, 'closed fork should be disposed once its closure turn finished');
|
|
525
|
-
const internals = framework;
|
|
526
|
-
assert.equal(internals.turnRouting.has('conversation-slack-D3-g1'), false, 'the closed fork leaves no routing');
|
|
527
|
-
assert.equal(internals.proseSpeechChains.has('conversation-slack-D3-g1'), false, 'the closed fork leaves no speech chain');
|
|
528
|
-
// Next DM spawns a fresh generation.
|
|
529
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hi again' }]));
|
|
530
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:D3', text: 'back again', channelType: 'im' }));
|
|
531
|
-
await framework.runUntilIdle();
|
|
532
|
-
assert.ok(framework.getAgent('conversation-slack-D3-g2'), 'rebind spawns generation 2');
|
|
533
|
-
await framework.stop();
|
|
534
|
-
});
|
|
535
|
-
it('restart does not reuse generation names or re-seed an existing namespace', async () => {
|
|
536
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'noted' }]));
|
|
537
|
-
const fw1 = await makeFramework({}, 'restart.chronicle');
|
|
538
|
-
fw1.getAgent('trunk').getContextManager().addMessage('user', [
|
|
539
|
-
{ type: 'text', text: 'HANDBOOK-V1: always check the logs first.' },
|
|
540
|
-
]);
|
|
541
|
-
fw1.pushEvent(incomingEvent({ channelId: 'slack:D9', text: 'case one', channelType: 'im' }));
|
|
542
|
-
await fw1.runUntilIdle();
|
|
543
|
-
assert.ok(fw1.getAgent('conversation-slack-D9-g1'), 'first engagement spawns g1');
|
|
544
|
-
await fw1.stop();
|
|
545
|
-
// Restart: same store, fresh framework. The generation counter must come
|
|
546
|
-
// back from Chronicle so the next engagement is g2 in a fresh namespace.
|
|
547
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'fresh' }]));
|
|
548
|
-
const fw2 = await makeFramework({}, 'restart.chronicle');
|
|
549
|
-
fw2.pushEvent(incomingEvent({ channelId: 'slack:D9', text: 'case two', channelType: 'im' }));
|
|
550
|
-
await fw2.runUntilIdle();
|
|
551
|
-
assert.equal(fw2.getAgent('conversation-slack-D9-g1'), null, 'g1 must not be resurrected');
|
|
552
|
-
const g2 = fw2.getAgent('conversation-slack-D9-g2');
|
|
553
|
-
assert.ok(g2, 'restart spawns the next generation, not generation 1 again');
|
|
554
|
-
const { messages } = await g2.getContextManager().compile();
|
|
555
|
-
const handbookCopies = messages.filter((m) => JSON.stringify(m.content).includes('HANDBOOK-V1')).length;
|
|
556
|
-
assert.equal(handbookCopies, 1, 'fresh namespace is seeded with exactly one template copy');
|
|
557
|
-
assert.ok(!messages.some((m) => JSON.stringify(m.content).includes('case one')), 'a new generation must not inherit the previous engagement history');
|
|
558
|
-
await fw2.stop();
|
|
559
|
-
});
|
|
560
|
-
it('forks cannot open channels or close foreign ones', async () => {
|
|
561
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hi' }]));
|
|
562
|
-
const framework = await makeFramework();
|
|
563
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C7', text: 'bot, help', mentioned: true }));
|
|
564
|
-
await framework.runUntilIdle();
|
|
565
|
-
const forkName = 'conversation-slack-C7-g1';
|
|
566
|
-
assert.ok(framework.getAgent(forkName), 'fork should exist');
|
|
567
|
-
const failures = [];
|
|
568
|
-
framework.onTrace((e) => {
|
|
569
|
-
if (e.type === 'tool:failed') {
|
|
570
|
-
failures.push({ tool: e.tool, error: e.error });
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
const fw = framework;
|
|
574
|
-
fw.dispatchChannelToolCall(forkName, { id: 't1', name: 'channel_open', input: { channelId: 'slack:C8' } });
|
|
575
|
-
fw.dispatchChannelToolCall(forkName, { id: 't2', name: 'channel_close', input: { channelId: 'slack:C8' } });
|
|
576
|
-
assert.equal(failures.length, 2, 'both foreign channel operations should be rejected');
|
|
577
|
-
assert.ok(failures[0].error.includes('cannot open channels'), 'channel_open is rejected outright');
|
|
578
|
-
assert.ok(failures[1].error.includes('closing slack:C8 is not allowed'), 'foreign channel_close is rejected');
|
|
579
|
-
await framework.stop();
|
|
580
|
-
});
|
|
581
|
-
it('fork channel_publish: omitted channelId defaults to home; foreign publish is rejected', async () => {
|
|
582
|
-
membrane.pushResponse(createMockResponse([{ type: 'text', text: 'hi' }]));
|
|
583
|
-
const framework = await makeFramework();
|
|
584
|
-
framework.pushEvent(incomingEvent({ channelId: 'slack:C7', text: 'bot, help', mentioned: true }));
|
|
585
|
-
await framework.runUntilIdle();
|
|
586
|
-
const forkName = 'conversation-slack-C7-g1';
|
|
587
|
-
assert.ok(framework.getAgent(forkName), 'fork should exist');
|
|
588
|
-
// tool:started is emitted AFTER the fence with the (possibly rewritten)
|
|
589
|
-
// input, so home-defaulting is observable there; a fence rejection emits
|
|
590
|
-
// tool:failed and never reaches tool:started.
|
|
591
|
-
const started = [];
|
|
592
|
-
const failures = [];
|
|
593
|
-
framework.onTrace((e) => {
|
|
594
|
-
if (e.type === 'tool:started')
|
|
595
|
-
started.push(e);
|
|
596
|
-
if (e.type === 'tool:failed')
|
|
597
|
-
failures.push(e);
|
|
598
|
-
});
|
|
599
|
-
const fw = framework;
|
|
600
|
-
// This harness runs no MCPL servers, so the framework never builds a real
|
|
601
|
-
// ChannelRegistry (the public dispatch path guards on it before routing
|
|
602
|
-
// channel_* tools). Stub the downstream boundary — the unit under test is
|
|
603
|
-
// the fence ABOVE it, and a home-defaulted publish must get past the fence
|
|
604
|
-
// to be observable at tool:started.
|
|
605
|
-
fw.channelRegistry = { handleChannelToolCall: async () => ({ success: true }), stopAll: () => { } };
|
|
606
|
-
// (a) omitted channelId → rewritten to the home channel, passes the fence
|
|
607
|
-
fw.dispatchChannelToolCall(forkName, { id: 'p1', name: 'channel_publish', input: { content: 'hello home' } });
|
|
608
|
-
const homePublish = started.find((t) => t.tool === 'channel_publish');
|
|
609
|
-
assert.ok(homePublish, 'home-defaulted publish should pass the fence and reach tool:started');
|
|
610
|
-
assert.equal(homePublish.input?.channelId, 'slack:C7', 'omitted channelId is rewritten to the home channel');
|
|
611
|
-
assert.ok(!failures.some((f) => f.callId === 'p1'), 'home-defaulted publish must not be rejected by the fence');
|
|
612
|
-
// (b) foreign channelId → rejected by the fence, never starts
|
|
613
|
-
fw.dispatchChannelToolCall(forkName, { id: 'p2', name: 'channel_publish', input: { channelId: 'slack:C8', content: 'sneaky' } });
|
|
614
|
-
const rejection = failures.find((f) => f.callId === 'p2');
|
|
615
|
-
assert.ok(rejection, 'foreign publish should be rejected');
|
|
616
|
-
assert.ok(rejection.error.includes('publishing to slack:C8 is not allowed'), 'rejection names the foreign channel');
|
|
617
|
-
assert.equal(started.filter((t) => t.tool === 'channel_publish').length, 1, 'foreign publish never reaches tool:started');
|
|
618
|
-
await framework.stop();
|
|
619
|
-
});
|
|
620
|
-
});
|
|
621
|
-
//# sourceMappingURL=conversation-routing.test.js.map
|