@animalabs/agent-framework 0.23.3 → 0.24.1
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 +212 -42
- package/dist/src/agent.d.ts +65 -9
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +98 -12
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +14 -12
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/clock-rows.d.ts +115 -0
- package/dist/src/clock-rows.d.ts.map +1 -0
- package/dist/src/clock-rows.js +222 -0
- package/dist/src/clock-rows.js.map +1 -0
- package/dist/src/code-execution/engine.d.ts +177 -0
- package/dist/src/code-execution/engine.d.ts.map +1 -0
- package/dist/src/code-execution/engine.js +494 -0
- package/dist/src/code-execution/engine.js.map +1 -0
- package/dist/src/code-execution/index.d.ts +5 -10
- package/dist/src/code-execution/index.d.ts.map +1 -1
- package/dist/src/code-execution/index.js +5 -9
- package/dist/src/code-execution/index.js.map +1 -1
- package/dist/src/code-execution/isolate/calls.d.ts +114 -0
- package/dist/src/code-execution/isolate/calls.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/calls.js +145 -0
- package/dist/src/code-execution/isolate/calls.js.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts +2 -0
- package/dist/src/code-execution/isolate/child-entry.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-entry.js +5 -0
- package/dist/src/code-execution/isolate/child-entry.js.map +1 -0
- package/dist/src/code-execution/isolate/child-main.d.ts +26 -0
- package/dist/src/code-execution/isolate/child-main.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child-main.js +132 -0
- package/dist/src/code-execution/isolate/child-main.js.map +1 -0
- package/dist/src/code-execution/isolate/child.d.ts +44 -0
- package/dist/src/code-execution/isolate/child.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/child.js +315 -0
- package/dist/src/code-execution/isolate/child.js.map +1 -0
- package/dist/src/code-execution/isolate/frames.d.ts +80 -0
- package/dist/src/code-execution/isolate/frames.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/frames.js +210 -0
- package/dist/src/code-execution/isolate/frames.js.map +1 -0
- package/dist/src/code-execution/isolate/output.d.ts +68 -0
- package/dist/src/code-execution/isolate/output.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/output.js +143 -0
- package/dist/src/code-execution/isolate/output.js.map +1 -0
- package/dist/src/code-execution/isolate/prelude.d.ts +109 -0
- package/dist/src/code-execution/isolate/prelude.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/prelude.js +401 -0
- package/dist/src/code-execution/isolate/prelude.js.map +1 -0
- package/dist/src/code-execution/isolate/protocol.d.ts +151 -0
- package/dist/src/code-execution/isolate/protocol.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/protocol.js +150 -0
- package/dist/src/code-execution/isolate/protocol.js.map +1 -0
- package/dist/src/code-execution/isolate/render.d.ts +57 -0
- package/dist/src/code-execution/isolate/render.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/render.js +214 -0
- package/dist/src/code-execution/isolate/render.js.map +1 -0
- package/dist/src/code-execution/isolate/runner.d.ts +250 -0
- package/dist/src/code-execution/isolate/runner.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/runner.js +854 -0
- package/dist/src/code-execution/isolate/runner.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +175 -0
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -0
- package/dist/src/code-execution/isolate/scripts.js +357 -0
- package/dist/src/code-execution/isolate/scripts.js.map +1 -0
- package/dist/src/code-execution/quickjs.wasm +0 -0
- package/dist/src/code-execution/tool-definition.d.ts +93 -43
- package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
- package/dist/src/code-execution/tool-definition.js +176 -142
- package/dist/src/code-execution/tool-definition.js.map +1 -1
- package/dist/src/deadline-timer.d.ts +3 -0
- package/dist/src/deadline-timer.d.ts.map +1 -1
- package/dist/src/deadline-timer.js +1 -1
- package/dist/src/deadline-timer.js.map +1 -1
- package/dist/src/framework.d.ts +1120 -457
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +4635 -2505
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +28 -4
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +89 -13
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/held-writes.d.ts +16 -3
- package/dist/src/held-writes.d.ts.map +1 -1
- package/dist/src/held-writes.js +16 -3
- package/dist/src/held-writes.js.map +1 -1
- package/dist/src/index.d.ts +8 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/channel-registry.d.ts +483 -115
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +1735 -425
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/conversation-router.d.ts +19 -39
- package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
- package/dist/src/mcpl/conversation-router.js +27 -59
- package/dist/src/mcpl/conversation-router.js.map +1 -1
- package/dist/src/mcpl/convert-block.d.ts.map +1 -1
- package/dist/src/mcpl/convert-block.js +9 -5
- package/dist/src/mcpl/convert-block.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +50 -0
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +130 -0
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +2 -1
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js +3 -2
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/log-value.d.ts +6 -0
- package/dist/src/mcpl/log-value.d.ts.map +1 -1
- package/dist/src/mcpl/log-value.js +8 -0
- package/dist/src/mcpl/log-value.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +15 -6
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +168 -53
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/prose-grammar.d.ts +4 -5
- package/dist/src/mcpl/prose-grammar.d.ts.map +1 -1
- package/dist/src/mcpl/prose-grammar.js +4 -5
- package/dist/src/mcpl/prose-grammar.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +97 -10
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +174 -17
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +132 -14
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +227 -50
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +9 -20
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +7 -49
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +2 -2
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +4 -4
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +50 -21
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +158 -74
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tags.d.ts +24 -0
- package/dist/src/mcpl/tags.d.ts.map +1 -1
- package/dist/src/mcpl/tags.js +33 -0
- package/dist/src/mcpl/tags.js.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts +2 -1
- package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -1
- package/dist/src/mcpl/tool-result-normalize.js.map +1 -1
- package/dist/src/mcpl/transport.d.ts +55 -7
- package/dist/src/mcpl/transport.d.ts.map +1 -1
- package/dist/src/mcpl/transport.js +163 -34
- package/dist/src/mcpl/transport.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +22 -6
- 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 +4 -2
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +100 -13
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +8 -13
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +27 -4
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +15 -3
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +27 -5
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/index.d.ts +1 -1
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/unknown-tool.d.ts +4 -1
- package/dist/src/modules/unknown-tool.d.ts.map +1 -1
- package/dist/src/modules/unknown-tool.js +4 -1
- package/dist/src/modules/unknown-tool.js.map +1 -1
- package/dist/src/modules/workspace/branch-intent.d.ts +3 -1
- package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
- package/dist/src/modules/workspace/branch-intent.js +3 -1
- package/dist/src/modules/workspace/branch-intent.js.map +1 -1
- package/dist/src/modules/workspace/edit-plan.d.ts +265 -0
- package/dist/src/modules/workspace/edit-plan.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-plan.js +794 -0
- package/dist/src/modules/workspace/edit-plan.js.map +1 -0
- package/dist/src/modules/workspace/edit-text.d.ts +117 -0
- package/dist/src/modules/workspace/edit-text.d.ts.map +1 -0
- package/dist/src/modules/workspace/edit-text.js +584 -0
- package/dist/src/modules/workspace/edit-text.js.map +1 -0
- package/dist/src/modules/workspace/effects.d.ts +5 -4
- package/dist/src/modules/workspace/effects.d.ts.map +1 -1
- package/dist/src/modules/workspace/effects.js +78 -25
- package/dist/src/modules/workspace/effects.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +493 -62
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +2216 -652
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +213 -38
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +416 -36
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +15 -8
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/modules/workspace/text.d.ts +32 -0
- package/dist/src/modules/workspace/text.d.ts.map +1 -0
- package/dist/src/modules/workspace/text.js +67 -0
- package/dist/src/modules/workspace/text.js.map +1 -0
- package/dist/src/modules/workspace/types.d.ts +210 -6
- 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 +3 -2
- 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 +52 -24
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.d.ts +496 -72
- package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
- package/dist/src/recovery/discord-awareness-outbox.js +1196 -289
- package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
- package/dist/src/recovery/offline-branch.d.ts +26 -1
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +164 -39
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +23 -4
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/send-tools.d.ts +11 -0
- package/dist/src/send-tools.d.ts.map +1 -0
- package/dist/src/send-tools.js +11 -0
- package/dist/src/send-tools.js.map +1 -0
- package/dist/src/timezone.d.ts +4 -2
- package/dist/src/timezone.d.ts.map +1 -1
- package/dist/src/timezone.js +4 -2
- package/dist/src/timezone.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts +46 -7
- package/dist/src/tool-image-ledger.d.ts.map +1 -1
- package/dist/src/tool-image-ledger.js +60 -7
- package/dist/src/tool-image-ledger.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts +14 -11
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +17 -14
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tool-result-history.d.ts +3 -2
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +3 -2
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +21 -0
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +142 -40
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/types/agent.d.ts +31 -6
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +66 -9
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +69 -62
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +40 -8
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +111 -10
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/src/usage/types.d.ts +16 -0
- package/dist/src/usage/types.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.d.ts +14 -1
- package/dist/src/usage/usage-tracker.d.ts.map +1 -1
- package/dist/src/usage/usage-tracker.js +81 -41
- package/dist/src/usage/usage-tracker.js.map +1 -1
- package/package.json +6 -8
- package/src/agent.ts +99 -12
- package/src/api/server.ts +14 -12
- package/src/clock-rows.ts +302 -0
- package/src/code-execution/engine.ts +595 -0
- package/src/code-execution/index.ts +5 -17
- package/src/code-execution/isolate/calls.ts +199 -0
- package/src/code-execution/isolate/child-entry.ts +5 -0
- package/src/code-execution/isolate/child-main.ts +132 -0
- package/src/code-execution/isolate/child.ts +327 -0
- package/src/code-execution/isolate/frames.ts +209 -0
- package/src/code-execution/isolate/output.ts +161 -0
- package/src/code-execution/isolate/prelude.ts +409 -0
- package/src/code-execution/isolate/protocol.ts +240 -0
- package/src/code-execution/isolate/render.ts +230 -0
- package/src/code-execution/isolate/runner.ts +911 -0
- package/src/code-execution/isolate/scripts.ts +479 -0
- package/src/code-execution/quickjs.wasm +0 -0
- package/src/code-execution/quickjs.wasm.LICENSES +149 -0
- package/src/code-execution/tool-definition.ts +236 -167
- package/src/deadline-timer.ts +1 -1
- package/src/framework.ts +4978 -2671
- package/src/gate/event-gate.ts +79 -17
- package/src/held-writes.ts +17 -3
- package/src/index.ts +32 -22
- package/src/mcpl/channel-registry.ts +1892 -471
- package/src/mcpl/conversation-router.ts +26 -72
- package/src/mcpl/convert-block.ts +9 -5
- package/src/mcpl/inbound-source.ts +131 -0
- package/src/mcpl/index.ts +4 -2
- package/src/mcpl/log-value.ts +9 -0
- package/src/mcpl/modern-connection.ts +162 -53
- package/src/mcpl/prose-grammar.ts +4 -5
- package/src/mcpl/protocol-family.ts +200 -22
- package/src/mcpl/push-coalescer.ts +306 -62
- package/src/mcpl/push-handler.ts +12 -54
- package/src/mcpl/reference-fetcher.ts +4 -4
- package/src/mcpl/server-connection.ts +180 -79
- package/src/mcpl/tags.ts +36 -0
- package/src/mcpl/tool-result-normalize.ts +2 -1
- package/src/mcpl/transport.ts +162 -33
- package/src/mcpl/types.ts +23 -6
- package/src/module-registry.ts +92 -13
- package/src/modules/discord/index.ts +8 -13
- package/src/modules/history/index.ts +25 -3
- package/src/modules/history/semantic.ts +29 -6
- package/src/modules/index.ts +1 -0
- package/src/modules/unknown-tool.ts +4 -1
- package/src/modules/workspace/branch-intent.ts +3 -1
- package/src/modules/workspace/edit-plan.ts +954 -0
- package/src/modules/workspace/edit-text.ts +618 -0
- package/src/modules/workspace/effects.ts +70 -19
- package/src/modules/workspace/index.ts +2293 -650
- package/src/modules/workspace/observe.ts +465 -56
- package/src/modules/workspace/reconcile.ts +14 -7
- package/src/modules/workspace/text.ts +68 -0
- package/src/modules/workspace/types.ts +211 -6
- package/src/modules/workspace/watcher.ts +3 -2
- package/src/operator-log.ts +47 -19
- package/src/recovery/discord-awareness-outbox.ts +1500 -356
- package/src/recovery/offline-branch.ts +189 -55
- package/src/recovery/recover-cli.ts +25 -4
- package/src/send-tools.ts +11 -0
- package/src/timezone.ts +4 -2
- package/src/tool-image-ledger.ts +62 -8
- package/src/tool-result-guard.ts +18 -15
- package/src/tool-result-history.ts +3 -2
- package/src/tune-out/coordinator.ts +166 -45
- package/src/types/agent.ts +32 -6
- package/src/types/events.ts +66 -9
- package/src/types/framework.ts +69 -62
- package/src/types/module.ts +40 -8
- package/src/types/trace.ts +121 -15
- package/src/usage/types.ts +16 -0
- package/src/usage/usage-tracker.ts +86 -43
- package/dist/src/code-execution/py-runner.d.ts +0 -191
- package/dist/src/code-execution/py-runner.d.ts.map +0 -1
- package/dist/src/code-execution/py-runner.js +0 -655
- package/dist/src/code-execution/py-runner.js.map +0 -1
- package/dist/src/code-execution/runtime-py.d.ts +0 -50
- package/dist/src/code-execution/runtime-py.d.ts.map +0 -1
- package/dist/src/code-execution/runtime-py.js +0 -677
- package/dist/src/code-execution/runtime-py.js.map +0 -1
- package/dist/src/mcpl/prose-stream-router.d.ts +0 -88
- package/dist/src/mcpl/prose-stream-router.d.ts.map +0 -1
- package/dist/src/mcpl/prose-stream-router.js +0 -291
- package/dist/src/mcpl/prose-stream-router.js.map +0 -1
- package/src/code-execution/py-runner.ts +0 -791
- package/src/code-execution/runtime-py.ts +0 -677
- package/src/mcpl/prose-stream-router.ts +0 -268
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Incremental prose router: turns a stream of text deltas into a stream of
|
|
3
|
-
* (channelId, delta) pairs AS THE MODEL GENERATES, so downstream surfaces
|
|
4
|
-
* (voice synthesis, streamed message rendering, future platforms) can act on
|
|
5
|
-
* speech before the turn completes. This is the emission half of MCPL Spec
|
|
6
|
-
* 14.3 (`channels/outgoing/chunk`) — the notification has existed in the
|
|
7
|
-
* wire types since the spec landed; this class is what finally produces it.
|
|
8
|
-
*
|
|
9
|
-
* Correctness contract: routing decisions here MUST agree with the delivery
|
|
10
|
-
* path (deliverProse/parseProsePrefix). Both use prose-grammar.ts; this
|
|
11
|
-
* router additionally holds back exactly as much text as needed to make each
|
|
12
|
-
* line's decision — the start of a line is buffered only until it either
|
|
13
|
-
* cannot be a `>>` prefix (flush as body) or its prefix token (+ optional
|
|
14
|
-
* ` !` modifier) completes (switch target, swallow the prefix). Body text
|
|
15
|
-
* after the decision point streams through with zero added latency.
|
|
16
|
-
*
|
|
17
|
-
* Suppression is fail-closed: text whose destination is unknown (explicit
|
|
18
|
-
* mode before the first `>>`, unresolvable/ambiguous targets, `>>skip_reply`)
|
|
19
|
-
* emits NOTHING — the delivery path will bounce/retain it; a stream consumer
|
|
20
|
-
* must never see text that delivery would refuse to send.
|
|
21
|
-
*
|
|
22
|
-
* Three modes, mirroring proseRouting:
|
|
23
|
-
* - explicit: parse `>>` prefixes. A fresh turn's stream starts suppressed;
|
|
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
|
-
* fallback. An envelope with no target, or `>>>skip_reply`,
|
|
28
|
-
* holds back what follows until a later `>>>` names a target.
|
|
29
|
-
* - locus: NO prefix parsing (locus mode's `>>` lines are plain text);
|
|
30
|
-
* everything streams to the turn's locus.
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
export interface RoutedDelta {
|
|
34
|
-
channelId: string;
|
|
35
|
-
delta: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type State = 'line-start' | 'indent' | 'maybe-prefix' | 'prefix-gap' | 'prefix-token' | 'after-token' | 'body';
|
|
39
|
-
|
|
40
|
-
/** Whitespace as the delivery path reads it (`trimStart()`, `\s`, `\S`). */
|
|
41
|
-
const isSpace = (ch: string): boolean => /\s/.test(ch);
|
|
42
|
-
|
|
43
|
-
export class ProseStreamRouter {
|
|
44
|
-
private target: string | null;
|
|
45
|
-
private state: State = 'line-start';
|
|
46
|
-
private held = ''; // text held while a line's decision is pending
|
|
47
|
-
private token = ''; // the >>spec token being accumulated
|
|
48
|
-
private sawBang = false;
|
|
49
|
-
private accumulated = new Map<string, string>();
|
|
50
|
-
|
|
51
|
-
constructor(
|
|
52
|
-
private opts: {
|
|
53
|
-
/** explicit parses `>>`; hybrid parses `>>>` while retaining locus fallback. */
|
|
54
|
-
mode: 'explicit' | 'hybrid' | 'locus';
|
|
55
|
-
/** Initial destination: the turn's locus (locus and hybrid mode); in
|
|
56
|
-
* explicit mode, null on a fresh turn, or the turn's destination on a
|
|
57
|
-
* later stream of the turn. */
|
|
58
|
-
initialTarget: string | null;
|
|
59
|
-
/** Resolve a `>>spec` to a channelId, or null (unresolved/ambiguous). */
|
|
60
|
-
resolve: (spec: string) => string | null;
|
|
61
|
-
},
|
|
62
|
-
) {
|
|
63
|
-
this.target = opts.initialTarget;
|
|
64
|
-
if (opts.mode === 'locus') this.state = 'body';
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Per-channel full text emitted so far (for outgoing/complete). */
|
|
68
|
-
byChannel(): ReadonlyMap<string, string> {
|
|
69
|
-
return this.accumulated;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Point the stream at a destination decided outside it. Explicit mode does
|
|
74
|
-
* this at each round's end, with the turn's destination: a private round's
|
|
75
|
-
* prefixes, a `>>skip_reply` envelope and a target that didn't resolve all
|
|
76
|
-
* leave that destination as it was, though the stream followed them while
|
|
77
|
-
* the round was written.
|
|
78
|
-
*/
|
|
79
|
-
retarget(target: string | null): void {
|
|
80
|
-
this.target = target;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Drop everything routed so far and return to the constructed state.
|
|
85
|
-
*
|
|
86
|
-
* For a membrane refusal retry (RetryingEvent): the abandoned attempt's
|
|
87
|
-
* prose must not survive into the new one, and `accumulated` feeds
|
|
88
|
-
* outgoing/complete — leaving it would finalize text the model never
|
|
89
|
-
* actually said in the attempt that stands.
|
|
90
|
-
*/
|
|
91
|
-
reset(): void {
|
|
92
|
-
this.target = this.opts.initialTarget;
|
|
93
|
-
this.state = this.opts.mode === 'locus' ? 'body' : 'line-start';
|
|
94
|
-
this.held = '';
|
|
95
|
-
this.token = '';
|
|
96
|
-
this.sawBang = false;
|
|
97
|
-
this.accumulated = new Map();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
feed(delta: string): RoutedDelta[] {
|
|
101
|
-
const out: RoutedDelta[] = [];
|
|
102
|
-
for (const ch of delta) this.step(ch, out);
|
|
103
|
-
return coalesce(out);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* The end of a segment: one round's text, which delivery parses on its
|
|
108
|
-
* own. The pending line's decision is made now. Held line-start text can
|
|
109
|
-
* no longer become a prefix, so it is body. A prefix whose target is
|
|
110
|
-
* written but has no body takes effect, as delivery reads `>>#chan` with
|
|
111
|
-
* nothing after it. The next segment starts a new line.
|
|
112
|
-
*/
|
|
113
|
-
endSegment(): RoutedDelta[] {
|
|
114
|
-
const out: RoutedDelta[] = [];
|
|
115
|
-
if (this.state === 'indent') this.emit(this.held, out);
|
|
116
|
-
if (this.state === 'maybe-prefix') {
|
|
117
|
-
// Hybrid's `>>>` with nothing after it is an envelope with no target:
|
|
118
|
-
// delivery bounces it and holds back what follows. Anything else held
|
|
119
|
-
// is text to delivery, explicit's bare `>>` included.
|
|
120
|
-
const arrows = this.held.trimStart();
|
|
121
|
-
if (this.opts.mode === 'hybrid' && arrows === '>>>') this.target = null;
|
|
122
|
-
else this.emit(this.held, out);
|
|
123
|
-
}
|
|
124
|
-
// Hybrid's `>>>` and a gap with nothing after it: no target either.
|
|
125
|
-
if (this.state === 'prefix-gap') this.target = null;
|
|
126
|
-
if (this.state === 'prefix-token') this.applyTarget();
|
|
127
|
-
this.held = '';
|
|
128
|
-
this.token = '';
|
|
129
|
-
if (this.opts.mode !== 'locus') this.state = 'line-start';
|
|
130
|
-
return coalesce(out);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/** End of stream: the last segment ends. */
|
|
134
|
-
finish(): RoutedDelta[] {
|
|
135
|
-
return this.endSegment();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
private step(ch: string, out: RoutedDelta[]): void {
|
|
139
|
-
switch (this.state) {
|
|
140
|
-
case 'body':
|
|
141
|
-
if (ch === '\n' && this.opts.mode !== 'locus') {
|
|
142
|
-
this.emit('\n', out);
|
|
143
|
-
this.state = 'line-start';
|
|
144
|
-
} else {
|
|
145
|
-
this.emit(ch, out);
|
|
146
|
-
}
|
|
147
|
-
return;
|
|
148
|
-
|
|
149
|
-
case 'line-start':
|
|
150
|
-
// Indentation before a prefix is held until the line's decision: the
|
|
151
|
-
// delivery path reads an indented `>>` (explicit) or `>>>` (hybrid)
|
|
152
|
-
// line as a prefix too, after any leading whitespace.
|
|
153
|
-
if (ch !== '\n' && isSpace(ch)) {
|
|
154
|
-
this.state = 'indent';
|
|
155
|
-
this.held = ch;
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
if (ch === '>') { this.state = 'maybe-prefix'; this.held = '>'; return; }
|
|
159
|
-
this.state = 'body';
|
|
160
|
-
this.step(ch, out);
|
|
161
|
-
return;
|
|
162
|
-
|
|
163
|
-
case 'indent':
|
|
164
|
-
if (ch !== '\n' && isSpace(ch)) { this.held += ch; return; }
|
|
165
|
-
if (ch === '>') { this.held += ch; this.state = 'maybe-prefix'; return; }
|
|
166
|
-
this.emit(this.held, out);
|
|
167
|
-
this.held = '';
|
|
168
|
-
this.state = 'body';
|
|
169
|
-
this.step(ch, out);
|
|
170
|
-
return;
|
|
171
|
-
|
|
172
|
-
case 'maybe-prefix': {
|
|
173
|
-
const prefix = this.opts.mode === 'hybrid' ? '>>>' : '>>';
|
|
174
|
-
const arrows = this.held.trimStart();
|
|
175
|
-
if (ch === '>' && arrows.length < prefix.length) {
|
|
176
|
-
this.held += '>';
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (arrows === prefix) {
|
|
180
|
-
if (this.opts.mode === 'hybrid' && (ch === ' ' || ch === '\t')) {
|
|
181
|
-
this.held = '';
|
|
182
|
-
this.state = 'prefix-gap';
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (isSpace(ch)) {
|
|
186
|
-
if (this.opts.mode === 'explicit') {
|
|
187
|
-
// `>>` and then whitespace is a quoted arrow: body text, since
|
|
188
|
-
// delivery's prefix needs a target right after the arrows.
|
|
189
|
-
this.emit(this.held, out);
|
|
190
|
-
} else {
|
|
191
|
-
// `>>>` and then whitespace other than a space or tab (a
|
|
192
|
-
// newline included) is an envelope with no target. Delivery
|
|
193
|
-
// bounces it and holds back what follows until a later `>>>`
|
|
194
|
-
// names a target.
|
|
195
|
-
this.target = null;
|
|
196
|
-
}
|
|
197
|
-
// The whitespace itself is body, a newline included.
|
|
198
|
-
this.held = '';
|
|
199
|
-
this.state = 'body';
|
|
200
|
-
this.step(ch, out);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
this.state = 'prefix-token';
|
|
204
|
-
this.token = ch;
|
|
205
|
-
this.held = '';
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
this.emit(this.held, out);
|
|
209
|
-
this.held = '';
|
|
210
|
-
this.state = 'body';
|
|
211
|
-
this.step(ch, out);
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
case 'prefix-gap':
|
|
216
|
-
if (ch === ' ' || ch === '\t') return;
|
|
217
|
-
if (ch === '\n') { this.target = null; this.state = 'line-start'; return; }
|
|
218
|
-
// Other whitespace can't start hybrid's target (`[ \t]*\S+`): an
|
|
219
|
-
// envelope with no target, as above.
|
|
220
|
-
if (isSpace(ch)) { this.target = null; this.state = 'body'; return; }
|
|
221
|
-
this.state = 'prefix-token';
|
|
222
|
-
this.token = ch;
|
|
223
|
-
return;
|
|
224
|
-
|
|
225
|
-
case 'prefix-token':
|
|
226
|
-
if (ch === ' ' || ch === '\t') { this.applyTarget(); this.state = 'after-token'; this.sawBang = false; return; }
|
|
227
|
-
if (ch === '\n') { this.applyTarget(); this.state = 'line-start'; return; }
|
|
228
|
-
// Any other whitespace ends the token too (`\S+`), and starts the
|
|
229
|
-
// body: the grammar's gap after a token is spaces and tabs only.
|
|
230
|
-
if (isSpace(ch)) { this.applyTarget(); this.state = 'body'; this.step(ch, out); return; }
|
|
231
|
-
this.token += ch;
|
|
232
|
-
return;
|
|
233
|
-
|
|
234
|
-
case 'after-token':
|
|
235
|
-
// Grammar: `([ \t]+!)?[ \t]*` — one optional `!` immediately after the
|
|
236
|
-
// first whitespace run is the continue-turn modifier, not body.
|
|
237
|
-
if (ch === ' ' || ch === '\t') return;
|
|
238
|
-
if (ch === '\n') { this.state = 'line-start'; return; }
|
|
239
|
-
if (ch === '!' && !this.sawBang) { this.sawBang = true; return; }
|
|
240
|
-
this.state = 'body';
|
|
241
|
-
this.step(ch, out);
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
private applyTarget(): void {
|
|
247
|
-
const spec = this.token;
|
|
248
|
-
this.token = '';
|
|
249
|
-
if (spec === 'skip_reply') { this.target = null; return; }
|
|
250
|
-
this.target = this.opts.resolve(spec);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private emit(text: string, out: RoutedDelta[]): void {
|
|
254
|
-
if (this.target === null || !text) return;
|
|
255
|
-
out.push({ channelId: this.target, delta: text });
|
|
256
|
-
this.accumulated.set(this.target, (this.accumulated.get(this.target) ?? '') + text);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function coalesce(deltas: RoutedDelta[]): RoutedDelta[] {
|
|
261
|
-
const out: RoutedDelta[] = [];
|
|
262
|
-
for (const d of deltas) {
|
|
263
|
-
const last = out[out.length - 1];
|
|
264
|
-
if (last && last.channelId === d.channelId) last.delta += d.delta;
|
|
265
|
-
else out.push({ ...d });
|
|
266
|
-
}
|
|
267
|
-
return out;
|
|
268
|
-
}
|