@animalabs/agent-framework 0.22.2 → 0.22.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/src/agent.d.ts +77 -12
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +143 -41
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/mcp-server-core.js +1 -1
- package/dist/src/api/mcp-server-core.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +5 -1
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/api/types.d.ts +1 -1
- package/dist/src/api/types.d.ts.map +1 -1
- package/dist/src/branch-names.d.ts +14 -0
- package/dist/src/branch-names.d.ts.map +1 -0
- package/dist/src/branch-names.js +22 -0
- package/dist/src/branch-names.js.map +1 -0
- package/dist/src/closest-names.d.ts +28 -0
- package/dist/src/closest-names.d.ts.map +1 -0
- package/dist/src/closest-names.js +98 -0
- package/dist/src/closest-names.js.map +1 -0
- package/dist/src/code-execution/py-runner.d.ts +16 -5
- package/dist/src/code-execution/py-runner.d.ts.map +1 -1
- package/dist/src/code-execution/py-runner.js +186 -74
- package/dist/src/code-execution/py-runner.js.map +1 -1
- package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
- package/dist/src/code-execution/runtime-py.js +49 -3
- package/dist/src/code-execution/runtime-py.js.map +1 -1
- package/dist/src/code-execution/tool-definition.d.ts +12 -1
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +21 -3
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/config-checks.d.ts +28 -0
- package/dist/src/config-checks.d.ts.map +1 -0
- package/dist/src/config-checks.js +52 -0
- package/dist/src/config-checks.js.map +1 -0
- package/dist/src/deadline-timer.d.ts +21 -0
- package/dist/src/deadline-timer.d.ts.map +1 -0
- package/dist/src/deadline-timer.js +43 -0
- package/dist/src/deadline-timer.js.map +1 -0
- package/dist/src/error-message.d.ts +30 -0
- package/dist/src/error-message.d.ts.map +1 -0
- package/dist/src/error-message.js +50 -0
- package/dist/src/error-message.js.map +1 -0
- package/dist/src/framework.d.ts +828 -88
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +5011 -1326
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +8 -0
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +27 -3
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +144 -6
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +424 -263
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.js +91 -30
- package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +19 -3
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +23 -8
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts +20 -0
- package/dist/src/mcpl/convert-block.d.ts.map +1 -0
- package/dist/src/mcpl/convert-block.js +89 -0
- package/dist/src/mcpl/convert-block.js.map +1 -0
- package/dist/src/mcpl/errors.d.ts +13 -0
- package/dist/src/mcpl/errors.d.ts.map +1 -1
- package/dist/src/mcpl/errors.js +28 -0
- package/dist/src/mcpl/errors.js.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.js +83 -72
- package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +114 -0
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
- package/dist/src/mcpl/inbound-source.js +83 -0
- package/dist/src/mcpl/inbound-source.js.map +1 -0
- package/dist/src/mcpl/index.d.ts +3 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -1
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts +15 -11
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.js +153 -84
- package/dist/src/mcpl/inference-router.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +33 -11
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +52 -20
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +16 -9
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +18 -83
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +72 -30
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +47 -12
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js +74 -21
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +89 -10
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +405 -129
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/server-registry.d.ts +10 -1
- package/dist/src/mcpl/server-registry.d.ts.map +1 -1
- package/dist/src/mcpl/server-registry.js +14 -3
- package/dist/src/mcpl/server-registry.js.map +1 -1
- package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
- package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
- package/dist/src/mcpl/skip-reply-wake.js +55 -0
- package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
- package/dist/src/mcpl/transport.d.ts +51 -2
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +114 -20
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +14 -3
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/mcpl/visible-content.d.ts +15 -0
- package/dist/src/mcpl/visible-content.d.ts.map +1 -1
- package/dist/src/mcpl/visible-content.js +25 -0
- package/dist/src/mcpl/visible-content.js.map +1 -1
- package/dist/src/module-registry.d.ts +19 -1
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +54 -25
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/api/index.js +1 -1
- package/dist/src/modules/api/index.js.map +1 -1
- package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
- package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
- package/dist/src/modules/discord/discord-js-client.js +25 -9
- package/dist/src/modules/discord/discord-js-client.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts +29 -3
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +379 -143
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/discord/types.d.ts +14 -1
- package/dist/src/modules/discord/types.d.ts.map +1 -1
- package/dist/src/modules/health/index.d.ts.map +1 -1
- package/dist/src/modules/health/index.js +2 -1
- package/dist/src/modules/health/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts +3 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +359 -127
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +28 -1
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +177 -32
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/unknown-tool.d.ts +10 -0
- package/dist/src/modules/unknown-tool.d.ts.map +1 -0
- package/dist/src/modules/unknown-tool.js +17 -0
- package/dist/src/modules/unknown-tool.js.map +1 -0
- package/dist/src/modules/workspace/disk-agreement.d.ts +32 -2
- package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +30 -2
- package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
- package/dist/src/modules/workspace/effects.d.ts +64 -6
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +291 -44
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +119 -23
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +793 -247
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +75 -8
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +174 -14
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts +58 -7
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +521 -56
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +18 -4
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/modules/workspace/watcher.d.ts +7 -2
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
- package/dist/src/modules/workspace/watcher.js +28 -4
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/prose-drafts.d.ts +240 -0
- package/dist/src/prose-drafts.d.ts.map +1 -0
- package/dist/src/prose-drafts.js +362 -0
- package/dist/src/prose-drafts.js.map +1 -0
- package/dist/src/prose-segments.d.ts +21 -2
- package/dist/src/prose-segments.d.ts.map +1 -1
- package/dist/src/prose-segments.js +46 -9
- package/dist/src/prose-segments.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts +1 -0
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +3 -1
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/safe-slice.d.ts +5 -1
- package/dist/src/safe-slice.d.ts.map +1 -1
- package/dist/src/safe-slice.js +9 -1
- package/dist/src/safe-slice.js.map +1 -1
- package/dist/src/thinking-token-stamp.d.ts +12 -0
- package/dist/src/thinking-token-stamp.d.ts.map +1 -1
- package/dist/src/thinking-token-stamp.js +34 -3
- package/dist/src/thinking-token-stamp.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts +87 -19
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js +135 -32
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-presentation.d.ts +9 -0
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +257 -60
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +7 -10
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +32 -3
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +106 -19
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +25 -1
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +260 -65
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/types/agent.d.ts +17 -5
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +17 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +21 -5
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/inference-log.d.ts +1 -1
- package/dist/src/types/inference-log.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +23 -4
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +95 -6
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts +5 -0
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.js +35 -8
- package/dist/src/usage/usage-tracker.js.map +1 -1
- package/package.json +6 -4
- package/src/agent.ts +169 -41
- package/src/api/mcp-server-core.ts +1 -1
- package/src/api/server.ts +4 -1
- package/src/api/types.ts +1 -1
- package/src/branch-names.ts +19 -0
- package/src/closest-names.ts +94 -0
- package/src/code-execution/py-runner.ts +200 -76
- package/src/code-execution/runtime-py.ts +49 -3
- package/src/code-execution/tool-definition.ts +28 -4
- package/src/config-checks.ts +48 -0
- package/src/deadline-timer.ts +44 -0
- package/src/error-message.ts +48 -0
- package/src/framework.ts +5352 -1388
- package/src/gate/event-gate.ts +28 -3
- package/src/index.ts +11 -2
- package/src/mcpl/channel-registry.ts +517 -286
- package/src/mcpl/checkpoint-manager.ts +104 -29
- package/src/mcpl/conversation-router.ts +28 -8
- package/src/mcpl/convert-block.ts +97 -0
- package/src/mcpl/errors.ts +28 -0
- package/src/mcpl/hook-orchestrator.ts +84 -77
- package/src/mcpl/inbound-source.ts +156 -0
- package/src/mcpl/index.ts +10 -1
- package/src/mcpl/inference-router.ts +174 -99
- package/src/mcpl/push-coalescer.ts +60 -24
- package/src/mcpl/push-handler.ts +20 -90
- package/src/mcpl/reference-fetcher.ts +71 -26
- package/src/mcpl/references.ts +81 -22
- package/src/mcpl/server-connection.ts +427 -132
- package/src/mcpl/server-registry.ts +15 -4
- package/src/mcpl/skip-reply-wake.ts +73 -0
- package/src/mcpl/transport.ts +120 -18
- package/src/mcpl/types.ts +14 -3
- package/src/mcpl/visible-content.ts +27 -0
- package/src/module-registry.ts +58 -23
- package/src/modules/api/index.ts +1 -1
- package/src/modules/discord/discord-js-client.ts +26 -10
- package/src/modules/discord/index.ts +391 -158
- package/src/modules/discord/types.ts +15 -2
- package/src/modules/health/index.ts +2 -1
- package/src/modules/history/index.ts +410 -120
- package/src/modules/history/semantic.ts +189 -32
- package/src/modules/unknown-tool.ts +16 -0
- package/src/modules/workspace/disk-agreement.ts +51 -3
- package/src/modules/workspace/effects.ts +279 -35
- package/src/modules/workspace/index.ts +810 -260
- package/src/modules/workspace/observe.ts +194 -20
- package/src/modules/workspace/reconcile.ts +619 -64
- package/src/modules/workspace/types.ts +18 -4
- package/src/modules/workspace/watcher.ts +27 -4
- package/src/prose-drafts.ts +481 -0
- package/src/prose-segments.ts +51 -8
- package/src/recovery/offline-branch.ts +4 -1
- package/src/safe-slice.ts +9 -1
- package/src/thinking-token-stamp.ts +34 -3
- package/src/tool-image-ledger.ts +153 -34
- package/src/tool-presentation.ts +224 -40
- package/src/tool-result-guard.ts +7 -8
- package/src/tool-result-history.ts +124 -20
- package/src/tune-out/coordinator.ts +259 -65
- package/src/types/agent.ts +17 -7
- package/src/types/events.ts +17 -0
- package/src/types/framework.ts +21 -5
- package/src/types/inference-log.ts +1 -1
- package/src/types/module.ts +24 -4
- package/src/types/trace.ts +101 -6
- package/src/usage/usage-tracker.ts +32 -8
- package/dist/test/activation-request-sanitize.test.d.ts +0 -2
- package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
- package/dist/test/activation-request-sanitize.test.js +0 -89
- package/dist/test/activation-request-sanitize.test.js.map +0 -1
- package/dist/test/agent-cache-ttl.test.d.ts +0 -2
- package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
- package/dist/test/agent-cache-ttl.test.js +0 -41
- package/dist/test/agent-cache-ttl.test.js.map +0 -1
- package/dist/test/agent-runtime-settings.test.d.ts +0 -2
- package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
- package/dist/test/agent-runtime-settings.test.js +0 -1598
- package/dist/test/agent-runtime-settings.test.js.map +0 -1
- package/dist/test/api-admin-gate.test.d.ts +0 -2
- package/dist/test/api-admin-gate.test.d.ts.map +0 -1
- package/dist/test/api-admin-gate.test.js +0 -116
- package/dist/test/api-admin-gate.test.js.map +0 -1
- package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
- package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
- package/dist/test/assistant-persist-refusal.test.js +0 -63
- package/dist/test/assistant-persist-refusal.test.js.map +0 -1
- package/dist/test/batched-wake-locus.test.d.ts +0 -2
- package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
- package/dist/test/batched-wake-locus.test.js +0 -166
- package/dist/test/batched-wake-locus.test.js.map +0 -1
- package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
- package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
- package/dist/test/busy-agent-scheduler.test.js +0 -92
- package/dist/test/busy-agent-scheduler.test.js.map +0 -1
- package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
- package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
- package/dist/test/channel-incoming-targeting.test.js +0 -81
- package/dist/test/channel-incoming-targeting.test.js.map +0 -1
- package/dist/test/channel-label-history.test.d.ts +0 -2
- package/dist/test/channel-label-history.test.d.ts.map +0 -1
- package/dist/test/channel-label-history.test.js +0 -424
- package/dist/test/channel-label-history.test.js.map +0 -1
- package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
- package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
- package/dist/test/channel-lifecycle-provenance.test.js +0 -47
- package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
- package/dist/test/channel-registry-routing.test.d.ts +0 -2
- package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
- package/dist/test/channel-registry-routing.test.js +0 -446
- package/dist/test/channel-registry-routing.test.js.map +0 -1
- package/dist/test/channel-registry-typing.test.d.ts +0 -2
- package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
- package/dist/test/channel-registry-typing.test.js +0 -91
- package/dist/test/channel-registry-typing.test.js.map +0 -1
- package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
- package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
- package/dist/test/channels-changed-respond-first.test.js +0 -74
- package/dist/test/channels-changed-respond-first.test.js.map +0 -1
- package/dist/test/checkpoint-attribution.test.d.ts +0 -2
- package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
- package/dist/test/checkpoint-attribution.test.js +0 -200
- package/dist/test/checkpoint-attribution.test.js.map +0 -1
- package/dist/test/code-execution.test.d.ts +0 -11
- package/dist/test/code-execution.test.d.ts.map +0 -1
- package/dist/test/code-execution.test.js +0 -1272
- package/dist/test/code-execution.test.js.map +0 -1
- package/dist/test/component-defaults.test.d.ts +0 -2
- package/dist/test/component-defaults.test.d.ts.map +0 -1
- package/dist/test/component-defaults.test.js +0 -54
- package/dist/test/component-defaults.test.js.map +0 -1
- package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
- package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
- package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
- package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
- package/dist/test/conversation-router.test.d.ts +0 -2
- package/dist/test/conversation-router.test.d.ts.map +0 -1
- package/dist/test/conversation-router.test.js +0 -174
- package/dist/test/conversation-router.test.js.map +0 -1
- package/dist/test/conversation-routing.test.d.ts +0 -7
- package/dist/test/conversation-routing.test.d.ts.map +0 -1
- package/dist/test/conversation-routing.test.js +0 -621
- package/dist/test/conversation-routing.test.js.map +0 -1
- package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
- package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
- package/dist/test/deferred-wake-integrity.test.js +0 -320
- package/dist/test/deferred-wake-integrity.test.js.map +0 -1
- package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
- package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
- package/dist/test/discord-awareness-outbox.test.js +0 -371
- package/dist/test/discord-awareness-outbox.test.js.map +0 -1
- package/dist/test/discord-history-delete-window.test.d.ts +0 -2
- package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
- package/dist/test/discord-history-delete-window.test.js +0 -81
- package/dist/test/discord-history-delete-window.test.js.map +0 -1
- package/dist/test/discord-history-sync.test.d.ts +0 -2
- package/dist/test/discord-history-sync.test.d.ts.map +0 -1
- package/dist/test/discord-history-sync.test.js +0 -56
- package/dist/test/discord-history-sync.test.js.map +0 -1
- package/dist/test/discord-typing-keepalive.test.d.ts +0 -2
- package/dist/test/discord-typing-keepalive.test.d.ts.map +0 -1
- package/dist/test/discord-typing-keepalive.test.js +0 -77
- package/dist/test/discord-typing-keepalive.test.js.map +0 -1
- package/dist/test/ephemeral-settle.test.d.ts +0 -2
- package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
- package/dist/test/ephemeral-settle.test.js +0 -354
- package/dist/test/ephemeral-settle.test.js.map +0 -1
- package/dist/test/event-gate-passthrough.test.d.ts +0 -15
- package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
- package/dist/test/event-gate-passthrough.test.js +0 -289
- package/dist/test/event-gate-passthrough.test.js.map +0 -1
- package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
- package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
- package/dist/test/event-gate-policy-mutation.test.js +0 -137
- package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
- package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
- package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
- package/dist/test/event-gate-rate-limit.test.js +0 -627
- package/dist/test/event-gate-rate-limit.test.js.map +0 -1
- package/dist/test/event-gate-script.test.d.ts +0 -2
- package/dist/test/event-gate-script.test.d.ts.map +0 -1
- package/dist/test/event-gate-script.test.js +0 -95
- package/dist/test/event-gate-script.test.js.map +0 -1
- package/dist/test/event-gate-selfwake.test.d.ts +0 -15
- package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
- package/dist/test/event-gate-selfwake.test.js +0 -125
- package/dist/test/event-gate-selfwake.test.js.map +0 -1
- package/dist/test/event-gate-tags.test.d.ts +0 -2
- package/dist/test/event-gate-tags.test.d.ts.map +0 -1
- package/dist/test/event-gate-tags.test.js +0 -76
- package/dist/test/event-gate-tags.test.js.map +0 -1
- package/dist/test/event-gate.test.d.ts +0 -2
- package/dist/test/event-gate.test.d.ts.map +0 -1
- package/dist/test/event-gate.test.js +0 -919
- package/dist/test/event-gate.test.js.map +0 -1
- package/dist/test/explicit-prose-routing.test.d.ts +0 -11
- package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
- package/dist/test/explicit-prose-routing.test.js +0 -1715
- package/dist/test/explicit-prose-routing.test.js.map +0 -1
- package/dist/test/framework.test.d.ts +0 -5
- package/dist/test/framework.test.d.ts.map +0 -1
- package/dist/test/framework.test.js +0 -1048
- package/dist/test/framework.test.js.map +0 -1
- package/dist/test/gather-context-timeout.test.d.ts +0 -2
- package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
- package/dist/test/gather-context-timeout.test.js +0 -120
- package/dist/test/gather-context-timeout.test.js.map +0 -1
- package/dist/test/health-snapshot.test.d.ts +0 -2
- package/dist/test/health-snapshot.test.d.ts.map +0 -1
- package/dist/test/health-snapshot.test.js +0 -74
- package/dist/test/health-snapshot.test.js.map +0 -1
- package/dist/test/helpers/coalescing-fixture.d.ts +0 -74
- package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
- package/dist/test/helpers/coalescing-fixture.js +0 -152
- package/dist/test/helpers/coalescing-fixture.js.map +0 -1
- package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
- package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
- package/dist/test/helpers/coalescing-kill-child.js +0 -24
- package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
- package/dist/test/helpers/mock-membrane.d.ts +0 -53
- package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
- package/dist/test/helpers/mock-membrane.js +0 -168
- package/dist/test/helpers/mock-membrane.js.map +0 -1
- package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
- package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
- package/dist/test/helpers/pytc-stop-rows.js +0 -143
- package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
- package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
- package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
- package/dist/test/helpers/quiesce-crash-child.js +0 -156
- package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
- package/dist/test/hide-then-turn.test.d.ts +0 -2
- package/dist/test/hide-then-turn.test.d.ts.map +0 -1
- package/dist/test/hide-then-turn.test.js +0 -101
- package/dist/test/hide-then-turn.test.js.map +0 -1
- package/dist/test/history-module-overview.test.d.ts +0 -2
- package/dist/test/history-module-overview.test.d.ts.map +0 -1
- package/dist/test/history-module-overview.test.js +0 -711
- package/dist/test/history-module-overview.test.js.map +0 -1
- package/dist/test/history-module-realstore.test.d.ts +0 -2
- package/dist/test/history-module-realstore.test.d.ts.map +0 -1
- package/dist/test/history-module-realstore.test.js +0 -363
- package/dist/test/history-module-realstore.test.js.map +0 -1
- package/dist/test/history-module-semantic.test.d.ts +0 -2
- package/dist/test/history-module-semantic.test.d.ts.map +0 -1
- package/dist/test/history-module-semantic.test.js +0 -213
- package/dist/test/history-module-semantic.test.js.map +0 -1
- package/dist/test/history-module-ux.test.d.ts +0 -2
- package/dist/test/history-module-ux.test.d.ts.map +0 -1
- package/dist/test/history-module-ux.test.js +0 -304
- package/dist/test/history-module-ux.test.js.map +0 -1
- package/dist/test/history-module.test.d.ts +0 -2
- package/dist/test/history-module.test.d.ts.map +0 -1
- package/dist/test/history-module.test.js +0 -619
- package/dist/test/history-module.test.js.map +0 -1
- package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
- package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
- package/dist/test/history-semantic-review-findings.test.js +0 -338
- package/dist/test/history-semantic-review-findings.test.js.map +0 -1
- package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
- package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
- package/dist/test/history-semantic-sync-converges.test.js +0 -109
- package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
- package/dist/test/host-quiesce.test.d.ts +0 -2
- package/dist/test/host-quiesce.test.d.ts.map +0 -1
- package/dist/test/host-quiesce.test.js +0 -988
- package/dist/test/host-quiesce.test.js.map +0 -1
- package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
- package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
- package/dist/test/inference-exhaustion-rewind.test.js +0 -387
- package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
- package/dist/test/inference-failure-bounds.test.d.ts +0 -2
- package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
- package/dist/test/inference-failure-bounds.test.js +0 -1202
- package/dist/test/inference-failure-bounds.test.js.map +0 -1
- package/dist/test/inference-failure-observability.test.d.ts +0 -2
- package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
- package/dist/test/inference-failure-observability.test.js +0 -84
- package/dist/test/inference-failure-observability.test.js.map +0 -1
- package/dist/test/journal-tool.test.d.ts +0 -2
- package/dist/test/journal-tool.test.d.ts.map +0 -1
- package/dist/test/journal-tool.test.js +0 -33
- package/dist/test/journal-tool.test.js.map +0 -1
- package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
- package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
- package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
- package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
- package/dist/test/kv-unified-wiring.test.d.ts +0 -2
- package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
- package/dist/test/kv-unified-wiring.test.js +0 -95
- package/dist/test/kv-unified-wiring.test.js.map +0 -1
- package/dist/test/late-events-after-stop.test.d.ts +0 -2
- package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
- package/dist/test/late-events-after-stop.test.js +0 -122
- package/dist/test/late-events-after-stop.test.js.map +0 -1
- package/dist/test/liveness-watchdog.test.d.ts +0 -2
- package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
- package/dist/test/liveness-watchdog.test.js +0 -94
- package/dist/test/liveness-watchdog.test.js.map +0 -1
- package/dist/test/machine-close-provenance.test.d.ts +0 -2
- package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
- package/dist/test/machine-close-provenance.test.js +0 -116
- package/dist/test/machine-close-provenance.test.js.map +0 -1
- package/dist/test/maintenance-timer.test.d.ts +0 -2
- package/dist/test/maintenance-timer.test.d.ts.map +0 -1
- package/dist/test/maintenance-timer.test.js +0 -1827
- package/dist/test/maintenance-timer.test.js.map +0 -1
- package/dist/test/mcp-server-bin.test.d.ts +0 -2
- package/dist/test/mcp-server-bin.test.d.ts.map +0 -1
- package/dist/test/mcp-server-bin.test.js +0 -142
- package/dist/test/mcp-server-bin.test.js.map +0 -1
- package/dist/test/mcpl-access-provider.test.d.ts +0 -2
- package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
- package/dist/test/mcpl-access-provider.test.js +0 -20
- package/dist/test/mcpl-access-provider.test.js.map +0 -1
- package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
- package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
- package/dist/test/mcpl-awareness-barrier.test.js +0 -769
- package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
- package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
- package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
- package/dist/test/mcpl-capability-grant.test.js +0 -111
- package/dist/test/mcpl-capability-grant.test.js.map +0 -1
- package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
- package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
- package/dist/test/mcpl-capability-scoping.test.js +0 -266
- package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
- package/dist/test/mcpl-child-env.test.d.ts +0 -2
- package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
- package/dist/test/mcpl-child-env.test.js +0 -158
- package/dist/test/mcpl-child-env.test.js.map +0 -1
- package/dist/test/mcpl-coalesced-content-parity.test.d.ts +0 -2
- package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +0 -1
- package/dist/test/mcpl-coalesced-content-parity.test.js +0 -532
- package/dist/test/mcpl-coalesced-content-parity.test.js.map +0 -1
- package/dist/test/mcpl-coalescing.test.d.ts +0 -2
- package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
- package/dist/test/mcpl-coalescing.test.js +0 -1125
- package/dist/test/mcpl-coalescing.test.js.map +0 -1
- package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
- package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
- package/dist/test/mcpl-config-diagnostics.test.js +0 -452
- package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
- package/dist/test/mcpl-empty-content.test.d.ts +0 -2
- package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
- package/dist/test/mcpl-empty-content.test.js +0 -368
- package/dist/test/mcpl-empty-content.test.js.map +0 -1
- package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
- package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
- package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
- package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
- package/dist/test/mcpl-list-status.test.d.ts +0 -2
- package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
- package/dist/test/mcpl-list-status.test.js +0 -82
- package/dist/test/mcpl-list-status.test.js.map +0 -1
- package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
- package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
- package/dist/test/mcpl-manifest-changed.test.js +0 -178
- package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
- package/dist/test/mcpl-push-convert.test.d.ts +0 -2
- package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
- package/dist/test/mcpl-push-convert.test.js +0 -42
- package/dist/test/mcpl-push-convert.test.js.map +0 -1
- package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
- package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
- package/dist/test/mcpl-reconnect-events.test.js +0 -144
- package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
- package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
- package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
- package/dist/test/mcpl-reconnect-reregistration.test.js +0 -238
- package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
- package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
- package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
- package/dist/test/mcpl-reference-fetcher.test.js +0 -427
- package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
- package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
- package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
- package/dist/test/mcpl-reference-fields.test.js +0 -149
- package/dist/test/mcpl-reference-fields.test.js.map +0 -1
- package/dist/test/mcpl-rejection-log-lines.test.d.ts +0 -2
- package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +0 -1
- package/dist/test/mcpl-rejection-log-lines.test.js +0 -349
- package/dist/test/mcpl-rejection-log-lines.test.js.map +0 -1
- package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
- package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
- package/dist/test/mcpl-request-timeout.test.js +0 -138
- package/dist/test/mcpl-request-timeout.test.js.map +0 -1
- package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
- package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
- package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
- package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
- package/dist/test/mcpl-stderr-tail.test.d.ts +0 -2
- package/dist/test/mcpl-stderr-tail.test.d.ts.map +0 -1
- package/dist/test/mcpl-stderr-tail.test.js +0 -210
- package/dist/test/mcpl-stderr-tail.test.js.map +0 -1
- package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
- package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-class-listing.test.js +0 -147
- package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
- package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
- package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-classes.test.js +0 -80
- package/dist/test/mcpl-tool-classes.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
- package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
- package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
- package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
- package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
- package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
- package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
- package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
- package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
- package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
- package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
- package/dist/test/mcpl-transport-close.test.d.ts +0 -2
- package/dist/test/mcpl-transport-close.test.d.ts.map +0 -1
- package/dist/test/mcpl-transport-close.test.js +0 -373
- package/dist/test/mcpl-transport-close.test.js.map +0 -1
- package/dist/test/mcpl-transport-spawn.test.d.ts +0 -2
- package/dist/test/mcpl-transport-spawn.test.d.ts.map +0 -1
- package/dist/test/mcpl-transport-spawn.test.js +0 -58
- package/dist/test/mcpl-transport-spawn.test.js.map +0 -1
- package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
- package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
- package/dist/test/mcpl-ws-transport.test.js +0 -259
- package/dist/test/mcpl-ws-transport.test.js.map +0 -1
- package/dist/test/module-context-integration.test.d.ts +0 -18
- package/dist/test/module-context-integration.test.d.ts.map +0 -1
- package/dist/test/module-context-integration.test.js +0 -181
- package/dist/test/module-context-integration.test.js.map +0 -1
- package/dist/test/offline-recovery-branch.test.d.ts +0 -2
- package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
- package/dist/test/offline-recovery-branch.test.js +0 -570
- package/dist/test/offline-recovery-branch.test.js.map +0 -1
- package/dist/test/operator-surgery.test.d.ts +0 -2
- package/dist/test/operator-surgery.test.d.ts.map +0 -1
- package/dist/test/operator-surgery.test.js +0 -595
- package/dist/test/operator-surgery.test.js.map +0 -1
- package/dist/test/ops-alert.test.d.ts +0 -2
- package/dist/test/ops-alert.test.d.ts.map +0 -1
- package/dist/test/ops-alert.test.js +0 -153
- package/dist/test/ops-alert.test.js.map +0 -1
- package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
- package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
- package/dist/test/overbudget-drain-breaker.test.js +0 -198
- package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
- package/dist/test/pack-installs-alone.test.d.ts +0 -2
- package/dist/test/pack-installs-alone.test.d.ts.map +0 -1
- package/dist/test/pack-installs-alone.test.js +0 -284
- package/dist/test/pack-installs-alone.test.js.map +0 -1
- package/dist/test/per-agent-delivery.test.d.ts +0 -2
- package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
- package/dist/test/per-agent-delivery.test.js +0 -108
- package/dist/test/per-agent-delivery.test.js.map +0 -1
- package/dist/test/physical-window-restart.test.d.ts +0 -16
- package/dist/test/physical-window-restart.test.d.ts.map +0 -1
- package/dist/test/physical-window-restart.test.js +0 -487
- package/dist/test/physical-window-restart.test.js.map +0 -1
- package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
- package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
- package/dist/test/placed-reaction-baseline.test.js +0 -312
- package/dist/test/placed-reaction-baseline.test.js.map +0 -1
- package/dist/test/present-while-acting.test.d.ts +0 -19
- package/dist/test/present-while-acting.test.d.ts.map +0 -1
- package/dist/test/present-while-acting.test.js +0 -1649
- package/dist/test/present-while-acting.test.js.map +0 -1
- package/dist/test/prose-segments.test.d.ts +0 -2
- package/dist/test/prose-segments.test.d.ts.map +0 -1
- package/dist/test/prose-segments.test.js +0 -52
- package/dist/test/prose-segments.test.js.map +0 -1
- package/dist/test/prose-stream-router.test.d.ts +0 -2
- package/dist/test/prose-stream-router.test.d.ts.map +0 -1
- package/dist/test/prose-stream-router.test.js +0 -171
- package/dist/test/prose-stream-router.test.js.map +0 -1
- package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
- package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
- package/dist/test/provider-acceleration-cooldown.test.js +0 -435
- package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
- package/dist/test/provider-waits.test.d.ts +0 -2
- package/dist/test/provider-waits.test.d.ts.map +0 -1
- package/dist/test/provider-waits.test.js +0 -2259
- package/dist/test/provider-waits.test.js.map +0 -1
- package/dist/test/puppet-tool-call.test.d.ts +0 -2
- package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
- package/dist/test/puppet-tool-call.test.js +0 -226
- package/dist/test/puppet-tool-call.test.js.map +0 -1
- package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
- package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
- package/dist/test/puppet-turn-reservation.test.js +0 -139
- package/dist/test/puppet-turn-reservation.test.js.map +0 -1
- package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
- package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
- package/dist/test/reaction-baseline-platform.test.js +0 -124
- package/dist/test/reaction-baseline-platform.test.js.map +0 -1
- package/dist/test/record-journal.test.d.ts +0 -6
- package/dist/test/record-journal.test.d.ts.map +0 -1
- package/dist/test/record-journal.test.js +0 -269
- package/dist/test/record-journal.test.js.map +0 -1
- package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
- package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
- package/dist/test/refusal-reaction-baseline.test.js +0 -81
- package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
- package/dist/test/refusal-rewind.test.d.ts +0 -2
- package/dist/test/refusal-rewind.test.d.ts.map +0 -1
- package/dist/test/refusal-rewind.test.js +0 -117
- package/dist/test/refusal-rewind.test.js.map +0 -1
- package/dist/test/refusal-single-call.test.d.ts +0 -2
- package/dist/test/refusal-single-call.test.d.ts.map +0 -1
- package/dist/test/refusal-single-call.test.js +0 -177
- package/dist/test/refusal-single-call.test.js.map +0 -1
- package/dist/test/release-bump.test.d.ts +0 -2
- package/dist/test/release-bump.test.d.ts.map +0 -1
- package/dist/test/release-bump.test.js +0 -248
- package/dist/test/release-bump.test.js.map +0 -1
- package/dist/test/release-changelog.test.d.ts +0 -2
- package/dist/test/release-changelog.test.d.ts.map +0 -1
- package/dist/test/release-changelog.test.js +0 -159
- package/dist/test/release-changelog.test.js.map +0 -1
- package/dist/test/release-holds.test.d.ts +0 -2
- package/dist/test/release-holds.test.d.ts.map +0 -1
- package/dist/test/release-holds.test.js +0 -456
- package/dist/test/release-holds.test.js.map +0 -1
- package/dist/test/same-round-think-policy.test.d.ts +0 -2
- package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
- package/dist/test/same-round-think-policy.test.js +0 -853
- package/dist/test/same-round-think-policy.test.js.map +0 -1
- package/dist/test/save-recent-image.test.d.ts +0 -26
- package/dist/test/save-recent-image.test.d.ts.map +0 -1
- package/dist/test/save-recent-image.test.js +0 -974
- package/dist/test/save-recent-image.test.js.map +0 -1
- package/dist/test/shutdown-errors.test.d.ts +0 -2
- package/dist/test/shutdown-errors.test.d.ts.map +0 -1
- package/dist/test/shutdown-errors.test.js +0 -662
- package/dist/test/shutdown-errors.test.js.map +0 -1
- package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
- package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
- package/dist/test/silent-heartbeat-rows.test.js +0 -451
- package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
- package/dist/test/silent-heartbeat.test.d.ts +0 -2
- package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
- package/dist/test/silent-heartbeat.test.js +0 -165
- package/dist/test/silent-heartbeat.test.js.map +0 -1
- package/dist/test/state-scaling-e2e.test.d.ts +0 -22
- package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
- package/dist/test/state-scaling-e2e.test.js +0 -206
- package/dist/test/state-scaling-e2e.test.js.map +0 -1
- package/dist/test/state-scaling.test.d.ts +0 -12
- package/dist/test/state-scaling.test.d.ts.map +0 -1
- package/dist/test/state-scaling.test.js +0 -251
- package/dist/test/state-scaling.test.js.map +0 -1
- package/dist/test/stop-with-host-operations.test.d.ts +0 -20
- package/dist/test/stop-with-host-operations.test.d.ts.map +0 -1
- package/dist/test/stop-with-host-operations.test.js +0 -1174
- package/dist/test/stop-with-host-operations.test.js.map +0 -1
- package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
- package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
- package/dist/test/stop-with-work-in-flight.test.js +0 -784
- package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
- package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
- package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
- package/dist/test/surgery-marks-receipt.test.js +0 -540
- package/dist/test/surgery-marks-receipt.test.js.map +0 -1
- package/dist/test/thinking-token-stamp.test.d.ts +0 -12
- package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
- package/dist/test/thinking-token-stamp.test.js +0 -129
- package/dist/test/thinking-token-stamp.test.js.map +0 -1
- package/dist/test/timezone.test.d.ts +0 -2
- package/dist/test/timezone.test.d.ts.map +0 -1
- package/dist/test/timezone.test.js +0 -18
- package/dist/test/timezone.test.js.map +0 -1
- package/dist/test/tool-batch-hook.test.d.ts +0 -8
- package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
- package/dist/test/tool-batch-hook.test.js +0 -275
- package/dist/test/tool-batch-hook.test.js.map +0 -1
- package/dist/test/tool-policy.test.d.ts +0 -2
- package/dist/test/tool-policy.test.d.ts.map +0 -1
- package/dist/test/tool-policy.test.js +0 -51
- package/dist/test/tool-policy.test.js.map +0 -1
- package/dist/test/tool-presentation.test.d.ts +0 -2
- package/dist/test/tool-presentation.test.d.ts.map +0 -1
- package/dist/test/tool-presentation.test.js +0 -268
- package/dist/test/tool-presentation.test.js.map +0 -1
- package/dist/test/tool-result-content.test.d.ts +0 -2
- package/dist/test/tool-result-content.test.d.ts.map +0 -1
- package/dist/test/tool-result-content.test.js +0 -37
- package/dist/test/tool-result-content.test.js.map +0 -1
- package/dist/test/tool-result-guard.test.d.ts +0 -2
- package/dist/test/tool-result-guard.test.d.ts.map +0 -1
- package/dist/test/tool-result-guard.test.js +0 -3729
- package/dist/test/tool-result-guard.test.js.map +0 -1
- package/dist/test/tool-result-history.test.d.ts +0 -7
- package/dist/test/tool-result-history.test.d.ts.map +0 -1
- package/dist/test/tool-result-history.test.js +0 -156
- package/dist/test/tool-result-history.test.js.map +0 -1
- package/dist/test/tool-result-spill.test.d.ts +0 -13
- package/dist/test/tool-result-spill.test.d.ts.map +0 -1
- package/dist/test/tool-result-spill.test.js +0 -586
- package/dist/test/tool-result-spill.test.js.map +0 -1
- package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
- package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
- package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
- package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
- package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
- package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
- package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
- package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
- package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
- package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
- package/dist/test/tools-observe-parser-conformance.test.js +0 -129
- package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
- package/dist/test/trunk-channel-routing.test.d.ts +0 -19
- package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
- package/dist/test/trunk-channel-routing.test.js +0 -652
- package/dist/test/trunk-channel-routing.test.js.map +0 -1
- package/dist/test/tune-out-e2e.test.d.ts +0 -2
- package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
- package/dist/test/tune-out-e2e.test.js +0 -142
- package/dist/test/tune-out-e2e.test.js.map +0 -1
- package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
- package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
- package/dist/test/tune-out-gate-composition.test.js +0 -221
- package/dist/test/tune-out-gate-composition.test.js.map +0 -1
- package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
- package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
- package/dist/test/tune-out-lifecycle.test.js +0 -121
- package/dist/test/tune-out-lifecycle.test.js.map +0 -1
- package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
- package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
- package/dist/test/turn-trigger-provenance.test.js +0 -137
- package/dist/test/turn-trigger-provenance.test.js.map +0 -1
- package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
- package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
- package/dist/test/unconvertible-tool-result.test.js +0 -358
- package/dist/test/unconvertible-tool-result.test.js.map +0 -1
- package/dist/test/unsent-compiles.test.d.ts +0 -2
- package/dist/test/unsent-compiles.test.d.ts.map +0 -1
- package/dist/test/unsent-compiles.test.js +0 -139
- package/dist/test/unsent-compiles.test.js.map +0 -1
- package/dist/test/usage-accounting.test.d.ts +0 -2
- package/dist/test/usage-accounting.test.d.ts.map +0 -1
- package/dist/test/usage-accounting.test.js +0 -13
- package/dist/test/usage-accounting.test.js.map +0 -1
- package/dist/test/usage-tracker.test.d.ts +0 -2
- package/dist/test/usage-tracker.test.d.ts.map +0 -1
- package/dist/test/usage-tracker.test.js +0 -129
- package/dist/test/usage-tracker.test.js.map +0 -1
- package/dist/test/utils-surface.test.d.ts +0 -2
- package/dist/test/utils-surface.test.d.ts.map +0 -1
- package/dist/test/utils-surface.test.js +0 -145
- package/dist/test/utils-surface.test.js.map +0 -1
- package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
- package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
- package/dist/test/workspace-branch-continuation.test.js +0 -183
- package/dist/test/workspace-branch-continuation.test.js.map +0 -1
- package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
- package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
- package/dist/test/workspace-materialize-freshness.test.js +0 -252
- package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
- package/dist/test/workspace-path-containment.test.d.ts +0 -19
- package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
- package/dist/test/workspace-path-containment.test.js +0 -91
- package/dist/test/workspace-path-containment.test.js.map +0 -1
- package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
- package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
- package/dist/test/workspace-read-file-from-disk.test.js +0 -174
- package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
- package/dist/test/workspace-read-image.test.d.ts +0 -2
- package/dist/test/workspace-read-image.test.d.ts.map +0 -1
- package/dist/test/workspace-read-image.test.js +0 -597
- package/dist/test/workspace-read-image.test.js.map +0 -1
- package/dist/test/workspace-read-text.test.d.ts +0 -2
- package/dist/test/workspace-read-text.test.d.ts.map +0 -1
- package/dist/test/workspace-read-text.test.js +0 -101
- package/dist/test/workspace-read-text.test.js.map +0 -1
- package/dist/test/workspace-restore-order.test.d.ts +0 -16
- package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
- package/dist/test/workspace-restore-order.test.js +0 -140
- package/dist/test/workspace-restore-order.test.js.map +0 -1
- package/dist/test/workspace-three-way.test.d.ts +0 -12
- package/dist/test/workspace-three-way.test.d.ts.map +0 -1
- package/dist/test/workspace-three-way.test.js +0 -4094
- package/dist/test/workspace-three-way.test.js.map +0 -1
- package/dist/test/workspace-watcher.test.d.ts +0 -2
- package/dist/test/workspace-watcher.test.d.ts.map +0 -1
- package/dist/test/workspace-watcher.test.js +0 -281
- package/dist/test/workspace-watcher.test.js.map +0 -1
- package/dist/test/xml-round-persist.test.d.ts +0 -19
- package/dist/test/xml-round-persist.test.d.ts.map +0 -1
- package/dist/test/xml-round-persist.test.js +0 -235
- package/dist/test/xml-round-persist.test.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -19,6 +19,7 @@ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
|
19
19
|
import { tmpdir } from 'node:os';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { createInterface, type Interface } from 'node:readline';
|
|
22
|
+
import { boundedErrorMessage } from '../error-message.js';
|
|
22
23
|
import { PYTHON_RUNTIME_SOURCE } from './runtime-py.js';
|
|
23
24
|
|
|
24
25
|
export interface InjectedTool {
|
|
@@ -91,6 +92,56 @@ export function formatLimit(ms: number): string {
|
|
|
91
92
|
return `${Math.round(ms / 360_000) / 10} h`;
|
|
92
93
|
}
|
|
93
94
|
|
|
95
|
+
/**
|
|
96
|
+
* What a script stopped at its time limit is told after why: that the tool
|
|
97
|
+
* calls it made keep their effects, and whether a longer limit can help,
|
|
98
|
+
* which only the deployment's ceiling for its kind of script can say. A
|
|
99
|
+
* foreground script at its ceiling is offered background mode too, when its
|
|
100
|
+
* caller passes `backgroundCeilingMs` (the framework does for an agent that
|
|
101
|
+
* could start a background script as the script starts) and a background
|
|
102
|
+
* script may run longer.
|
|
103
|
+
*/
|
|
104
|
+
function limitRemedy(limitMs: number, ceilingMs: number | undefined, background: boolean, backgroundCeilingMs?: number): string {
|
|
105
|
+
const effects = 'Tool calls it had already made keep their effects, so check them before running it again.';
|
|
106
|
+
if (ceilingMs === undefined) return effects;
|
|
107
|
+
if (limitMs < ceilingMs) return `${effects} To give it longer, ${background ? 'start it with' : 'pass'} time_limit_ms up to ${ceilingMs} (${formatLimit(ceilingMs)}).`;
|
|
108
|
+
if (background) return `${effects} ${formatLimit(limitMs)} is the longest a background script runs here; starting it again runs it from the top.`;
|
|
109
|
+
const inBackground = backgroundCeilingMs !== undefined && backgroundCeilingMs > limitMs
|
|
110
|
+
? `, or run it with background: true, where a script can run up to ${formatLimit(backgroundCeilingMs)}` : '';
|
|
111
|
+
return `${effects} ${formatLimit(limitMs)} is the longest a script can run here, so split the work across shorter scripts${inBackground}.`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Why a script didn't run when its interpreter didn't start. A spawn that
|
|
116
|
+
* found nothing it could run (ENOENT, EACCES) fails the same way until the
|
|
117
|
+
* host changes, so that one says code_execution can't run here rather than
|
|
118
|
+
* to try again. A failure before the spawn, while creating or writing the
|
|
119
|
+
* runtime's files, is about those files rather than the interpreter, and
|
|
120
|
+
* keeps Node's own text, which names the path for an open or a mkdtemp.
|
|
121
|
+
*/
|
|
122
|
+
function startFailure(pythonPath: string, err: unknown): string {
|
|
123
|
+
const { code, syscall } = (err ?? {}) as { code?: unknown; syscall?: unknown };
|
|
124
|
+
const spawning = typeof syscall === 'string' && syscall.startsWith('spawn');
|
|
125
|
+
if (spawning && (code === 'ENOENT' || code === 'EACCES')) {
|
|
126
|
+
const until = code === 'ENOENT' ? 'installs it or points this host at one' : 'makes it executable or points this host at another';
|
|
127
|
+
return `script didn't run: this host can't start its Python interpreter, ${pythonPath} (${code}), so code_execution can't run scripts here until whoever runs this host ${until}. Calling it again before then fails the same way.`;
|
|
128
|
+
}
|
|
129
|
+
if (typeof syscall === 'string' && !spawning) {
|
|
130
|
+
return `script didn't run: this host couldn't create or write the files its Python runtime starts from (${boundedErrorMessage(err)}), so none of the script ran. Run it again; if it fails the same way, ask whoever runs this host.`;
|
|
131
|
+
}
|
|
132
|
+
const why = typeof code === 'string' ? `couldn't be started (${code})` : boundedErrorMessage(err);
|
|
133
|
+
return `script didn't run: the Python interpreter, ${pythonPath}, ${why}, so none of the script ran. Run it again; if it fails the same way, ask whoever runs this host.`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Why a script stopped when its interpreter exited under it, and what running it again does. */
|
|
137
|
+
function interpreterExit(exitCode: number | null, signal: NodeJS.Signals | null, background: boolean): string {
|
|
138
|
+
const how = signal ? `was ended by ${signal}` : `exited with code ${exitCode}`;
|
|
139
|
+
return `script stopped: the Python interpreter ${how} while it ran, so the rest of the script didn't run`
|
|
140
|
+
+ `${background ? '' : ', and variables from earlier scripts are gone'}. Tool calls it had already made keep their effects, `
|
|
141
|
+
+ 'so check them before you run it again in a new interpreter. If it stops the same way, check whether the script itself '
|
|
142
|
+
+ `ends the process, for example ${signal ? 'by using too much memory' : 'with os._exit()'}; if not, ask whoever runs this host.`;
|
|
143
|
+
}
|
|
144
|
+
|
|
94
145
|
interface PendingExec {
|
|
95
146
|
id: string;
|
|
96
147
|
resolve: (result: ExecResult) => void;
|
|
@@ -101,6 +152,16 @@ interface PendingExec {
|
|
|
101
152
|
settled: boolean;
|
|
102
153
|
/** Set once the deadline fired: the result then says the script ran out of time. */
|
|
103
154
|
deadlineMs: number | null;
|
|
155
|
+
/** The longest limit this exec could have had (exec's opts): whether a longer one would help. */
|
|
156
|
+
ceilingMs: number | undefined;
|
|
157
|
+
/** For a foreground exec, the longest a background script may run (exec's opts): whether background mode would help. */
|
|
158
|
+
backgroundCeilingMs: number | undefined;
|
|
159
|
+
/** A background exec has its interpreter to itself, so no earlier script's state is lost with it. */
|
|
160
|
+
background: boolean;
|
|
161
|
+
/** Set once the script went to the interpreter. Before that, the exec is
|
|
162
|
+
* waiting for the interpreter to start, and an interpreter that exits then
|
|
163
|
+
* failed to start (see exec). */
|
|
164
|
+
sent: boolean;
|
|
104
165
|
}
|
|
105
166
|
|
|
106
167
|
export class PyRunner {
|
|
@@ -121,8 +182,6 @@ export class PyRunner {
|
|
|
121
182
|
private idleTimer: ReturnType<typeof setTimeout> | null = null;
|
|
122
183
|
private execCounter = 0;
|
|
123
184
|
private disposed = false;
|
|
124
|
-
/** An exec has passed the busy check but is still awaiting the interpreter. */
|
|
125
|
-
private starting = false;
|
|
126
185
|
|
|
127
186
|
constructor(options: PyRunnerOptions) {
|
|
128
187
|
this.pythonPath = options.pythonPath ?? 'python3';
|
|
@@ -135,7 +194,7 @@ export class PyRunner {
|
|
|
135
194
|
}
|
|
136
195
|
|
|
137
196
|
get busy(): boolean {
|
|
138
|
-
return this.pending !== null
|
|
197
|
+
return this.pending !== null;
|
|
139
198
|
}
|
|
140
199
|
|
|
141
200
|
/**
|
|
@@ -150,12 +209,18 @@ export class PyRunner {
|
|
|
150
209
|
*
|
|
151
210
|
* `opts.deadlineMs` replaces the runner's scriptTimeoutMs for this exec (a
|
|
152
211
|
* per-call time limit); a background exec uses its `lifetimeMs` instead.
|
|
212
|
+
* `opts.ceilingMs` is the longest limit the deployment allows this kind of
|
|
213
|
+
* script: a script stopped at its limit is offered a longer one only below
|
|
214
|
+
* it. Without it, the stop doesn't say whether a longer limit would help.
|
|
215
|
+
* `opts.backgroundCeilingMs`, for a foreground exec, is the longest a
|
|
216
|
+
* background script may run: one stopped at its ceiling is offered
|
|
217
|
+
* background mode when that is longer.
|
|
153
218
|
*/
|
|
154
219
|
async exec(
|
|
155
220
|
code: string,
|
|
156
221
|
tools: InjectedTool[],
|
|
157
222
|
background?: BackgroundExecOptions,
|
|
158
|
-
opts?: { deadlineMs?: number },
|
|
223
|
+
opts?: { deadlineMs?: number; ceilingMs?: number; backgroundCeilingMs?: number },
|
|
159
224
|
): Promise<ExecResult> {
|
|
160
225
|
if (this.disposed) {
|
|
161
226
|
return { stdout: '', stderr: 'code_execution runner disposed', returnCode: 1, aborted: true };
|
|
@@ -163,83 +228,98 @@ export class PyRunner {
|
|
|
163
228
|
if (this.busy) {
|
|
164
229
|
return {
|
|
165
230
|
stdout: '',
|
|
166
|
-
stderr: '
|
|
231
|
+
stderr: "script didn't run: another code_execution script of yours is already running, and they run one at a time. "
|
|
232
|
+
+ 'Run this one again once that one has finished, or combine the two into one script.',
|
|
167
233
|
returnCode: 1,
|
|
168
234
|
aborted: true,
|
|
169
235
|
};
|
|
170
236
|
}
|
|
171
237
|
this.clearIdleTimer();
|
|
172
238
|
|
|
173
|
-
|
|
239
|
+
// The exec claims the runner before the await: a same-tick second exec
|
|
240
|
+
// sees it busy, and abort() or dispose() while the interpreter starts
|
|
241
|
+
// settles this exec, whose script then never runs.
|
|
242
|
+
let resolveResult!: (result: ExecResult) => void;
|
|
243
|
+
const settled = new Promise<ExecResult>((resolve) => {
|
|
244
|
+
resolveResult = resolve;
|
|
245
|
+
});
|
|
246
|
+
const pending: PendingExec = {
|
|
247
|
+
id: `e${++this.execCounter}`,
|
|
248
|
+
resolve: resolveResult,
|
|
249
|
+
deadlineTimer: null,
|
|
250
|
+
killTimer: null,
|
|
251
|
+
settled: false,
|
|
252
|
+
deadlineMs: null,
|
|
253
|
+
ceilingMs: opts?.ceilingMs,
|
|
254
|
+
backgroundCeilingMs: opts?.backgroundCeilingMs,
|
|
255
|
+
background: background !== undefined,
|
|
256
|
+
sent: false,
|
|
257
|
+
};
|
|
258
|
+
this.pending = pending;
|
|
174
259
|
try {
|
|
175
260
|
await this.ensureChild();
|
|
176
261
|
} catch (err) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
262
|
+
// Settled already when an abort or dispose reclaimed the interpreter
|
|
263
|
+
// as it started; another exec may have claimed the runner since.
|
|
264
|
+
if (!pending.settled) {
|
|
265
|
+
this.settlePending({
|
|
266
|
+
stdout: '',
|
|
267
|
+
stderr: startFailure(this.pythonPath, err),
|
|
268
|
+
returnCode: 1,
|
|
269
|
+
aborted: true,
|
|
270
|
+
});
|
|
271
|
+
this.reclaim('spawn-failed');
|
|
272
|
+
}
|
|
273
|
+
return settled;
|
|
187
274
|
}
|
|
275
|
+
if (pending.settled) return settled;
|
|
188
276
|
|
|
189
|
-
const execId =
|
|
277
|
+
const execId = pending.id;
|
|
190
278
|
// Clamped: a deadline past Node's timer range would fire at once instead of never.
|
|
191
279
|
const deadlineMs = Math.min(MAX_TIMER_MS, background?.lifetimeMs ?? opts?.deadlineMs ?? this.scriptTimeoutMs);
|
|
192
280
|
this.onWake = background?.onWake ?? null;
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
this.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (background) pending.deadlineTimer.unref?.();
|
|
232
|
-
|
|
233
|
-
this.send({
|
|
234
|
-
op: 'init',
|
|
235
|
-
tools: tools.map((t) => ({ py_name: t.pyName, tool_name: t.toolName })),
|
|
236
|
-
call_timeout_s: Math.round(this.toolCallTimeoutMs / 1000),
|
|
237
|
-
...(background
|
|
238
|
-
? { background: true, log_path: background.logPath ?? null }
|
|
239
|
-
: {}),
|
|
240
|
-
});
|
|
241
|
-
this.send({ op: 'exec', id: execId, code });
|
|
281
|
+
pending.deadlineTimer = setTimeout(() => {
|
|
282
|
+
pending.deadlineMs = deadlineMs;
|
|
283
|
+
// Deadline: ask politely first (script sees CancelledError and its
|
|
284
|
+
// exec_result still flows back), then kill on unresponsiveness.
|
|
285
|
+
this.send({ op: 'cancel', id: execId, reason: 'deadline' });
|
|
286
|
+
// The cancel lands only when the script awaits. Blocking code (time.sleep, a
|
|
287
|
+
// busy loop, a blocking read) never does, so interrupt it as well: the runtime
|
|
288
|
+
// raises KeyboardInterrupt in the script's own code, or schedules the
|
|
289
|
+
// cancellation of a script that is waiting. Repeated, because a waiting script
|
|
290
|
+
// can resume into blocking code before that cancellation runs; the runtime
|
|
291
|
+
// ignores the repeats once the script was interrupted or cancelled.
|
|
292
|
+
this.interruptChild();
|
|
293
|
+
pending.interruptTimer = setInterval(() => this.interruptChild(), INTERRUPT_REPEAT_MS);
|
|
294
|
+
pending.killTimer = setTimeout(() => {
|
|
295
|
+
pending.deadlineMs = null; // this message already says why
|
|
296
|
+
this.settlePending({
|
|
297
|
+
stdout: '',
|
|
298
|
+
stderr:
|
|
299
|
+
`script stopped: it reached its ${formatLimit(deadlineMs)} time limit and did not respond, so it was killed` +
|
|
300
|
+
(pending.background ? '. ' : ' and the interpreter restarted (variables from earlier scripts are gone). ') +
|
|
301
|
+
limitRemedy(deadlineMs, pending.ceilingMs, pending.background, pending.backgroundCeilingMs),
|
|
302
|
+
returnCode: 1,
|
|
303
|
+
aborted: true,
|
|
304
|
+
});
|
|
305
|
+
this.reclaim('deadline-kill');
|
|
306
|
+
}, this.cancelGraceMs);
|
|
307
|
+
}, deadlineMs);
|
|
308
|
+
// A day-scale background deadline must not hold the process open.
|
|
309
|
+
if (background) pending.deadlineTimer.unref?.();
|
|
310
|
+
|
|
311
|
+
pending.sent = true;
|
|
312
|
+
this.send({
|
|
313
|
+
op: 'init',
|
|
314
|
+
tools: tools.map((t) => ({ py_name: t.pyName, tool_name: t.toolName })),
|
|
315
|
+
call_timeout_s: Math.round(this.toolCallTimeoutMs / 1000),
|
|
316
|
+
...(background
|
|
317
|
+
? { background: true, log_path: background.logPath ?? null }
|
|
318
|
+
: {}),
|
|
242
319
|
});
|
|
320
|
+
this.send({ op: 'exec', id: execId, code });
|
|
321
|
+
|
|
322
|
+
const result = await settled;
|
|
243
323
|
|
|
244
324
|
this.onWake = null;
|
|
245
325
|
if (!background) this.armIdleTimer();
|
|
@@ -247,9 +327,12 @@ export class PyRunner {
|
|
|
247
327
|
}
|
|
248
328
|
|
|
249
329
|
/**
|
|
250
|
-
* Abort
|
|
251
|
-
*
|
|
252
|
-
*
|
|
330
|
+
* Abort the runner's script (its turn ended or is reset to run again, or the
|
|
331
|
+
* agent was reset or stopped), whether it's running or still waiting for its
|
|
332
|
+
* interpreter to start; a waiting script then never runs. The exec settles
|
|
333
|
+
* at once, and the interpreter is reclaimed, a starting one too: after an
|
|
334
|
+
* abort its state is suspect (a script died midway), and the next exec gets
|
|
335
|
+
* a fresh one.
|
|
253
336
|
*/
|
|
254
337
|
abort(reason: string): void {
|
|
255
338
|
if (!this.pending) return;
|
|
@@ -302,16 +385,38 @@ export class PyRunner {
|
|
|
302
385
|
console.error(`[pytc:${this.label}] ${chunk.trimEnd()}`);
|
|
303
386
|
});
|
|
304
387
|
|
|
388
|
+
// A write to an interpreter that no longer reads its input fails on the
|
|
389
|
+
// stream after write() returns; with no listener, that error is thrown as
|
|
390
|
+
// an uncaught exception. Such an interpreter can go on running, as after a
|
|
391
|
+
// script closes file descriptor 0, and every later message to it is lost:
|
|
392
|
+
// its exec would wait out its time limit. So end it, and its exit settles
|
|
393
|
+
// the exec now. One already dead or killed is left to its own exit.
|
|
394
|
+
let inputFailed = false;
|
|
395
|
+
child.stdin.on('error', (err) => {
|
|
396
|
+
console.error(`[pytc:${this.label}] write to the python runtime failed: ${err.message}`);
|
|
397
|
+
if (child.exitCode === null && !child.killed && child.pid !== undefined) {
|
|
398
|
+
inputFailed = true;
|
|
399
|
+
child.kill('SIGKILL');
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
305
403
|
child.on('error', (err) => {
|
|
306
404
|
// Spawn failure lands here (e.g. python3 missing); readiness rejects.
|
|
307
405
|
console.error(`[pytc:${this.label}] python process error: ${err.message}`);
|
|
308
406
|
});
|
|
309
407
|
|
|
310
408
|
child.on('exit', (exitCode, signal) => {
|
|
311
|
-
|
|
409
|
+
// An exec still waiting for the interpreter is settled by exec, as a
|
|
410
|
+
// runtime that failed to start.
|
|
411
|
+
if (this.pending?.sent) {
|
|
312
412
|
this.settlePending({
|
|
313
413
|
stdout: '',
|
|
314
|
-
stderr:
|
|
414
|
+
stderr:
|
|
415
|
+
inputFailed && signal === 'SIGKILL'
|
|
416
|
+
? 'python runtime stopped reading its input, so it was killed and the interpreter restarted ' +
|
|
417
|
+
'(variables from earlier scripts are gone). A script that closes its standard input ' +
|
|
418
|
+
'(file descriptor 0) does this.'
|
|
419
|
+
: interpreterExit(exitCode, signal, this.pending.background),
|
|
315
420
|
returnCode: 1,
|
|
316
421
|
aborted: true,
|
|
317
422
|
});
|
|
@@ -331,7 +436,7 @@ export class PyRunner {
|
|
|
331
436
|
};
|
|
332
437
|
const onExit = () => {
|
|
333
438
|
cleanup();
|
|
334
|
-
reject(new Error('
|
|
439
|
+
reject(new Error('exited as it started'));
|
|
335
440
|
};
|
|
336
441
|
const onError = (err: Error) => {
|
|
337
442
|
cleanup();
|
|
@@ -339,15 +444,17 @@ export class PyRunner {
|
|
|
339
444
|
};
|
|
340
445
|
const timeout = setTimeout(() => {
|
|
341
446
|
cleanup();
|
|
342
|
-
reject(new Error('
|
|
447
|
+
reject(new Error("didn't start within 15 seconds"));
|
|
343
448
|
}, 15_000);
|
|
344
449
|
const cleanup = () => {
|
|
345
450
|
clearTimeout(timeout);
|
|
346
451
|
this.readyResolver = null;
|
|
452
|
+
this.readyFailer = null;
|
|
347
453
|
child.off('exit', onExit);
|
|
348
454
|
child.off('error', onError);
|
|
349
455
|
};
|
|
350
456
|
this.readyResolver = onReady;
|
|
457
|
+
this.readyFailer = onError;
|
|
351
458
|
child.on('exit', onExit);
|
|
352
459
|
child.on('error', onError);
|
|
353
460
|
});
|
|
@@ -355,6 +462,8 @@ export class PyRunner {
|
|
|
355
462
|
}
|
|
356
463
|
|
|
357
464
|
private readyResolver: (() => void) | null = null;
|
|
465
|
+
/** Fails the readiness of an interpreter that is still starting (see reclaim). */
|
|
466
|
+
private readyFailer: ((err: Error) => void) | null = null;
|
|
358
467
|
|
|
359
468
|
private handleLine(line: string, child: ChildProcessWithoutNullStreams): void {
|
|
360
469
|
let msg: { op?: string; id?: string; name?: string; args?: unknown; stdout?: string; stderr?: string; return_code?: number };
|
|
@@ -431,9 +540,12 @@ export class PyRunner {
|
|
|
431
540
|
// Only a script that ended unsuccessfully was stopped: one that caught the cancellation
|
|
432
541
|
// and finished its work returns 0, and must not read as stopped.
|
|
433
542
|
if (pending.deadlineMs !== null && result.returnCode !== 0) {
|
|
434
|
-
const note = `script stopped: it reached its ${formatLimit(pending.deadlineMs)} time limit
|
|
543
|
+
const note = `script stopped: it reached its ${formatLimit(pending.deadlineMs)} time limit. `
|
|
544
|
+
+ `${limitRemedy(pending.deadlineMs, pending.ceilingMs, pending.background, pending.backgroundCeilingMs)}\n`;
|
|
545
|
+
// On a line of its own: the runner's own texts, such as an interpreter's exit, end without a newline.
|
|
546
|
+
const withNote = (text: string) => (text === '' || text.endsWith('\n') ? text : `${text}\n`) + note;
|
|
435
547
|
// A background script reports its output tail, so the note goes there too.
|
|
436
|
-
result = { ...result, stderr: result.stderr
|
|
548
|
+
result = { ...result, stderr: withNote(result.stderr), ...(result.tail !== undefined ? { tail: withNote(result.tail) } : {}) };
|
|
437
549
|
}
|
|
438
550
|
if (pending.deadlineTimer) clearTimeout(pending.deadlineTimer);
|
|
439
551
|
if (pending.killTimer) clearTimeout(pending.killTimer);
|
|
@@ -492,6 +604,12 @@ export class PyRunner {
|
|
|
492
604
|
if (this.child) {
|
|
493
605
|
console.error(`[pytc:${this.label}] reclaiming python interpreter (${reason})`);
|
|
494
606
|
}
|
|
607
|
+
// An interpreter killed as it starts never says it's ready: fail its
|
|
608
|
+
// readiness now, so an exec waiting on it returns at once rather than at
|
|
609
|
+
// the 15 s timeout. Here rather than in teardownChild, which an
|
|
610
|
+
// interpreter's own exit also runs, so that one still reads "exited as
|
|
611
|
+
// it started".
|
|
612
|
+
this.readyFailer?.(new Error(`python runtime reclaimed (${reason}) before it was ready`));
|
|
495
613
|
this.teardownChild();
|
|
496
614
|
this.clearIdleTimer();
|
|
497
615
|
}
|
|
@@ -506,13 +624,19 @@ export class PyRunner {
|
|
|
506
624
|
this.child = null;
|
|
507
625
|
this.childReady = null;
|
|
508
626
|
this.readyResolver = null;
|
|
627
|
+
this.readyFailer = null;
|
|
509
628
|
child.removeAllListeners('exit');
|
|
510
629
|
try {
|
|
511
630
|
child.stdin.end();
|
|
512
631
|
} catch {
|
|
513
632
|
// stream may already be destroyed
|
|
514
633
|
}
|
|
515
|
-
|
|
634
|
+
// A child whose spawn failed has no pid, and its exitCode stays null
|
|
635
|
+
// until Node's 'error' for it, a tick later. A kill() in that tick, as
|
|
636
|
+
// from an abort or dispose on the tick exec was called, signals no
|
|
637
|
+
// child of ours but whatever pid Node's handle held: the host's own
|
|
638
|
+
// process group on Node 20.20.2, another process's pid on 24.19.
|
|
639
|
+
if (child.exitCode === null && !child.killed && child.pid !== undefined) {
|
|
516
640
|
child.kill('SIGKILL');
|
|
517
641
|
}
|
|
518
642
|
}
|
|
@@ -259,15 +259,61 @@ def _resolve(fut, value):
|
|
|
259
259
|
pass
|
|
260
260
|
|
|
261
261
|
|
|
262
|
+
def _brief(value):
|
|
263
|
+
# A value as a refusal shows it: by its type, such as <str>, which fails
|
|
264
|
+
# loudly if copied rather than sending something else. The agent has its
|
|
265
|
+
# values in the call it just wrote. No value's own code runs here: its
|
|
266
|
+
# __repr__ isn't called, and its type is named through type's own
|
|
267
|
+
# descriptor, so a metaclass's __name__ doesn't run either.
|
|
268
|
+
return "<" + type.__dict__["__name__"].__get__(type(value)) + ">"
|
|
269
|
+
|
|
270
|
+
|
|
262
271
|
def _make_tool_fn(tool_name, py_name):
|
|
263
|
-
async def tool_fn(
|
|
272
|
+
async def tool_fn(*positional, **kwargs):
|
|
264
273
|
global _next_tool_call_id
|
|
274
|
+
if len(positional) > 1:
|
|
275
|
+
raise TypeError(
|
|
276
|
+
py_name + " wasn't called: a tool function takes one dict of "
|
|
277
|
+
"arguments, such as await " + py_name + "({...}), and this call "
|
|
278
|
+
"gave it " + str(len(positional)) + " positional arguments"
|
|
279
|
+
)
|
|
280
|
+
# args= on its own is the dict, as it has always been. Beside other
|
|
281
|
+
# keywords it's one of them, since a tool such as utils has a field
|
|
282
|
+
# of that name, so the suggested dict keeps it.
|
|
283
|
+
if positional:
|
|
284
|
+
args = positional[0]
|
|
285
|
+
elif list(kwargs) == ["args"]:
|
|
286
|
+
args = kwargs.pop("args")
|
|
287
|
+
else:
|
|
288
|
+
args = None
|
|
289
|
+
if kwargs:
|
|
290
|
+
if args is not None and not isinstance(args, dict):
|
|
291
|
+
raise TypeError(
|
|
292
|
+
py_name + " wasn't called: a tool function takes one dict of "
|
|
293
|
+
"arguments, not keyword arguments, and this call also gave it "
|
|
294
|
+
+ _brief(args) + ", so put every argument in one dict: await "
|
|
295
|
+
+ py_name + "({...})"
|
|
296
|
+
)
|
|
297
|
+
# The likely intent is plain: the same arguments in one dict.
|
|
298
|
+
meant = dict(args) if isinstance(args, dict) else {}
|
|
299
|
+
meant.update(kwargs)
|
|
300
|
+
# A key is what the agent has to write, so a str key is shown
|
|
301
|
+
# whole up to 60 characters, as names are elsewhere; a longer one,
|
|
302
|
+
# or any other key, is shown as a value is.
|
|
303
|
+
shown = ", ".join((repr(k) if type(k) is str and len(k) <= 60 else _brief(k)) + ": " + _brief(v)
|
|
304
|
+
for k, v in meant.items())
|
|
305
|
+
raise TypeError(
|
|
306
|
+
py_name + " wasn't called: a tool function takes one dict of "
|
|
307
|
+
"arguments, not keyword arguments, so write await "
|
|
308
|
+
+ py_name + "({" + shown + "})"
|
|
309
|
+
)
|
|
265
310
|
if args is None:
|
|
266
311
|
args = {}
|
|
267
312
|
if not isinstance(args, dict):
|
|
268
313
|
raise TypeError(
|
|
269
|
-
"
|
|
270
|
-
+ py_name + "({...})"
|
|
314
|
+
py_name + " wasn't called: a tool function takes one dict of "
|
|
315
|
+
"arguments, such as await " + py_name + "({...}), and this call "
|
|
316
|
+
"gave it " + _brief(args)
|
|
271
317
|
)
|
|
272
318
|
_next_tool_call_id += 1
|
|
273
319
|
call_id = "t" + str(_next_tool_call_id)
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { ToolDefinition } from '../types/index.js';
|
|
12
|
+
import { assertBooleanSetting, holdsSettings } from '../config-checks.js';
|
|
12
13
|
import { formatLimit, MAX_TIMER_MS } from './py-runner.js';
|
|
13
14
|
|
|
14
15
|
export const CODE_EXECUTION_TOOL_NAME = 'code_execution';
|
|
@@ -106,15 +107,38 @@ export function scriptTimeLimits(opts?: {
|
|
|
106
107
|
const defaultMs = Math.min(MAX_TIMER_MS, opts?.scriptTimeoutMs ?? 600_000);
|
|
107
108
|
return {
|
|
108
109
|
defaultMs,
|
|
109
|
-
// A ceiling below the default is refused when
|
|
110
|
-
// (validateCodeExecutionConfig); never below the
|
|
110
|
+
// A ceiling below the default is refused when a framework with code
|
|
111
|
+
// execution on is created (validateCodeExecutionConfig); never below the
|
|
112
|
+
// default here either.
|
|
111
113
|
maxMs: Math.min(MAX_TIMER_MS, Math.max(defaultMs, opts?.maxScriptTimeoutMs ?? defaultMs)),
|
|
112
114
|
backgroundMaxMs: Math.min(MAX_TIMER_MS, opts?.backgroundMaxLifetimeMs ?? 86_400_000),
|
|
113
115
|
};
|
|
114
116
|
}
|
|
115
117
|
|
|
116
|
-
/**
|
|
117
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Refuse a codeExecution that isn't an object, or whose switch is set to
|
|
120
|
+
* anything but true or false, and, once it's on, one whose time limits
|
|
121
|
+
* contradict each other. A JSON config, or a `${VAR}` substituted as a string,
|
|
122
|
+
* can carry a quoted "false" where the type says boolean, and only `true` turns
|
|
123
|
+
* code execution on, so the quotes would hide what the value does; a bare
|
|
124
|
+
* `codeExecution: true` would be read as off. A null or false codeExecution,
|
|
125
|
+
* and a null switch, count as not set, as left-out ones do. The refusal names
|
|
126
|
+
* the value's kind, not the value. A configuration that isn't on has nothing
|
|
127
|
+
* else read.
|
|
128
|
+
*/
|
|
129
|
+
export function validateCodeExecutionConfig(cfg: {
|
|
130
|
+
enabled?: unknown;
|
|
131
|
+
scriptTimeoutMs?: number;
|
|
132
|
+
maxScriptTimeoutMs?: number;
|
|
133
|
+
}): void {
|
|
134
|
+
if (!holdsSettings('codeExecution', cfg, '{ enabled: true }')) return;
|
|
135
|
+
assertBooleanSetting(
|
|
136
|
+
'codeExecution.enabled',
|
|
137
|
+
cfg.enabled,
|
|
138
|
+
'true gives agents the code_execution tool, which runs their scripts in a python interpreter on the host, ' +
|
|
139
|
+
'and false or leaving it out doesn\'t',
|
|
140
|
+
);
|
|
141
|
+
if (cfg.enabled !== true) return;
|
|
118
142
|
const defaultMs = cfg.scriptTimeoutMs ?? 600_000;
|
|
119
143
|
if (cfg.maxScriptTimeoutMs !== undefined && !(cfg.maxScriptTimeoutMs >= defaultMs)) {
|
|
120
144
|
throw new Error(
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusals shared by the configuration checks. A setting read by truthiness
|
|
3
|
+
* turns on for a quoted "false", and a settings object such as `true`, which
|
|
4
|
+
* isn't an object, has every setting in it read as left out. A JSON config,
|
|
5
|
+
* or a `${VAR}` substituted as a string, can carry either where the type says
|
|
6
|
+
* otherwise, so each refusal says what the value would have done. Each names
|
|
7
|
+
* the setting and the value's kind, never the value, which could be a secret
|
|
8
|
+
* pasted into the wrong field.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** The kind of a value that isn't undefined, null or a boolean, as a refusal
|
|
12
|
+
* names it in place of the value. */
|
|
13
|
+
export function kindOf(value: unknown): string {
|
|
14
|
+
if (Array.isArray(value)) return 'an array';
|
|
15
|
+
if (typeof value !== 'object') return `a ${typeof value}`;
|
|
16
|
+
const prototype = Object.getPrototypeOf(value) as { constructor?: { name?: string } } | null;
|
|
17
|
+
if (prototype === null || prototype === Object.prototype) return 'an object';
|
|
18
|
+
const name = prototype.constructor?.name;
|
|
19
|
+
if (!name) return 'an object that isn\'t plain';
|
|
20
|
+
return `${/^[aeiou]/i.test(name) ? 'an' : 'a'} ${name}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Refuse a boolean setting that holds anything but true or false. null counts
|
|
25
|
+
* as not set, as leaving it out does, so a generated config that writes an
|
|
26
|
+
* unset setting as null keeps working. `whatItDoes` ends the refusal: what
|
|
27
|
+
* true does, and what false or leaving it out does.
|
|
28
|
+
*/
|
|
29
|
+
export function assertBooleanSetting(setting: string, value: unknown, whatItDoes: string): void {
|
|
30
|
+
if (value === undefined || value === null || typeof value === 'boolean') return;
|
|
31
|
+
const wanted = typeof value === 'string' ? 'true or false, unquoted,' : 'true or false,';
|
|
32
|
+
throw new Error(`${setting} must be ${wanted} not ${kindOf(value)}: ${whatItDoes}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether a settings object holds settings to check: false when it's null,
|
|
37
|
+
* false or left out, which count as not set. Each of those has every setting
|
|
38
|
+
* in it read as left out, which is what null and false ask for. Anything else
|
|
39
|
+
* that isn't an object, `true` and an array included, is refused, since every
|
|
40
|
+
* setting in it would read as left out too, whatever it says.
|
|
41
|
+
*/
|
|
42
|
+
export function holdsSettings<T>(setting: string, value: T, example: string): value is NonNullable<T> {
|
|
43
|
+
if (value === undefined || value === null || value === false) return false;
|
|
44
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
45
|
+
throw new Error(`${setting} must be an object, such as ${example}, not ${kindOf(value)}`);
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** The longest delay one setTimeout holds (2^31 - 1 ms, about 24.8 days).
|
|
2
|
+
* Node fires a longer one almost at once, with a TimeoutOverflowWarning. */
|
|
3
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
4
|
+
|
|
5
|
+
type Hold = (timer: ReturnType<typeof setTimeout>) => void;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Call `fire` at `deadlineMs` (epoch ms) by the wall clock, through timers no
|
|
9
|
+
* longer than one holds, so a deadline weeks away fires then rather than at
|
|
10
|
+
* once. When a step ends, it reads the wall clock against the deadline and
|
|
11
|
+
* arms the next for what's left, so the steps' own delays don't add up, and a
|
|
12
|
+
* process that restarts and arms the same stored deadline aims at the same
|
|
13
|
+
* time. A step's own wait runs on Node's monotonic clock, so a change to the
|
|
14
|
+
* wall clock during a step is seen when that step ends. `hold` gets each
|
|
15
|
+
* step's timer: clearing the latest one stops the rest.
|
|
16
|
+
*/
|
|
17
|
+
export function armAt(deadlineMs: number, hold: Hold, fire: () => void): void {
|
|
18
|
+
const arm = (): void => {
|
|
19
|
+
// A deadline that has just passed arms a 0 ms step rather than a negative
|
|
20
|
+
// one, which Node 23 and later warn about.
|
|
21
|
+
hold(setTimeout(step, Math.min(Math.max(0, deadlineMs - Date.now()), MAX_TIMER_MS)));
|
|
22
|
+
};
|
|
23
|
+
const step = (): void => {
|
|
24
|
+
if (deadlineMs - Date.now() > 0) arm();
|
|
25
|
+
else fire();
|
|
26
|
+
};
|
|
27
|
+
arm();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Call `fire` after `delayMs`, counted on timers no longer than one holds, so
|
|
32
|
+
* a delay weeks long fires then rather than at once. The timers count the
|
|
33
|
+
* time, so setting the wall clock doesn't move it. `hold` gets each step's
|
|
34
|
+
* timer: clearing the latest one stops the rest.
|
|
35
|
+
*/
|
|
36
|
+
export function armAfter(delayMs: number, hold: Hold, fire: () => void): void {
|
|
37
|
+
let left = delayMs;
|
|
38
|
+
const arm = (): void => {
|
|
39
|
+
const step = Math.min(left, MAX_TIMER_MS);
|
|
40
|
+
left -= step;
|
|
41
|
+
hold(setTimeout(left > 0 ? arm : fire, step));
|
|
42
|
+
};
|
|
43
|
+
arm();
|
|
44
|
+
}
|