@animalabs/agent-framework 0.22.1 → 0.22.2
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 +1 -1
- package/dist/src/agent.d.ts +192 -19
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +404 -65
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/mcp-server-core.d.ts +41 -0
- package/dist/src/api/mcp-server-core.d.ts.map +1 -0
- package/dist/src/api/mcp-server-core.js +593 -0
- package/dist/src/api/mcp-server-core.js.map +1 -0
- package/dist/src/api/mcp-server.d.ts +2 -36
- package/dist/src/api/mcp-server.d.ts.map +1 -1
- package/dist/src/api/mcp-server.js +15 -595
- package/dist/src/api/mcp-server.js.map +1 -1
- package/dist/src/api/server.d.ts +9 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +50 -26
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/api/types.d.ts +9 -1
- package/dist/src/api/types.d.ts.map +1 -1
- package/dist/src/code-execution/py-runner.d.ts.map +1 -1
- package/dist/src/code-execution/py-runner.js.map +1 -1
- package/dist/src/framework.d.ts +393 -113
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +1748 -582
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/gate-script.d.ts.map +1 -1
- package/dist/src/gate/gate-script.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +26 -7
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +102 -22
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/errors.js.map +1 -1
- package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
- package/dist/src/mcpl/feature-set-manager.js +4 -3
- package/dist/src/mcpl/feature-set-manager.js.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/log-value.d.ts +54 -0
- package/dist/src/mcpl/log-value.d.ts.map +1 -0
- package/dist/src/mcpl/log-value.js +109 -0
- package/dist/src/mcpl/log-value.js.map +1 -0
- package/dist/src/mcpl/prose-stream-router.d.ts +6 -6
- package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -1
- package/dist/src/mcpl/prose-stream-router.js +4 -4
- package/dist/src/mcpl/prose-stream-router.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +38 -3
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +81 -16
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +26 -3
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +87 -23
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +2 -2
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/refusal-lines.d.ts +37 -0
- package/dist/src/mcpl/refusal-lines.d.ts.map +1 -0
- package/dist/src/mcpl/refusal-lines.js +61 -0
- package/dist/src/mcpl/refusal-lines.js.map +1 -0
- package/dist/src/mcpl/scope-manager.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +18 -2
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +66 -11
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/server-registry.d.ts.map +1 -1
- package/dist/src/mcpl/tool-classes.d.ts +1 -1
- package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
- package/dist/src/mcpl/tool-classes.js +3 -2
- package/dist/src/mcpl/tool-classes.js.map +1 -1
- package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
- package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
- package/dist/src/mcpl/transport.d.ts +23 -5
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +103 -10
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +30 -26
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/api/index.d.ts.map +1 -1
- package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
- package/dist/src/modules/discord/discord-js-client.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +4 -2
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/health/index.d.ts.map +1 -1
- package/dist/src/modules/health/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
- package/dist/src/modules/workspace/branch-intent.js.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.d.ts +22 -4
- package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +63 -25
- package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +8 -4
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +39 -12
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +43 -8
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +264 -39
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts +17 -1
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +57 -14
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +27 -2
- 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.map +1 -1
- package/dist/src/modules/workspace/watcher.js.map +1 -1
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/provider-waits.d.ts.map +1 -1
- package/dist/src/provider-waits.js.map +1 -1
- package/dist/src/queue.d.ts.map +1 -1
- package/dist/src/record-journal.d.ts.map +1 -1
- package/dist/src/record-journal.js.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +29 -24
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/runtime/liveness-watchdog.d.ts.map +1 -1
- package/dist/src/runtime/liveness-watchdog.js.map +1 -1
- package/dist/src/shutdown.d.ts.map +1 -1
- package/dist/src/shutdown.js.map +1 -1
- package/dist/src/stored-removal.d.ts +73 -0
- package/dist/src/stored-removal.d.ts.map +1 -0
- package/dist/src/stored-removal.js +100 -0
- package/dist/src/stored-removal.js.map +1 -0
- package/dist/src/thinking-token-stamp.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-presentation.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/tune-out/tools.d.ts +1 -1
- package/dist/src/tune-out/tools.d.ts.map +1 -1
- package/dist/src/types/agent.d.ts +42 -6
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +10 -0
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +8 -4
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +61 -10
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/test/agent-runtime-settings.test.js +1139 -3
- package/dist/test/agent-runtime-settings.test.js.map +1 -1
- package/dist/test/batched-wake-locus.test.js.map +1 -1
- package/dist/test/channel-label-history.test.js.map +1 -1
- package/dist/test/code-execution.test.js.map +1 -1
- package/dist/test/conversation-fork-injection-scoping.test.js.map +1 -1
- package/dist/test/conversation-router.test.js.map +1 -1
- package/dist/test/conversation-routing.test.js +240 -6
- package/dist/test/conversation-routing.test.js.map +1 -1
- package/dist/test/discord-awareness-outbox.test.js +104 -0
- package/dist/test/discord-awareness-outbox.test.js.map +1 -1
- package/dist/test/discord-typing-keepalive.test.d.ts +2 -0
- package/dist/test/discord-typing-keepalive.test.d.ts.map +1 -0
- package/dist/test/discord-typing-keepalive.test.js +77 -0
- package/dist/test/discord-typing-keepalive.test.js.map +1 -0
- package/dist/test/ephemeral-settle.test.js.map +1 -1
- package/dist/test/event-gate-passthrough.test.js.map +1 -1
- package/dist/test/event-gate-policy-mutation.test.js.map +1 -1
- package/dist/test/event-gate-rate-limit.test.js.map +1 -1
- package/dist/test/event-gate-script.test.js.map +1 -1
- package/dist/test/event-gate-selfwake.test.js.map +1 -1
- package/dist/test/event-gate-tags.test.js.map +1 -1
- package/dist/test/event-gate.test.js.map +1 -1
- package/dist/test/explicit-prose-routing.test.js +363 -42
- package/dist/test/explicit-prose-routing.test.js.map +1 -1
- package/dist/test/framework.test.js.map +1 -1
- package/dist/test/helpers/coalescing-fixture.d.ts +2 -0
- package/dist/test/helpers/coalescing-fixture.d.ts.map +1 -1
- package/dist/test/helpers/coalescing-fixture.js +8 -2
- package/dist/test/helpers/coalescing-fixture.js.map +1 -1
- package/dist/test/helpers/mock-membrane.d.ts.map +1 -1
- package/dist/test/helpers/mock-membrane.js.map +1 -1
- package/dist/test/hide-then-turn.test.d.ts +2 -0
- package/dist/test/hide-then-turn.test.d.ts.map +1 -0
- package/dist/test/hide-then-turn.test.js +101 -0
- package/dist/test/hide-then-turn.test.js.map +1 -0
- package/dist/test/history-module-overview.test.js.map +1 -1
- package/dist/test/history-module-semantic.test.js.map +1 -1
- package/dist/test/history-module.test.js.map +1 -1
- package/dist/test/history-semantic-review-findings.test.js.map +1 -1
- package/dist/test/host-quiesce.test.js +125 -0
- package/dist/test/host-quiesce.test.js.map +1 -1
- package/dist/test/inference-exhaustion-rewind.test.js +81 -3
- package/dist/test/inference-exhaustion-rewind.test.js.map +1 -1
- package/dist/test/inference-failure-bounds.test.js +1 -0
- package/dist/test/inference-failure-bounds.test.js.map +1 -1
- package/dist/test/kv-unified-open-flight-retry.test.js.map +1 -1
- package/dist/test/liveness-watchdog.test.js.map +1 -1
- package/dist/test/maintenance-timer.test.js +1564 -2
- package/dist/test/maintenance-timer.test.js.map +1 -1
- package/dist/test/mcp-server-bin.test.d.ts +2 -0
- package/dist/test/mcp-server-bin.test.d.ts.map +1 -0
- package/dist/test/mcp-server-bin.test.js +142 -0
- package/dist/test/mcp-server-bin.test.js.map +1 -0
- package/dist/test/mcpl-awareness-barrier.test.js.map +1 -1
- package/dist/test/mcpl-child-env.test.js +1 -1
- package/dist/test/mcpl-child-env.test.js.map +1 -1
- package/dist/test/mcpl-coalesced-content-parity.test.d.ts +2 -0
- package/dist/test/mcpl-coalesced-content-parity.test.d.ts.map +1 -0
- package/dist/test/mcpl-coalesced-content-parity.test.js +532 -0
- package/dist/test/mcpl-coalesced-content-parity.test.js.map +1 -0
- package/dist/test/mcpl-coalescing.test.js.map +1 -1
- package/dist/test/mcpl-config-diagnostics.test.js.map +1 -1
- package/dist/test/mcpl-gate-roundtrip.test.js.map +1 -1
- package/dist/test/mcpl-manifest-changed.test.js.map +1 -1
- package/dist/test/mcpl-reconnect-events.test.js.map +1 -1
- package/dist/test/mcpl-reconnect-reregistration.test.js +2 -0
- package/dist/test/mcpl-reconnect-reregistration.test.js.map +1 -1
- package/dist/test/mcpl-reference-fetcher.test.js.map +1 -1
- package/dist/test/mcpl-reference-fields.test.js.map +1 -1
- package/dist/test/mcpl-rejection-log-lines.test.d.ts +2 -0
- package/dist/test/mcpl-rejection-log-lines.test.d.ts.map +1 -0
- package/dist/test/mcpl-rejection-log-lines.test.js +349 -0
- package/dist/test/mcpl-rejection-log-lines.test.js.map +1 -0
- package/dist/test/mcpl-stderr-tail.test.d.ts +2 -0
- package/dist/test/mcpl-stderr-tail.test.d.ts.map +1 -0
- package/dist/test/mcpl-stderr-tail.test.js +210 -0
- package/dist/test/mcpl-stderr-tail.test.js.map +1 -0
- package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +1 -1
- package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +1 -1
- package/dist/test/mcpl-tool-lifecycle-script.test.js.map +1 -1
- package/dist/test/mcpl-tool-lifecycle.test.js.map +1 -1
- package/dist/test/mcpl-transport-close.test.d.ts +2 -0
- package/dist/test/mcpl-transport-close.test.d.ts.map +1 -0
- package/dist/test/mcpl-transport-close.test.js +373 -0
- package/dist/test/mcpl-transport-close.test.js.map +1 -0
- package/dist/test/mcpl-transport-spawn.test.d.ts +2 -0
- package/dist/test/mcpl-transport-spawn.test.d.ts.map +1 -0
- package/dist/test/mcpl-transport-spawn.test.js +58 -0
- package/dist/test/mcpl-transport-spawn.test.js.map +1 -0
- package/dist/test/mcpl-ws-transport.test.js +1 -0
- package/dist/test/mcpl-ws-transport.test.js.map +1 -1
- package/dist/test/offline-recovery-branch.test.js +344 -0
- package/dist/test/offline-recovery-branch.test.js.map +1 -1
- package/dist/test/operator-surgery.test.js +197 -0
- package/dist/test/operator-surgery.test.js.map +1 -1
- package/dist/test/overbudget-drain-breaker.test.js +1 -0
- package/dist/test/overbudget-drain-breaker.test.js.map +1 -1
- package/dist/test/pack-installs-alone.test.d.ts +2 -0
- package/dist/test/pack-installs-alone.test.d.ts.map +1 -0
- package/dist/test/pack-installs-alone.test.js +284 -0
- package/dist/test/pack-installs-alone.test.js.map +1 -0
- package/dist/test/physical-window-restart.test.d.ts +6 -4
- package/dist/test/physical-window-restart.test.d.ts.map +1 -1
- package/dist/test/physical-window-restart.test.js +275 -10
- package/dist/test/physical-window-restart.test.js.map +1 -1
- package/dist/test/placed-reaction-baseline.test.js.map +1 -1
- package/dist/test/present-while-acting.test.js +949 -6
- package/dist/test/present-while-acting.test.js.map +1 -1
- package/dist/test/provider-acceleration-cooldown.test.js.map +1 -1
- package/dist/test/provider-waits.test.js +67 -4
- package/dist/test/provider-waits.test.js.map +1 -1
- package/dist/test/puppet-tool-call.test.js +2 -0
- package/dist/test/puppet-tool-call.test.js.map +1 -1
- package/dist/test/reaction-baseline-platform.test.js.map +1 -1
- package/dist/test/record-journal.test.js.map +1 -1
- package/dist/test/refusal-rewind.test.js +9 -0
- package/dist/test/refusal-rewind.test.js.map +1 -1
- package/dist/test/refusal-single-call.test.js.map +1 -1
- package/dist/test/release-bump.test.d.ts +2 -0
- package/dist/test/release-bump.test.d.ts.map +1 -0
- package/dist/test/release-bump.test.js +248 -0
- package/dist/test/release-bump.test.js.map +1 -0
- package/dist/test/release-changelog.test.js.map +1 -1
- package/dist/test/release-holds.test.d.ts +2 -0
- package/dist/test/release-holds.test.d.ts.map +1 -0
- package/dist/test/release-holds.test.js +456 -0
- package/dist/test/release-holds.test.js.map +1 -0
- package/dist/test/same-round-think-policy.test.js.map +1 -1
- package/dist/test/shutdown-errors.test.js.map +1 -1
- package/dist/test/silent-heartbeat-rows.test.js.map +1 -1
- package/dist/test/stop-with-host-operations.test.d.ts +20 -0
- package/dist/test/stop-with-host-operations.test.d.ts.map +1 -0
- package/dist/test/stop-with-host-operations.test.js +1174 -0
- package/dist/test/stop-with-host-operations.test.js.map +1 -0
- package/dist/test/stop-with-work-in-flight.test.js +162 -50
- package/dist/test/stop-with-work-in-flight.test.js.map +1 -1
- package/dist/test/surgery-marks-receipt.test.js.map +1 -1
- package/dist/test/tool-batch-hook.test.js.map +1 -1
- package/dist/test/tool-result-guard.test.js +131 -9
- package/dist/test/tool-result-guard.test.js.map +1 -1
- package/dist/test/tool-result-spill.test.js.map +1 -1
- package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +1 -1
- package/dist/test/trunk-channel-routing.test.js +330 -7
- package/dist/test/trunk-channel-routing.test.js.map +1 -1
- package/dist/test/tune-out-e2e.test.js.map +1 -1
- package/dist/test/unconvertible-tool-result.test.js.map +1 -1
- package/dist/test/unsent-compiles.test.d.ts +2 -0
- package/dist/test/unsent-compiles.test.d.ts.map +1 -0
- package/dist/test/unsent-compiles.test.js +139 -0
- package/dist/test/unsent-compiles.test.js.map +1 -0
- package/dist/test/workspace-branch-continuation.test.js.map +1 -1
- package/dist/test/workspace-materialize-freshness.test.js.map +1 -1
- package/dist/test/workspace-read-text.test.js.map +1 -1
- package/dist/test/workspace-three-way.test.js +907 -7
- package/dist/test/workspace-three-way.test.js.map +1 -1
- package/dist/test/workspace-watcher.test.js.map +1 -1
- package/dist/test/xml-round-persist.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -6
- package/src/agent.ts +411 -66
- package/src/api/mcp-server-core.ts +681 -0
- package/src/api/mcp-server.ts +16 -685
- package/src/api/server.ts +51 -29
- package/src/api/types.ts +9 -1
- package/src/framework.ts +1899 -641
- package/src/index.ts +2 -2
- package/src/mcpl/channel-registry.ts +126 -31
- package/src/mcpl/feature-set-manager.ts +4 -3
- package/src/mcpl/log-value.ts +116 -0
- package/src/mcpl/prose-stream-router.ts +6 -6
- package/src/mcpl/push-coalescer.ts +76 -12
- package/src/mcpl/push-handler.ts +95 -23
- package/src/mcpl/refusal-lines.ts +59 -0
- package/src/mcpl/server-connection.ts +70 -11
- package/src/mcpl/tool-classes.ts +3 -2
- package/src/mcpl/transport.ts +105 -14
- package/src/mcpl/types.ts +5 -1
- package/src/modules/discord/index.ts +4 -2
- package/src/modules/workspace/disk-agreement.ts +74 -18
- package/src/modules/workspace/index.ts +41 -11
- package/src/modules/workspace/observe.ts +265 -39
- package/src/modules/workspace/reconcile.ts +71 -14
- package/src/modules/workspace/types.ts +26 -1
- package/src/recovery/offline-branch.ts +32 -28
- package/src/stored-removal.ts +126 -0
- package/src/types/agent.ts +42 -6
- package/src/types/framework.ts +10 -0
- package/src/types/module.ts +8 -4
- package/src/types/trace.ts +62 -11
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A value a connected server chose, as one field of a host log line.
|
|
3
|
+
*
|
|
4
|
+
* The rejection lines (`[channel-incoming-rejected]`, `[push-event-rejected]`)
|
|
5
|
+
* and the other host lines that name a server's own identifiers are read a
|
|
6
|
+
* line at a time, by eye and with grep. Printed raw, an identifier carrying a
|
|
7
|
+
* line break prints a second line that reads as another host record, about
|
|
8
|
+
* another server; one carrying a space can pose as another field of the same
|
|
9
|
+
* line; and one carrying `=` can hold a lookalike field (`reason=…`) that a
|
|
10
|
+
* search for that field finds before the real one.
|
|
11
|
+
*
|
|
12
|
+
* A plain token (visible characters only: no space, quote, backslash or `=`)
|
|
13
|
+
* prints as it is, so ordinary ids read and grep as they always have.
|
|
14
|
+
* Anything else prints as a JSON string with every `=` and every invisible
|
|
15
|
+
* character escaped: controls, format and bidi characters, line and paragraph
|
|
16
|
+
* separators, every space (the plain one included), default-ignorable
|
|
17
|
+
* characters (Hangul fillers, the combining grapheme joiner, variation
|
|
18
|
+
* selectors) and the blank Braille pattern. So it stays one field on one line,
|
|
19
|
+
* a reader that splits on whitespace keeps it whole, no field holds a raw
|
|
20
|
+
* `=` (so every `=` before a line's free-text tail, `logDetail`, belongs to
|
|
21
|
+
* a real field), and `JSON.parse` of a quoted value that isn't cut gives
|
|
22
|
+
* back exactly what was sent. Escaping rather than stripping keeps two
|
|
23
|
+
* identifiers that differ in invisible characters within the units a line
|
|
24
|
+
* prints from printing alike; canonically equivalent or lookalike
|
|
25
|
+
* identifiers still can.
|
|
26
|
+
*
|
|
27
|
+
* A value longer than 256 UTF-16 units is cut, so one value can't make a line
|
|
28
|
+
* long: it prints quoted, as its first 256 units (255 when the 256th is a
|
|
29
|
+
* high surrogate, so a pair is never split), each at most six characters once
|
|
30
|
+
* escaped, followed by `…(N)`, N being its full length. `JSON.parse` of the
|
|
31
|
+
* quoted part gives back those first units. A cut value always opens with a
|
|
32
|
+
* quote, and its marker follows the closing quote. A plain token never holds
|
|
33
|
+
* a quote, and a quoted value that isn't cut ends at its closing quote, so
|
|
34
|
+
* only a value that was cut prints as one.
|
|
35
|
+
*
|
|
36
|
+
* A value that isn't a string prints as its JSON text, quoted as any text is
|
|
37
|
+
* that isn't a plain token: the number 5 prints as `5`, and `{"toString":1}`
|
|
38
|
+
* as `"{\"toString\":1}"`. So the number 5 and the string "5" print alike, as
|
|
39
|
+
* they name the same message. A number JSON writes as `null` (NaN, Infinity)
|
|
40
|
+
* prints as `String()` of it. Converting a value never throws: one JSON can't
|
|
41
|
+
* write prints as `String()` of it, or else as its object tag, and one none
|
|
42
|
+
* of those can read (a revoked Proxy) as `[unprintable]`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function logValue(value: unknown): string;
|
|
45
|
+
/**
|
|
46
|
+
* The host's own message, as the free text that ends a log line after its
|
|
47
|
+
* fields: `reason=coalesce-invalid field=payload.content: "content must be an
|
|
48
|
+
* array"`. It prints as `logValue` prints a field, cut the same way, except
|
|
49
|
+
* that a plain space and `=` stay raw, for reading. That is safe because the
|
|
50
|
+
* text is the host's (an error the host raised), not an id a sender chose,
|
|
51
|
+
* and every real field of the line comes before it.
|
|
52
|
+
*/
|
|
53
|
+
export declare function logDetail(value: unknown): string;
|
|
54
|
+
//# sourceMappingURL=log-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-value.d.ts","sourceRoot":"","sources":["../../../src/mcpl/log-value.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE/C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A value a connected server chose, as one field of a host log line.
|
|
3
|
+
*
|
|
4
|
+
* The rejection lines (`[channel-incoming-rejected]`, `[push-event-rejected]`)
|
|
5
|
+
* and the other host lines that name a server's own identifiers are read a
|
|
6
|
+
* line at a time, by eye and with grep. Printed raw, an identifier carrying a
|
|
7
|
+
* line break prints a second line that reads as another host record, about
|
|
8
|
+
* another server; one carrying a space can pose as another field of the same
|
|
9
|
+
* line; and one carrying `=` can hold a lookalike field (`reason=…`) that a
|
|
10
|
+
* search for that field finds before the real one.
|
|
11
|
+
*
|
|
12
|
+
* A plain token (visible characters only: no space, quote, backslash or `=`)
|
|
13
|
+
* prints as it is, so ordinary ids read and grep as they always have.
|
|
14
|
+
* Anything else prints as a JSON string with every `=` and every invisible
|
|
15
|
+
* character escaped: controls, format and bidi characters, line and paragraph
|
|
16
|
+
* separators, every space (the plain one included), default-ignorable
|
|
17
|
+
* characters (Hangul fillers, the combining grapheme joiner, variation
|
|
18
|
+
* selectors) and the blank Braille pattern. So it stays one field on one line,
|
|
19
|
+
* a reader that splits on whitespace keeps it whole, no field holds a raw
|
|
20
|
+
* `=` (so every `=` before a line's free-text tail, `logDetail`, belongs to
|
|
21
|
+
* a real field), and `JSON.parse` of a quoted value that isn't cut gives
|
|
22
|
+
* back exactly what was sent. Escaping rather than stripping keeps two
|
|
23
|
+
* identifiers that differ in invisible characters within the units a line
|
|
24
|
+
* prints from printing alike; canonically equivalent or lookalike
|
|
25
|
+
* identifiers still can.
|
|
26
|
+
*
|
|
27
|
+
* A value longer than 256 UTF-16 units is cut, so one value can't make a line
|
|
28
|
+
* long: it prints quoted, as its first 256 units (255 when the 256th is a
|
|
29
|
+
* high surrogate, so a pair is never split), each at most six characters once
|
|
30
|
+
* escaped, followed by `…(N)`, N being its full length. `JSON.parse` of the
|
|
31
|
+
* quoted part gives back those first units. A cut value always opens with a
|
|
32
|
+
* quote, and its marker follows the closing quote. A plain token never holds
|
|
33
|
+
* a quote, and a quoted value that isn't cut ends at its closing quote, so
|
|
34
|
+
* only a value that was cut prints as one.
|
|
35
|
+
*
|
|
36
|
+
* A value that isn't a string prints as its JSON text, quoted as any text is
|
|
37
|
+
* that isn't a plain token: the number 5 prints as `5`, and `{"toString":1}`
|
|
38
|
+
* as `"{\"toString\":1}"`. So the number 5 and the string "5" print alike, as
|
|
39
|
+
* they name the same message. A number JSON writes as `null` (NaN, Infinity)
|
|
40
|
+
* prints as `String()` of it. Converting a value never throws: one JSON can't
|
|
41
|
+
* write prints as `String()` of it, or else as its object tag, and one none
|
|
42
|
+
* of those can read (a revoked Proxy) as `[unprintable]`.
|
|
43
|
+
*/
|
|
44
|
+
export function logValue(value) {
|
|
45
|
+
return printed(textOf(value), FIELD);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The host's own message, as the free text that ends a log line after its
|
|
49
|
+
* fields: `reason=coalesce-invalid field=payload.content: "content must be an
|
|
50
|
+
* array"`. It prints as `logValue` prints a field, cut the same way, except
|
|
51
|
+
* that a plain space and `=` stay raw, for reading. That is safe because the
|
|
52
|
+
* text is the host's (an error the host raised), not an id a sender chose,
|
|
53
|
+
* and every real field of the line comes before it.
|
|
54
|
+
*/
|
|
55
|
+
export function logDetail(value) {
|
|
56
|
+
return printed(textOf(value), DETAIL);
|
|
57
|
+
}
|
|
58
|
+
const FIELD = {
|
|
59
|
+
plain: /^[^"\\=\p{C}\p{Z}\p{Default_Ignorable_Code_Point}\u2800]+$/u,
|
|
60
|
+
escaped: /[=\p{C}\p{Z}\p{Default_Ignorable_Code_Point}\u2800]/gu,
|
|
61
|
+
};
|
|
62
|
+
const DETAIL = {
|
|
63
|
+
plain: /^[^"\\\p{C}\p{Z}\p{Default_Ignorable_Code_Point}\u2800]+$/u,
|
|
64
|
+
escaped: /(?! )[\p{C}\p{Z}\p{Default_Ignorable_Code_Point}\u2800]/gu,
|
|
65
|
+
};
|
|
66
|
+
/** The most of a value's text a line prints, in UTF-16 units. */
|
|
67
|
+
const MAX_PRINTED = 256;
|
|
68
|
+
function printed(text, form) {
|
|
69
|
+
if (text.length <= MAX_PRINTED)
|
|
70
|
+
return form.plain.test(text) ? text : quoted(text, form);
|
|
71
|
+
let end = MAX_PRINTED;
|
|
72
|
+
const last = text.charCodeAt(end - 1);
|
|
73
|
+
if (last >= 0xd800 && last <= 0xdbff)
|
|
74
|
+
end--;
|
|
75
|
+
return `${quoted(text.slice(0, end), form)}…(${text.length})`;
|
|
76
|
+
}
|
|
77
|
+
function quoted(text, form) {
|
|
78
|
+
// JSON escapes C0 controls, quotes and backslashes and leaves the rest of
|
|
79
|
+
// the escaped set raw: escape those here, per UTF-16 unit, as JSON does.
|
|
80
|
+
return JSON.stringify(text).replace(form.escaped, escapeUnits);
|
|
81
|
+
}
|
|
82
|
+
function textOf(value) {
|
|
83
|
+
if (typeof value === 'string')
|
|
84
|
+
return value;
|
|
85
|
+
// JSON writes a non-finite number as null, which reads as a missing value.
|
|
86
|
+
if (typeof value === 'number' && !Number.isFinite(value))
|
|
87
|
+
return String(value);
|
|
88
|
+
const readers = [
|
|
89
|
+
() => JSON.stringify(value) ?? String(value),
|
|
90
|
+
() => String(value),
|
|
91
|
+
() => Object.prototype.toString.call(value),
|
|
92
|
+
];
|
|
93
|
+
for (const read of readers) {
|
|
94
|
+
try {
|
|
95
|
+
return read();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// the next reader
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return '[unprintable]';
|
|
102
|
+
}
|
|
103
|
+
function escapeUnits(chars) {
|
|
104
|
+
let out = '';
|
|
105
|
+
for (let i = 0; i < chars.length; i++)
|
|
106
|
+
out += `\\u${chars.charCodeAt(i).toString(16).padStart(4, '0')}`;
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=log-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-value.js","sourceRoot":"","sources":["../../../src/mcpl/log-value.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAQD,MAAM,KAAK,GAAS;IAClB,KAAK,EAAE,6DAA6D;IACpE,OAAO,EAAE,uDAAuD;CACjE,CAAC;AAEF,MAAM,MAAM,GAAS;IACnB,KAAK,EAAE,4DAA4D;IACnE,OAAO,EAAE,2DAA2D;CACrE,CAAC;AAEF,iEAAiE;AACjE,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,SAAS,OAAO,CAAC,IAAY,EAAE,IAAU;IACvC,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzF,IAAI,GAAG,GAAG,WAAW,CAAC;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACtC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM;QAAE,GAAG,EAAE,CAAC;IAC5C,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC;AAChE,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,IAAU;IACtC,0EAA0E;IAC1E,yEAAyE;IACzE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,2EAA2E;IAC3E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG;QACd,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC;QAC5C,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;QACnB,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;KAC5C,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACxG,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
*
|
|
22
22
|
* Three modes, mirroring proseRouting:
|
|
23
23
|
* - explicit: parse `>>` prefixes. A fresh turn's stream starts suppressed;
|
|
24
|
-
*
|
|
25
|
-
* each round's end returns the stream to it (retarget).
|
|
26
|
-
* - hybrid: parse `>>>` envelopes, with the
|
|
24
|
+
* a later stream of the turn starts at the turn's destination,
|
|
25
|
+
* and each round's end returns the stream to it (retarget).
|
|
26
|
+
* - hybrid: parse `>>>` envelopes, with the turn's locus as the
|
|
27
27
|
* fallback. An envelope with no target, or `>>>skip_reply`,
|
|
28
28
|
* holds back what follows until a later `>>>` names a target.
|
|
29
29
|
* - locus: NO prefix parsing (locus mode's `>>` lines are plain text);
|
|
30
|
-
* everything streams to the
|
|
30
|
+
* everything streams to the turn's locus.
|
|
31
31
|
*/
|
|
32
32
|
export interface RoutedDelta {
|
|
33
33
|
channelId: string;
|
|
@@ -44,9 +44,9 @@ export declare class ProseStreamRouter {
|
|
|
44
44
|
constructor(opts: {
|
|
45
45
|
/** explicit parses `>>`; hybrid parses `>>>` while retaining locus fallback. */
|
|
46
46
|
mode: 'explicit' | 'hybrid' | 'locus';
|
|
47
|
-
/** Initial destination: the
|
|
47
|
+
/** Initial destination: the turn's locus (locus and hybrid mode); in
|
|
48
48
|
* explicit mode, null on a fresh turn, or the turn's destination on a
|
|
49
|
-
* stream
|
|
49
|
+
* later stream of the turn. */
|
|
50
50
|
initialTarget: string | null;
|
|
51
51
|
/** Resolve a `>>spec` to a channelId, or null (unresolved/ambiguous). */
|
|
52
52
|
resolve: (spec: string) => string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prose-stream-router.d.ts","sourceRoot":"","sources":["../../../src/mcpl/prose-stream-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,qBAAa,iBAAiB;IAS1B,OAAO,CAAC,IAAI;IARd,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA6B;
|
|
1
|
+
{"version":3,"file":"prose-stream-router.d.ts","sourceRoot":"","sources":["../../../src/mcpl/prose-stream-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,qBAAa,iBAAiB;IAS1B,OAAO,CAAC,IAAI;IARd,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA6B;IAEhD,YACU,IAAI,EAAE;QACZ,gFAAgF;QAChF,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;QACtC;;wCAEgC;QAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,yEAAyE;QACzE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;KAC1C,EAIF;IAED,oEAAoE;IACpE,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAEvC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEpC;IAED;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI,CAOZ;IAED,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAIjC;IAED;;;;;;OAMG;IACH,UAAU,IAAI,WAAW,EAAE,CAkB1B;IAED,4CAA4C;IAC5C,MAAM,IAAI,WAAW,EAAE,CAEtB;IAED,OAAO,CAAC,IAAI;IA4GZ,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,IAAI;CAKb"}
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
*
|
|
22
22
|
* Three modes, mirroring proseRouting:
|
|
23
23
|
* - explicit: parse `>>` prefixes. A fresh turn's stream starts suppressed;
|
|
24
|
-
*
|
|
25
|
-
* each round's end returns the stream to it (retarget).
|
|
26
|
-
* - hybrid: parse `>>>` envelopes, with the
|
|
24
|
+
* a later stream of the turn starts at the turn's destination,
|
|
25
|
+
* and each round's end returns the stream to it (retarget).
|
|
26
|
+
* - hybrid: parse `>>>` envelopes, with the turn's locus as the
|
|
27
27
|
* fallback. An envelope with no target, or `>>>skip_reply`,
|
|
28
28
|
* holds back what follows until a later `>>>` names a target.
|
|
29
29
|
* - locus: NO prefix parsing (locus mode's `>>` lines are plain text);
|
|
30
|
-
* everything streams to the
|
|
30
|
+
* everything streams to the turn's locus.
|
|
31
31
|
*/
|
|
32
32
|
/** Whitespace as the delivery path reads it (`trimStart()`, `\s`, `\S`). */
|
|
33
33
|
const isSpace = (ch) => /\s/.test(ch);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prose-stream-router.js","sourceRoot":"","sources":["../../../src/mcpl/prose-stream-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AASH,4EAA4E;AAC5E,MAAM,OAAO,GAAG,CAAC,EAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEvD,MAAM,OAAO,iBAAiB;IASlB;
|
|
1
|
+
{"version":3,"file":"prose-stream-router.js","sourceRoot":"","sources":["../../../src/mcpl/prose-stream-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,13 +25,22 @@ export declare const PUSH_COALESCING_SUPPORT: {
|
|
|
25
25
|
readonly channelScopedPush: true;
|
|
26
26
|
readonly retryWindowMs: 3600000;
|
|
27
27
|
};
|
|
28
|
-
export declare const COALESCE_OUTCOMES: readonly [
|
|
28
|
+
export declare const COALESCE_OUTCOMES: readonly ['first', 'replaced', 'appended', 'retracted', 'noted', 'consumed'];
|
|
29
29
|
export type CoalesceOutcome = typeof COALESCE_OUTCOMES[number];
|
|
30
30
|
export declare class CoalesceError extends Error {
|
|
31
31
|
readonly field: string;
|
|
32
32
|
readonly code: number;
|
|
33
33
|
constructor(field: string, message: string, code?: number);
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* How the host names a coalesce rejection, from the code the wire answered
|
|
37
|
+
* with. `coalesce-failed` is the host's own failure: -32000 (coalescing
|
|
38
|
+
* unavailable, the host stopping, or an acceptance it couldn't make durable)
|
|
39
|
+
* and -32603 (an internal error). `coalesce-invalid` is every other answer,
|
|
40
|
+
* the sender's: -32602 for a malformed item, -32017 or -32023 for a channel
|
|
41
|
+
* that isn't permitted or isn't registered.
|
|
42
|
+
*/
|
|
43
|
+
export declare function coalesceRejectionReason(answered: number): 'coalesce-failed' | 'coalesce-invalid';
|
|
35
44
|
/** Content with nothing model-visible (see visible-content.ts): -32602. */
|
|
36
45
|
export declare class EmptyContentError extends CoalesceError {
|
|
37
46
|
readonly reason = "empty-content";
|
|
@@ -227,7 +236,6 @@ export interface CoalescerOptions {
|
|
|
227
236
|
recoveryBackoffMs?: number;
|
|
228
237
|
maxSubjects?: number;
|
|
229
238
|
maxNotices?: number;
|
|
230
|
-
maxContentBytes?: number;
|
|
231
239
|
maxDataBytes?: number;
|
|
232
240
|
}
|
|
233
241
|
export declare function coalescingSubjectKey(serverId: string, binding: string, scope: CoalescingScope, key: string): string;
|
|
@@ -235,14 +243,41 @@ export declare function coalescingReceiptKey(serverId: string, binding: string,
|
|
|
235
243
|
/**
|
|
236
244
|
* Validate wire content before it is stored, rendered or converted.
|
|
237
245
|
*
|
|
246
|
+
* Its shape and its visible emptiness, nothing else. An incoming coalesced
|
|
247
|
+
* occurrence reaches context through the converters an uncoalesced message
|
|
248
|
+
* goes through: a plain occurrence the moment it is admitted (the coalescer
|
|
249
|
+
* only remembers where it landed), a deferred one when its render settles or
|
|
250
|
+
* falls back to it. Its content must be an array of objects. A block the
|
|
251
|
+
* converters can't render (a video, an unknown type, an image with neither
|
|
252
|
+
* uri nor data) becomes a placeholder, as it does uncoalesced, and so does a
|
|
253
|
+
* malformed one, since the converters take any object without throwing: a
|
|
254
|
+
* type, text, data, mimeType or uri that isn't a string counts as absent, a
|
|
255
|
+
* text block's as no text. The uncoalesced lane doesn't check the array:
|
|
256
|
+
* there a member that isn't an object becomes the untyped placeholder, and a
|
|
257
|
+
* null member or content that isn't an array throws in conversion
|
|
258
|
+
* (agent-framework#297 brings that lane to this rule).
|
|
259
|
+
* Nor does the uncoalesced path set a byte budget on content:
|
|
260
|
+
* an inline image is admitted here as it is there (agent-framework#266: a
|
|
261
|
+
* 1 MiB serialized-content budget here dropped every coalesced message
|
|
262
|
+
* carrying a screenshot). A deferred occurrence's content is held, until then,
|
|
263
|
+
* in the coalescer's state and its persisted snapshot and receipts.
|
|
264
|
+
*
|
|
265
|
+
* A render result, which the host delivers in the occurrence's place, gets
|
|
266
|
+
* these checks, as RFC-006 §5.2 gives it every check a pushed payload gets,
|
|
267
|
+
* and one more (`checkBlockShapes`): each block must be one the converters
|
|
268
|
+
* show as itself or as a reference stub, not as a placeholder. A malformed
|
|
269
|
+
* render falls back to the occurrence's own content; a pushed payload has
|
|
270
|
+
* nothing to fall back to, and gets its placeholders.
|
|
271
|
+
*
|
|
238
272
|
* Visibly-empty content is refused unless `allowEmpty`: an admitted
|
|
239
273
|
* occurrence with nothing to show would wake the model with no visible cause.
|
|
240
274
|
* Empty is legitimate only where the RFC gives it a meaning — a retraction
|
|
241
275
|
* with nothing to announce (§6) and a render result that says nothing
|
|
242
276
|
* happened (§5.2) — and for the silent-heartbeat marker.
|
|
243
277
|
*/
|
|
244
|
-
export declare function validateCoalescedContent(content: unknown,
|
|
278
|
+
export declare function validateCoalescedContent(content: unknown, options?: {
|
|
245
279
|
allowEmpty?: boolean;
|
|
280
|
+
checkBlockShapes?: boolean;
|
|
246
281
|
}): asserts content is McplContentBlock[];
|
|
247
282
|
/** Validate the `coalesce` member of either lane (§13). */
|
|
248
283
|
export declare function validateCoalesceMember(c: unknown, lane: 'push' | 'channel', maxDataBytes?: number): asserts c is NonNullable<import('./types.js').PushEventParams['coalesce']>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push-coalescer.d.ts","sourceRoot":"","sources":["../../../src/mcpl/push-coalescer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"push-coalescer.d.ts","sourceRoot":"","sources":["../../../src/mcpl/push-coalescer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classifyBlock, isInlineContradiction } from './references.js';
|
|
1
2
|
import { isVisiblyEmptyContent } from './visible-content.js';
|
|
2
3
|
export const PUSH_COALESCING_SUPPORT = {
|
|
3
4
|
pushEvents: true, channelsIncoming: true, deferred: true, channelScopedPush: true,
|
|
@@ -16,6 +17,17 @@ export class CoalesceError extends Error {
|
|
|
16
17
|
this.name = 'CoalesceError';
|
|
17
18
|
}
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* How the host names a coalesce rejection, from the code the wire answered
|
|
22
|
+
* with. `coalesce-failed` is the host's own failure: -32000 (coalescing
|
|
23
|
+
* unavailable, the host stopping, or an acceptance it couldn't make durable)
|
|
24
|
+
* and -32603 (an internal error). `coalesce-invalid` is every other answer,
|
|
25
|
+
* the sender's: -32602 for a malformed item, -32017 or -32023 for a channel
|
|
26
|
+
* that isn't permitted or isn't registered.
|
|
27
|
+
*/
|
|
28
|
+
export function coalesceRejectionReason(answered) {
|
|
29
|
+
return answered === -32000 || answered === -32603 ? 'coalesce-failed' : 'coalesce-invalid';
|
|
30
|
+
}
|
|
19
31
|
/** Content with nothing model-visible (see visible-content.ts): -32602. */
|
|
20
32
|
export class EmptyContentError extends CoalesceError {
|
|
21
33
|
reason = 'empty-content';
|
|
@@ -41,32 +53,76 @@ function mergeIdentity(prior, next) {
|
|
|
41
53
|
/**
|
|
42
54
|
* Validate wire content before it is stored, rendered or converted.
|
|
43
55
|
*
|
|
56
|
+
* Its shape and its visible emptiness, nothing else. An incoming coalesced
|
|
57
|
+
* occurrence reaches context through the converters an uncoalesced message
|
|
58
|
+
* goes through: a plain occurrence the moment it is admitted (the coalescer
|
|
59
|
+
* only remembers where it landed), a deferred one when its render settles or
|
|
60
|
+
* falls back to it. Its content must be an array of objects. A block the
|
|
61
|
+
* converters can't render (a video, an unknown type, an image with neither
|
|
62
|
+
* uri nor data) becomes a placeholder, as it does uncoalesced, and so does a
|
|
63
|
+
* malformed one, since the converters take any object without throwing: a
|
|
64
|
+
* type, text, data, mimeType or uri that isn't a string counts as absent, a
|
|
65
|
+
* text block's as no text. The uncoalesced lane doesn't check the array:
|
|
66
|
+
* there a member that isn't an object becomes the untyped placeholder, and a
|
|
67
|
+
* null member or content that isn't an array throws in conversion
|
|
68
|
+
* (agent-framework#297 brings that lane to this rule).
|
|
69
|
+
* Nor does the uncoalesced path set a byte budget on content:
|
|
70
|
+
* an inline image is admitted here as it is there (agent-framework#266: a
|
|
71
|
+
* 1 MiB serialized-content budget here dropped every coalesced message
|
|
72
|
+
* carrying a screenshot). A deferred occurrence's content is held, until then,
|
|
73
|
+
* in the coalescer's state and its persisted snapshot and receipts.
|
|
74
|
+
*
|
|
75
|
+
* A render result, which the host delivers in the occurrence's place, gets
|
|
76
|
+
* these checks, as RFC-006 §5.2 gives it every check a pushed payload gets,
|
|
77
|
+
* and one more (`checkBlockShapes`): each block must be one the converters
|
|
78
|
+
* show as itself or as a reference stub, not as a placeholder. A malformed
|
|
79
|
+
* render falls back to the occurrence's own content; a pushed payload has
|
|
80
|
+
* nothing to fall back to, and gets its placeholders.
|
|
81
|
+
*
|
|
44
82
|
* Visibly-empty content is refused unless `allowEmpty`: an admitted
|
|
45
83
|
* occurrence with nothing to show would wake the model with no visible cause.
|
|
46
84
|
* Empty is legitimate only where the RFC gives it a meaning — a retraction
|
|
47
85
|
* with nothing to announce (§6) and a render result that says nothing
|
|
48
86
|
* happened (§5.2) — and for the silent-heartbeat marker.
|
|
49
87
|
*/
|
|
50
|
-
export function validateCoalescedContent(content,
|
|
88
|
+
export function validateCoalescedContent(content, options = {}) {
|
|
51
89
|
if (!Array.isArray(content))
|
|
52
90
|
throw new CoalesceError('payload.content', 'content must be an array');
|
|
53
91
|
for (const b of content) {
|
|
54
92
|
if (!b || typeof b !== 'object' || Array.isArray(b))
|
|
55
93
|
throw new CoalesceError('payload.content', 'invalid content block');
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
continue;
|
|
60
|
-
if ((b.type === 'image' || b.type === 'audio')
|
|
61
|
-
&& (typeof b.uri === 'string' || (typeof b.data === 'string' && typeof b.mimeType === 'string')))
|
|
62
|
-
continue;
|
|
63
|
-
throw new CoalesceError('payload.content', 'invalid content block');
|
|
64
|
-
}
|
|
65
|
-
if (Buffer.byteLength(JSON.stringify(content)) > maxBytes)
|
|
66
|
-
throw new CoalesceError('payload.content', 'content exceeds host byte limit');
|
|
94
|
+
if (options.checkBlockShapes && !showsAsItself(b))
|
|
95
|
+
throw new CoalesceError('payload.content', 'invalid content block');
|
|
96
|
+
}
|
|
67
97
|
if (!options.allowEmpty && isVisiblyEmptyContent(content))
|
|
68
98
|
throw new EmptyContentError();
|
|
69
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Whether the converters (`convertBlock` in push-handler.ts and
|
|
102
|
+
* channel-registry.ts) show a block as itself, its text or its image or
|
|
103
|
+
* audio source, or as a reference stub, and not as a placeholder: an
|
|
104
|
+
* unrecognized block, a no-data or no-media-type one, or withheld inline
|
|
105
|
+
* data. A text block whose text isn't a string, which they show as no text,
|
|
106
|
+
* is refused too. This follows their branches in their order.
|
|
107
|
+
*/
|
|
108
|
+
function showsAsItself(b) {
|
|
109
|
+
if (b.type === 'text')
|
|
110
|
+
return typeof b.text === 'string';
|
|
111
|
+
if (b.type === 'resource')
|
|
112
|
+
return classifyBlock(b).kind === 'reference';
|
|
113
|
+
if (b.type !== 'image' && b.type !== 'audio')
|
|
114
|
+
return false;
|
|
115
|
+
if (isInlineContradiction(b))
|
|
116
|
+
return false;
|
|
117
|
+
if (isFilledString(b.uri) && b.disposition)
|
|
118
|
+
return classifyBlock(b).kind === 'reference';
|
|
119
|
+
if (isFilledString(b.data) && isFilledString(b.mimeType))
|
|
120
|
+
return true;
|
|
121
|
+
return b.type === 'image' && isFilledString(b.uri);
|
|
122
|
+
}
|
|
123
|
+
function isFilledString(value) {
|
|
124
|
+
return typeof value === 'string' && value !== '';
|
|
125
|
+
}
|
|
70
126
|
/** Validate the `coalesce` member of either lane (§13). */
|
|
71
127
|
export function validateCoalesceMember(c, lane, maxDataBytes = 4096) {
|
|
72
128
|
if (!c || typeof c !== 'object' || Array.isArray(c))
|
|
@@ -546,9 +602,10 @@ export class PushCoalescer {
|
|
|
546
602
|
if (rendering.cancelled) {
|
|
547
603
|
this.host.audit({ kind: 'late-render', subject, eventId: occurrence.eventId, discarded: true });
|
|
548
604
|
}
|
|
549
|
-
// §5.2: an empty result is legitimate ("nothing happened")
|
|
605
|
+
// §5.2: an empty result is legitimate ("nothing happened"); each
|
|
606
|
+
// block must be well formed.
|
|
550
607
|
else
|
|
551
|
-
validateCoalescedContent(result?.content,
|
|
608
|
+
validateCoalescedContent(result?.content, { allowEmpty: true, checkBlockShapes: true });
|
|
552
609
|
if (rendering.cancelled)
|
|
553
610
|
throw new CancelledRender();
|
|
554
611
|
content = result.content;
|
|
@@ -556,8 +613,16 @@ export class PushCoalescer {
|
|
|
556
613
|
source = 'render';
|
|
557
614
|
}
|
|
558
615
|
catch (error) {
|
|
559
|
-
if (!(error instanceof CancelledRender))
|
|
560
|
-
|
|
616
|
+
if (!(error instanceof CancelledRender)) {
|
|
617
|
+
// The occurrence's own content is delivered instead; the host names
|
|
618
|
+
// the failure where operators look (a console line, not only this
|
|
619
|
+
// audit record).
|
|
620
|
+
this.host.audit({
|
|
621
|
+
kind: 'render-failed', subject, serverId: occurrence.serverId, eventId: occurrence.eventId,
|
|
622
|
+
...(error instanceof CoalesceError ? { field: error.field } : {}),
|
|
623
|
+
error: String(error),
|
|
624
|
+
});
|
|
625
|
+
}
|
|
561
626
|
}
|
|
562
627
|
finally {
|
|
563
628
|
const left = (this.rendersInFlight.get(occurrence.serverId) ?? 1) - 1;
|