@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
|
@@ -49,7 +49,9 @@ import type { ToolDefinition, ToolCall, ToolResult, ProcessEvent } from '../../t
|
|
|
49
49
|
import type { EventResponse, ProcessState } from '../../types/module.js';
|
|
50
50
|
import type { SearchWorkerMessage, SearchWorkerMatch } from './search-regex-worker.js';
|
|
51
51
|
import type { ChannelRegistry } from '../../mcpl/channel-registry.js';
|
|
52
|
-
import { SemanticIndexClient, SemanticIndexer, messageIndexText, type SemanticIndexConfig, type SyncReport, type PendingChanges } from './semantic.js';
|
|
52
|
+
import { EmbedServiceError, SemanticIndexClient, SemanticIndexer, messageIndexText, type SearchResponse, type SemanticIndexConfig, type SyncReport, type PendingChanges } from './semantic.js';
|
|
53
|
+
import { unknownToolMessage } from '../unknown-tool.js';
|
|
54
|
+
import { safeSlice } from '../../safe-slice.js';
|
|
53
55
|
|
|
54
56
|
// ============================================================================
|
|
55
57
|
// Tool input shapes
|
|
@@ -177,10 +179,15 @@ const AROUND_MAX = 100;
|
|
|
177
179
|
* see a handful; past this the call fails loudly rather than guessing. */
|
|
178
180
|
const AROUND_TIE_CAP = 5000;
|
|
179
181
|
|
|
180
|
-
function tieCapError(anchorId: string,
|
|
182
|
+
function tieCapError(anchorId: string, ms: number, channelId: string | undefined): Error {
|
|
183
|
+
const at = new Date(ms).toISOString();
|
|
184
|
+
// The channel is the agent's to send back, so it's quoted whole: a cut one
|
|
185
|
+
// couldn't be sent. It's one the store holds, with all those messages in it.
|
|
186
|
+
const inChannel = channelId !== undefined ? ` and "channelId" set to ${JSON.stringify(channelId)}` : '';
|
|
181
187
|
return new Error(
|
|
182
|
-
`
|
|
183
|
-
|
|
188
|
+
`Nothing was read: more than ${AROUND_TIE_CAP} messages share the timestamp of message ${shown(anchorId)}, ${at}, too ` +
|
|
189
|
+
`many for aroundId to put in order. To read them, call history--extract with "from" and "to" both set to ${at}` +
|
|
190
|
+
`${inChannel}; it pages through them with "offset" and "limit".`,
|
|
184
191
|
);
|
|
185
192
|
}
|
|
186
193
|
|
|
@@ -208,9 +215,13 @@ const SEMANTIC_DEFAULT_LIMIT = 10;
|
|
|
208
215
|
const SEMANTIC_MAX_LIMIT = 50;
|
|
209
216
|
/** Largest k sent to the embed-service when over-fetching past dropped hits (its own cap is 200). */
|
|
210
217
|
const SEMANTIC_MAX_FETCH = 200;
|
|
211
|
-
/**
|
|
218
|
+
/**
|
|
219
|
+
* Local snippet: the leading SEMANTIC_SNIPPET_CHARS of the current text, one
|
|
220
|
+
* fewer where the last would split a surrogate pair, since the snippet reaches
|
|
221
|
+
* the agent's context.
|
|
222
|
+
*/
|
|
212
223
|
function snippetOf(text: string): string {
|
|
213
|
-
return text.length <= SEMANTIC_SNIPPET_CHARS ? text : `${text
|
|
224
|
+
return text.length <= SEMANTIC_SNIPPET_CHARS ? text : `${safeSlice(text, 0, SEMANTIC_SNIPPET_CHARS)}…`;
|
|
214
225
|
}
|
|
215
226
|
const SEMANTIC_SNIPPET_CHARS = 400;
|
|
216
227
|
|
|
@@ -336,16 +347,20 @@ export class HistoryModule implements Module {
|
|
|
336
347
|
* you're trying to deliver a message, nonsense advice from a read-only
|
|
337
348
|
* history tool. This module always uses its own read-only-appropriate
|
|
338
349
|
* wording instead, regardless of which branch of the live resolver
|
|
339
|
-
* produced the miss.
|
|
350
|
+
* produced the miss. Its refusals open with "Nothing was read", which
|
|
351
|
+
* holds because every tool that resolves a channel here only reads (see
|
|
352
|
+
* the note above the helpers).
|
|
340
353
|
*/
|
|
341
354
|
private resolveChannel(input: string | undefined): string | undefined {
|
|
342
355
|
if (!input || !this.channelRegistry) return input;
|
|
343
356
|
const resolved = this.channelRegistry.resolveProseTargetDurable(input);
|
|
344
357
|
if (!('error' in resolved)) return resolved.channelId;
|
|
345
358
|
if (input.startsWith('#') || input.startsWith('@') || DM_MENTION_RE.test(input)) {
|
|
346
|
-
const suggestions = resolved.candidates?.length ? ` Did you mean
|
|
359
|
+
const suggestions = resolved.candidates?.length ? ` Did you mean ${quotedList(resolved.candidates, 'or')}?` : '';
|
|
347
360
|
throw new Error(
|
|
348
|
-
`
|
|
361
|
+
`Nothing was read: no channel history matches ${shown(input)}. This host may never have seen a channel by that ` +
|
|
362
|
+
`name, or saw it before it kept channel names.${suggestions} Each message history--search returns carries ` +
|
|
363
|
+
'its "channelId", so searching for something said in that channel shows its id; pass that id as "channelId".',
|
|
349
364
|
);
|
|
350
365
|
}
|
|
351
366
|
return input;
|
|
@@ -390,9 +405,15 @@ export class HistoryModule implements Module {
|
|
|
390
405
|
? cm.queryMessagesByTimeAndChannel({ fromMs: ms, toMs: ms, channelId, limit: 0 }).matchedCount
|
|
391
406
|
: cm.queryMessagesByTime({ fromMs: ms, toMs: ms, limit: AROUND_TIE_CAP + 1 }).messages.length;
|
|
392
407
|
if (n > AROUND_TIE_CAP) {
|
|
408
|
+
// The count is by channel alone, so an author filter can't bring it down.
|
|
409
|
+
const at = new Date(ms).toISOString();
|
|
393
410
|
throw new Error(
|
|
394
|
-
`
|
|
395
|
-
|
|
411
|
+
`Nothing was searched: more than ${AROUND_TIE_CAP} messages share the instant ${at}, too many for a ` +
|
|
412
|
+
`continuation to step past. To read them, call history--extract with "from" and "to" both set to ${at}` +
|
|
413
|
+
(channelId !== undefined
|
|
414
|
+
? ' and the same "channelId"; it pages through them with "offset" and "limit".'
|
|
415
|
+
: '; it pages through them with "offset" and "limit". Searching one channel, with "channelId", may also ' +
|
|
416
|
+
'bring them under the limit.'),
|
|
396
417
|
);
|
|
397
418
|
}
|
|
398
419
|
return n;
|
|
@@ -450,13 +471,19 @@ export class HistoryModule implements Module {
|
|
|
450
471
|
q: { fromMs?: number; toMs?: number; channelId?: string },
|
|
451
472
|
): { windowOffset: number; shift: number } {
|
|
452
473
|
if (windowOffset === 0) {
|
|
453
|
-
if (afterId != null)
|
|
474
|
+
if (afterId != null) {
|
|
475
|
+
throw new Error(
|
|
476
|
+
'Nothing was read: "afterId" goes with a "windowOffset" above 0, both copied from a truncated response\'s ' +
|
|
477
|
+
'"resume". For a first page, leave afterId out; to continue, copy the fields of that "resume" into the call.',
|
|
478
|
+
);
|
|
479
|
+
}
|
|
454
480
|
return { windowOffset, shift: 0 };
|
|
455
481
|
}
|
|
456
482
|
if (afterId == null) {
|
|
457
483
|
throw new Error(
|
|
458
|
-
'"windowOffset" needs the "afterId" from the same
|
|
459
|
-
'since the previous call would be
|
|
484
|
+
'Nothing was read: "windowOffset" needs the "afterId" from the same "resume", or a message added or removed ' +
|
|
485
|
+
'since the previous call would be skipped unseen. Copy the fields of the previous response\'s "resume" into ' +
|
|
486
|
+
'the call.',
|
|
460
487
|
);
|
|
461
488
|
}
|
|
462
489
|
const cm = this.cm as ContextManager;
|
|
@@ -467,9 +494,9 @@ export class HistoryModule implements Module {
|
|
|
467
494
|
const i = around.findIndex((m) => String(m.id) === afterId);
|
|
468
495
|
if (i === -1) {
|
|
469
496
|
throw new Error(
|
|
470
|
-
`
|
|
471
|
-
`within ${RELOCATE_RADIUS} positions of windowOffset ${windowOffset}
|
|
472
|
-
'Restart the scan without windowOffset
|
|
497
|
+
`Nothing was read: the window changed since the previous call. Message ${shown(afterId)}, where that scan stopped, ` +
|
|
498
|
+
`is no longer within ${RELOCATE_RADIUS} positions of windowOffset ${windowOffset}; it may have been deleted. ` +
|
|
499
|
+
'Restart the scan without "windowOffset" and "afterId", over the same range or one narrowed with "from" and "to".',
|
|
473
500
|
);
|
|
474
501
|
}
|
|
475
502
|
const relocated = lo + i + 1;
|
|
@@ -717,7 +744,7 @@ export class HistoryModule implements Module {
|
|
|
717
744
|
excludeAuthor: EXCLUDE_AUTHOR_SCHEMA,
|
|
718
745
|
order: { type: 'string', enum: ['oldest', 'newest'], description: 'Scan and return oldest-first (default) or newest-first.' },
|
|
719
746
|
limit: { type: 'number', description: `Max matches to return (default ${SEARCH_DEFAULT_LIMIT}, hard cap ${SEARCH_MAX_LIMIT}). Must be a non-negative integer.` },
|
|
720
|
-
maxScan: { type: 'number', description: `Max candidate messages to scan (default ${SEARCH_DEFAULT_MAX_SCAN}, hard cap ${SEARCH_MAX_MAX_SCAN}). Must be a
|
|
747
|
+
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.` },
|
|
721
748
|
skipSequences: {
|
|
722
749
|
type: 'array',
|
|
723
750
|
items: { type: 'number' },
|
|
@@ -793,7 +820,10 @@ export class HistoryModule implements Module {
|
|
|
793
820
|
'Purely a read: nothing is written to your history. Hits are checked against your current branch ' +
|
|
794
821
|
'before they come back: a message you undid or a summary from a branch you left is dropped and ' +
|
|
795
822
|
'counted in index.droppedOffBranch; a message edited down to nothing searchable is dropped and ' +
|
|
796
|
-
'counted in index.droppedStale.
|
|
823
|
+
'counted in index.droppedStale. When that leaves fewer than `limit` hits and the index may hold more, it ' +
|
|
824
|
+
'searches again, deeper, down to its first 200 hits; if a search after the first fails, the hits found so ' +
|
|
825
|
+
'far come back, with why in index.searchAgainError. Message snippets ' +
|
|
826
|
+
'always show the current text of the message.',
|
|
797
827
|
inputSchema: {
|
|
798
828
|
type: 'object' as const,
|
|
799
829
|
properties: {
|
|
@@ -814,7 +844,13 @@ export class HistoryModule implements Module {
|
|
|
814
844
|
async handleToolCall(call: ToolCall): Promise<ToolResult> {
|
|
815
845
|
try {
|
|
816
846
|
if (!this.cm) {
|
|
817
|
-
|
|
847
|
+
// The host's mistake, named for whoever runs it; the agent reads what
|
|
848
|
+
// it can do about it, which is nothing.
|
|
849
|
+
console.error('[history] a tool was called before the host bound the module: call bind(contextManager) before tool dispatch');
|
|
850
|
+
throw new Error(
|
|
851
|
+
"The history tools aren't available: this host hasn't finished setting up the history module, so nothing " +
|
|
852
|
+
"was read. Calling them again won't change that; ask whoever runs this host.",
|
|
853
|
+
);
|
|
818
854
|
}
|
|
819
855
|
switch (call.name) {
|
|
820
856
|
case 'stats':
|
|
@@ -828,7 +864,7 @@ export class HistoryModule implements Module {
|
|
|
828
864
|
case 'semantic_search':
|
|
829
865
|
return await this.handleSemanticSearch((call.input ?? {}) as SemanticSearchInput);
|
|
830
866
|
default:
|
|
831
|
-
return { success: false, isError: true, error:
|
|
867
|
+
return { success: false, isError: true, error: unknownToolMessage(this.name, call.name, this.getTools()) };
|
|
832
868
|
}
|
|
833
869
|
} catch (error) {
|
|
834
870
|
// Catches our own validation errors (bad ISO date, invalid regex,
|
|
@@ -897,20 +933,33 @@ export class HistoryModule implements Module {
|
|
|
897
933
|
|
|
898
934
|
private handleExtract(input: ExtractInput): ToolResult {
|
|
899
935
|
if (input.aroundId !== undefined) return this.handleExtractAround(input);
|
|
900
|
-
|
|
901
|
-
|
|
936
|
+
const aroundOnly = (['before', 'after', 'allChannels'] as const).filter((k) => input[k] !== undefined);
|
|
937
|
+
if (aroundOnly.length > 0) {
|
|
938
|
+
const one = aroundOnly.length === 1;
|
|
939
|
+
throw new Error(
|
|
940
|
+
`Nothing was read: ${quotedList(aroundOnly, 'and')} ${one ? 'goes' : 'go'} with "aroundId", which reads the ` +
|
|
941
|
+
`conversation around one message. Pass aroundId too, or leave ${one ? 'it' : 'them'} out to read a range ` +
|
|
942
|
+
'with "from", "to" and "channelId".',
|
|
943
|
+
);
|
|
902
944
|
}
|
|
903
945
|
const channelId = this.resolveChannel(input.channelId);
|
|
904
946
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
905
947
|
const toMs = parseIsoDate(input.to, 'to');
|
|
906
|
-
const limit = clampCount(input.limit, EXTRACT_DEFAULT_LIMIT, EXTRACT_MAX_LIMIT, 'limit');
|
|
907
|
-
const offset = clampCount(input.offset, 0, NATIVE_OFFSET_MAX, 'offset');
|
|
948
|
+
const limit = clampCount(input.limit, EXTRACT_DEFAULT_LIMIT, EXTRACT_MAX_LIMIT, 'limit', 'read');
|
|
949
|
+
const offset = clampCount(input.offset, 0, NATIVE_OFFSET_MAX, 'offset', 'read');
|
|
908
950
|
const format = input.format ?? 'text';
|
|
909
951
|
const authorFilter = buildAuthorFilter(input.author, input.excludeAuthor);
|
|
910
952
|
|
|
911
953
|
const cm = this.cm as ContextManager;
|
|
912
|
-
|
|
913
|
-
|
|
954
|
+
const resumeOnly = (['windowOffset', 'afterId', 'seqMark'] as const).filter((k) => input[k] !== undefined);
|
|
955
|
+
if (!authorFilter && resumeOnly.length > 0) {
|
|
956
|
+
const one = resumeOnly.length === 1;
|
|
957
|
+
throw new Error(
|
|
958
|
+
`Nothing was read: ${quotedList(resumeOnly, 'and')} ${one ? 'resumes' : 'resume'} an author-filtered ` +
|
|
959
|
+
`extract, so ${one ? 'it goes' : 'they go'} with the "author" or "excludeAuthor" of the call that returned ` +
|
|
960
|
+
`${one ? 'it' : 'them'}: repeat that call with the fields of its "resume". To page through a range without an ` +
|
|
961
|
+
'author filter, use "offset".',
|
|
962
|
+
);
|
|
914
963
|
}
|
|
915
964
|
|
|
916
965
|
if (authorFilter) {
|
|
@@ -924,9 +973,11 @@ export class HistoryModule implements Module {
|
|
|
924
973
|
// channel-scoped window pages in append order, and Discord catch-up
|
|
925
974
|
// appends old-timestamped messages late, so "continue from the last
|
|
926
975
|
// timestamp seen" would skip them.
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
976
|
+
// An author-filtered extract has to examine at least 1 message.
|
|
977
|
+
const maxScan = clampCount(
|
|
978
|
+
input.maxScan, EXTRACT_FILTER_DEFAULT_MAX_SCAN, EXTRACT_FILTER_MAX_MAX_SCAN, 'maxScan', 'read', 1,
|
|
979
|
+
);
|
|
980
|
+
const requestedOffset = clampCount(input.windowOffset, 0, NATIVE_OFFSET_MAX, 'windowOffset', 'read');
|
|
930
981
|
// A position is only meaningful against the window it was taken in:
|
|
931
982
|
// a removal before it (every discord:delete, host hide, /undo) shifts
|
|
932
983
|
// later positions left, and a message inserted before it (a
|
|
@@ -951,7 +1002,8 @@ export class HistoryModule implements Module {
|
|
|
951
1002
|
if (channelId === undefined && windowOffset > 0) {
|
|
952
1003
|
if (typeof input.seqMark !== 'number') {
|
|
953
1004
|
throw new Error(
|
|
954
|
-
'"windowOffset" without channelId needs the "seqMark" from the same
|
|
1005
|
+
'Nothing was read: "windowOffset" without "channelId" needs the "seqMark" from the same "resume". Copy the ' +
|
|
1006
|
+
'fields of the previous response\'s "resume" into the call.',
|
|
955
1007
|
);
|
|
956
1008
|
}
|
|
957
1009
|
const cursor = cm.queryMessagesByTimeAndChannel({ fromMs, toMs, limit: 1, offset: windowOffset - 1 }).messages[0];
|
|
@@ -1128,25 +1180,27 @@ export class HistoryModule implements Module {
|
|
|
1128
1180
|
* via edgeWindow, which is exact by timestamp).
|
|
1129
1181
|
*/
|
|
1130
1182
|
private handleExtractAround(input: ExtractInput): ToolResult {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
input.to !== undefined ||
|
|
1134
|
-
input.offset !== undefined ||
|
|
1135
|
-
input.windowOffset !== undefined ||
|
|
1136
|
-
input.limit !== undefined
|
|
1137
|
-
) {
|
|
1183
|
+
const windowFields = (['from', 'to', 'offset', 'windowOffset', 'limit'] as const).filter((k) => input[k] !== undefined);
|
|
1184
|
+
if (windowFields.length > 0) {
|
|
1138
1185
|
throw new Error(
|
|
1139
|
-
|
|
1186
|
+
`Nothing was read: "aroundId" picks its own window, so it doesn't take ${quotedList(windowFields, 'or')}. Size ` +
|
|
1187
|
+
'the window with "before" and "after", or leave out "aroundId" to read a range.',
|
|
1140
1188
|
);
|
|
1141
1189
|
}
|
|
1142
1190
|
if (input.author !== undefined || input.excludeAuthor !== undefined) {
|
|
1143
|
-
throw new Error(
|
|
1191
|
+
throw new Error(
|
|
1192
|
+
'Nothing was read: "aroundId" reads the whole conversation around one message, so author filters don\'t ' +
|
|
1193
|
+
'apply to it. To find someone\'s messages, use history--search or history--extract with "author".',
|
|
1194
|
+
);
|
|
1144
1195
|
}
|
|
1145
1196
|
if (input.allChannels && input.channelId !== undefined) {
|
|
1146
|
-
throw new Error(
|
|
1197
|
+
throw new Error(
|
|
1198
|
+
'Nothing was read: "channelId" and "allChannels" can\'t go together. Leave out "channelId" to read around the ' +
|
|
1199
|
+
'message in every channel, or leave out both to read around it in its own channel.',
|
|
1200
|
+
);
|
|
1147
1201
|
}
|
|
1148
|
-
const before = clampCount(input.before, AROUND_DEFAULT, AROUND_MAX, 'before');
|
|
1149
|
-
const after = clampCount(input.after, AROUND_DEFAULT, AROUND_MAX, 'after');
|
|
1202
|
+
const before = clampCount(input.before, AROUND_DEFAULT, AROUND_MAX, 'before', 'read');
|
|
1203
|
+
const after = clampCount(input.after, AROUND_DEFAULT, AROUND_MAX, 'after', 'read');
|
|
1150
1204
|
const format = input.format ?? 'text';
|
|
1151
1205
|
const cm = this.cm as ContextManager;
|
|
1152
1206
|
|
|
@@ -1155,12 +1209,20 @@ export class HistoryModule implements Module {
|
|
|
1155
1209
|
const rawId = String(input.aroundId);
|
|
1156
1210
|
if (/^sum:/.test(rawId)) {
|
|
1157
1211
|
throw new Error(
|
|
1158
|
-
|
|
1212
|
+
`Nothing was read: ${shown(rawId)} is a compression summary, not a message. history--overview reads ` +
|
|
1213
|
+
'summaries; "aroundId" takes a message, such as ' +
|
|
1214
|
+
(this.semanticCfg
|
|
1215
|
+
? 'the "messageId" of a history--semantic_search hit.'
|
|
1216
|
+
: 'the "id" of a history--search or history--extract result.'),
|
|
1159
1217
|
);
|
|
1160
1218
|
}
|
|
1161
1219
|
const anchor = cm.getMessage(rawId.replace(/^msg:/, ''));
|
|
1162
1220
|
if (!anchor) {
|
|
1163
|
-
throw new Error(
|
|
1221
|
+
throw new Error(
|
|
1222
|
+
`Nothing was read: no message in your history has the id ${shown(input.aroundId)}. Pass the "id" ` +
|
|
1223
|
+
'of a history--search or history--extract result' +
|
|
1224
|
+
(this.semanticCfg ? ', or the "messageId" of a history--semantic_search hit.' : '.'),
|
|
1225
|
+
);
|
|
1164
1226
|
}
|
|
1165
1227
|
const anchorId = String(anchor.id);
|
|
1166
1228
|
const anchorChannel = getChannelId(anchor);
|
|
@@ -1175,11 +1237,11 @@ export class HistoryModule implements Module {
|
|
|
1175
1237
|
let ties: StoredMessage[];
|
|
1176
1238
|
if (channelId !== undefined) {
|
|
1177
1239
|
const n = cm.queryMessagesByTimeAndChannel({ fromMs: t, toMs: t, channelId, limit: 0 }).matchedCount;
|
|
1178
|
-
if (n > AROUND_TIE_CAP) throw tieCapError(anchorId,
|
|
1240
|
+
if (n > AROUND_TIE_CAP) throw tieCapError(anchorId, t, channelId);
|
|
1179
1241
|
ties = cm.queryMessagesByTimeAndChannel({ fromMs: t, toMs: t, channelId, limit: n }).messages;
|
|
1180
1242
|
} else {
|
|
1181
1243
|
ties = cm.queryMessagesByTime({ fromMs: t, toMs: t, limit: AROUND_TIE_CAP + 1 }).messages;
|
|
1182
|
-
if (ties.length > AROUND_TIE_CAP) throw tieCapError(anchorId,
|
|
1244
|
+
if (ties.length > AROUND_TIE_CAP) throw tieCapError(anchorId, t, undefined);
|
|
1183
1245
|
}
|
|
1184
1246
|
ties = [...ties].sort((x, y) => x.sequence - y.sequence);
|
|
1185
1247
|
const idx = ties.findIndex((m) => String(m.id) === anchorId);
|
|
@@ -1187,9 +1249,9 @@ export class HistoryModule implements Module {
|
|
|
1187
1249
|
// The anchor is in the store and every message of its millisecond in
|
|
1188
1250
|
// `channelId` was fetched, so only an explicit channelId excludes it.
|
|
1189
1251
|
throw new Error(
|
|
1190
|
-
`
|
|
1191
|
-
(anchorChannel ? ` (it
|
|
1192
|
-
'
|
|
1252
|
+
`Nothing was read: message ${shown(anchorId)} isn't in channel ${shown(input.channelId)}` +
|
|
1253
|
+
(anchorChannel ? ` (it's in ${shown(anchorChannel)}).` : '.') +
|
|
1254
|
+
' Leave out "channelId" to read around it in its own channel.',
|
|
1193
1255
|
);
|
|
1194
1256
|
}
|
|
1195
1257
|
const tiesBefore = ties.slice(Math.max(0, idx - before), idx);
|
|
@@ -1219,22 +1281,35 @@ export class HistoryModule implements Module {
|
|
|
1219
1281
|
// ==========================================================================
|
|
1220
1282
|
|
|
1221
1283
|
private async handleSearch(input: SearchInput): Promise<ToolResult> {
|
|
1222
|
-
|
|
1223
|
-
|
|
1284
|
+
// A finite number is searched as its text, as a regular expression made
|
|
1285
|
+
// from it reads it; any other value that isn't text is refused.
|
|
1286
|
+
const given: unknown = input.query;
|
|
1287
|
+
const query = typeof given === 'number' && Number.isFinite(given) ? String(given) : given;
|
|
1288
|
+
if (typeof query !== 'string' || query === '') {
|
|
1289
|
+
throw new Error(
|
|
1290
|
+
'Nothing was searched: "query" must be the text to look for; ' +
|
|
1291
|
+
`${given === undefined ? 'this call gave none' : `it's ${shown(given)}`}.`,
|
|
1292
|
+
);
|
|
1224
1293
|
}
|
|
1225
1294
|
const channelId = this.resolveChannel(input.channelId);
|
|
1226
1295
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
1227
1296
|
const toMs = parseIsoDate(input.to, 'to');
|
|
1228
|
-
const limit = clampCount(input.limit, SEARCH_DEFAULT_LIMIT, SEARCH_MAX_LIMIT, 'limit');
|
|
1229
|
-
|
|
1297
|
+
const limit = clampCount(input.limit, SEARCH_DEFAULT_LIMIT, SEARCH_MAX_LIMIT, 'limit', 'searched');
|
|
1298
|
+
// A search has to scan at least 1 message.
|
|
1299
|
+
const maxScan = clampCount(input.maxScan, SEARCH_DEFAULT_MAX_SCAN, SEARCH_MAX_MAX_SCAN, 'maxScan', 'searched', 1);
|
|
1230
1300
|
const caseSensitive = input.caseSensitive ?? false;
|
|
1231
1301
|
const flags = caseSensitive ? '' : 'i';
|
|
1232
1302
|
const order = input.order ?? 'oldest';
|
|
1233
1303
|
if (order !== 'oldest' && order !== 'newest') {
|
|
1234
|
-
throw new Error(
|
|
1304
|
+
throw new Error(
|
|
1305
|
+
`Nothing was searched: "order" must be "oldest" or "newest", or left out for "oldest"; it's ${shown(input.order)}.`,
|
|
1306
|
+
);
|
|
1235
1307
|
}
|
|
1236
1308
|
if (input.wholeWord && input.regex) {
|
|
1237
|
-
throw new Error(
|
|
1309
|
+
throw new Error(
|
|
1310
|
+
'Nothing was searched: "wholeWord" applies to a search for text, not a regular expression. In a regular ' +
|
|
1311
|
+
'expression, write \\b around the pattern instead, or set "regex" to false.',
|
|
1312
|
+
);
|
|
1238
1313
|
}
|
|
1239
1314
|
const authorFilter = buildAuthorFilter(input.author, input.excludeAuthor);
|
|
1240
1315
|
|
|
@@ -1245,12 +1320,18 @@ export class HistoryModule implements Module {
|
|
|
1245
1320
|
// than here.
|
|
1246
1321
|
if (input.regex) {
|
|
1247
1322
|
try {
|
|
1248
|
-
new RegExp(
|
|
1323
|
+
new RegExp(query, flags);
|
|
1249
1324
|
} catch (error) {
|
|
1250
|
-
|
|
1325
|
+
// V8's message restates the pattern; the reason alone follows it.
|
|
1326
|
+
const reason = (error instanceof Error ? error.message : String(error))
|
|
1327
|
+
.replace(/^Invalid regular expression: \/.*\/[a-z]*: /s, '');
|
|
1328
|
+
throw new Error(
|
|
1329
|
+
`Nothing was searched: "query" ${shown(query)} isn't a valid regular expression (${reason}). ` +
|
|
1330
|
+
'Fix the pattern, or set "regex" to false to search for the text as written.',
|
|
1331
|
+
);
|
|
1251
1332
|
}
|
|
1252
1333
|
}
|
|
1253
|
-
const needle = caseSensitive ?
|
|
1334
|
+
const needle = caseSensitive ? query : query.toLowerCase();
|
|
1254
1335
|
|
|
1255
1336
|
const cm = this.cm as ContextManager;
|
|
1256
1337
|
// The candidate window is the oldest (order:"oldest") or newest
|
|
@@ -1259,7 +1340,7 @@ export class HistoryModule implements Module {
|
|
|
1259
1340
|
// detected up front rather than
|
|
1260
1341
|
// silently scanning maxScan candidates and returning as if that were the
|
|
1261
1342
|
// whole window. See the tool description's `truncated` contract.
|
|
1262
|
-
|
|
1343
|
+
//
|
|
1263
1344
|
// Continuation: `skipSequences` names what the previous call already
|
|
1264
1345
|
// scanned at exactly the resume bound's millisecond (the bound is
|
|
1265
1346
|
// inclusive). Identified by sequence range rather than a count, so a
|
|
@@ -1269,7 +1350,11 @@ export class HistoryModule implements Module {
|
|
|
1269
1350
|
const skipRange = parseSkipSequences(input.skipSequences);
|
|
1270
1351
|
const edgeMs = order === 'oldest' ? fromMs : toMs;
|
|
1271
1352
|
if (skipRange && edgeMs === undefined) {
|
|
1272
|
-
throw new Error(
|
|
1353
|
+
throw new Error(
|
|
1354
|
+
`Nothing was searched: "skipSequences" goes with the "${order === 'oldest' ? 'from' : 'to'}" from the same ` +
|
|
1355
|
+
'"resume". Copy the fields of the previous response\'s "resume" into the call, or leave "skipSequences" ' +
|
|
1356
|
+
'out for a new search.',
|
|
1357
|
+
);
|
|
1273
1358
|
}
|
|
1274
1359
|
const isSkipped = (m: StoredMessage) =>
|
|
1275
1360
|
!!skipRange && m.timestamp.getTime() === edgeMs && m.sequence >= skipRange[0] && m.sequence <= skipRange[1];
|
|
@@ -1350,7 +1435,7 @@ export class HistoryModule implements Module {
|
|
|
1350
1435
|
// through a worker thread instead, which can be forcibly terminated
|
|
1351
1436
|
// on a deadline. See search-regex-worker.ts's header for the full
|
|
1352
1437
|
// rationale.
|
|
1353
|
-
const { matches, scanned } = await this.searchWithRegexWorker(candidates,
|
|
1438
|
+
const { matches, scanned } = await this.searchWithRegexWorker(candidates, query, flags, limit);
|
|
1354
1439
|
return { success: true, data: { scanned, ...poolInfo, truncated, ...resumeInfo(scanned), matches } };
|
|
1355
1440
|
}
|
|
1356
1441
|
|
|
@@ -1416,22 +1501,32 @@ export class HistoryModule implements Module {
|
|
|
1416
1501
|
const timer = setTimeout(() => {
|
|
1417
1502
|
reject(
|
|
1418
1503
|
new Error(
|
|
1419
|
-
`search
|
|
1420
|
-
`up to ${texts.length}
|
|
1421
|
-
|
|
1422
|
-
'
|
|
1504
|
+
`The search stopped, and returned nothing: matching the regular expression ${shown(pattern)} ` +
|
|
1505
|
+
`against up to ${texts.length} ${texts.length === 1 ? 'message' : 'messages'} took longer than ` +
|
|
1506
|
+
`${SEARCH_REGEX_TIMEOUT_MS} ms, as a ` +
|
|
1507
|
+
'pattern that backtracks heavily can. Try a simpler pattern, set "regex" to false to search for the ' +
|
|
1508
|
+
'text as written, or lower "maxScan".',
|
|
1423
1509
|
),
|
|
1424
1510
|
);
|
|
1425
1511
|
}, SEARCH_REGEX_TIMEOUT_MS);
|
|
1426
1512
|
timer.unref?.();
|
|
1427
1513
|
worker.once('message', (msg: SearchWorkerMessage) => {
|
|
1428
1514
|
clearTimeout(timer);
|
|
1429
|
-
if (msg.type === 'error')
|
|
1430
|
-
|
|
1515
|
+
if (msg.type === 'error') {
|
|
1516
|
+
reject(new Error(
|
|
1517
|
+
`The search stopped, and returned nothing: matching the regular expression ${shown(pattern)} ` +
|
|
1518
|
+
`failed (${msg.error}). Try a simpler pattern, or set "regex" to false to search for the text as written.`,
|
|
1519
|
+
));
|
|
1520
|
+
} else {
|
|
1521
|
+
resolve({ matches: msg.matches, scanned: msg.scanned });
|
|
1522
|
+
}
|
|
1431
1523
|
});
|
|
1432
1524
|
worker.once('error', (err) => {
|
|
1433
1525
|
clearTimeout(timer);
|
|
1434
|
-
reject(
|
|
1526
|
+
reject(new Error(
|
|
1527
|
+
`The search stopped, and returned nothing: the worker matching the regular expression ${shown(pattern)} ` +
|
|
1528
|
+
`failed (${err.message}). Set "regex" to false to search for the text as written.`,
|
|
1529
|
+
));
|
|
1435
1530
|
});
|
|
1436
1531
|
},
|
|
1437
1532
|
);
|
|
@@ -1463,30 +1558,54 @@ export class HistoryModule implements Module {
|
|
|
1463
1558
|
|
|
1464
1559
|
private async handleSemanticSearch(input: SemanticSearchInput): Promise<ToolResult> {
|
|
1465
1560
|
if (!this.semanticCfg || !this.semanticClient) {
|
|
1466
|
-
throw new Error(
|
|
1561
|
+
throw new Error(
|
|
1562
|
+
"Nothing was searched: this host has no semantic index set up, so history--semantic_search isn't available " +
|
|
1563
|
+
"here, and calling it again won't change that. history--search finds messages by their words.",
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
if (typeof input.query !== 'string' || !input.query.trim()) {
|
|
1567
|
+
throw new Error(
|
|
1568
|
+
'Nothing was searched: "query" must be a sentence describing what you\'re looking for; ' +
|
|
1569
|
+
`${input.query === undefined ? 'this call gave none' : `it's ${shown(input.query)}`}.`,
|
|
1570
|
+
);
|
|
1467
1571
|
}
|
|
1468
|
-
|
|
1469
|
-
const limit = clampCount(input.limit, SEMANTIC_DEFAULT_LIMIT, SEMANTIC_MAX_LIMIT, 'limit');
|
|
1470
|
-
if (limit < 1) throw new Error('limit must be at least 1');
|
|
1572
|
+
// A search has to return at least 1 hit.
|
|
1573
|
+
const limit = clampCount(input.limit, SEMANTIC_DEFAULT_LIMIT, SEMANTIC_MAX_LIMIT, 'limit', 'searched', 1);
|
|
1471
1574
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
1472
1575
|
const toMs = parseIsoDate(input.to, 'to');
|
|
1473
|
-
|
|
1576
|
+
assertOrderedRange(fromMs, toMs, input.from, input.to);
|
|
1474
1577
|
const channelId = this.resolveChannel(input.channelId);
|
|
1475
1578
|
// Summaries carry no channel, so a channel filter on a summaries-only
|
|
1476
1579
|
// search can only ever match nothing. Say so instead of returning [].
|
|
1477
1580
|
const wantsSummariesOnly = input.level !== undefined || input.kinds === 'summaries';
|
|
1478
1581
|
if (channelId && wantsSummariesOnly) {
|
|
1479
|
-
|
|
1582
|
+
const picks = [
|
|
1583
|
+
...(input.kinds === 'summaries' ? ['"kinds": "summaries"'] : []),
|
|
1584
|
+
...(input.level !== undefined ? ['"level"'] : []),
|
|
1585
|
+
];
|
|
1586
|
+
const fields = [...(input.kinds === 'summaries' ? ['kinds'] : []), ...(input.level !== undefined ? ['level'] : [])];
|
|
1587
|
+
throw new Error(
|
|
1588
|
+
`Nothing was searched: summaries aren't kept by channel, so "channelId" can't go with ${picks.join(' or ')}. ` +
|
|
1589
|
+
`Leave out "channelId" to search summaries, or leave out ${quotedList(fields, 'and')} to search that ` +
|
|
1590
|
+
'channel\'s messages.',
|
|
1591
|
+
);
|
|
1480
1592
|
}
|
|
1481
1593
|
if (input.level !== undefined && input.kinds === 'messages') {
|
|
1482
|
-
throw new Error(
|
|
1594
|
+
throw new Error(
|
|
1595
|
+
'Nothing was searched: "level" picks summaries, and "kinds" is "messages", so the two can\'t go together. ' +
|
|
1596
|
+
'Leave out "kinds" to search summaries of that level, or leave out "level" to search messages.',
|
|
1597
|
+
);
|
|
1483
1598
|
}
|
|
1484
1599
|
let kinds: string[] | undefined;
|
|
1485
1600
|
if (wantsSummariesOnly) kinds = ['summary'];
|
|
1486
1601
|
else if (input.kinds === 'messages' || channelId) kinds = ['message'];
|
|
1487
|
-
if (input.level !== undefined && (!Number.isInteger(input.level) || input.level < 0))
|
|
1602
|
+
if (input.level !== undefined && (!Number.isInteger(input.level) || input.level < 0)) {
|
|
1603
|
+
throw new Error(`Nothing was searched: "level" must be a whole number, 0 or more, such as 1; it's ${shown(input.level)}.`);
|
|
1604
|
+
}
|
|
1488
1605
|
if (input.minScore !== undefined && (typeof input.minScore !== 'number' || input.minScore < -1 || input.minScore > 1)) {
|
|
1489
|
-
throw new Error(
|
|
1606
|
+
throw new Error(
|
|
1607
|
+
`Nothing was searched: "minScore" must be a number from -1 to 1, or left out; it's ${shown(input.minScore)}.`,
|
|
1608
|
+
);
|
|
1490
1609
|
}
|
|
1491
1610
|
|
|
1492
1611
|
// Bounded catch-up so the newest messages are searchable; never block on a backlog.
|
|
@@ -1501,6 +1620,48 @@ export class HistoryModule implements Module {
|
|
|
1501
1620
|
ts_to: toMs === undefined ? undefined : toMs / 1000,
|
|
1502
1621
|
channel: channelId, kinds, level: input.level, min_score: input.minScore, snippet: SEMANTIC_SNIPPET_CHARS,
|
|
1503
1622
|
});
|
|
1623
|
+
// The client says what went wrong with the service; what that means for
|
|
1624
|
+
// this call, and what the agent can do, is said here. The service's own
|
|
1625
|
+
// source isn't in this repository, so a 404's advice holds whether it
|
|
1626
|
+
// means this store's index doesn't exist yet or a route the service lacks.
|
|
1627
|
+
const failure = (e: unknown): { reason: string; advice: string; mayPass: boolean } => {
|
|
1628
|
+
const status = e instanceof EmbedServiceError ? e.status : null;
|
|
1629
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
1630
|
+
const later = {
|
|
1631
|
+
reason, mayPass: true,
|
|
1632
|
+
advice: 'You can try again later; if it keeps happening, ask whoever runs this host',
|
|
1633
|
+
};
|
|
1634
|
+
if (status === 404) {
|
|
1635
|
+
return {
|
|
1636
|
+
reason, mayPass: true,
|
|
1637
|
+
advice: "If this store's index doesn't exist yet, the first messages indexed create it, and a later call " +
|
|
1638
|
+
'can work; if it keeps happening, ask whoever runs this host',
|
|
1639
|
+
};
|
|
1640
|
+
}
|
|
1641
|
+
if (status === 408 || status === 429 || (status !== null && status >= 500)) return later;
|
|
1642
|
+
// An answer without what a search reads: a page shown while the service
|
|
1643
|
+
// restarts clears, and an address that points at something else doesn't.
|
|
1644
|
+
if (status !== null && status >= 200 && status < 300) {
|
|
1645
|
+
return {
|
|
1646
|
+
reason, mayPass: true,
|
|
1647
|
+
advice: 'If the service was restarting, a later call can work; if its address points at something else, ' +
|
|
1648
|
+
"none will until whoever runs this host fixes the semantic index's settings",
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
if (status !== null) {
|
|
1652
|
+
return {
|
|
1653
|
+
reason, mayPass: false,
|
|
1654
|
+
advice: "Calling it again the same way won't change that; if it keeps happening, ask whoever runs this host",
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
// No answer: the service down or slow, or the connection dropped, which
|
|
1658
|
+
// clears, or its address or certificate wrong, which doesn't.
|
|
1659
|
+
return {
|
|
1660
|
+
reason, mayPass: true,
|
|
1661
|
+
advice: 'If the service is down or slow, or the connection dropped, a later call can work; if its address ' +
|
|
1662
|
+
"or certificate is wrong, none will until whoever runs this host fixes the semantic index's settings",
|
|
1663
|
+
};
|
|
1664
|
+
};
|
|
1504
1665
|
// The remote index is append-only and knows nothing about branches: a
|
|
1505
1666
|
// message removed from the agent's reach by /undo, /checkout, /restore or
|
|
1506
1667
|
// /newtopic keeps its id (a new message gets a fresh one) and stays
|
|
@@ -1525,7 +1686,7 @@ export class HistoryModule implements Module {
|
|
|
1525
1686
|
if (msgId !== undefined) {
|
|
1526
1687
|
const m = cm.getMessage(msgId);
|
|
1527
1688
|
if (!m) return 'offBranch';
|
|
1528
|
-
const text = messageIndexText(m, includePrivate)
|
|
1689
|
+
const text = safeSlice(messageIndexText(m, includePrivate), 0, this.semanticCfg!.maxChars ?? 32_000);
|
|
1529
1690
|
if (!text) return 'stale';
|
|
1530
1691
|
currentText.set(h.id, text);
|
|
1531
1692
|
return 'ok';
|
|
@@ -1534,11 +1695,21 @@ export class HistoryModule implements Module {
|
|
|
1534
1695
|
return 'ok';
|
|
1535
1696
|
};
|
|
1536
1697
|
let k = limit;
|
|
1537
|
-
let res
|
|
1698
|
+
let res: SearchResponse;
|
|
1699
|
+
try {
|
|
1700
|
+
res = await runSearch(k);
|
|
1701
|
+
} catch (e) {
|
|
1702
|
+
const { reason, advice } = failure(e);
|
|
1703
|
+
throw new Error(`Nothing was searched: ${reason}. ${advice}. history--search finds messages by their words meanwhile.`);
|
|
1704
|
+
}
|
|
1538
1705
|
let droppedOffBranch = 0;
|
|
1539
1706
|
let droppedStale = 0;
|
|
1707
|
+
// Why searching again for more hits failed, when it did. The search
|
|
1708
|
+
// before it answered, so its hits on this branch are returned.
|
|
1709
|
+
let searchAgainError: string | null = null;
|
|
1540
1710
|
let onBranch: typeof res.hits = [];
|
|
1541
|
-
|
|
1711
|
+
// The last answer's hits on this branch, checked as they are now.
|
|
1712
|
+
const check = (): void => {
|
|
1542
1713
|
droppedOffBranch = 0; droppedStale = 0;
|
|
1543
1714
|
onBranch = res.hits.filter((h) => {
|
|
1544
1715
|
const v = keep(h);
|
|
@@ -1546,25 +1717,58 @@ export class HistoryModule implements Module {
|
|
|
1546
1717
|
else if (v === 'stale') droppedStale++;
|
|
1547
1718
|
return v === 'ok';
|
|
1548
1719
|
});
|
|
1720
|
+
};
|
|
1721
|
+
for (;;) {
|
|
1722
|
+
check();
|
|
1549
1723
|
if (onBranch.length >= limit || res.hits.length < k || k >= SEMANTIC_MAX_FETCH) break;
|
|
1550
1724
|
k = Math.min(SEMANTIC_MAX_FETCH, k * 4);
|
|
1551
|
-
|
|
1725
|
+
try {
|
|
1726
|
+
res = await runSearch(k);
|
|
1727
|
+
} catch (e) {
|
|
1728
|
+
const { reason, mayPass } = failure(e);
|
|
1729
|
+
searchAgainError = `searching again for more hits failed: ${reason}. ` +
|
|
1730
|
+
(mayPass ? 'Calling again may bring more.' : "Calling again the same way won't change that.");
|
|
1731
|
+
// A message may have been edited, deleted or taken off this branch
|
|
1732
|
+
// while that search waited, so the hits are checked again.
|
|
1733
|
+
check();
|
|
1734
|
+
break;
|
|
1735
|
+
}
|
|
1552
1736
|
}
|
|
1553
1737
|
onBranch = onBranch.slice(0, limit);
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1738
|
+
// A ts that makes no date reads as no timestamp, as a null one does, and a
|
|
1739
|
+
// meta that isn't an object as no participant or author. The hit is still
|
|
1740
|
+
// returned, but the index holds data written wrong, so the host is told.
|
|
1741
|
+
// The index writes ts as a number of seconds, and text holding one reads
|
|
1742
|
+
// as main read it; nothing else makes a date, and reading it can't throw.
|
|
1743
|
+
const unread: string[] = [];
|
|
1744
|
+
const hits = onBranch.map((h) => {
|
|
1745
|
+
const ts: unknown = h.ts;
|
|
1746
|
+
const seconds = typeof ts === 'number' ? ts : typeof ts === 'string' && ts.trim() !== '' ? Number(ts) : NaN;
|
|
1747
|
+
const at = new Date(seconds * 1000);
|
|
1748
|
+
const timestamp = Number.isNaN(at.getTime()) ? null : at.toISOString();
|
|
1749
|
+
const meta = typeof h.meta === 'object' && h.meta !== null && !Array.isArray(h.meta)
|
|
1750
|
+
? h.meta as { participant?: unknown; author?: unknown }
|
|
1751
|
+
: null;
|
|
1752
|
+
const missing = [...(h.ts !== null && timestamp === null ? ['ts'] : []), ...(meta === null ? ['meta'] : [])];
|
|
1753
|
+
if (missing.length > 0) unread.push(`${shown(h.id)} (${missing.join(' and ')})`);
|
|
1754
|
+
return {
|
|
1755
|
+
id: h.id,
|
|
1756
|
+
/** Raw message id for a `msg:` hit (null for summaries) — pass it to extract({ aroundId }). */
|
|
1757
|
+
messageId: h.id.startsWith('msg:') ? h.id.slice(4) : null,
|
|
1758
|
+
kind: h.kind,
|
|
1759
|
+
level: h.level,
|
|
1760
|
+
score: h.score,
|
|
1761
|
+
timestamp,
|
|
1762
|
+
channelId: h.channel,
|
|
1763
|
+
participant: meta?.participant ?? null,
|
|
1764
|
+
author: meta?.author ?? null,
|
|
1765
|
+
snippet: currentText.has(h.id) ? snippetOf(currentText.get(h.id)!) : (h.text ?? ''),
|
|
1766
|
+
chars: currentText.has(h.id) ? currentText.get(h.id)!.length : h.chars,
|
|
1767
|
+
};
|
|
1768
|
+
});
|
|
1769
|
+
if (unread.length > 0) {
|
|
1770
|
+
this.indexer?.warn(`a search returned hits whose ts or meta couldn't be read, without them: ${unread.join(', ')}`);
|
|
1771
|
+
}
|
|
1568
1772
|
return {
|
|
1569
1773
|
success: true,
|
|
1570
1774
|
data: {
|
|
@@ -1576,8 +1780,10 @@ export class HistoryModule implements Module {
|
|
|
1576
1780
|
lastError: this.indexer?.lastError ?? null,
|
|
1577
1781
|
/** Hits the index returned for messages/summaries not on the current branch (undone, checked out past). */
|
|
1578
1782
|
droppedOffBranch,
|
|
1579
|
-
/** Hits for messages whose current text has nothing indexable (edited blank; the index delete
|
|
1783
|
+
/** 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). */
|
|
1580
1784
|
droppedStale,
|
|
1785
|
+
/** When too few hits were on this branch and searching again for more failed: why, and whether calling again can help. */
|
|
1786
|
+
searchAgainError,
|
|
1581
1787
|
},
|
|
1582
1788
|
timingMs: res.timing_ms,
|
|
1583
1789
|
},
|
|
@@ -1589,7 +1795,7 @@ export class HistoryModule implements Module {
|
|
|
1589
1795
|
const fromMs = parseIsoDate(input.from, 'from');
|
|
1590
1796
|
const toMs = parseIsoDate(input.to, 'to');
|
|
1591
1797
|
assertOrderedRange(fromMs, toMs, input.from, input.to);
|
|
1592
|
-
const limit = clampCount(input.limit, OVERVIEW_DEFAULT_LIMIT, OVERVIEW_MAX_LIMIT, 'limit');
|
|
1798
|
+
const limit = clampCount(input.limit, OVERVIEW_DEFAULT_LIMIT, OVERVIEW_MAX_LIMIT, 'limit', 'read');
|
|
1593
1799
|
const cm = this.cm as ContextManager;
|
|
1594
1800
|
|
|
1595
1801
|
let entries: TimeRangeSummaryEntry[];
|
|
@@ -1959,6 +2165,12 @@ export class HistoryModule implements Module {
|
|
|
1959
2165
|
// Helpers
|
|
1960
2166
|
// ============================================================================
|
|
1961
2167
|
|
|
2168
|
+
// The checks here (and resolveChannel) are shared by several tools. Their
|
|
2169
|
+
// refusals open with "Nothing was read", or for clampCount with the outcome
|
|
2170
|
+
// its caller names, and "Nothing was read" holds because every history tool
|
|
2171
|
+
// only reads. A tool that changes something should give its refusals an
|
|
2172
|
+
// opener of its own rather than reach these.
|
|
2173
|
+
|
|
1962
2174
|
/** Parse an ISO 8601 date string to Unix ms. Throws a clear error (not a
|
|
1963
2175
|
* crash) on an unparseable string; returns undefined for an omitted field
|
|
1964
2176
|
* (open-ended bound). */
|
|
@@ -1966,7 +2178,10 @@ function parseIsoDate(value: string | undefined, field: string): number | undefi
|
|
|
1966
2178
|
if (value === undefined) return undefined;
|
|
1967
2179
|
const ms = Date.parse(value);
|
|
1968
2180
|
if (Number.isNaN(ms)) {
|
|
1969
|
-
throw new Error(
|
|
2181
|
+
throw new Error(
|
|
2182
|
+
`Nothing was read: "${field}" is ${shown(value)}, which isn't an ISO 8601 date. Write it like 2026-03-01 or ` +
|
|
2183
|
+
'2026-03-01T09:00:00Z.',
|
|
2184
|
+
);
|
|
1970
2185
|
}
|
|
1971
2186
|
return ms;
|
|
1972
2187
|
}
|
|
@@ -1980,7 +2195,10 @@ function parseIsoDate(value: string | undefined, field: string): number | undefi
|
|
|
1980
2195
|
*/
|
|
1981
2196
|
function assertOrderedRange(fromMs: number | undefined, toMs: number | undefined, fromRaw: string | undefined, toRaw: string | undefined): void {
|
|
1982
2197
|
if (fromMs !== undefined && toMs !== undefined && fromMs > toMs) {
|
|
1983
|
-
throw new Error(
|
|
2198
|
+
throw new Error(
|
|
2199
|
+
`Nothing was read: "from" (${shown(fromRaw)}) is after "to" (${shown(toRaw)}), so the range holds nothing. Swap them, ` +
|
|
2200
|
+
'or correct the one that\'s wrong.',
|
|
2201
|
+
);
|
|
1984
2202
|
}
|
|
1985
2203
|
}
|
|
1986
2204
|
|
|
@@ -1992,24 +2210,54 @@ function assertOrderedRange(fromMs: number | undefined, toMs: number | undefined
|
|
|
1992
2210
|
* "hard cap" and reach a native chronicle call expecting an unsigned
|
|
1993
2211
|
* pagination argument (observed: `extract({limit:-1})` returning every
|
|
1994
2212
|
* message in the store instead of being capped). Rejects (rather than
|
|
1995
|
-
* silently clamping) anything that isn't a
|
|
1996
|
-
* a caller mistake is surfaced as a clean tool error instead of silently
|
|
1997
|
-
* doing something other than what was asked.
|
|
2213
|
+
* silently clamping) anything that isn't a whole number of at least `min`,
|
|
2214
|
+
* so a caller mistake is surfaced as a clean tool error instead of silently
|
|
2215
|
+
* doing something other than what was asked. The refusal opens with what
|
|
2216
|
+
* didn't happen for the calling tool (`outcome`), and gives the range and
|
|
2217
|
+
* the default.
|
|
1998
2218
|
*/
|
|
1999
|
-
function clampCount(
|
|
2219
|
+
function clampCount(
|
|
2220
|
+
value: number | undefined, def: number, max: number, field: string, outcome: 'read' | 'searched', min = 0,
|
|
2221
|
+
): number {
|
|
2000
2222
|
if (value === undefined) return def;
|
|
2001
|
-
if (typeof value !== 'number' || !Number.
|
|
2002
|
-
throw new Error(
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
}
|
|
2007
|
-
if (value < 0) {
|
|
2008
|
-
throw new Error(`"${field}" must be >= 0, got ${value}.`);
|
|
2223
|
+
if (typeof value !== 'number' || !Number.isInteger(value) || value < min) {
|
|
2224
|
+
throw new Error(
|
|
2225
|
+
`Nothing was ${outcome}: "${field}" is ${shown(value)}, which isn't a whole number from ${min} to ${max}. `
|
|
2226
|
+
+ `Pass one, or leave it out for ${def}.`,
|
|
2227
|
+
);
|
|
2009
2228
|
}
|
|
2010
2229
|
return Math.min(value, max);
|
|
2011
2230
|
}
|
|
2012
2231
|
|
|
2232
|
+
/**
|
|
2233
|
+
* A value a message names, the call's or the store's, as the message quotes
|
|
2234
|
+
* it: its JSON, or what String() gives where JSON can't give the value itself,
|
|
2235
|
+
* cut to 80 UTF-16 units, or one fewer where the 80th would split a surrogate
|
|
2236
|
+
* pair: the message stays in the agent's context, and half a pair isn't
|
|
2237
|
+
* well-formed text. Inside a list or an object, JSON writes Infinity and NaN
|
|
2238
|
+
* as null, and so does the quote. A value the message gives the agent to send
|
|
2239
|
+
* is quoted whole instead, since a cut one couldn't be sent.
|
|
2240
|
+
*/
|
|
2241
|
+
function shown(value: unknown): string {
|
|
2242
|
+
let text: string | undefined;
|
|
2243
|
+
// A value JSON can't give, such as a cycle, or Infinity or NaN as the whole
|
|
2244
|
+
// value, which JSON.stringify gives as null, is shown as String() shows it.
|
|
2245
|
+
if (typeof value !== 'number' || Number.isFinite(value)) {
|
|
2246
|
+
try { text = JSON.stringify(value); } catch { /* String() below */ }
|
|
2247
|
+
}
|
|
2248
|
+
text ??= String(value);
|
|
2249
|
+
return text.length <= 80 ? text : `${safeSlice(text, 0, 80)}…`;
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
/**
|
|
2253
|
+
* Names in prose, each quoted whole: "a"; "a" and "b"; "a", "b" and "c" (or
|
|
2254
|
+
* "or"). They're the tools' own field names, or names the agent can send.
|
|
2255
|
+
*/
|
|
2256
|
+
function quotedList(names: readonly string[], joiner: 'and' | 'or'): string {
|
|
2257
|
+
const quoted = names.map((name) => JSON.stringify(name));
|
|
2258
|
+
return quoted.length <= 1 ? quoted.join('') : `${quoted.slice(0, -1).join(', ')} ${joiner} ${quoted[quoted.length - 1]}`;
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2013
2261
|
/** channelId lives at metadata.external.channelId — same path context-manager's
|
|
2014
2262
|
* own native index reads from (message-store.ts's CHANNEL_FIELD). Metadata's
|
|
2015
2263
|
* index-signature type means this needs an explicit narrow, same as
|
|
@@ -2219,7 +2467,9 @@ function codePointBefore(s: string, i: number): string | undefined {
|
|
|
2219
2467
|
}
|
|
2220
2468
|
|
|
2221
2469
|
/**
|
|
2222
|
-
* First occurrence of `needle` in `text
|
|
2470
|
+
* First occurrence of `needle` in `text`, as the units of `text` it covers.
|
|
2471
|
+
* Without `caseSensitive`, `needle` is lower case already, and is found in
|
|
2472
|
+
* `text.toLowerCase()`. With `wholeWord`, an occurrence
|
|
2223
2473
|
* only counts when it isn't glued to a letter/digit/underscore on either
|
|
2224
2474
|
* side (Unicode-aware, so Cyrillic words work too) — "mission" no longer
|
|
2225
2475
|
* hits inside "uncommissioned". Word-ness is checked only on the sides
|
|
@@ -2228,6 +2478,13 @@ function codePointBefore(s: string, i: number): string | undefined {
|
|
|
2228
2478
|
*/
|
|
2229
2479
|
function matchSubstring(text: string, needle: string, caseSensitive: boolean, wholeWord = false): MatchHit | null {
|
|
2230
2480
|
const haystack = caseSensitive ? text : text.toLowerCase();
|
|
2481
|
+
const hit = firstOccurrence(haystack, needle, wholeWord);
|
|
2482
|
+
// Lowering can lengthen a character, as it does `İ` (one unit to two). Then
|
|
2483
|
+
// the lowered text's units aren't the text's, and the snippet cuts the text.
|
|
2484
|
+
return hit !== null && haystack.length !== text.length ? inTextUnits(text, hit) : hit;
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
function firstOccurrence(haystack: string, needle: string, wholeWord: boolean): MatchHit | null {
|
|
2231
2488
|
if (!wholeWord) {
|
|
2232
2489
|
const index = haystack.indexOf(needle);
|
|
2233
2490
|
return index === -1 ? null : { index, length: needle.length };
|
|
@@ -2245,6 +2502,26 @@ function matchSubstring(text: string, needle: string, caseSensitive: boolean, wh
|
|
|
2245
2502
|
}
|
|
2246
2503
|
}
|
|
2247
2504
|
|
|
2505
|
+
/**
|
|
2506
|
+
* The units of `text` that a hit in `text.toLowerCase()` covers. Each code
|
|
2507
|
+
* point of `text` takes as many units there as its own lower case has, so a
|
|
2508
|
+
* hit that starts or ends inside a character's lower case takes in the whole
|
|
2509
|
+
* character.
|
|
2510
|
+
*/
|
|
2511
|
+
function inTextUnits(text: string, hit: MatchHit): MatchHit {
|
|
2512
|
+
const end = hit.index + hit.length;
|
|
2513
|
+
let start = -1;
|
|
2514
|
+
let lowered = 0;
|
|
2515
|
+
let at = 0;
|
|
2516
|
+
while (at < text.length && lowered < end) {
|
|
2517
|
+
const cp = text.codePointAt(at)!;
|
|
2518
|
+
lowered += String.fromCodePoint(cp).toLowerCase().length;
|
|
2519
|
+
if (start === -1 && lowered > hit.index) start = at;
|
|
2520
|
+
at += cp > 0xffff ? 2 : 1;
|
|
2521
|
+
}
|
|
2522
|
+
return { index: start, length: at - start };
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2248
2525
|
// ============================================================================
|
|
2249
2526
|
// author filtering
|
|
2250
2527
|
// ============================================================================
|
|
@@ -2270,7 +2547,11 @@ function parseSkipSequences(v: unknown): [number, number] | null {
|
|
|
2270
2547
|
!v.every((x) => typeof x === 'number' && Number.isInteger(x) && x >= 0) ||
|
|
2271
2548
|
v[0] > v[1]
|
|
2272
2549
|
) {
|
|
2273
|
-
throw new Error(
|
|
2550
|
+
throw new Error(
|
|
2551
|
+
'Nothing was searched: "skipSequences" must be two whole numbers, 0 or more, the first no larger than the ' +
|
|
2552
|
+
`second, as a search's "resume" gives it; it's ${shown(v)}. Copy it from "resume" with its "from" or "to", ` +
|
|
2553
|
+
'or leave it out for a new search.',
|
|
2554
|
+
);
|
|
2274
2555
|
}
|
|
2275
2556
|
return [v[0], v[1]];
|
|
2276
2557
|
}
|
|
@@ -2295,11 +2576,20 @@ function normalizeAuthorSpec(spec: string): string {
|
|
|
2295
2576
|
function toAuthorSet(spec: AuthorSpec | undefined, field: string): Set<string> | null {
|
|
2296
2577
|
if (spec === undefined) return null;
|
|
2297
2578
|
const list = Array.isArray(spec) ? spec : [spec];
|
|
2298
|
-
|
|
2299
|
-
|
|
2579
|
+
const odd = list.findIndex((s) => typeof s !== 'string');
|
|
2580
|
+
if (odd !== -1) {
|
|
2581
|
+
throw new Error(
|
|
2582
|
+
`Nothing was read: "${field}" must list names or ids as text, such as ["alice", "1234"], and ` +
|
|
2583
|
+
`${shown(list[odd])} isn't text.`,
|
|
2584
|
+
);
|
|
2300
2585
|
}
|
|
2301
2586
|
const set = new Set(list.map(normalizeAuthorSpec).filter((s) => s.length > 0));
|
|
2302
|
-
if (set.size === 0)
|
|
2587
|
+
if (set.size === 0) {
|
|
2588
|
+
throw new Error(
|
|
2589
|
+
`Nothing was read: "${field}" names no one: ${list.length > 0 ? 'its entries are blank' : 'the list is empty'}. ` +
|
|
2590
|
+
`List at least one name or id, such as ["alice"], or leave "${field}" out.`,
|
|
2591
|
+
);
|
|
2592
|
+
}
|
|
2303
2593
|
return set;
|
|
2304
2594
|
}
|
|
2305
2595
|
|
|
@@ -2331,12 +2621,12 @@ function buildAuthorFilter(include: AuthorSpec | undefined, exclude: AuthorSpec
|
|
|
2331
2621
|
/** ~SNIPPET_CONTEXT_CHARS of surrounding context on each side of a match, or
|
|
2332
2622
|
* the first ~SNIPPET_FALLBACK_CHARS of content when no meaningful match
|
|
2333
2623
|
* position is given (kept simple on purpose — this is a readability aid,
|
|
2334
|
-
* not a highlighting engine). */
|
|
2624
|
+
* not a highlighting engine). Neither end splits a surrogate pair. */
|
|
2335
2625
|
function snippetAround(text: string, index: number, length: number): string {
|
|
2336
|
-
if (index < 0) return text
|
|
2626
|
+
if (index < 0) return safeSlice(text, 0, SNIPPET_FALLBACK_CHARS);
|
|
2337
2627
|
const start = Math.max(0, index - SNIPPET_CONTEXT_CHARS);
|
|
2338
2628
|
const end = Math.min(text.length, index + length + SNIPPET_CONTEXT_CHARS);
|
|
2339
2629
|
const prefix = start > 0 ? '…' : '';
|
|
2340
2630
|
const suffix = end < text.length ? '…' : '';
|
|
2341
|
-
return prefix + text
|
|
2631
|
+
return prefix + safeSlice(text, start, end) + suffix;
|
|
2342
2632
|
}
|