@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
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clock rows: a time marker an agent's window takes when an interval
|
|
3
|
+
* boundary has passed since the last one it holds.
|
|
4
|
+
*
|
|
5
|
+
* The model is a tick event at every boundary of the agent's local wall
|
|
6
|
+
* clock (every 10 minutes, say, from local midnight). The ticks aren't
|
|
7
|
+
* written as they fire. One is written when the window next takes something
|
|
8
|
+
* (an incoming event, a tool round's results, the start of a turn), and only
|
|
9
|
+
* the latest of the ticks that fired meanwhile: nothing was written between
|
|
10
|
+
* them, and a clock wakes no one, so the window reads exactly as it would
|
|
11
|
+
* had every tick been written and the earlier ones coalesced away.
|
|
12
|
+
*
|
|
13
|
+
* A clock never lies about order. One that lands where its tick would have
|
|
14
|
+
* been (the row before it is no newer than the boundary) reads the
|
|
15
|
+
* boundary's time, which is in the past by the time it is written. One that
|
|
16
|
+
* can't (the boundary passed while the agent was mid-reply or a tool ran:
|
|
17
|
+
* a tool's results must follow its call directly, so nothing can be written
|
|
18
|
+
* between them) reads the time it is written instead.
|
|
19
|
+
*
|
|
20
|
+
* Everything the next clock needs is read back from the window: the last
|
|
21
|
+
* clock row's time, wherever it is, and the newest row's. A window that
|
|
22
|
+
* holds no clock row takes one the next time it would take a clock (an
|
|
23
|
+
* incoming event, a turn's start, a tool boundary), so a window that has
|
|
24
|
+
* just had a clock turned on, or a fork seeded with copies of its
|
|
25
|
+
* template's rows (which carry none of their metadata), reads the time
|
|
26
|
+
* then. A restart, a rollback or a second resident sharing the window
|
|
27
|
+
* leaves nothing stale to reconcile.
|
|
28
|
+
*/
|
|
29
|
+
import type { ContentBlock } from '@animalabs/membrane';
|
|
30
|
+
/** `AgentConfig.clock`: when the agent's window takes clock rows. */
|
|
31
|
+
export interface ClockConfig {
|
|
32
|
+
/** Minutes between boundaries. Give this or `intervalSeconds`. */
|
|
33
|
+
intervalMinutes?: number;
|
|
34
|
+
/** Seconds between boundaries, for clocks finer than a minute. */
|
|
35
|
+
intervalSeconds?: number;
|
|
36
|
+
/**
|
|
37
|
+
* How a clock reads: `'minutes'` (`10:50`) or `'seconds'` (`10:50:30`).
|
|
38
|
+
* Defaults to minutes for an interval of whole minutes, else seconds.
|
|
39
|
+
*/
|
|
40
|
+
precision?: 'minutes' | 'seconds';
|
|
41
|
+
}
|
|
42
|
+
export interface ResolvedClockConfig {
|
|
43
|
+
intervalSeconds: number;
|
|
44
|
+
precision: 'minutes' | 'seconds';
|
|
45
|
+
}
|
|
46
|
+
/** `metadata.kind` of a clock row. */
|
|
47
|
+
export declare const CLOCK_ROW_KIND = "clock";
|
|
48
|
+
/** `metadata.clock` of a clock row. */
|
|
49
|
+
export interface ClockStamp {
|
|
50
|
+
/** The instant the row reads, epoch ms. */
|
|
51
|
+
at: number;
|
|
52
|
+
/** Whether that instant is the boundary itself (else, when it was written). */
|
|
53
|
+
onBoundary: boolean;
|
|
54
|
+
/** The IANA zone it reads in. */
|
|
55
|
+
zone: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validate `AgentConfig.clock`. Undefined when the agent has no clock; throws
|
|
59
|
+
* on a setting that can't be read as one, naming the agent.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveClockConfig(agentName: string, config: ClockConfig | undefined): ResolvedClockConfig | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* The latest boundary at or before `now`: an instant at which the zone's
|
|
64
|
+
* wall clock read a whole multiple of the interval since local midnight. A
|
|
65
|
+
* boundary whose wall time a DST change skips doesn't occur; one it repeats
|
|
66
|
+
* occurs twice.
|
|
67
|
+
*
|
|
68
|
+
* While the zone's offset stays the same, its wall clock runs with real
|
|
69
|
+
* time, so the latest boundary is `now` less how far the wall clock has run
|
|
70
|
+
* past its last multiple of the interval. Where that instant has another
|
|
71
|
+
* offset, the offset changed in between and no boundary falls between the
|
|
72
|
+
* change and `now`: the walk goes on from just before the change. The change
|
|
73
|
+
* is found by searching between the two instants, whatever their offsets
|
|
74
|
+
* are. The same offset at both is taken to mean no change between them: in
|
|
75
|
+
* the tz data, no zone changes its offset twice within a day, the longest
|
|
76
|
+
* interval, from 2024 through 2040. Throws if the walk passes 24 changes,
|
|
77
|
+
* which no real zone reaches, rather than return an instant that isn't a
|
|
78
|
+
* boundary.
|
|
79
|
+
*/
|
|
80
|
+
export declare function latestBoundary(now: number, intervalSeconds: number, zone: string): number;
|
|
81
|
+
/**
|
|
82
|
+
* A clock row's text: `Clock: 10:50 Europe/Berlin (UTC+02:00)`, with the
|
|
83
|
+
* weekday and date ahead of the time when `withDate`
|
|
84
|
+
* (`Clock: Thursday 2026-10-22, 00:00 Europe/Berlin (UTC+02:00)`).
|
|
85
|
+
*/
|
|
86
|
+
export declare function formatClockText(at: number, zone: string, precision: 'minutes' | 'seconds', withDate: boolean): string;
|
|
87
|
+
/** A clock row to store. */
|
|
88
|
+
export interface PlannedClock {
|
|
89
|
+
content: ContentBlock[];
|
|
90
|
+
stamp: ClockStamp;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The clock row the window takes next, or null when no boundary has passed
|
|
94
|
+
* since the last clock it holds. The framework asks before an incoming
|
|
95
|
+
* event, at a turn's start and at a tool boundary (storeDueClock).
|
|
96
|
+
*
|
|
97
|
+
* - `newestRowAt`: the newest row's time, which the clock goes after.
|
|
98
|
+
* - `lastClockAt`: the time the window's last clock row reads, when it holds
|
|
99
|
+
* one. Without one, no boundary counts as told: the window takes a clock
|
|
100
|
+
* now, and it carries the date.
|
|
101
|
+
*/
|
|
102
|
+
export declare function planClock(args: {
|
|
103
|
+
now: number;
|
|
104
|
+
newestRowAt: number | undefined;
|
|
105
|
+
lastClockAt: number | undefined;
|
|
106
|
+
config: ResolvedClockConfig;
|
|
107
|
+
zone: string;
|
|
108
|
+
}): PlannedClock | null;
|
|
109
|
+
/** The clock stamp a stored row's metadata carries, if it is a clock row. */
|
|
110
|
+
export declare function clockStampOf(metadata: unknown): ClockStamp | undefined;
|
|
111
|
+
/** Whether a row can have a clock written before it: not the agent's own
|
|
112
|
+
* (an assistant turn), no tool blocks (a tool's results follow its call
|
|
113
|
+
* directly), and not itself a clock. */
|
|
114
|
+
export declare function takesClockBefore(participant: string, content: readonly ContentBlock[], metadata: unknown, agentName: string): boolean;
|
|
115
|
+
//# sourceMappingURL=clock-rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock-rows.d.ts","sourceRoot":"","sources":["../../src/clock-rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,SAAS,GAAG,SAAS,CAAC;CAClC;AAED,sCAAsC;AACtC,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,+EAA+E;IAC/E,UAAU,EAAE,OAAO,CAAC;IACpB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,mBAAmB,GAAG,SAAS,CA4BtH;AAsDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAczF;AAkCD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,QAAQ,EAAE,OAAO,GAChB,MAAM,CAaR;AAED,4BAA4B;AAC5B,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,YAAY,GAAG,IAAI,CAgBtB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAItE;AAED;;yCAEyC;AACzC,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAIT"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clock rows: a time marker an agent's window takes when an interval
|
|
3
|
+
* boundary has passed since the last one it holds.
|
|
4
|
+
*
|
|
5
|
+
* The model is a tick event at every boundary of the agent's local wall
|
|
6
|
+
* clock (every 10 minutes, say, from local midnight). The ticks aren't
|
|
7
|
+
* written as they fire. One is written when the window next takes something
|
|
8
|
+
* (an incoming event, a tool round's results, the start of a turn), and only
|
|
9
|
+
* the latest of the ticks that fired meanwhile: nothing was written between
|
|
10
|
+
* them, and a clock wakes no one, so the window reads exactly as it would
|
|
11
|
+
* had every tick been written and the earlier ones coalesced away.
|
|
12
|
+
*
|
|
13
|
+
* A clock never lies about order. One that lands where its tick would have
|
|
14
|
+
* been (the row before it is no newer than the boundary) reads the
|
|
15
|
+
* boundary's time, which is in the past by the time it is written. One that
|
|
16
|
+
* can't (the boundary passed while the agent was mid-reply or a tool ran:
|
|
17
|
+
* a tool's results must follow its call directly, so nothing can be written
|
|
18
|
+
* between them) reads the time it is written instead.
|
|
19
|
+
*
|
|
20
|
+
* Everything the next clock needs is read back from the window: the last
|
|
21
|
+
* clock row's time, wherever it is, and the newest row's. A window that
|
|
22
|
+
* holds no clock row takes one the next time it would take a clock (an
|
|
23
|
+
* incoming event, a turn's start, a tool boundary), so a window that has
|
|
24
|
+
* just had a clock turned on, or a fork seeded with copies of its
|
|
25
|
+
* template's rows (which carry none of their metadata), reads the time
|
|
26
|
+
* then. A restart, a rollback or a second resident sharing the window
|
|
27
|
+
* leaves nothing stale to reconcile.
|
|
28
|
+
*/
|
|
29
|
+
import { resolveTimeZone } from './timezone.js';
|
|
30
|
+
/** `metadata.kind` of a clock row. */
|
|
31
|
+
export const CLOCK_ROW_KIND = 'clock';
|
|
32
|
+
const DAY_SECONDS = 86_400;
|
|
33
|
+
/**
|
|
34
|
+
* Validate `AgentConfig.clock`. Undefined when the agent has no clock; throws
|
|
35
|
+
* on a setting that can't be read as one, naming the agent.
|
|
36
|
+
*/
|
|
37
|
+
export function resolveClockConfig(agentName, config) {
|
|
38
|
+
if (config === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
const at = `Agent "${agentName}" clock`;
|
|
41
|
+
if (config === null || typeof config !== 'object' || Array.isArray(config)) {
|
|
42
|
+
throw new Error(`${at} must be an object such as { intervalMinutes: 10 }, or left out for no clock rows of its own`);
|
|
43
|
+
}
|
|
44
|
+
const { intervalMinutes, intervalSeconds, precision } = config;
|
|
45
|
+
if ((intervalMinutes === undefined) === (intervalSeconds === undefined)) {
|
|
46
|
+
throw new Error(`${at} takes exactly one of intervalMinutes and intervalSeconds`);
|
|
47
|
+
}
|
|
48
|
+
const given = intervalMinutes !== undefined ? intervalMinutes : intervalSeconds;
|
|
49
|
+
if (typeof given !== 'number' || !Number.isInteger(given) || given <= 0) {
|
|
50
|
+
throw new Error(`${at}.${intervalMinutes !== undefined ? 'intervalMinutes' : 'intervalSeconds'} must be a positive whole number`);
|
|
51
|
+
}
|
|
52
|
+
const seconds = intervalMinutes !== undefined ? given * 60 : given;
|
|
53
|
+
if (seconds > DAY_SECONDS) {
|
|
54
|
+
throw new Error(`${at} interval is at most a day (1440 minutes); boundaries count from local midnight`);
|
|
55
|
+
}
|
|
56
|
+
if (precision !== undefined && precision !== 'minutes' && precision !== 'seconds') {
|
|
57
|
+
throw new Error(`${at}.precision must be 'minutes' or 'seconds'`);
|
|
58
|
+
}
|
|
59
|
+
const resolved = precision ?? (seconds % 60 === 0 ? 'minutes' : 'seconds');
|
|
60
|
+
if (resolved === 'minutes' && seconds % 60 !== 0) {
|
|
61
|
+
throw new Error(`${at}: an interval of ${seconds} seconds isn't whole minutes, so its clocks need precision 'seconds'`);
|
|
62
|
+
}
|
|
63
|
+
return { intervalSeconds: seconds, precision: resolved };
|
|
64
|
+
}
|
|
65
|
+
const formatters = new Map();
|
|
66
|
+
function formatterFor(zone) {
|
|
67
|
+
let formatter = formatters.get(zone);
|
|
68
|
+
if (!formatter) {
|
|
69
|
+
formatter = new Intl.DateTimeFormat('en-CA', {
|
|
70
|
+
timeZone: zone,
|
|
71
|
+
year: 'numeric',
|
|
72
|
+
month: '2-digit',
|
|
73
|
+
day: '2-digit',
|
|
74
|
+
hour: '2-digit',
|
|
75
|
+
minute: '2-digit',
|
|
76
|
+
second: '2-digit',
|
|
77
|
+
hourCycle: 'h23',
|
|
78
|
+
});
|
|
79
|
+
formatters.set(zone, formatter);
|
|
80
|
+
}
|
|
81
|
+
return formatter;
|
|
82
|
+
}
|
|
83
|
+
function wallFields(at, zone) {
|
|
84
|
+
const parts = formatterFor(zone).formatToParts(new Date(at));
|
|
85
|
+
const get = (type) => Number(parts.find((part) => part.type === type)?.value ?? NaN);
|
|
86
|
+
const fields = {
|
|
87
|
+
year: get('year'),
|
|
88
|
+
month: get('month'),
|
|
89
|
+
day: get('day'),
|
|
90
|
+
hour: get('hour'),
|
|
91
|
+
minute: get('minute'),
|
|
92
|
+
second: get('second'),
|
|
93
|
+
};
|
|
94
|
+
const shownAsUtc = Date.UTC(fields.year, fields.month - 1, fields.day, fields.hour, fields.minute, fields.second);
|
|
95
|
+
const offsetMinutes = Math.round((shownAsUtc - Math.floor(at / 1000) * 1000) / 60_000);
|
|
96
|
+
return { ...fields, offsetMinutes };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The latest boundary at or before `now`: an instant at which the zone's
|
|
100
|
+
* wall clock read a whole multiple of the interval since local midnight. A
|
|
101
|
+
* boundary whose wall time a DST change skips doesn't occur; one it repeats
|
|
102
|
+
* occurs twice.
|
|
103
|
+
*
|
|
104
|
+
* While the zone's offset stays the same, its wall clock runs with real
|
|
105
|
+
* time, so the latest boundary is `now` less how far the wall clock has run
|
|
106
|
+
* past its last multiple of the interval. Where that instant has another
|
|
107
|
+
* offset, the offset changed in between and no boundary falls between the
|
|
108
|
+
* change and `now`: the walk goes on from just before the change. The change
|
|
109
|
+
* is found by searching between the two instants, whatever their offsets
|
|
110
|
+
* are. The same offset at both is taken to mean no change between them: in
|
|
111
|
+
* the tz data, no zone changes its offset twice within a day, the longest
|
|
112
|
+
* interval, from 2024 through 2040. Throws if the walk passes 24 changes,
|
|
113
|
+
* which no real zone reaches, rather than return an instant that isn't a
|
|
114
|
+
* boundary.
|
|
115
|
+
*/
|
|
116
|
+
export function latestBoundary(now, intervalSeconds, zone) {
|
|
117
|
+
let at = now;
|
|
118
|
+
// A pass that doesn't return steps back past an offset change, and a day
|
|
119
|
+
// of a real zone holds at most two of them; running out of passes is a
|
|
120
|
+
// defect, and it throws rather than return an instant that isn't a boundary.
|
|
121
|
+
for (let pass = 0; pass < 24; pass++) {
|
|
122
|
+
const f = wallFields(at, zone);
|
|
123
|
+
const secondOfDay = f.hour * 3600 + f.minute * 60 + f.second;
|
|
124
|
+
const subSecond = at - Math.floor(at / 1000) * 1000;
|
|
125
|
+
const candidate = at - (secondOfDay % intervalSeconds) * 1000 - subSecond;
|
|
126
|
+
if (wallFields(candidate, zone).offsetMinutes === f.offsetMinutes)
|
|
127
|
+
return candidate;
|
|
128
|
+
at = offsetTakenAt(candidate, at, f.offsetMinutes, zone) - 1;
|
|
129
|
+
}
|
|
130
|
+
throw new Error(`no clock boundary found within 24 offset changes of ${new Date(now).toISOString()} in ${zone}`);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The instant in (`from`, `to`] at which the zone took `offset`, given that
|
|
134
|
+
* `to` reads at that offset and `from` doesn't, to the millisecond.
|
|
135
|
+
*/
|
|
136
|
+
function offsetTakenAt(from, to, offset, zone) {
|
|
137
|
+
let before = from;
|
|
138
|
+
let after = to;
|
|
139
|
+
while (after - before > 1) {
|
|
140
|
+
const mid = Math.floor((before + after) / 2);
|
|
141
|
+
if (wallFields(mid, zone).offsetMinutes === offset)
|
|
142
|
+
after = mid;
|
|
143
|
+
else
|
|
144
|
+
before = mid;
|
|
145
|
+
}
|
|
146
|
+
return after;
|
|
147
|
+
}
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// What a clock reads
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
const WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
152
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
153
|
+
function localDate(at, zone) {
|
|
154
|
+
const f = wallFields(at, zone);
|
|
155
|
+
return `${f.year}-${pad(f.month)}-${pad(f.day)}`;
|
|
156
|
+
}
|
|
157
|
+
function isUtcZone(zone) {
|
|
158
|
+
return /^(Etc\/)?(UTC|UCT|Zulu|Universal|GMT|Greenwich)$/.test(zone) || zone === 'Etc/GMT0' || zone === 'GMT0';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* A clock row's text: `Clock: 10:50 Europe/Berlin (UTC+02:00)`, with the
|
|
162
|
+
* weekday and date ahead of the time when `withDate`
|
|
163
|
+
* (`Clock: Thursday 2026-10-22, 00:00 Europe/Berlin (UTC+02:00)`).
|
|
164
|
+
*/
|
|
165
|
+
export function formatClockText(at, zone, precision, withDate) {
|
|
166
|
+
const f = wallFields(at, zone);
|
|
167
|
+
const time = precision === 'seconds'
|
|
168
|
+
? `${pad(f.hour)}:${pad(f.minute)}:${pad(f.second)}`
|
|
169
|
+
: `${pad(f.hour)}:${pad(f.minute)}`;
|
|
170
|
+
const weekday = WEEKDAYS[new Date(Date.UTC(f.year, f.month - 1, f.day)).getUTCDay()];
|
|
171
|
+
const date = withDate ? `${weekday} ${f.year}-${pad(f.month)}-${pad(f.day)}, ` : '';
|
|
172
|
+
const sign = f.offsetMinutes < 0 ? '-' : '+';
|
|
173
|
+
const offset = Math.abs(f.offsetMinutes);
|
|
174
|
+
const where = isUtcZone(zone) && f.offsetMinutes === 0
|
|
175
|
+
? 'UTC'
|
|
176
|
+
: `${zone} (UTC${sign}${pad(Math.floor(offset / 60))}:${pad(offset % 60)})`;
|
|
177
|
+
return `Clock: ${date}${time} ${where}`;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The clock row the window takes next, or null when no boundary has passed
|
|
181
|
+
* since the last clock it holds. The framework asks before an incoming
|
|
182
|
+
* event, at a turn's start and at a tool boundary (storeDueClock).
|
|
183
|
+
*
|
|
184
|
+
* - `newestRowAt`: the newest row's time, which the clock goes after.
|
|
185
|
+
* - `lastClockAt`: the time the window's last clock row reads, when it holds
|
|
186
|
+
* one. Without one, no boundary counts as told: the window takes a clock
|
|
187
|
+
* now, and it carries the date.
|
|
188
|
+
*/
|
|
189
|
+
export function planClock(args) {
|
|
190
|
+
const { now, newestRowAt, lastClockAt, config } = args;
|
|
191
|
+
const zone = resolveTimeZone(args.zone);
|
|
192
|
+
const boundary = latestBoundary(now, config.intervalSeconds, zone);
|
|
193
|
+
const told = lastClockAt !== undefined ? latestBoundary(lastClockAt, config.intervalSeconds, zone) : -Infinity;
|
|
194
|
+
if (boundary <= told)
|
|
195
|
+
return null;
|
|
196
|
+
// The boundary's own time only where its tick would have been: no row
|
|
197
|
+
// after the boundary comes before the clock. Otherwise the time it is
|
|
198
|
+
// written, and never earlier than the row it follows.
|
|
199
|
+
const onBoundary = newestRowAt === undefined || newestRowAt <= boundary;
|
|
200
|
+
const at = onBoundary ? boundary : Math.max(now, newestRowAt);
|
|
201
|
+
const withDate = lastClockAt === undefined || localDate(lastClockAt, zone) !== localDate(at, zone);
|
|
202
|
+
return {
|
|
203
|
+
content: [{ type: 'text', text: formatClockText(at, zone, config.precision, withDate) }],
|
|
204
|
+
stamp: { at, onBoundary, zone },
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/** The clock stamp a stored row's metadata carries, if it is a clock row. */
|
|
208
|
+
export function clockStampOf(metadata) {
|
|
209
|
+
const m = metadata;
|
|
210
|
+
if (m?.kind !== CLOCK_ROW_KIND || typeof m.clock?.at !== 'number')
|
|
211
|
+
return undefined;
|
|
212
|
+
return m.clock;
|
|
213
|
+
}
|
|
214
|
+
/** Whether a row can have a clock written before it: not the agent's own
|
|
215
|
+
* (an assistant turn), no tool blocks (a tool's results follow its call
|
|
216
|
+
* directly), and not itself a clock. */
|
|
217
|
+
export function takesClockBefore(participant, content, metadata, agentName) {
|
|
218
|
+
return participant !== agentName
|
|
219
|
+
&& !content.some((b) => b.type === 'tool_use' || b.type === 'tool_result')
|
|
220
|
+
&& clockStampOf(metadata) === undefined;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=clock-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock-rows.js","sourceRoot":"","sources":["../../src/clock-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/** What the child sets once, before any script code runs. */
|
|
2
|
+
export interface EngineLimits {
|
|
3
|
+
/**
|
|
4
|
+
* The linear memory's maximum, the guest's budget: a whole number of 64 KiB pages, from
|
|
5
|
+
* `MIN_MEMORY_BYTES` to `MAX_MEMORY_BYTES`. The engine's own stack and data take its first ~1.1 MiB, and
|
|
6
|
+
* QuickJS's allocation limit sits a margin below the rest, so that a script reaching it gets a
|
|
7
|
+
* catchable out-of-memory error rather than a failed allocation inside the engine.
|
|
8
|
+
*/
|
|
9
|
+
memoryMaxBytes: number;
|
|
10
|
+
/** QuickJS's stack limit, at most `MAX_STACK_BYTES`; `DEFAULT_STACK_BYTES` when left out. */
|
|
11
|
+
maxStackBytes?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The four imports, as slots the child fills. Each is called synchronously from inside the
|
|
15
|
+
* engine, so none may await, and none may call back into the engine: a call into it from a slot
|
|
16
|
+
* throws an `EngineError`. A slot that throws ends the run: the call in progress throws that
|
|
17
|
+
* error, wrapped as an `EngineError`, and no slot is called again but `supervise()`.
|
|
18
|
+
*/
|
|
19
|
+
export interface EngineSlots {
|
|
20
|
+
/**
|
|
21
|
+
* The guest called `__host(name, argsJson)`, which returned a pending promise to the guest.
|
|
22
|
+
* `callId` names that promise for `settle`. Ids are the engine's, 1, 2, 3 and on.
|
|
23
|
+
*/
|
|
24
|
+
hostCall(callId: number, name: string, argsJson: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Called while the guest runs, every few thousand of its operations. Return true to stop it for
|
|
27
|
+
* good: the engine doesn't ask again, the call in progress answers `interrupted`, and so does
|
|
28
|
+
* every call after, with two exceptions. A stop in the jobs that reading the script's ending
|
|
29
|
+
* queued, after the ending was read whole, lets that call answer the ending, and the calls after
|
|
30
|
+
* it answer `interrupted`. And a run answered `failed` stays so, a stop while its exception is
|
|
31
|
+
* read included; a throw as the run starts is the script's own ending, answered `rejected`, which
|
|
32
|
+
* a stop while it's read turns into `interrupted`, as for any rejection.
|
|
33
|
+
*/
|
|
34
|
+
interrupt(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Called at every interrupt check, before `interrupt()` is asked, and after it has said stop or a
|
|
37
|
+
* slot has failed, when it's asked no more: the child's watch over its own process, such as its
|
|
38
|
+
* parent going, which no stop or failure ends, since a script can keep a stop from landing. It
|
|
39
|
+
* returns nothing: a stop it calls for comes through `interrupt()`. One that throws ends the run
|
|
40
|
+
* as any slot's failure, and is still called at the checks after.
|
|
41
|
+
*/
|
|
42
|
+
supervise(): void;
|
|
43
|
+
/** The guest called `__output(stream, text)`: stream 1 is out, 2 is err. */
|
|
44
|
+
output(stream: 1 | 2, text: string): void;
|
|
45
|
+
}
|
|
46
|
+
/** How a call into the guest left it. */
|
|
47
|
+
export type RunState =
|
|
48
|
+
/** The queue is empty and the script hasn't settled: it awaits a call, or a promise nothing settles. */
|
|
49
|
+
{
|
|
50
|
+
kind: 'pending';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The script settled. `json` is JSON.stringify of its value, undefined when that gives none. It's
|
|
54
|
+
* taken once: every later answer of this state carries the same text.
|
|
55
|
+
*/
|
|
56
|
+
| {
|
|
57
|
+
kind: 'fulfilled';
|
|
58
|
+
json: string | undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The prelude or the script threw, or its value couldn't be stringified (a BigInt, a cycle).
|
|
62
|
+
* The fields are what was thrown: an Error's name, message and stack. A thrown value with no
|
|
63
|
+
* message of its own has name `''`, and as its message an object's JSON, or else its string
|
|
64
|
+
* form; a Symbol, which has none here, leaves the message `''`.
|
|
65
|
+
*/
|
|
66
|
+
| {
|
|
67
|
+
kind: 'rejected';
|
|
68
|
+
name: string;
|
|
69
|
+
message: string;
|
|
70
|
+
stack?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Once the script was running, an exception escaped its promises and ended the run, even after
|
|
74
|
+
* its own ending: a callback it gave `queueMicrotask` or a `FinalizationRegistry` threw, or a job
|
|
75
|
+
* failed in the engine itself; or the engine couldn't settle a call. The fields are the
|
|
76
|
+
* exception's, read as the engine reads a `rejected` one (an Error's name, message and stack; a
|
|
77
|
+
* value with no message of its own, its JSON or string form), less any part a stop cut off while
|
|
78
|
+
* it was read: a stop ends the read, and nothing after it is read. Every later call answers
|
|
79
|
+
* the same, a stop after it included, and no later result reaches the script.
|
|
80
|
+
*/
|
|
81
|
+
| {
|
|
82
|
+
kind: 'failed';
|
|
83
|
+
name: string;
|
|
84
|
+
message: string;
|
|
85
|
+
stack?: string;
|
|
86
|
+
}
|
|
87
|
+
/** `interrupt()` returned true while it ran. */
|
|
88
|
+
| {
|
|
89
|
+
kind: 'interrupted';
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* What `settle` answers: the run's state; `unfit` when the guest couldn't take the result, for
|
|
93
|
+
* want of memory to copy it in or of memory or stack to parse it, and the call took the child's
|
|
94
|
+
* own error instead; and `dropped` when neither was handed over, because the run had been stopped
|
|
95
|
+
* or had failed before this settle (`interrupted` or `failed`), or the call of the promise's
|
|
96
|
+
* resolve or reject function was stopped or failed before it ran. Without `dropped`, that function
|
|
97
|
+
* ran with the result or the child's error, and the script's own code runs with it: a `then`
|
|
98
|
+
* getter it put on Object.prototype, which can reject the promise instead, and its continuations.
|
|
99
|
+
* A stop or failure in that code, or in the jobs after, leaves it handed over. The two are never
|
|
100
|
+
* both set.
|
|
101
|
+
*/
|
|
102
|
+
export type SettleState = RunState & {
|
|
103
|
+
unfit?: true;
|
|
104
|
+
dropped?: true;
|
|
105
|
+
};
|
|
106
|
+
export interface Engine {
|
|
107
|
+
/**
|
|
108
|
+
* Evaluates the prelude as a global script, then the script as global code with top-level
|
|
109
|
+
* await, then runs pending jobs until none is left, the guest is interrupted or the run fails.
|
|
110
|
+
* The script's value is that of its last expression statement. Called once.
|
|
111
|
+
*/
|
|
112
|
+
start(prelude: string, script: string, filename: string): RunState;
|
|
113
|
+
/**
|
|
114
|
+
* Settles call `callId`, then runs pending jobs as `start` does. With `ok`, the call's promise
|
|
115
|
+
* resolves to the parsed JSON; otherwise it rejects with it, and the prelude makes an Error of
|
|
116
|
+
* it. A result the guest can't take, for want of memory to copy it in or of memory or stack to
|
|
117
|
+
* parse it, nested deeper than `MAX_RESULT_DEPTH`, or not JSON, rejects it with `unfitJson`
|
|
118
|
+
* parsed, the child's own error (`ResultTooLarge`), and the answer has `unfit: true`: the call
|
|
119
|
+
* took effect, and an error at its await would read as a failed call. Allowed after `fulfilled`,
|
|
120
|
+
* for calls still in flight when a script returned. Throws for an id that isn't pending.
|
|
121
|
+
*
|
|
122
|
+
* Once a call has answered the script's ending, later calls answer it again, unless something
|
|
123
|
+
* came after it: a stop answers `interrupted`, a slot's failure throws, and an exception that
|
|
124
|
+
* escapes the script's promises answers `failed`. One that escapes the jobs reading the ending
|
|
125
|
+
* queued is answered by the call that read it, in the ending's place.
|
|
126
|
+
*/
|
|
127
|
+
settle(callId: number, ok: boolean, json: string | Uint8Array, unfitJson: string): SettleState;
|
|
128
|
+
/** Frees the engine's runtime, unless the module trapped, which leaves it as it is. Nothing may be called after it. */
|
|
129
|
+
dispose(): void;
|
|
130
|
+
}
|
|
131
|
+
/** The engine failed, rather than the script: a slot threw, the engine crashed, or it was misused. */
|
|
132
|
+
export declare class EngineError extends Error {
|
|
133
|
+
constructor(message: string, options?: {
|
|
134
|
+
cause?: unknown;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
export declare const MIN_MEMORY_BYTES: number;
|
|
138
|
+
/**
|
|
139
|
+
* 2 GiB, so that every address in linear memory fits the signed 32-bit numbers the module's
|
|
140
|
+
* pointers arrive as, and no conversion is needed where the host reads them.
|
|
141
|
+
*/
|
|
142
|
+
export declare const MAX_MEMORY_BYTES: number;
|
|
143
|
+
/**
|
|
144
|
+
* The most QuickJS's stack limit may be, and its default. QuickJS measures its stack in the
|
|
145
|
+
* module's linear memory, but each level of a script's recursion through calls also takes the
|
|
146
|
+
* host's own stack, two to three times as much in the 31 ways to recurse that were measured, and
|
|
147
|
+
* under Node that stack is about 984 KiB. Recursing through a getter, a proxy trap or a built-in
|
|
148
|
+
* that calls back (map, toString, for...of), the host's stack ran out first, crashing the engine,
|
|
149
|
+
* once QuickJS's limit passed about 320 KiB. At this limit, QuickJS's catchable RangeError comes
|
|
150
|
+
* first in each of the 31, with about two fifths of the host's stack to spare. Bun's stack is
|
|
151
|
+
* larger, and the same limit holds there, so recursion through calls ends the same way on either.
|
|
152
|
+
*
|
|
153
|
+
* Recursion in C that the check barely sees isn't held to it, and under Node crashes the run, the
|
|
154
|
+
* host's stack running out: a script's text nesting function expressions 300 deep or brackets 700
|
|
155
|
+
* deep (the parser), a chain of 3,000 iterator helpers, and the script's own data nested about
|
|
156
|
+
* 5,000 deep in JSON.stringify (4,000 with V8's optimizing tier alone), as a call's arguments
|
|
157
|
+
* are, or about 8,000 deep in JSON.parse (5,000; see MAX_RESULT_DEPTH). Under Bun, whose stack
|
|
158
|
+
* is larger, QuickJS's check ends JSON's recursion first, with a RangeError the script can catch,
|
|
159
|
+
* from about 15,000 deep, though a parse nested 22,000 deep still runs Bun's stack out. Each
|
|
160
|
+
* iterator helper's next calls the one before directly, past QuickJS's checks, so under Bun a
|
|
161
|
+
* chain of 30,000 runs the module's own 1 MiB stack out instead, and the module traps: the stack
|
|
162
|
+
* sits first in its memory, so an overflow wraps below address 0 to past the memory's end.
|
|
163
|
+
*/
|
|
164
|
+
export declare const MAX_STACK_BYTES: number;
|
|
165
|
+
export declare const DEFAULT_STACK_BYTES: number;
|
|
166
|
+
/**
|
|
167
|
+
* The deepest nesting of arrays and objects a result may have. QuickJS's stack check measures the
|
|
168
|
+
* module's own stack, which the C recursion of JSON's parse and stringify barely uses, so under
|
|
169
|
+
* Node a parse nested about 8,000 deep (5,000 with V8's optimizing tier alone) overflows the
|
|
170
|
+
* host's stack first, and the engine crashes (under Bun, QuickJS's check comes first). A deeper
|
|
171
|
+
* result is unfit, since the call took effect. A script's own data isn't held to this, and nested
|
|
172
|
+
* thousands deep, it can crash its own run (see MAX_STACK_BYTES).
|
|
173
|
+
*/
|
|
174
|
+
export declare const MAX_RESULT_DEPTH = 2000;
|
|
175
|
+
/** Instantiates the committed module with these limits and slots. One instance per child. */
|
|
176
|
+
export declare function loadEngine(limits: EngineLimits, slots: EngineSlots): Promise<Engine>;
|
|
177
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/code-execution/engine.ts"],"names":[],"mappings":"AAcA,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/D;;;;;;;;OAQG;IACH,SAAS,IAAI,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,SAAS,IAAI,IAAI,CAAC;IAClB,4EAA4E;IAC5E,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,yCAAyC;AACzC,MAAM,MAAM,QAAQ;AAClB,wGAAwG;AACtG;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE;AACrB;;;GAGG;GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE;AACjD;;;;;GAKG;GACD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AACrE;;;;;;;;GAQG;GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AACnE,gDAAgD;GAC9C;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE5B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG;IAAE,KAAK,CAAC,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEtE,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IACnE;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/F,uHAAuH;IACvH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,sGAAsG;AACtG,qBAAa,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;CACF;AAKD,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAChD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAqB,CAAC;AACnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,QAAa,CAAC;AAC1C,eAAO,MAAM,mBAAmB,QAAkB,CAAC;AACnD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AA2ErC,6FAA6F;AAC7F,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqV1F"}
|