@animalabs/agent-framework 0.22.2 → 0.22.3
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 +136 -40
- 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/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 +3 -4
- package/src/agent.ts +162 -40
- 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/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
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
import { Worker } from 'node:worker_threads';
|
|
42
42
|
import { fileURLToPath } from 'node:url';
|
|
43
43
|
import { dirname, join } from 'node:path';
|
|
44
|
-
import { SemanticIndexClient, SemanticIndexer, messageIndexText } from './semantic.js';
|
|
44
|
+
import { EmbedServiceError, SemanticIndexClient, SemanticIndexer, messageIndexText } from './semantic.js';
|
|
45
|
+
import { unknownToolMessage } from '../unknown-tool.js';
|
|
46
|
+
import { safeSlice } from '../../safe-slice.js';
|
|
45
47
|
// ============================================================================
|
|
46
48
|
// Limits
|
|
47
49
|
// ============================================================================
|
|
@@ -84,9 +86,14 @@ const AROUND_MAX = 100;
|
|
|
84
86
|
* `extract({aroundId})` will fetch to order them by sequence — real stores
|
|
85
87
|
* see a handful; past this the call fails loudly rather than guessing. */
|
|
86
88
|
const AROUND_TIE_CAP = 5000;
|
|
87
|
-
function tieCapError(anchorId,
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
function tieCapError(anchorId, ms, channelId) {
|
|
90
|
+
const at = new Date(ms).toISOString();
|
|
91
|
+
// The channel is the agent's to send back, so it's quoted whole: a cut one
|
|
92
|
+
// couldn't be sent. It's one the store holds, with all those messages in it.
|
|
93
|
+
const inChannel = channelId !== undefined ? ` and "channelId" set to ${JSON.stringify(channelId)}` : '';
|
|
94
|
+
return new Error(`Nothing was read: more than ${AROUND_TIE_CAP} messages share the timestamp of message ${shown(anchorId)}, ${at}, too ` +
|
|
95
|
+
`many for aroundId to put in order. To read them, call history--extract with "from" and "to" both set to ${at}` +
|
|
96
|
+
`${inChannel}; it pages through them with "offset" and "limit".`);
|
|
90
97
|
}
|
|
91
98
|
/** Largest valid Date value (ms) — an open newest edge. */
|
|
92
99
|
const MAX_DATE_MS = 8.64e15;
|
|
@@ -109,9 +116,13 @@ const SEMANTIC_DEFAULT_LIMIT = 10;
|
|
|
109
116
|
const SEMANTIC_MAX_LIMIT = 50;
|
|
110
117
|
/** Largest k sent to the embed-service when over-fetching past dropped hits (its own cap is 200). */
|
|
111
118
|
const SEMANTIC_MAX_FETCH = 200;
|
|
112
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* Local snippet: the leading SEMANTIC_SNIPPET_CHARS of the current text, one
|
|
121
|
+
* fewer where the last would split a surrogate pair, since the snippet reaches
|
|
122
|
+
* the agent's context.
|
|
123
|
+
*/
|
|
113
124
|
function snippetOf(text) {
|
|
114
|
-
return text.length <= SEMANTIC_SNIPPET_CHARS ? text : `${text
|
|
125
|
+
return text.length <= SEMANTIC_SNIPPET_CHARS ? text : `${safeSlice(text, 0, SEMANTIC_SNIPPET_CHARS)}…`;
|
|
115
126
|
}
|
|
116
127
|
const SEMANTIC_SNIPPET_CHARS = 400;
|
|
117
128
|
/**
|
|
@@ -229,7 +240,9 @@ export class HistoryModule {
|
|
|
229
240
|
* you're trying to deliver a message, nonsense advice from a read-only
|
|
230
241
|
* history tool. This module always uses its own read-only-appropriate
|
|
231
242
|
* wording instead, regardless of which branch of the live resolver
|
|
232
|
-
* produced the miss.
|
|
243
|
+
* produced the miss. Its refusals open with "Nothing was read", which
|
|
244
|
+
* holds because every tool that resolves a channel here only reads (see
|
|
245
|
+
* the note above the helpers).
|
|
233
246
|
*/
|
|
234
247
|
resolveChannel(input) {
|
|
235
248
|
if (!input || !this.channelRegistry)
|
|
@@ -238,8 +251,10 @@ export class HistoryModule {
|
|
|
238
251
|
if (!('error' in resolved))
|
|
239
252
|
return resolved.channelId;
|
|
240
253
|
if (input.startsWith('#') || input.startsWith('@') || DM_MENTION_RE.test(input)) {
|
|
241
|
-
const suggestions = resolved.candidates?.length ? ` Did you mean
|
|
242
|
-
throw new Error(`
|
|
254
|
+
const suggestions = resolved.candidates?.length ? ` Did you mean ${quotedList(resolved.candidates, 'or')}?` : '';
|
|
255
|
+
throw new Error(`Nothing was read: no channel history matches ${shown(input)}. This host may never have seen a channel by that ` +
|
|
256
|
+
`name, or saw it before it kept channel names.${suggestions} Each message history--search returns carries ` +
|
|
257
|
+
'its "channelId", so searching for something said in that channel shows its id; pass that id as "channelId".');
|
|
243
258
|
}
|
|
244
259
|
return input;
|
|
245
260
|
}
|
|
@@ -279,8 +294,14 @@ export class HistoryModule {
|
|
|
279
294
|
? cm.queryMessagesByTimeAndChannel({ fromMs: ms, toMs: ms, channelId, limit: 0 }).matchedCount
|
|
280
295
|
: cm.queryMessagesByTime({ fromMs: ms, toMs: ms, limit: AROUND_TIE_CAP + 1 }).messages.length;
|
|
281
296
|
if (n > AROUND_TIE_CAP) {
|
|
282
|
-
|
|
283
|
-
|
|
297
|
+
// The count is by channel alone, so an author filter can't bring it down.
|
|
298
|
+
const at = new Date(ms).toISOString();
|
|
299
|
+
throw new Error(`Nothing was searched: more than ${AROUND_TIE_CAP} messages share the instant ${at}, too many for a ` +
|
|
300
|
+
`continuation to step past. To read them, call history--extract with "from" and "to" both set to ${at}` +
|
|
301
|
+
(channelId !== undefined
|
|
302
|
+
? ' and the same "channelId"; it pages through them with "offset" and "limit".'
|
|
303
|
+
: '; it pages through them with "offset" and "limit". Searching one channel, with "channelId", may also ' +
|
|
304
|
+
'bring them under the limit.'));
|
|
284
305
|
}
|
|
285
306
|
return n;
|
|
286
307
|
}
|
|
@@ -331,13 +352,16 @@ export class HistoryModule {
|
|
|
331
352
|
*/
|
|
332
353
|
relocateWindowOffset(windowOffset, afterId, q) {
|
|
333
354
|
if (windowOffset === 0) {
|
|
334
|
-
if (afterId != null)
|
|
335
|
-
throw new Error('"afterId"
|
|
355
|
+
if (afterId != null) {
|
|
356
|
+
throw new Error('Nothing was read: "afterId" goes with a "windowOffset" above 0, both copied from a truncated response\'s ' +
|
|
357
|
+
'"resume". For a first page, leave afterId out; to continue, copy the fields of that "resume" into the call.');
|
|
358
|
+
}
|
|
336
359
|
return { windowOffset, shift: 0 };
|
|
337
360
|
}
|
|
338
361
|
if (afterId == null) {
|
|
339
|
-
throw new Error('"windowOffset" needs the "afterId" from the same
|
|
340
|
-
'since the previous call would be
|
|
362
|
+
throw new Error('Nothing was read: "windowOffset" needs the "afterId" from the same "resume", or a message added or removed ' +
|
|
363
|
+
'since the previous call would be skipped unseen. Copy the fields of the previous response\'s "resume" into ' +
|
|
364
|
+
'the call.');
|
|
341
365
|
}
|
|
342
366
|
const cm = this.cm;
|
|
343
367
|
const at = cm.queryMessagesByTimeAndChannel({ ...q, limit: 1, offset: windowOffset - 1 }).messages[0];
|
|
@@ -347,9 +371,9 @@ export class HistoryModule {
|
|
|
347
371
|
const around = cm.queryMessagesByTimeAndChannel({ ...q, limit: 2 * RELOCATE_RADIUS + 1, offset: lo }).messages;
|
|
348
372
|
const i = around.findIndex((m) => String(m.id) === afterId);
|
|
349
373
|
if (i === -1) {
|
|
350
|
-
throw new Error(`
|
|
351
|
-
`within ${RELOCATE_RADIUS} positions of windowOffset ${windowOffset}
|
|
352
|
-
'Restart the scan without windowOffset
|
|
374
|
+
throw new Error(`Nothing was read: the window changed since the previous call. Message ${shown(afterId)}, where that scan stopped, ` +
|
|
375
|
+
`is no longer within ${RELOCATE_RADIUS} positions of windowOffset ${windowOffset}; it may have been deleted. ` +
|
|
376
|
+
'Restart the scan without "windowOffset" and "afterId", over the same range or one narrowed with "from" and "to".');
|
|
353
377
|
}
|
|
354
378
|
const relocated = lo + i + 1;
|
|
355
379
|
return { windowOffset: relocated, shift: relocated - windowOffset };
|
|
@@ -589,7 +613,7 @@ export class HistoryModule {
|
|
|
589
613
|
excludeAuthor: EXCLUDE_AUTHOR_SCHEMA,
|
|
590
614
|
order: { type: 'string', enum: ['oldest', 'newest'], description: 'Scan and return oldest-first (default) or newest-first.' },
|
|
591
615
|
limit: { type: 'number', description: `Max matches to return (default ${SEARCH_DEFAULT_LIMIT}, hard cap ${SEARCH_MAX_LIMIT}). Must be a non-negative integer.` },
|
|
592
|
-
maxScan: { type: 'number', description: `Max candidate messages to scan (default ${SEARCH_DEFAULT_MAX_SCAN}, hard cap ${SEARCH_MAX_MAX_SCAN}). Must be a
|
|
616
|
+
maxScan: { type: 'number', description: `Max candidate messages to scan (default ${SEARCH_DEFAULT_MAX_SCAN}, hard cap ${SEARCH_MAX_MAX_SCAN}). Must be a whole number, 1 or more.` },
|
|
593
617
|
skipSequences: {
|
|
594
618
|
type: 'array',
|
|
595
619
|
items: { type: 'number' },
|
|
@@ -661,7 +685,10 @@ export class HistoryModule {
|
|
|
661
685
|
'Purely a read: nothing is written to your history. Hits are checked against your current branch ' +
|
|
662
686
|
'before they come back: a message you undid or a summary from a branch you left is dropped and ' +
|
|
663
687
|
'counted in index.droppedOffBranch; a message edited down to nothing searchable is dropped and ' +
|
|
664
|
-
'counted in index.droppedStale.
|
|
688
|
+
'counted in index.droppedStale. When that leaves fewer than `limit` hits and the index may hold more, it ' +
|
|
689
|
+
'searches again, deeper, down to its first 200 hits; if a search after the first fails, the hits found so ' +
|
|
690
|
+
'far come back, with why in index.searchAgainError. Message snippets ' +
|
|
691
|
+
'always show the current text of the message.',
|
|
665
692
|
inputSchema: {
|
|
666
693
|
type: 'object',
|
|
667
694
|
properties: {
|
|
@@ -681,7 +708,11 @@ export class HistoryModule {
|
|
|
681
708
|
async handleToolCall(call) {
|
|
682
709
|
try {
|
|
683
710
|
if (!this.cm) {
|
|
684
|
-
|
|
711
|
+
// The host's mistake, named for whoever runs it; the agent reads what
|
|
712
|
+
// it can do about it, which is nothing.
|
|
713
|
+
console.error('[history] a tool was called before the host bound the module: call bind(contextManager) before tool dispatch');
|
|
714
|
+
throw new Error("The history tools aren't available: this host hasn't finished setting up the history module, so nothing " +
|
|
715
|
+
"was read. Calling them again won't change that; ask whoever runs this host.");
|
|
685
716
|
}
|
|
686
717
|
switch (call.name) {
|
|
687
718
|
case 'stats':
|
|
@@ -695,7 +726,7 @@ export class HistoryModule {
|
|
|
695
726
|
case 'semantic_search':
|
|
696
727
|
return await this.handleSemanticSearch((call.input ?? {}));
|
|
697
728
|
default:
|
|
698
|
-
return { success: false, isError: true, error:
|
|
729
|
+
return { success: false, isError: true, error: unknownToolMessage(this.name, call.name, this.getTools()) };
|
|
699
730
|
}
|
|
700
731
|
}
|
|
701
732
|
catch (error) {
|
|
@@ -758,19 +789,28 @@ export class HistoryModule {
|
|
|
758
789
|
handleExtract(input) {
|
|
759
790
|
if (input.aroundId !== undefined)
|
|
760
791
|
return this.handleExtractAround(input);
|
|
761
|
-
|
|
762
|
-
|
|
792
|
+
const aroundOnly = ['before', 'after', 'allChannels'].filter((k) => input[k] !== undefined);
|
|
793
|
+
if (aroundOnly.length > 0) {
|
|
794
|
+
const one = aroundOnly.length === 1;
|
|
795
|
+
throw new Error(`Nothing was read: ${quotedList(aroundOnly, 'and')} ${one ? 'goes' : 'go'} with "aroundId", which reads the ` +
|
|
796
|
+
`conversation around one message. Pass aroundId too, or leave ${one ? 'it' : 'them'} out to read a range ` +
|
|
797
|
+
'with "from", "to" and "channelId".');
|
|
763
798
|
}
|
|
764
799
|
const channelId = this.resolveChannel(input.channelId);
|
|
765
800
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
766
801
|
const toMs = parseIsoDate(input.to, 'to');
|
|
767
|
-
const limit = clampCount(input.limit, EXTRACT_DEFAULT_LIMIT, EXTRACT_MAX_LIMIT, 'limit');
|
|
768
|
-
const offset = clampCount(input.offset, 0, NATIVE_OFFSET_MAX, 'offset');
|
|
802
|
+
const limit = clampCount(input.limit, EXTRACT_DEFAULT_LIMIT, EXTRACT_MAX_LIMIT, 'limit', 'read');
|
|
803
|
+
const offset = clampCount(input.offset, 0, NATIVE_OFFSET_MAX, 'offset', 'read');
|
|
769
804
|
const format = input.format ?? 'text';
|
|
770
805
|
const authorFilter = buildAuthorFilter(input.author, input.excludeAuthor);
|
|
771
806
|
const cm = this.cm;
|
|
772
|
-
|
|
773
|
-
|
|
807
|
+
const resumeOnly = ['windowOffset', 'afterId', 'seqMark'].filter((k) => input[k] !== undefined);
|
|
808
|
+
if (!authorFilter && resumeOnly.length > 0) {
|
|
809
|
+
const one = resumeOnly.length === 1;
|
|
810
|
+
throw new Error(`Nothing was read: ${quotedList(resumeOnly, 'and')} ${one ? 'resumes' : 'resume'} an author-filtered ` +
|
|
811
|
+
`extract, so ${one ? 'it goes' : 'they go'} with the "author" or "excludeAuthor" of the call that returned ` +
|
|
812
|
+
`${one ? 'it' : 'them'}: repeat that call with the fields of its "resume". To page through a range without an ` +
|
|
813
|
+
'author filter, use "offset".');
|
|
774
814
|
}
|
|
775
815
|
if (authorFilter) {
|
|
776
816
|
// No native author index: page through the time/channel window and
|
|
@@ -783,10 +823,9 @@ export class HistoryModule {
|
|
|
783
823
|
// channel-scoped window pages in append order, and Discord catch-up
|
|
784
824
|
// appends old-timestamped messages late, so "continue from the last
|
|
785
825
|
// timestamp seen" would skip them.
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
const requestedOffset = clampCount(input.windowOffset, 0, NATIVE_OFFSET_MAX, 'windowOffset');
|
|
826
|
+
// An author-filtered extract has to examine at least 1 message.
|
|
827
|
+
const maxScan = clampCount(input.maxScan, EXTRACT_FILTER_DEFAULT_MAX_SCAN, EXTRACT_FILTER_MAX_MAX_SCAN, 'maxScan', 'read', 1);
|
|
828
|
+
const requestedOffset = clampCount(input.windowOffset, 0, NATIVE_OFFSET_MAX, 'windowOffset', 'read');
|
|
790
829
|
// A position is only meaningful against the window it was taken in:
|
|
791
830
|
// a removal before it (every discord:delete, host hide, /undo) shifts
|
|
792
831
|
// later positions left, and a message inserted before it (a
|
|
@@ -806,7 +845,8 @@ export class HistoryModule {
|
|
|
806
845
|
let unverified = false;
|
|
807
846
|
if (channelId === undefined && windowOffset > 0) {
|
|
808
847
|
if (typeof input.seqMark !== 'number') {
|
|
809
|
-
throw new Error('"windowOffset" without channelId needs the "seqMark" from the same
|
|
848
|
+
throw new Error('Nothing was read: "windowOffset" without "channelId" needs the "seqMark" from the same "resume". Copy the ' +
|
|
849
|
+
'fields of the previous response\'s "resume" into the call.');
|
|
810
850
|
}
|
|
811
851
|
const cursor = cm.queryMessagesByTimeAndChannel({ fromMs, toMs, limit: 1, offset: windowOffset - 1 }).messages[0];
|
|
812
852
|
if (cursor) {
|
|
@@ -980,32 +1020,38 @@ export class HistoryModule {
|
|
|
980
1020
|
* via edgeWindow, which is exact by timestamp).
|
|
981
1021
|
*/
|
|
982
1022
|
handleExtractAround(input) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
input.limit !== undefined) {
|
|
988
|
-
throw new Error('"aroundId" cannot be combined with from/to/offset/windowOffset/limit — it picks its own window; size it with before/after.');
|
|
1023
|
+
const windowFields = ['from', 'to', 'offset', 'windowOffset', 'limit'].filter((k) => input[k] !== undefined);
|
|
1024
|
+
if (windowFields.length > 0) {
|
|
1025
|
+
throw new Error(`Nothing was read: "aroundId" picks its own window, so it doesn't take ${quotedList(windowFields, 'or')}. Size ` +
|
|
1026
|
+
'the window with "before" and "after", or leave out "aroundId" to read a range.');
|
|
989
1027
|
}
|
|
990
1028
|
if (input.author !== undefined || input.excludeAuthor !== undefined) {
|
|
991
|
-
throw new Error('"aroundId"
|
|
1029
|
+
throw new Error('Nothing was read: "aroundId" reads the whole conversation around one message, so author filters don\'t ' +
|
|
1030
|
+
'apply to it. To find someone\'s messages, use history--search or history--extract with "author".');
|
|
992
1031
|
}
|
|
993
1032
|
if (input.allChannels && input.channelId !== undefined) {
|
|
994
|
-
throw new Error('
|
|
1033
|
+
throw new Error('Nothing was read: "channelId" and "allChannels" can\'t go together. Leave out "channelId" to read around the ' +
|
|
1034
|
+
'message in every channel, or leave out both to read around it in its own channel.');
|
|
995
1035
|
}
|
|
996
|
-
const before = clampCount(input.before, AROUND_DEFAULT, AROUND_MAX, 'before');
|
|
997
|
-
const after = clampCount(input.after, AROUND_DEFAULT, AROUND_MAX, 'after');
|
|
1036
|
+
const before = clampCount(input.before, AROUND_DEFAULT, AROUND_MAX, 'before', 'read');
|
|
1037
|
+
const after = clampCount(input.after, AROUND_DEFAULT, AROUND_MAX, 'after', 'read');
|
|
998
1038
|
const format = input.format ?? 'text';
|
|
999
1039
|
const cm = this.cm;
|
|
1000
1040
|
// semantic_search (#173) hands out `msg:<id>` / `sum:<id>`; accept the
|
|
1001
1041
|
// message form as-is, and say plainly what a summary id is.
|
|
1002
1042
|
const rawId = String(input.aroundId);
|
|
1003
1043
|
if (/^sum:/.test(rawId)) {
|
|
1004
|
-
throw new Error(
|
|
1044
|
+
throw new Error(`Nothing was read: ${shown(rawId)} is a compression summary, not a message. history--overview reads ` +
|
|
1045
|
+
'summaries; "aroundId" takes a message, such as ' +
|
|
1046
|
+
(this.semanticCfg
|
|
1047
|
+
? 'the "messageId" of a history--semantic_search hit.'
|
|
1048
|
+
: 'the "id" of a history--search or history--extract result.'));
|
|
1005
1049
|
}
|
|
1006
1050
|
const anchor = cm.getMessage(rawId.replace(/^msg:/, ''));
|
|
1007
1051
|
if (!anchor) {
|
|
1008
|
-
throw new Error(`
|
|
1052
|
+
throw new Error(`Nothing was read: no message in your history has the id ${shown(input.aroundId)}. Pass the "id" ` +
|
|
1053
|
+
'of a history--search or history--extract result' +
|
|
1054
|
+
(this.semanticCfg ? ', or the "messageId" of a history--semantic_search hit.' : '.'));
|
|
1009
1055
|
}
|
|
1010
1056
|
const anchorId = String(anchor.id);
|
|
1011
1057
|
const anchorChannel = getChannelId(anchor);
|
|
@@ -1020,22 +1066,22 @@ export class HistoryModule {
|
|
|
1020
1066
|
if (channelId !== undefined) {
|
|
1021
1067
|
const n = cm.queryMessagesByTimeAndChannel({ fromMs: t, toMs: t, channelId, limit: 0 }).matchedCount;
|
|
1022
1068
|
if (n > AROUND_TIE_CAP)
|
|
1023
|
-
throw tieCapError(anchorId,
|
|
1069
|
+
throw tieCapError(anchorId, t, channelId);
|
|
1024
1070
|
ties = cm.queryMessagesByTimeAndChannel({ fromMs: t, toMs: t, channelId, limit: n }).messages;
|
|
1025
1071
|
}
|
|
1026
1072
|
else {
|
|
1027
1073
|
ties = cm.queryMessagesByTime({ fromMs: t, toMs: t, limit: AROUND_TIE_CAP + 1 }).messages;
|
|
1028
1074
|
if (ties.length > AROUND_TIE_CAP)
|
|
1029
|
-
throw tieCapError(anchorId,
|
|
1075
|
+
throw tieCapError(anchorId, t, undefined);
|
|
1030
1076
|
}
|
|
1031
1077
|
ties = [...ties].sort((x, y) => x.sequence - y.sequence);
|
|
1032
1078
|
const idx = ties.findIndex((m) => String(m.id) === anchorId);
|
|
1033
1079
|
if (idx === -1) {
|
|
1034
1080
|
// The anchor is in the store and every message of its millisecond in
|
|
1035
1081
|
// `channelId` was fetched, so only an explicit channelId excludes it.
|
|
1036
|
-
throw new Error(`
|
|
1037
|
-
(anchorChannel ? ` (it
|
|
1038
|
-
'
|
|
1082
|
+
throw new Error(`Nothing was read: message ${shown(anchorId)} isn't in channel ${shown(input.channelId)}` +
|
|
1083
|
+
(anchorChannel ? ` (it's in ${shown(anchorChannel)}).` : '.') +
|
|
1084
|
+
' Leave out "channelId" to read around it in its own channel.');
|
|
1039
1085
|
}
|
|
1040
1086
|
const tiesBefore = ties.slice(Math.max(0, idx - before), idx);
|
|
1041
1087
|
const tiesAfter = ties.slice(idx + 1, idx + 1 + after);
|
|
@@ -1061,22 +1107,29 @@ export class HistoryModule {
|
|
|
1061
1107
|
// search
|
|
1062
1108
|
// ==========================================================================
|
|
1063
1109
|
async handleSearch(input) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1110
|
+
// A finite number is searched as its text, as a regular expression made
|
|
1111
|
+
// from it reads it; any other value that isn't text is refused.
|
|
1112
|
+
const given = input.query;
|
|
1113
|
+
const query = typeof given === 'number' && Number.isFinite(given) ? String(given) : given;
|
|
1114
|
+
if (typeof query !== 'string' || query === '') {
|
|
1115
|
+
throw new Error('Nothing was searched: "query" must be the text to look for; ' +
|
|
1116
|
+
`${given === undefined ? 'this call gave none' : `it's ${shown(given)}`}.`);
|
|
1066
1117
|
}
|
|
1067
1118
|
const channelId = this.resolveChannel(input.channelId);
|
|
1068
1119
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
1069
1120
|
const toMs = parseIsoDate(input.to, 'to');
|
|
1070
|
-
const limit = clampCount(input.limit, SEARCH_DEFAULT_LIMIT, SEARCH_MAX_LIMIT, 'limit');
|
|
1071
|
-
|
|
1121
|
+
const limit = clampCount(input.limit, SEARCH_DEFAULT_LIMIT, SEARCH_MAX_LIMIT, 'limit', 'searched');
|
|
1122
|
+
// A search has to scan at least 1 message.
|
|
1123
|
+
const maxScan = clampCount(input.maxScan, SEARCH_DEFAULT_MAX_SCAN, SEARCH_MAX_MAX_SCAN, 'maxScan', 'searched', 1);
|
|
1072
1124
|
const caseSensitive = input.caseSensitive ?? false;
|
|
1073
1125
|
const flags = caseSensitive ? '' : 'i';
|
|
1074
1126
|
const order = input.order ?? 'oldest';
|
|
1075
1127
|
if (order !== 'oldest' && order !== 'newest') {
|
|
1076
|
-
throw new Error(`"order" must be "oldest" or "newest",
|
|
1128
|
+
throw new Error(`Nothing was searched: "order" must be "oldest" or "newest", or left out for "oldest"; it's ${shown(input.order)}.`);
|
|
1077
1129
|
}
|
|
1078
1130
|
if (input.wholeWord && input.regex) {
|
|
1079
|
-
throw new Error('"wholeWord" applies to
|
|
1131
|
+
throw new Error('Nothing was searched: "wholeWord" applies to a search for text, not a regular expression. In a regular ' +
|
|
1132
|
+
'expression, write \\b around the pattern instead, or set "regex" to false.');
|
|
1080
1133
|
}
|
|
1081
1134
|
const authorFilter = buildAuthorFilter(input.author, input.excludeAuthor);
|
|
1082
1135
|
// Validate regex SYNTAX up front — an invalid pattern is a clean tool
|
|
@@ -1086,13 +1139,17 @@ export class HistoryModule {
|
|
|
1086
1139
|
// than here.
|
|
1087
1140
|
if (input.regex) {
|
|
1088
1141
|
try {
|
|
1089
|
-
new RegExp(
|
|
1142
|
+
new RegExp(query, flags);
|
|
1090
1143
|
}
|
|
1091
1144
|
catch (error) {
|
|
1092
|
-
|
|
1145
|
+
// V8's message restates the pattern; the reason alone follows it.
|
|
1146
|
+
const reason = (error instanceof Error ? error.message : String(error))
|
|
1147
|
+
.replace(/^Invalid regular expression: \/.*\/[a-z]*: /s, '');
|
|
1148
|
+
throw new Error(`Nothing was searched: "query" ${shown(query)} isn't a valid regular expression (${reason}). ` +
|
|
1149
|
+
'Fix the pattern, or set "regex" to false to search for the text as written.');
|
|
1093
1150
|
}
|
|
1094
1151
|
}
|
|
1095
|
-
const needle = caseSensitive ?
|
|
1152
|
+
const needle = caseSensitive ? query : query.toLowerCase();
|
|
1096
1153
|
const cm = this.cm;
|
|
1097
1154
|
// The candidate window is the oldest (order:"oldest") or newest
|
|
1098
1155
|
// (order:"newest", via edgeWindow — see there for why not an offset
|
|
@@ -1100,8 +1157,7 @@ export class HistoryModule {
|
|
|
1100
1157
|
// detected up front rather than
|
|
1101
1158
|
// silently scanning maxScan candidates and returning as if that were the
|
|
1102
1159
|
// whole window. See the tool description's `truncated` contract.
|
|
1103
|
-
|
|
1104
|
-
throw new Error('"maxScan" must be at least 1 — a zero-message scan can never make progress.');
|
|
1160
|
+
//
|
|
1105
1161
|
// Continuation: `skipSequences` names what the previous call already
|
|
1106
1162
|
// scanned at exactly the resume bound's millisecond (the bound is
|
|
1107
1163
|
// inclusive). Identified by sequence range rather than a count, so a
|
|
@@ -1111,7 +1167,9 @@ export class HistoryModule {
|
|
|
1111
1167
|
const skipRange = parseSkipSequences(input.skipSequences);
|
|
1112
1168
|
const edgeMs = order === 'oldest' ? fromMs : toMs;
|
|
1113
1169
|
if (skipRange && edgeMs === undefined) {
|
|
1114
|
-
throw new Error(`"skipSequences"
|
|
1170
|
+
throw new Error(`Nothing was searched: "skipSequences" goes with the "${order === 'oldest' ? 'from' : 'to'}" from the same ` +
|
|
1171
|
+
'"resume". Copy the fields of the previous response\'s "resume" into the call, or leave "skipSequences" ' +
|
|
1172
|
+
'out for a new search.');
|
|
1115
1173
|
}
|
|
1116
1174
|
const isSkipped = (m) => !!skipRange && m.timestamp.getTime() === edgeMs && m.sequence >= skipRange[0] && m.sequence <= skipRange[1];
|
|
1117
1175
|
let windowMessages;
|
|
@@ -1192,7 +1250,7 @@ export class HistoryModule {
|
|
|
1192
1250
|
// through a worker thread instead, which can be forcibly terminated
|
|
1193
1251
|
// on a deadline. See search-regex-worker.ts's header for the full
|
|
1194
1252
|
// rationale.
|
|
1195
|
-
const { matches, scanned } = await this.searchWithRegexWorker(candidates,
|
|
1253
|
+
const { matches, scanned } = await this.searchWithRegexWorker(candidates, query, flags, limit);
|
|
1196
1254
|
return { success: true, data: { scanned, ...poolInfo, truncated, ...resumeInfo(scanned), matches } };
|
|
1197
1255
|
}
|
|
1198
1256
|
// Plain substring search (String.prototype.indexOf) is inherently
|
|
@@ -1249,22 +1307,27 @@ export class HistoryModule {
|
|
|
1249
1307
|
const { matches: rawMatches, scanned } = await new Promise((resolve, reject) => {
|
|
1250
1308
|
worker = new Worker(SEARCH_WORKER_PATH, { workerData: { texts, pattern, flags, limit } });
|
|
1251
1309
|
const timer = setTimeout(() => {
|
|
1252
|
-
reject(new Error(`search
|
|
1253
|
-
`up to ${texts.length}
|
|
1254
|
-
|
|
1255
|
-
'
|
|
1310
|
+
reject(new Error(`The search stopped, and returned nothing: matching the regular expression ${shown(pattern)} ` +
|
|
1311
|
+
`against up to ${texts.length} ${texts.length === 1 ? 'message' : 'messages'} took longer than ` +
|
|
1312
|
+
`${SEARCH_REGEX_TIMEOUT_MS} ms, as a ` +
|
|
1313
|
+
'pattern that backtracks heavily can. Try a simpler pattern, set "regex" to false to search for the ' +
|
|
1314
|
+
'text as written, or lower "maxScan".'));
|
|
1256
1315
|
}, SEARCH_REGEX_TIMEOUT_MS);
|
|
1257
1316
|
timer.unref?.();
|
|
1258
1317
|
worker.once('message', (msg) => {
|
|
1259
1318
|
clearTimeout(timer);
|
|
1260
|
-
if (msg.type === 'error')
|
|
1261
|
-
reject(new Error(
|
|
1262
|
-
|
|
1319
|
+
if (msg.type === 'error') {
|
|
1320
|
+
reject(new Error(`The search stopped, and returned nothing: matching the regular expression ${shown(pattern)} ` +
|
|
1321
|
+
`failed (${msg.error}). Try a simpler pattern, or set "regex" to false to search for the text as written.`));
|
|
1322
|
+
}
|
|
1323
|
+
else {
|
|
1263
1324
|
resolve({ matches: msg.matches, scanned: msg.scanned });
|
|
1325
|
+
}
|
|
1264
1326
|
});
|
|
1265
1327
|
worker.once('error', (err) => {
|
|
1266
1328
|
clearTimeout(timer);
|
|
1267
|
-
reject(
|
|
1329
|
+
reject(new Error(`The search stopped, and returned nothing: the worker matching the regular expression ${shown(pattern)} ` +
|
|
1330
|
+
`failed (${err.message}). Set "regex" to false to search for the text as written.`));
|
|
1268
1331
|
});
|
|
1269
1332
|
});
|
|
1270
1333
|
const matches = rawMatches.map(({ candidateIndex, matchIndex, matchLength }) => {
|
|
@@ -1294,36 +1357,46 @@ export class HistoryModule {
|
|
|
1294
1357
|
// ==========================================================================
|
|
1295
1358
|
async handleSemanticSearch(input) {
|
|
1296
1359
|
if (!this.semanticCfg || !this.semanticClient) {
|
|
1297
|
-
throw new Error(
|
|
1360
|
+
throw new Error("Nothing was searched: this host has no semantic index set up, so history--semantic_search isn't available " +
|
|
1361
|
+
"here, and calling it again won't change that. history--search finds messages by their words.");
|
|
1362
|
+
}
|
|
1363
|
+
if (typeof input.query !== 'string' || !input.query.trim()) {
|
|
1364
|
+
throw new Error('Nothing was searched: "query" must be a sentence describing what you\'re looking for; ' +
|
|
1365
|
+
`${input.query === undefined ? 'this call gave none' : `it's ${shown(input.query)}`}.`);
|
|
1298
1366
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
const limit = clampCount(input.limit, SEMANTIC_DEFAULT_LIMIT, SEMANTIC_MAX_LIMIT, 'limit');
|
|
1302
|
-
if (limit < 1)
|
|
1303
|
-
throw new Error('limit must be at least 1');
|
|
1367
|
+
// A search has to return at least 1 hit.
|
|
1368
|
+
const limit = clampCount(input.limit, SEMANTIC_DEFAULT_LIMIT, SEMANTIC_MAX_LIMIT, 'limit', 'searched', 1);
|
|
1304
1369
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
1305
1370
|
const toMs = parseIsoDate(input.to, 'to');
|
|
1306
|
-
|
|
1307
|
-
throw new Error('`from` must not be after `to`');
|
|
1371
|
+
assertOrderedRange(fromMs, toMs, input.from, input.to);
|
|
1308
1372
|
const channelId = this.resolveChannel(input.channelId);
|
|
1309
1373
|
// Summaries carry no channel, so a channel filter on a summaries-only
|
|
1310
1374
|
// search can only ever match nothing. Say so instead of returning [].
|
|
1311
1375
|
const wantsSummariesOnly = input.level !== undefined || input.kinds === 'summaries';
|
|
1312
1376
|
if (channelId && wantsSummariesOnly) {
|
|
1313
|
-
|
|
1377
|
+
const picks = [
|
|
1378
|
+
...(input.kinds === 'summaries' ? ['"kinds": "summaries"'] : []),
|
|
1379
|
+
...(input.level !== undefined ? ['"level"'] : []),
|
|
1380
|
+
];
|
|
1381
|
+
const fields = [...(input.kinds === 'summaries' ? ['kinds'] : []), ...(input.level !== undefined ? ['level'] : [])];
|
|
1382
|
+
throw new Error(`Nothing was searched: summaries aren't kept by channel, so "channelId" can't go with ${picks.join(' or ')}. ` +
|
|
1383
|
+
`Leave out "channelId" to search summaries, or leave out ${quotedList(fields, 'and')} to search that ` +
|
|
1384
|
+
'channel\'s messages.');
|
|
1314
1385
|
}
|
|
1315
1386
|
if (input.level !== undefined && input.kinds === 'messages') {
|
|
1316
|
-
throw new Error('level
|
|
1387
|
+
throw new Error('Nothing was searched: "level" picks summaries, and "kinds" is "messages", so the two can\'t go together. ' +
|
|
1388
|
+
'Leave out "kinds" to search summaries of that level, or leave out "level" to search messages.');
|
|
1317
1389
|
}
|
|
1318
1390
|
let kinds;
|
|
1319
1391
|
if (wantsSummariesOnly)
|
|
1320
1392
|
kinds = ['summary'];
|
|
1321
1393
|
else if (input.kinds === 'messages' || channelId)
|
|
1322
1394
|
kinds = ['message'];
|
|
1323
|
-
if (input.level !== undefined && (!Number.isInteger(input.level) || input.level < 0))
|
|
1324
|
-
throw new Error(
|
|
1395
|
+
if (input.level !== undefined && (!Number.isInteger(input.level) || input.level < 0)) {
|
|
1396
|
+
throw new Error(`Nothing was searched: "level" must be a whole number, 0 or more, such as 1; it's ${shown(input.level)}.`);
|
|
1397
|
+
}
|
|
1325
1398
|
if (input.minScore !== undefined && (typeof input.minScore !== 'number' || input.minScore < -1 || input.minScore > 1)) {
|
|
1326
|
-
throw new Error(
|
|
1399
|
+
throw new Error(`Nothing was searched: "minScore" must be a number from -1 to 1, or left out; it's ${shown(input.minScore)}.`);
|
|
1327
1400
|
}
|
|
1328
1401
|
// Bounded catch-up so the newest messages are searchable; never block on a backlog.
|
|
1329
1402
|
let sync = null;
|
|
@@ -1339,6 +1412,49 @@ export class HistoryModule {
|
|
|
1339
1412
|
ts_to: toMs === undefined ? undefined : toMs / 1000,
|
|
1340
1413
|
channel: channelId, kinds, level: input.level, min_score: input.minScore, snippet: SEMANTIC_SNIPPET_CHARS,
|
|
1341
1414
|
});
|
|
1415
|
+
// The client says what went wrong with the service; what that means for
|
|
1416
|
+
// this call, and what the agent can do, is said here. The service's own
|
|
1417
|
+
// source isn't in this repository, so a 404's advice holds whether it
|
|
1418
|
+
// means this store's index doesn't exist yet or a route the service lacks.
|
|
1419
|
+
const failure = (e) => {
|
|
1420
|
+
const status = e instanceof EmbedServiceError ? e.status : null;
|
|
1421
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
1422
|
+
const later = {
|
|
1423
|
+
reason, mayPass: true,
|
|
1424
|
+
advice: 'You can try again later; if it keeps happening, ask whoever runs this host',
|
|
1425
|
+
};
|
|
1426
|
+
if (status === 404) {
|
|
1427
|
+
return {
|
|
1428
|
+
reason, mayPass: true,
|
|
1429
|
+
advice: "If this store's index doesn't exist yet, the first messages indexed create it, and a later call " +
|
|
1430
|
+
'can work; if it keeps happening, ask whoever runs this host',
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
if (status === 408 || status === 429 || (status !== null && status >= 500))
|
|
1434
|
+
return later;
|
|
1435
|
+
// An answer without what a search reads: a page shown while the service
|
|
1436
|
+
// restarts clears, and an address that points at something else doesn't.
|
|
1437
|
+
if (status !== null && status >= 200 && status < 300) {
|
|
1438
|
+
return {
|
|
1439
|
+
reason, mayPass: true,
|
|
1440
|
+
advice: 'If the service was restarting, a later call can work; if its address points at something else, ' +
|
|
1441
|
+
"none will until whoever runs this host fixes the semantic index's settings",
|
|
1442
|
+
};
|
|
1443
|
+
}
|
|
1444
|
+
if (status !== null) {
|
|
1445
|
+
return {
|
|
1446
|
+
reason, mayPass: false,
|
|
1447
|
+
advice: "Calling it again the same way won't change that; if it keeps happening, ask whoever runs this host",
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
// No answer: the service down or slow, or the connection dropped, which
|
|
1451
|
+
// clears, or its address or certificate wrong, which doesn't.
|
|
1452
|
+
return {
|
|
1453
|
+
reason, mayPass: true,
|
|
1454
|
+
advice: 'If the service is down or slow, or the connection dropped, a later call can work; if its address ' +
|
|
1455
|
+
"or certificate is wrong, none will until whoever runs this host fixes the semantic index's settings",
|
|
1456
|
+
};
|
|
1457
|
+
};
|
|
1342
1458
|
// The remote index is append-only and knows nothing about branches: a
|
|
1343
1459
|
// message removed from the agent's reach by /undo, /checkout, /restore or
|
|
1344
1460
|
// /newtopic keeps its id (a new message gets a fresh one) and stays
|
|
@@ -1364,7 +1480,7 @@ export class HistoryModule {
|
|
|
1364
1480
|
const m = cm.getMessage(msgId);
|
|
1365
1481
|
if (!m)
|
|
1366
1482
|
return 'offBranch';
|
|
1367
|
-
const text = messageIndexText(m, includePrivate)
|
|
1483
|
+
const text = safeSlice(messageIndexText(m, includePrivate), 0, this.semanticCfg.maxChars ?? 32_000);
|
|
1368
1484
|
if (!text)
|
|
1369
1485
|
return 'stale';
|
|
1370
1486
|
currentText.set(h.id, text);
|
|
@@ -1375,11 +1491,22 @@ export class HistoryModule {
|
|
|
1375
1491
|
return 'ok';
|
|
1376
1492
|
};
|
|
1377
1493
|
let k = limit;
|
|
1378
|
-
let res
|
|
1494
|
+
let res;
|
|
1495
|
+
try {
|
|
1496
|
+
res = await runSearch(k);
|
|
1497
|
+
}
|
|
1498
|
+
catch (e) {
|
|
1499
|
+
const { reason, advice } = failure(e);
|
|
1500
|
+
throw new Error(`Nothing was searched: ${reason}. ${advice}. history--search finds messages by their words meanwhile.`);
|
|
1501
|
+
}
|
|
1379
1502
|
let droppedOffBranch = 0;
|
|
1380
1503
|
let droppedStale = 0;
|
|
1504
|
+
// Why searching again for more hits failed, when it did. The search
|
|
1505
|
+
// before it answered, so its hits on this branch are returned.
|
|
1506
|
+
let searchAgainError = null;
|
|
1381
1507
|
let onBranch = [];
|
|
1382
|
-
|
|
1508
|
+
// The last answer's hits on this branch, checked as they are now.
|
|
1509
|
+
const check = () => {
|
|
1383
1510
|
droppedOffBranch = 0;
|
|
1384
1511
|
droppedStale = 0;
|
|
1385
1512
|
onBranch = res.hits.filter((h) => {
|
|
@@ -1390,26 +1517,61 @@ export class HistoryModule {
|
|
|
1390
1517
|
droppedStale++;
|
|
1391
1518
|
return v === 'ok';
|
|
1392
1519
|
});
|
|
1520
|
+
};
|
|
1521
|
+
for (;;) {
|
|
1522
|
+
check();
|
|
1393
1523
|
if (onBranch.length >= limit || res.hits.length < k || k >= SEMANTIC_MAX_FETCH)
|
|
1394
1524
|
break;
|
|
1395
1525
|
k = Math.min(SEMANTIC_MAX_FETCH, k * 4);
|
|
1396
|
-
|
|
1526
|
+
try {
|
|
1527
|
+
res = await runSearch(k);
|
|
1528
|
+
}
|
|
1529
|
+
catch (e) {
|
|
1530
|
+
const { reason, mayPass } = failure(e);
|
|
1531
|
+
searchAgainError = `searching again for more hits failed: ${reason}. ` +
|
|
1532
|
+
(mayPass ? 'Calling again may bring more.' : "Calling again the same way won't change that.");
|
|
1533
|
+
// A message may have been edited, deleted or taken off this branch
|
|
1534
|
+
// while that search waited, so the hits are checked again.
|
|
1535
|
+
check();
|
|
1536
|
+
break;
|
|
1537
|
+
}
|
|
1397
1538
|
}
|
|
1398
1539
|
onBranch = onBranch.slice(0, limit);
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1540
|
+
// A ts that makes no date reads as no timestamp, as a null one does, and a
|
|
1541
|
+
// meta that isn't an object as no participant or author. The hit is still
|
|
1542
|
+
// returned, but the index holds data written wrong, so the host is told.
|
|
1543
|
+
// The index writes ts as a number of seconds, and text holding one reads
|
|
1544
|
+
// as main read it; nothing else makes a date, and reading it can't throw.
|
|
1545
|
+
const unread = [];
|
|
1546
|
+
const hits = onBranch.map((h) => {
|
|
1547
|
+
const ts = h.ts;
|
|
1548
|
+
const seconds = typeof ts === 'number' ? ts : typeof ts === 'string' && ts.trim() !== '' ? Number(ts) : NaN;
|
|
1549
|
+
const at = new Date(seconds * 1000);
|
|
1550
|
+
const timestamp = Number.isNaN(at.getTime()) ? null : at.toISOString();
|
|
1551
|
+
const meta = typeof h.meta === 'object' && h.meta !== null && !Array.isArray(h.meta)
|
|
1552
|
+
? h.meta
|
|
1553
|
+
: null;
|
|
1554
|
+
const missing = [...(h.ts !== null && timestamp === null ? ['ts'] : []), ...(meta === null ? ['meta'] : [])];
|
|
1555
|
+
if (missing.length > 0)
|
|
1556
|
+
unread.push(`${shown(h.id)} (${missing.join(' and ')})`);
|
|
1557
|
+
return {
|
|
1558
|
+
id: h.id,
|
|
1559
|
+
/** Raw message id for a `msg:` hit (null for summaries) — pass it to extract({ aroundId }). */
|
|
1560
|
+
messageId: h.id.startsWith('msg:') ? h.id.slice(4) : null,
|
|
1561
|
+
kind: h.kind,
|
|
1562
|
+
level: h.level,
|
|
1563
|
+
score: h.score,
|
|
1564
|
+
timestamp,
|
|
1565
|
+
channelId: h.channel,
|
|
1566
|
+
participant: meta?.participant ?? null,
|
|
1567
|
+
author: meta?.author ?? null,
|
|
1568
|
+
snippet: currentText.has(h.id) ? snippetOf(currentText.get(h.id)) : (h.text ?? ''),
|
|
1569
|
+
chars: currentText.has(h.id) ? currentText.get(h.id).length : h.chars,
|
|
1570
|
+
};
|
|
1571
|
+
});
|
|
1572
|
+
if (unread.length > 0) {
|
|
1573
|
+
this.indexer?.warn(`a search returned hits whose ts or meta couldn't be read, without them: ${unread.join(', ')}`);
|
|
1574
|
+
}
|
|
1413
1575
|
return {
|
|
1414
1576
|
success: true,
|
|
1415
1577
|
data: {
|
|
@@ -1421,8 +1583,10 @@ export class HistoryModule {
|
|
|
1421
1583
|
lastError: this.indexer?.lastError ?? null,
|
|
1422
1584
|
/** Hits the index returned for messages/summaries not on the current branch (undone, checked out past). */
|
|
1423
1585
|
droppedOffBranch,
|
|
1424
|
-
/** Hits for messages whose current text has nothing indexable (edited blank; the index delete
|
|
1586
|
+
/** Hits for messages whose current text has nothing indexable (edited blank; the index keeps such a message until its delete goes through, and on a service without /delete it never does). */
|
|
1425
1587
|
droppedStale,
|
|
1588
|
+
/** When too few hits were on this branch and searching again for more failed: why, and whether calling again can help. */
|
|
1589
|
+
searchAgainError,
|
|
1426
1590
|
},
|
|
1427
1591
|
timingMs: res.timing_ms,
|
|
1428
1592
|
},
|
|
@@ -1433,7 +1597,7 @@ export class HistoryModule {
|
|
|
1433
1597
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
1434
1598
|
const toMs = parseIsoDate(input.to, 'to');
|
|
1435
1599
|
assertOrderedRange(fromMs, toMs, input.from, input.to);
|
|
1436
|
-
const limit = clampCount(input.limit, OVERVIEW_DEFAULT_LIMIT, OVERVIEW_MAX_LIMIT, 'limit');
|
|
1600
|
+
const limit = clampCount(input.limit, OVERVIEW_DEFAULT_LIMIT, OVERVIEW_MAX_LIMIT, 'limit', 'read');
|
|
1437
1601
|
const cm = this.cm;
|
|
1438
1602
|
let entries;
|
|
1439
1603
|
if (input.level !== undefined) {
|
|
@@ -1792,6 +1956,11 @@ export class HistoryModule {
|
|
|
1792
1956
|
// ============================================================================
|
|
1793
1957
|
// Helpers
|
|
1794
1958
|
// ============================================================================
|
|
1959
|
+
// The checks here (and resolveChannel) are shared by several tools. Their
|
|
1960
|
+
// refusals open with "Nothing was read", or for clampCount with the outcome
|
|
1961
|
+
// its caller names, and "Nothing was read" holds because every history tool
|
|
1962
|
+
// only reads. A tool that changes something should give its refusals an
|
|
1963
|
+
// opener of its own rather than reach these.
|
|
1795
1964
|
/** Parse an ISO 8601 date string to Unix ms. Throws a clear error (not a
|
|
1796
1965
|
* crash) on an unparseable string; returns undefined for an omitted field
|
|
1797
1966
|
* (open-ended bound). */
|
|
@@ -1800,7 +1969,8 @@ function parseIsoDate(value, field) {
|
|
|
1800
1969
|
return undefined;
|
|
1801
1970
|
const ms = Date.parse(value);
|
|
1802
1971
|
if (Number.isNaN(ms)) {
|
|
1803
|
-
throw new Error(`
|
|
1972
|
+
throw new Error(`Nothing was read: "${field}" is ${shown(value)}, which isn't an ISO 8601 date. Write it like 2026-03-01 or ` +
|
|
1973
|
+
'2026-03-01T09:00:00Z.');
|
|
1804
1974
|
}
|
|
1805
1975
|
return ms;
|
|
1806
1976
|
}
|
|
@@ -1813,7 +1983,8 @@ function parseIsoDate(value, field) {
|
|
|
1813
1983
|
*/
|
|
1814
1984
|
function assertOrderedRange(fromMs, toMs, fromRaw, toRaw) {
|
|
1815
1985
|
if (fromMs !== undefined && toMs !== undefined && fromMs > toMs) {
|
|
1816
|
-
throw new Error(`"from" (${fromRaw})
|
|
1986
|
+
throw new Error(`Nothing was read: "from" (${shown(fromRaw)}) is after "to" (${shown(toRaw)}), so the range holds nothing. Swap them, ` +
|
|
1987
|
+
'or correct the one that\'s wrong.');
|
|
1817
1988
|
}
|
|
1818
1989
|
}
|
|
1819
1990
|
/**
|
|
@@ -1824,24 +1995,51 @@ function assertOrderedRange(fromMs, toMs, fromRaw, toRaw) {
|
|
|
1824
1995
|
* "hard cap" and reach a native chronicle call expecting an unsigned
|
|
1825
1996
|
* pagination argument (observed: `extract({limit:-1})` returning every
|
|
1826
1997
|
* message in the store instead of being capped). Rejects (rather than
|
|
1827
|
-
* silently clamping) anything that isn't a
|
|
1828
|
-
* a caller mistake is surfaced as a clean tool error instead of silently
|
|
1829
|
-
* doing something other than what was asked.
|
|
1998
|
+
* silently clamping) anything that isn't a whole number of at least `min`,
|
|
1999
|
+
* so a caller mistake is surfaced as a clean tool error instead of silently
|
|
2000
|
+
* doing something other than what was asked. The refusal opens with what
|
|
2001
|
+
* didn't happen for the calling tool (`outcome`), and gives the range and
|
|
2002
|
+
* the default.
|
|
1830
2003
|
*/
|
|
1831
|
-
function clampCount(value, def, max, field) {
|
|
2004
|
+
function clampCount(value, def, max, field, outcome, min = 0) {
|
|
1832
2005
|
if (value === undefined)
|
|
1833
2006
|
return def;
|
|
1834
|
-
if (typeof value !== 'number' || !Number.
|
|
1835
|
-
throw new Error(`"${field}"
|
|
1836
|
-
|
|
1837
|
-
if (!Number.isInteger(value)) {
|
|
1838
|
-
throw new Error(`"${field}" must be an integer, got ${value}.`);
|
|
1839
|
-
}
|
|
1840
|
-
if (value < 0) {
|
|
1841
|
-
throw new Error(`"${field}" must be >= 0, got ${value}.`);
|
|
2007
|
+
if (typeof value !== 'number' || !Number.isInteger(value) || value < min) {
|
|
2008
|
+
throw new Error(`Nothing was ${outcome}: "${field}" is ${shown(value)}, which isn't a whole number from ${min} to ${max}. `
|
|
2009
|
+
+ `Pass one, or leave it out for ${def}.`);
|
|
1842
2010
|
}
|
|
1843
2011
|
return Math.min(value, max);
|
|
1844
2012
|
}
|
|
2013
|
+
/**
|
|
2014
|
+
* A value a message names, the call's or the store's, as the message quotes
|
|
2015
|
+
* it: its JSON, or what String() gives where JSON can't give the value itself,
|
|
2016
|
+
* cut to 80 UTF-16 units, or one fewer where the 80th would split a surrogate
|
|
2017
|
+
* pair: the message stays in the agent's context, and half a pair isn't
|
|
2018
|
+
* well-formed text. Inside a list or an object, JSON writes Infinity and NaN
|
|
2019
|
+
* as null, and so does the quote. A value the message gives the agent to send
|
|
2020
|
+
* is quoted whole instead, since a cut one couldn't be sent.
|
|
2021
|
+
*/
|
|
2022
|
+
function shown(value) {
|
|
2023
|
+
let text;
|
|
2024
|
+
// A value JSON can't give, such as a cycle, or Infinity or NaN as the whole
|
|
2025
|
+
// value, which JSON.stringify gives as null, is shown as String() shows it.
|
|
2026
|
+
if (typeof value !== 'number' || Number.isFinite(value)) {
|
|
2027
|
+
try {
|
|
2028
|
+
text = JSON.stringify(value);
|
|
2029
|
+
}
|
|
2030
|
+
catch { /* String() below */ }
|
|
2031
|
+
}
|
|
2032
|
+
text ??= String(value);
|
|
2033
|
+
return text.length <= 80 ? text : `${safeSlice(text, 0, 80)}…`;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Names in prose, each quoted whole: "a"; "a" and "b"; "a", "b" and "c" (or
|
|
2037
|
+
* "or"). They're the tools' own field names, or names the agent can send.
|
|
2038
|
+
*/
|
|
2039
|
+
function quotedList(names, joiner) {
|
|
2040
|
+
const quoted = names.map((name) => JSON.stringify(name));
|
|
2041
|
+
return quoted.length <= 1 ? quoted.join('') : `${quoted.slice(0, -1).join(', ')} ${joiner} ${quoted[quoted.length - 1]}`;
|
|
2042
|
+
}
|
|
1845
2043
|
/** channelId lives at metadata.external.channelId — same path context-manager's
|
|
1846
2044
|
* own native index reads from (message-store.ts's CHANNEL_FIELD). Metadata's
|
|
1847
2045
|
* index-signature type means this needs an explicit narrow, same as
|
|
@@ -2024,7 +2222,9 @@ function codePointBefore(s, i) {
|
|
|
2024
2222
|
return s[i - 1];
|
|
2025
2223
|
}
|
|
2026
2224
|
/**
|
|
2027
|
-
* First occurrence of `needle` in `text
|
|
2225
|
+
* First occurrence of `needle` in `text`, as the units of `text` it covers.
|
|
2226
|
+
* Without `caseSensitive`, `needle` is lower case already, and is found in
|
|
2227
|
+
* `text.toLowerCase()`. With `wholeWord`, an occurrence
|
|
2028
2228
|
* only counts when it isn't glued to a letter/digit/underscore on either
|
|
2029
2229
|
* side (Unicode-aware, so Cyrillic words work too) — "mission" no longer
|
|
2030
2230
|
* hits inside "uncommissioned". Word-ness is checked only on the sides
|
|
@@ -2033,6 +2233,12 @@ function codePointBefore(s, i) {
|
|
|
2033
2233
|
*/
|
|
2034
2234
|
function matchSubstring(text, needle, caseSensitive, wholeWord = false) {
|
|
2035
2235
|
const haystack = caseSensitive ? text : text.toLowerCase();
|
|
2236
|
+
const hit = firstOccurrence(haystack, needle, wholeWord);
|
|
2237
|
+
// Lowering can lengthen a character, as it does `İ` (one unit to two). Then
|
|
2238
|
+
// the lowered text's units aren't the text's, and the snippet cuts the text.
|
|
2239
|
+
return hit !== null && haystack.length !== text.length ? inTextUnits(text, hit) : hit;
|
|
2240
|
+
}
|
|
2241
|
+
function firstOccurrence(haystack, needle, wholeWord) {
|
|
2036
2242
|
if (!wholeWord) {
|
|
2037
2243
|
const index = haystack.indexOf(needle);
|
|
2038
2244
|
return index === -1 ? null : { index, length: needle.length };
|
|
@@ -2050,6 +2256,26 @@ function matchSubstring(text, needle, caseSensitive, wholeWord = false) {
|
|
|
2050
2256
|
from = index + 1;
|
|
2051
2257
|
}
|
|
2052
2258
|
}
|
|
2259
|
+
/**
|
|
2260
|
+
* The units of `text` that a hit in `text.toLowerCase()` covers. Each code
|
|
2261
|
+
* point of `text` takes as many units there as its own lower case has, so a
|
|
2262
|
+
* hit that starts or ends inside a character's lower case takes in the whole
|
|
2263
|
+
* character.
|
|
2264
|
+
*/
|
|
2265
|
+
function inTextUnits(text, hit) {
|
|
2266
|
+
const end = hit.index + hit.length;
|
|
2267
|
+
let start = -1;
|
|
2268
|
+
let lowered = 0;
|
|
2269
|
+
let at = 0;
|
|
2270
|
+
while (at < text.length && lowered < end) {
|
|
2271
|
+
const cp = text.codePointAt(at);
|
|
2272
|
+
lowered += String.fromCodePoint(cp).toLowerCase().length;
|
|
2273
|
+
if (start === -1 && lowered > hit.index)
|
|
2274
|
+
start = at;
|
|
2275
|
+
at += cp > 0xffff ? 2 : 1;
|
|
2276
|
+
}
|
|
2277
|
+
return { index: start, length: at - start };
|
|
2278
|
+
}
|
|
2053
2279
|
// ============================================================================
|
|
2054
2280
|
// author filtering
|
|
2055
2281
|
// ============================================================================
|
|
@@ -2073,7 +2299,9 @@ function parseSkipSequences(v) {
|
|
|
2073
2299
|
v.length !== 2 ||
|
|
2074
2300
|
!v.every((x) => typeof x === 'number' && Number.isInteger(x) && x >= 0) ||
|
|
2075
2301
|
v[0] > v[1]) {
|
|
2076
|
-
throw new Error('"skipSequences" must be
|
|
2302
|
+
throw new Error('Nothing was searched: "skipSequences" must be two whole numbers, 0 or more, the first no larger than the ' +
|
|
2303
|
+
`second, as a search's "resume" gives it; it's ${shown(v)}. Copy it from "resume" with its "from" or "to", ` +
|
|
2304
|
+
'or leave it out for a new search.');
|
|
2077
2305
|
}
|
|
2078
2306
|
return [v[0], v[1]];
|
|
2079
2307
|
}
|
|
@@ -2096,12 +2324,16 @@ function toAuthorSet(spec, field) {
|
|
|
2096
2324
|
if (spec === undefined)
|
|
2097
2325
|
return null;
|
|
2098
2326
|
const list = Array.isArray(spec) ? spec : [spec];
|
|
2099
|
-
|
|
2100
|
-
|
|
2327
|
+
const odd = list.findIndex((s) => typeof s !== 'string');
|
|
2328
|
+
if (odd !== -1) {
|
|
2329
|
+
throw new Error(`Nothing was read: "${field}" must list names or ids as text, such as ["alice", "1234"], and ` +
|
|
2330
|
+
`${shown(list[odd])} isn't text.`);
|
|
2101
2331
|
}
|
|
2102
2332
|
const set = new Set(list.map(normalizeAuthorSpec).filter((s) => s.length > 0));
|
|
2103
|
-
if (set.size === 0)
|
|
2104
|
-
throw new Error(`"${field}"
|
|
2333
|
+
if (set.size === 0) {
|
|
2334
|
+
throw new Error(`Nothing was read: "${field}" names no one: ${list.length > 0 ? 'its entries are blank' : 'the list is empty'}. ` +
|
|
2335
|
+
`List at least one name or id, such as ["alice"], or leave "${field}" out.`);
|
|
2336
|
+
}
|
|
2105
2337
|
return set;
|
|
2106
2338
|
}
|
|
2107
2339
|
/**
|
|
@@ -2132,14 +2364,14 @@ function buildAuthorFilter(include, exclude) {
|
|
|
2132
2364
|
/** ~SNIPPET_CONTEXT_CHARS of surrounding context on each side of a match, or
|
|
2133
2365
|
* the first ~SNIPPET_FALLBACK_CHARS of content when no meaningful match
|
|
2134
2366
|
* position is given (kept simple on purpose — this is a readability aid,
|
|
2135
|
-
* not a highlighting engine). */
|
|
2367
|
+
* not a highlighting engine). Neither end splits a surrogate pair. */
|
|
2136
2368
|
function snippetAround(text, index, length) {
|
|
2137
2369
|
if (index < 0)
|
|
2138
|
-
return text
|
|
2370
|
+
return safeSlice(text, 0, SNIPPET_FALLBACK_CHARS);
|
|
2139
2371
|
const start = Math.max(0, index - SNIPPET_CONTEXT_CHARS);
|
|
2140
2372
|
const end = Math.min(text.length, index + length + SNIPPET_CONTEXT_CHARS);
|
|
2141
2373
|
const prefix = start > 0 ? '…' : '';
|
|
2142
2374
|
const suffix = end < text.length ? '…' : '';
|
|
2143
|
-
return prefix + text
|
|
2375
|
+
return prefix + safeSlice(text, start, end) + suffix;
|
|
2144
2376
|
}
|
|
2145
2377
|
//# sourceMappingURL=index.js.map
|