@animalabs/agent-framework 0.32.0 → 0.34.0
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 +340 -22
- package/dist/src/admission/admit.d.ts +18 -0
- package/dist/src/admission/admit.d.ts.map +1 -1
- package/dist/src/admission/admit.js +16 -3
- package/dist/src/admission/admit.js.map +1 -1
- package/dist/src/agent.d.ts +208 -80
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +345 -113
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/mcp-server-core.d.ts.map +1 -1
- package/dist/src/api/mcp-server-core.js +50 -12
- package/dist/src/api/mcp-server-core.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +4 -20
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/append-all.d.ts +5 -0
- package/dist/src/append-all.d.ts.map +1 -0
- package/dist/src/append-all.js +8 -0
- package/dist/src/append-all.js.map +1 -0
- package/dist/src/code-execution/isolate/scripts.d.ts +12 -8
- package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
- package/dist/src/code-execution/isolate/scripts.js +24 -0
- package/dist/src/code-execution/isolate/scripts.js.map +1 -1
- package/dist/src/config-checks.d.ts +7 -0
- package/dist/src/config-checks.d.ts.map +1 -1
- package/dist/src/config-checks.js +14 -0
- package/dist/src/config-checks.js.map +1 -1
- package/dist/src/context-manager-errors.d.ts +25 -0
- package/dist/src/context-manager-errors.d.ts.map +1 -0
- package/dist/src/context-manager-errors.js +31 -0
- package/dist/src/context-manager-errors.js.map +1 -0
- package/dist/src/context-options.d.ts +70 -0
- package/dist/src/context-options.d.ts.map +1 -0
- package/dist/src/context-options.js +90 -0
- package/dist/src/context-options.js.map +1 -0
- package/dist/src/cut-off-round.js +4 -4
- package/dist/src/deferred-import.d.ts +93 -0
- package/dist/src/deferred-import.d.ts.map +1 -0
- package/dist/src/deferred-import.js +177 -0
- package/dist/src/deferred-import.js.map +1 -0
- package/dist/src/dendrite/audience.d.ts +223 -0
- package/dist/src/dendrite/audience.d.ts.map +1 -0
- package/dist/src/dendrite/audience.js +202 -0
- package/dist/src/dendrite/audience.js.map +1 -0
- package/dist/src/dendrite/index.d.ts +5 -3
- package/dist/src/dendrite/index.d.ts.map +1 -1
- package/dist/src/dendrite/index.js +2 -1
- package/dist/src/dendrite/index.js.map +1 -1
- package/dist/src/dendrite/presets.d.ts +10 -5
- package/dist/src/dendrite/presets.d.ts.map +1 -1
- package/dist/src/dendrite/presets.js +17 -5
- package/dist/src/dendrite/presets.js.map +1 -1
- package/dist/src/dendrite/registry.d.ts +62 -7
- package/dist/src/dendrite/registry.d.ts.map +1 -1
- package/dist/src/dendrite/registry.js +183 -12
- package/dist/src/dendrite/registry.js.map +1 -1
- package/dist/src/dendrite/types.d.ts +91 -8
- package/dist/src/dendrite/types.d.ts.map +1 -1
- package/dist/src/failure-text.d.ts +36 -0
- package/dist/src/failure-text.d.ts.map +1 -0
- package/dist/src/failure-text.js +89 -0
- package/dist/src/failure-text.js.map +1 -0
- package/dist/src/foreign-rounds.d.ts +69 -0
- package/dist/src/foreign-rounds.d.ts.map +1 -0
- package/dist/src/foreign-rounds.js +152 -0
- package/dist/src/foreign-rounds.js.map +1 -0
- package/dist/src/framework.d.ts +2064 -842
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +8586 -3739
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +125 -21
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +487 -72
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/gate/index.d.ts +1 -1
- package/dist/src/gate/index.d.ts.map +1 -1
- package/dist/src/gate/index.js.map +1 -1
- package/dist/src/gate/reply-judge.d.ts +4 -0
- package/dist/src/gate/reply-judge.d.ts.map +1 -1
- package/dist/src/gate/reply-judge.js +12 -3
- package/dist/src/gate/reply-judge.js.map +1 -1
- package/dist/src/gate/rule-scope.d.ts +30 -0
- package/dist/src/gate/rule-scope.d.ts.map +1 -0
- package/dist/src/gate/rule-scope.js +41 -0
- package/dist/src/gate/rule-scope.js.map +1 -0
- package/dist/src/gate/suppress-script-worker.d.ts +2 -0
- package/dist/src/gate/suppress-script-worker.d.ts.map +1 -0
- package/dist/src/gate/suppress-script-worker.js +103 -0
- package/dist/src/gate/suppress-script-worker.js.map +1 -0
- package/dist/src/gate/suppress-scripts.d.ts +105 -0
- package/dist/src/gate/suppress-scripts.d.ts.map +1 -0
- package/dist/src/gate/suppress-scripts.js +403 -0
- package/dist/src/gate/suppress-scripts.js.map +1 -0
- package/dist/src/gate/suppression-review.d.ts +143 -0
- package/dist/src/gate/suppression-review.d.ts.map +1 -0
- package/dist/src/gate/suppression-review.js +463 -0
- package/dist/src/gate/suppression-review.js.map +1 -0
- package/dist/src/gate/suppression-stats.d.ts +125 -0
- package/dist/src/gate/suppression-stats.d.ts.map +1 -0
- package/dist/src/gate/suppression-stats.js +214 -0
- package/dist/src/gate/suppression-stats.js.map +1 -0
- package/dist/src/gate/types.d.ts +142 -7
- package/dist/src/gate/types.d.ts.map +1 -1
- package/dist/src/gate/wake-onboarding.d.ts +119 -0
- package/dist/src/gate/wake-onboarding.d.ts.map +1 -0
- package/dist/src/gate/wake-onboarding.js +277 -0
- package/dist/src/gate/wake-onboarding.js.map +1 -0
- package/dist/src/heartbeat/heartbeat.js +1 -1
- package/dist/src/heartbeat/heartbeat.js.map +1 -1
- package/dist/src/held-writes.d.ts +31 -23
- package/dist/src/held-writes.d.ts.map +1 -1
- package/dist/src/held-writes.js +44 -59
- package/dist/src/held-writes.js.map +1 -1
- package/dist/src/index.d.ts +6 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/inference-bounds.d.ts +2 -1
- package/dist/src/inference-bounds.d.ts.map +1 -1
- package/dist/src/inference-bounds.js +9 -6
- package/dist/src/inference-bounds.js.map +1 -1
- package/dist/src/jsonrpc-envelope.d.ts +69 -0
- package/dist/src/jsonrpc-envelope.d.ts.map +1 -0
- package/dist/src/jsonrpc-envelope.js +66 -0
- package/dist/src/jsonrpc-envelope.js.map +1 -0
- package/dist/src/mcpl/channel-registry.d.ts +188 -28
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +426 -70
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/checkpoint-manager.d.ts +2 -4
- 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/feature-set-manager.d.ts +2 -4
- package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
- package/dist/src/mcpl/feature-set-manager.js.map +1 -1
- package/dist/src/mcpl/inbound-source.d.ts +2 -1
- package/dist/src/mcpl/inbound-source.d.ts.map +1 -1
- package/dist/src/mcpl/inbound-source.js +2 -1
- package/dist/src/mcpl/inbound-source.js.map +1 -1
- package/dist/src/mcpl/inference-router.d.ts +6 -6
- package/dist/src/mcpl/inference-router.d.ts.map +1 -1
- package/dist/src/mcpl/inference-router.js.map +1 -1
- package/dist/src/mcpl/modern-connection.d.ts +109 -15
- package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
- package/dist/src/mcpl/modern-connection.js +593 -86
- package/dist/src/mcpl/modern-connection.js.map +1 -1
- package/dist/src/mcpl/protocol-family.d.ts +3 -1
- package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
- package/dist/src/mcpl/protocol-family.js +15 -9
- package/dist/src/mcpl/protocol-family.js.map +1 -1
- package/dist/src/mcpl/push-coalescer.d.ts +132 -22
- package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
- package/dist/src/mcpl/push-coalescer.js +105 -15
- package/dist/src/mcpl/push-coalescer.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +9 -7
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +50 -28
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +165 -72
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
- package/dist/src/mcpl/tool-classes.js +3 -0
- package/dist/src/mcpl/tool-classes.js.map +1 -1
- package/dist/src/mcpl/tool-presence.d.ts.map +1 -1
- package/dist/src/mcpl/tool-presence.js +10 -6
- package/dist/src/mcpl/tool-presence.js.map +1 -1
- package/dist/src/mcpl/toolset-host.d.ts.map +1 -1
- package/dist/src/mcpl/toolset-host.js +7 -6
- package/dist/src/mcpl/toolset-host.js.map +1 -1
- package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
- package/dist/src/mcpl/toolsets-module.js +2 -1
- package/dist/src/mcpl/toolsets-module.js.map +1 -1
- package/dist/src/mcpl/types.d.ts +33 -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 +24 -1
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +68 -18
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/discord/index.d.ts +45 -8
- package/dist/src/modules/discord/index.d.ts.map +1 -1
- package/dist/src/modules/discord/index.js +238 -87
- package/dist/src/modules/discord/index.js.map +1 -1
- package/dist/src/modules/health/index.js +2 -2
- package/dist/src/modules/health/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts +59 -0
- package/dist/src/modules/history/index.d.ts.map +1 -1
- package/dist/src/modules/history/index.js +432 -67
- package/dist/src/modules/history/index.js.map +1 -1
- package/dist/src/modules/history/semantic.d.ts +6 -5
- package/dist/src/modules/history/semantic.d.ts.map +1 -1
- package/dist/src/modules/history/semantic.js +18 -25
- package/dist/src/modules/history/semantic.js.map +1 -1
- package/dist/src/modules/workspace/disk-agreement.d.ts +1 -1
- package/dist/src/modules/workspace/disk-agreement.js +1 -1
- package/dist/src/modules/workspace/index.d.ts +28 -7
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +80 -25
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +2 -1
- 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 +3 -2
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/notice-tags.d.ts +20 -9
- package/dist/src/notice-tags.d.ts.map +1 -1
- package/dist/src/notice-tags.js +20 -9
- package/dist/src/notice-tags.js.map +1 -1
- package/dist/src/operator-log.d.ts +36 -3
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js +2 -2
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/presentation.d.ts +747 -0
- package/dist/src/presentation.d.ts.map +1 -0
- package/dist/src/presentation.js +1437 -0
- package/dist/src/presentation.js.map +1 -0
- package/dist/src/prose-drafts.d.ts +15 -11
- package/dist/src/prose-drafts.d.ts.map +1 -1
- package/dist/src/prose-drafts.js +16 -12
- package/dist/src/prose-drafts.js.map +1 -1
- package/dist/src/read-marks.d.ts +192 -0
- package/dist/src/read-marks.d.ts.map +1 -0
- package/dist/src/read-marks.js +242 -0
- package/dist/src/read-marks.js.map +1 -0
- package/dist/src/reasoning-loss.d.ts +5 -0
- package/dist/src/reasoning-loss.d.ts.map +1 -0
- package/dist/src/reasoning-loss.js +8 -0
- package/dist/src/reasoning-loss.js.map +1 -0
- package/dist/src/recovery/offline-branch.d.ts +91 -6
- package/dist/src/recovery/offline-branch.d.ts.map +1 -1
- package/dist/src/recovery/offline-branch.js +277 -32
- package/dist/src/recovery/offline-branch.js.map +1 -1
- package/dist/src/recovery/recover-cli.js +24 -4
- package/dist/src/recovery/recover-cli.js.map +1 -1
- package/dist/src/send-tools.d.ts +5 -9
- package/dist/src/send-tools.d.ts.map +1 -1
- package/dist/src/send-tools.js +40 -7
- package/dist/src/send-tools.js.map +1 -1
- package/dist/src/sent-rows.js +1 -1
- package/dist/src/stored-injections.d.ts +2 -2
- package/dist/src/stored-injections.js +2 -2
- package/dist/src/stored-removal.d.ts +17 -4
- package/dist/src/stored-removal.d.ts.map +1 -1
- package/dist/src/stored-removal.js +29 -5
- package/dist/src/stored-removal.js.map +1 -1
- package/dist/src/supplied-text.d.ts +1 -1
- package/dist/src/supplied-text.js +3 -3
- package/dist/src/supplied-text.js.map +1 -1
- package/dist/src/thinking-drops.d.ts +2 -0
- package/dist/src/thinking-drops.d.ts.map +1 -1
- package/dist/src/thinking-drops.js.map +1 -1
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +38 -9
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts +12 -1
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +42 -8
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/tune-out/coordinator.d.ts +1170 -81
- package/dist/src/tune-out/coordinator.d.ts.map +1 -1
- package/dist/src/tune-out/coordinator.js +3732 -369
- package/dist/src/tune-out/coordinator.js.map +1 -1
- package/dist/src/tune-out/tools.d.ts +114 -17
- package/dist/src/tune-out/tools.d.ts.map +1 -1
- package/dist/src/tune-out/tools.js +89 -28
- package/dist/src/tune-out/tools.js.map +1 -1
- package/dist/src/tune-out/window-anchor.d.ts +143 -0
- package/dist/src/tune-out/window-anchor.d.ts.map +1 -0
- package/dist/src/tune-out/window-anchor.js +202 -0
- package/dist/src/tune-out/window-anchor.js.map +1 -0
- package/dist/src/types/agent.d.ts +121 -25
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/events.d.ts +2 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +72 -17
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/types/inference-log.d.ts +1 -0
- package/dist/src/types/inference-log.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +180 -69
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +573 -39
- package/dist/src/types/trace.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/admission/admit.ts +32 -3
- package/src/agent.ts +392 -132
- package/src/api/mcp-server-core.ts +54 -17
- package/src/api/server.ts +4 -23
- package/src/append-all.ts +6 -0
- package/src/code-execution/isolate/scripts.ts +28 -3
- package/src/config-checks.ts +14 -0
- package/src/context-manager-errors.ts +37 -0
- package/src/context-options.ts +106 -0
- package/src/cut-off-round.ts +4 -4
- package/src/deferred-import.ts +239 -0
- package/src/dendrite/audience.ts +315 -0
- package/src/dendrite/index.ts +14 -2
- package/src/dendrite/presets.ts +18 -6
- package/src/dendrite/registry.ts +213 -14
- package/src/dendrite/types.ts +92 -8
- package/src/failure-text.ts +88 -0
- package/src/foreign-rounds.ts +199 -0
- package/src/framework.ts +8796 -3813
- package/src/gate/event-gate.ts +518 -91
- package/src/gate/index.ts +3 -0
- package/src/gate/reply-judge.ts +12 -3
- package/src/gate/rule-scope.ts +45 -0
- package/src/gate/suppress-script-worker.ts +89 -0
- package/src/gate/suppress-scripts.ts +414 -0
- package/src/gate/suppression-review.ts +517 -0
- package/src/gate/suppression-stats.ts +314 -0
- package/src/gate/types.ts +148 -7
- package/src/gate/wake-onboarding.ts +309 -0
- package/src/heartbeat/heartbeat.ts +1 -1
- package/src/held-writes.ts +49 -60
- package/src/index.ts +10 -2
- package/src/inference-bounds.ts +11 -6
- package/src/jsonrpc-envelope.ts +81 -0
- package/src/mcpl/channel-registry.ts +513 -116
- package/src/mcpl/checkpoint-manager.ts +3 -2
- package/src/mcpl/feature-set-manager.ts +2 -1
- package/src/mcpl/inbound-source.ts +2 -1
- package/src/mcpl/inference-router.ts +7 -4
- package/src/mcpl/modern-connection.ts +629 -91
- package/src/mcpl/protocol-family.ts +15 -9
- package/src/mcpl/push-coalescer.ts +193 -34
- package/src/mcpl/push-handler.ts +10 -5
- package/src/mcpl/server-connection.ts +169 -75
- package/src/mcpl/tool-classes.ts +3 -0
- package/src/mcpl/tool-presence.ts +10 -5
- package/src/mcpl/toolset-host.ts +7 -6
- package/src/mcpl/toolsets-module.ts +2 -1
- package/src/mcpl/types.ts +33 -6
- package/src/module-registry.ts +73 -17
- package/src/modules/discord/index.ts +230 -82
- package/src/modules/health/index.ts +2 -2
- package/src/modules/history/index.ts +439 -70
- package/src/modules/history/semantic.ts +18 -24
- package/src/modules/workspace/disk-agreement.ts +1 -1
- package/src/modules/workspace/index.ts +89 -26
- package/src/modules/workspace/observe.ts +2 -1
- package/src/modules/workspace/reconcile.ts +3 -2
- package/src/notice-tags.ts +21 -9
- package/src/operator-log.ts +36 -3
- package/src/presentation.ts +1678 -0
- package/src/prose-drafts.ts +16 -12
- package/src/read-marks.ts +328 -0
- package/src/reasoning-loss.ts +7 -0
- package/src/recovery/offline-branch.ts +350 -35
- package/src/recovery/recover-cli.ts +23 -4
- package/src/send-tools.ts +40 -7
- package/src/sent-rows.ts +1 -1
- package/src/stored-injections.ts +2 -2
- package/src/stored-removal.ts +31 -7
- package/src/supplied-text.ts +3 -3
- package/src/thinking-drops.ts +2 -0
- package/src/tool-presentation.ts +34 -9
- package/src/tool-result-guard.ts +41 -7
- package/src/tune-out/coordinator.ts +4121 -472
- package/src/tune-out/tools.ts +162 -44
- package/src/tune-out/window-anchor.ts +277 -0
- package/src/types/agent.ts +122 -25
- package/src/types/events.ts +2 -0
- package/src/types/framework.ts +73 -17
- package/src/types/inference-log.ts +1 -0
- package/src/types/module.ts +181 -68
- package/src/types/trace.ts +607 -43
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The periodic review of what suppress rules hid (SuppressionReviewOptions).
|
|
3
|
+
*
|
|
4
|
+
* A suppress rule is the agent's own filter on its attention, and a filter
|
|
5
|
+
* written a little too wide hides what the agent would have wanted to see,
|
|
6
|
+
* with nothing in its context to show that it did. So every `intervalMs`
|
|
7
|
+
* (two hours by default), for each rule that hid events since the last
|
|
8
|
+
* review, a small model (Claude Haiku 5.5 by default) reads the rule's
|
|
9
|
+
* description, its match and the events it hid (a sample spread across the
|
|
10
|
+
* period, past `maxEventsPerRule`), and flags any that don't fit the
|
|
11
|
+
* description or that the agent would plausibly need to see. The agent is
|
|
12
|
+
* told, in a `[suppression review]` notice, what each rule hid and what was
|
|
13
|
+
* flagged, with the flagged events shown; a flagged event wakes it.
|
|
14
|
+
*
|
|
15
|
+
* What was reviewed is kept in a small file beside gate.json
|
|
16
|
+
* (`suppression-review.json`), written as the review starts and after each
|
|
17
|
+
* review: the time reviewed through, so a restart picks up where the last
|
|
18
|
+
* review stopped; for a rule the reviewer couldn't answer about, where its
|
|
19
|
+
* events still to be reviewed begin, so the next review takes them again; and
|
|
20
|
+
* each rule's description as last seen (the framework tells the review when a
|
|
21
|
+
* rule hides a row), so the events a rule hid before it was removed are still
|
|
22
|
+
* judged against it. The review reads a sample of each rule's events, sharing
|
|
23
|
+
* a fixed budget of text among them (EVENT_TEXT_BUDGET), not every event whole.
|
|
24
|
+
* The reviewer reads; it never decides what's suppressed and never edits a
|
|
25
|
+
* rule. The notice is the framework's own and is never suppressed.
|
|
26
|
+
*/
|
|
27
|
+
import { NativeFormatter } from '@animalabs/membrane';
|
|
28
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
29
|
+
import { dirname } from 'node:path';
|
|
30
|
+
import { NOTICE_TAG } from '../notice-tags.js';
|
|
31
|
+
export const DEFAULT_REVIEW_INTERVAL_MS = 2 * 60 * 60 * 1000;
|
|
32
|
+
export const MIN_REVIEW_INTERVAL_MS = 10 * 60 * 1000;
|
|
33
|
+
export const MAX_REVIEW_INTERVAL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
34
|
+
export const DEFAULT_REVIEW_MODEL = 'claude-haiku-5-5';
|
|
35
|
+
export const DEFAULT_REVIEW_MAX_EVENTS = 60;
|
|
36
|
+
const MAX_REVIEW_EVENTS = 200;
|
|
37
|
+
const DEFAULT_REVIEW_TIMEOUT_MS = 60_000;
|
|
38
|
+
/** How long after a start the first review may run, at the soonest: the host settles first. */
|
|
39
|
+
const FIRST_REVIEW_DELAY_MS = 60_000;
|
|
40
|
+
/**
|
|
41
|
+
* Characters of event text the reviewer reads for one rule, shared among its
|
|
42
|
+
* sample: a short event takes what it needs and a long one the rest
|
|
43
|
+
* (eventTextCap), so what makes a long message matter past its start is
|
|
44
|
+
* read. Chosen, not measured: with the default sample it keeps one rule's
|
|
45
|
+
* request to roughly 8,000 input tokens, which a review every two hours can
|
|
46
|
+
* afford.
|
|
47
|
+
*/
|
|
48
|
+
export const EVENT_TEXT_BUDGET = 24_000;
|
|
49
|
+
/** Characters of a rule's script the reviewer reads. */
|
|
50
|
+
const SCRIPT_CHARS = 3_000;
|
|
51
|
+
/** Characters of a flagged event's text the notice shows. */
|
|
52
|
+
const NOTICE_EVENT_CHARS = 200;
|
|
53
|
+
/** Flagged events the notice shows per rule; the rest are counted. */
|
|
54
|
+
const NOTICE_FLAGGED_SHOWN = 5;
|
|
55
|
+
/** Output tokens a verdict may take, adaptive thinking included. */
|
|
56
|
+
const VERDICT_MAX_TOKENS = 4_096;
|
|
57
|
+
const REVIEW_PARTICIPANT = 'suppression-review';
|
|
58
|
+
const entriesOf = (value) => value && typeof value === 'object' && !Array.isArray(value) ? Object.entries(value) : [];
|
|
59
|
+
/** The review state a file holds, or null when there's none; one that can't be used is named in the log and read as none. */
|
|
60
|
+
function readState(path) {
|
|
61
|
+
if (!existsSync(path))
|
|
62
|
+
return null;
|
|
63
|
+
try {
|
|
64
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
65
|
+
if (raw?.version !== 1 || typeof raw.reviewedThrough !== 'number' || !Number.isFinite(raw.reviewedThrough)) {
|
|
66
|
+
throw new Error('it holds no version 1 state with a reviewedThrough time');
|
|
67
|
+
}
|
|
68
|
+
const descriptions = new Map();
|
|
69
|
+
for (const [name, text] of entriesOf(raw.descriptions))
|
|
70
|
+
if (typeof text === 'string')
|
|
71
|
+
descriptions.set(name, text);
|
|
72
|
+
const retryFrom = new Map();
|
|
73
|
+
for (const [name, ms] of entriesOf(raw.retryFrom))
|
|
74
|
+
if (typeof ms === 'number' && Number.isFinite(ms))
|
|
75
|
+
retryFrom.set(name, ms);
|
|
76
|
+
return { version: 1, reviewedThrough: raw.reviewedThrough, retryFrom, descriptions };
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Moved aside, so the review's first save doesn't write over a file a later release wrote.
|
|
80
|
+
const aside = `${path}.unreadable`;
|
|
81
|
+
let moved = '';
|
|
82
|
+
try {
|
|
83
|
+
renameSync(path, aside);
|
|
84
|
+
moved = ` It's kept as ${aside}.`;
|
|
85
|
+
}
|
|
86
|
+
catch { /* the log says what was read */ }
|
|
87
|
+
console.error(`[gate] the suppression review's progress in ${path} can't be read, so it reviews from now on.${moved}`, error);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** The options as the review runs them: each at its default or within its bounds. */
|
|
92
|
+
export function reviewSettings(options = {}) {
|
|
93
|
+
const interval = typeof options.intervalMs === 'number' && Number.isFinite(options.intervalMs) ? options.intervalMs : DEFAULT_REVIEW_INTERVAL_MS;
|
|
94
|
+
const maxEvents = typeof options.maxEventsPerRule === 'number' && Number.isFinite(options.maxEventsPerRule)
|
|
95
|
+
? Math.round(options.maxEventsPerRule) : DEFAULT_REVIEW_MAX_EVENTS;
|
|
96
|
+
return {
|
|
97
|
+
intervalMs: Math.min(MAX_REVIEW_INTERVAL_MS, Math.max(MIN_REVIEW_INTERVAL_MS, interval)),
|
|
98
|
+
model: options.model || DEFAULT_REVIEW_MODEL,
|
|
99
|
+
notify: options.notify === 'flagged' ? 'flagged' : 'always',
|
|
100
|
+
wakeOnFlag: options.wakeOnFlag !== false,
|
|
101
|
+
maxEventsPerRule: Math.min(MAX_REVIEW_EVENTS, Math.max(1, maxEvents)),
|
|
102
|
+
timeoutMs: typeof options.timeoutMs === 'number' && options.timeoutMs > 0 ? options.timeoutMs : DEFAULT_REVIEW_TIMEOUT_MS,
|
|
103
|
+
effort: options.effort ?? 'low',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** `max` of `items`, spread evenly from the first to the last; all of them when there are no more. */
|
|
107
|
+
export function spread(items, max) {
|
|
108
|
+
if (items.length <= max)
|
|
109
|
+
return [...items];
|
|
110
|
+
if (max === 1)
|
|
111
|
+
return [items[items.length - 1]];
|
|
112
|
+
return Array.from({ length: max }, (_, k) => items[Math.round((k * (items.length - 1)) / (max - 1))]);
|
|
113
|
+
}
|
|
114
|
+
const oneLine = (text) => text.replace(/\s+/g, ' ').trim();
|
|
115
|
+
function cut(text, max) {
|
|
116
|
+
const chars = [...text];
|
|
117
|
+
return chars.length <= max ? text : `${chars.slice(0, max - 1).join('')}…`;
|
|
118
|
+
}
|
|
119
|
+
const REVIEW_SYSTEM = [
|
|
120
|
+
'You review a filter an AI agent set on its own attention. The agent wrote a rule that hides some incoming events',
|
|
121
|
+
'from its context, and described in its own words what the rule is for. You are shown that description, the',
|
|
122
|
+
"rule's match criteria, and events the rule hid, numbered.",
|
|
123
|
+
'',
|
|
124
|
+
'Flag an event when it falls outside what the description says the rule is for. Also flag one the agent would',
|
|
125
|
+
'plausibly need to see whatever the description says: something said to the agent by name or asking it something,',
|
|
126
|
+
"a warning, an error about the agent's own actions, or a person in distress or danger. Don't flag an event only",
|
|
127
|
+
'because it is interesting, or because the rule hides many events.',
|
|
128
|
+
'',
|
|
129
|
+
'Answer with one JSON object and nothing else:',
|
|
130
|
+
'{"fits": <true when you flag nothing>, "flagged": [<the numbers of the flagged events>], "note": "<one short sentence>"}',
|
|
131
|
+
].join('\n');
|
|
132
|
+
/**
|
|
133
|
+
* The most characters any event may take so that the sample fits `budget`:
|
|
134
|
+
* every event shorter than it is read whole, and the budget they leave is
|
|
135
|
+
* shared among the rest.
|
|
136
|
+
*/
|
|
137
|
+
export function eventTextCap(lengths, budget) {
|
|
138
|
+
const sorted = [...lengths].sort((a, b) => a - b);
|
|
139
|
+
let left = budget;
|
|
140
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
141
|
+
const share = Math.floor(left / (sorted.length - i));
|
|
142
|
+
if (sorted[i] > share)
|
|
143
|
+
return share;
|
|
144
|
+
left -= sorted[i];
|
|
145
|
+
}
|
|
146
|
+
return Number.POSITIVE_INFINITY;
|
|
147
|
+
}
|
|
148
|
+
/** The reviewer's request for one rule's events. */
|
|
149
|
+
export function reviewRequest(rule, events, hidden, period, settings) {
|
|
150
|
+
const script = rule.script !== undefined
|
|
151
|
+
? `Of the events it matches, it hides those this script of the agent's returns true for (state is the rule's own memory between events):\n${cut(rule.script, SCRIPT_CHARS)}\n`
|
|
152
|
+
: '';
|
|
153
|
+
const texts = events.map((e) => oneLine(e.text));
|
|
154
|
+
const cap = eventTextCap(texts.map((t) => [...t].length), EVENT_TEXT_BUDGET);
|
|
155
|
+
const listing = events.map((e, i) => `#${i + 1} [${e.at}] ${e.eventType}${e.source ? ` · ${e.source}` : ''}${e.channel ? ` · ${e.channel}` : ''}${e.author ? ` · ${e.author}` : ''}: ${cut(texts[i], cap)}`).join('\n');
|
|
156
|
+
const text = [
|
|
157
|
+
`The agent's rule ${JSON.stringify(rule.name)} hides events from its context. The agent described it as:`,
|
|
158
|
+
JSON.stringify(rule.description),
|
|
159
|
+
rule.match !== undefined ? `The rule matches: ${JSON.stringify(rule.match)}` : '',
|
|
160
|
+
script,
|
|
161
|
+
`From ${new Date(period.fromMs).toISOString()} to ${new Date(period.toMs).toISOString()} it hid ${hidden} event${hidden === 1 ? '' : 's'}. `
|
|
162
|
+
+ (events.length < hidden ? `Here are ${events.length} of them, spread across that time:` : 'Here they are:'),
|
|
163
|
+
'',
|
|
164
|
+
listing,
|
|
165
|
+
'',
|
|
166
|
+
'Which of these, if any, should the agent have seen? Answer with the JSON object.',
|
|
167
|
+
].filter((line, i, all) => line !== '' || (i > 0 && all[i - 1] !== '')).join('\n');
|
|
168
|
+
return {
|
|
169
|
+
system: REVIEW_SYSTEM,
|
|
170
|
+
messages: [{ participant: 'user', content: [{ type: 'text', text }] }],
|
|
171
|
+
config: { model: settings.model, maxTokens: VERDICT_MAX_TOKENS },
|
|
172
|
+
assistantParticipant: REVIEW_PARTICIPANT,
|
|
173
|
+
...(settings.effort !== 'none' ? { providerParams: { output_config: { effort: settings.effort } } } : {}),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/** The reviewer's answer read from its text, or undefined when it holds none this can use. */
|
|
177
|
+
export function parseReviewAnswer(text, count) {
|
|
178
|
+
const start = text.indexOf('{');
|
|
179
|
+
const end = text.lastIndexOf('}');
|
|
180
|
+
if (start < 0 || end <= start)
|
|
181
|
+
return undefined;
|
|
182
|
+
let raw;
|
|
183
|
+
try {
|
|
184
|
+
raw = JSON.parse(text.slice(start, end + 1));
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
if (!raw || typeof raw !== 'object')
|
|
190
|
+
return undefined;
|
|
191
|
+
const { fits, flagged, note } = raw;
|
|
192
|
+
if (flagged !== undefined && !Array.isArray(flagged))
|
|
193
|
+
return undefined;
|
|
194
|
+
const named = flagged ?? [];
|
|
195
|
+
const numbers = [...new Set(named.filter((n) => Number.isInteger(n) && n >= 1 && n <= count))].sort((a, b) => a - b);
|
|
196
|
+
if (typeof fits !== 'boolean' && flagged === undefined)
|
|
197
|
+
return undefined;
|
|
198
|
+
// An answer that says they don't all fit, or names events, but names none
|
|
199
|
+
// it was shown can't be taken as "they fit": it's no answer.
|
|
200
|
+
if (numbers.length === 0 && (fits === false || named.length > 0))
|
|
201
|
+
return undefined;
|
|
202
|
+
return { flagged: numbers, note: typeof note === 'string' ? cut(oneLine(note), 300) : '' };
|
|
203
|
+
}
|
|
204
|
+
const clockOf = (ms) => new Date(ms).toISOString().replace(/\.\d{3}Z$/, 'Z');
|
|
205
|
+
/** How long a span is, in the words the notice uses. */
|
|
206
|
+
function spanOf(ms) {
|
|
207
|
+
const minutes = Math.round(ms / 60_000);
|
|
208
|
+
if (minutes < 1)
|
|
209
|
+
return 'under a minute';
|
|
210
|
+
if (minutes < 120)
|
|
211
|
+
return `${minutes} minute${minutes === 1 ? '' : 's'}`;
|
|
212
|
+
const hours = Math.round(minutes / 60);
|
|
213
|
+
return hours < 48 ? `${hours} hours` : `${Math.round(hours / 24)} days`;
|
|
214
|
+
}
|
|
215
|
+
/** The `[suppression review]` notice the agent is told; `dump` when it has dump_suppressed to point at. */
|
|
216
|
+
export function reviewNoticeText(summary, opts = {}) {
|
|
217
|
+
const lines = [
|
|
218
|
+
`[${NOTICE_TAG.suppressionReview}] Since ${clockOf(summary.fromMs)} (${spanOf(summary.toMs - summary.fromMs)}), `
|
|
219
|
+
+ `your suppress rules hid ${summary.total} event${summary.total === 1 ? '' : 's'}`
|
|
220
|
+
+ (summary.flagged > 0 ? `, and the reviewer flagged ${summary.flagged} that may not fit their rule:` : '.'),
|
|
221
|
+
];
|
|
222
|
+
for (const r of summary.rules) {
|
|
223
|
+
const named = `"${r.rule}"${r.description ? ` (${r.description})` : ''}${r.inForce ? '' : ', since removed,'}`;
|
|
224
|
+
const read = r.read < r.suppressed ? `read ${r.read} of them` : 'read them';
|
|
225
|
+
let said;
|
|
226
|
+
if (r.verdict === 'fits')
|
|
227
|
+
said = `The reviewer ${read} and found they fit.`;
|
|
228
|
+
else if (r.verdict === 'flagged')
|
|
229
|
+
said = `The reviewer ${read} and flagged ${r.flagged.length}${r.note ? `: ${r.note}` : '.'}`;
|
|
230
|
+
else if (r.verdict === 'unjudged')
|
|
231
|
+
said = 'There was no description to judge them against.';
|
|
232
|
+
else
|
|
233
|
+
said = "The reviewer couldn't answer this time; they'll be reviewed again next time, as far back as a week.";
|
|
234
|
+
lines.push(`- ${named} hid ${r.suppressed}. ${said}`);
|
|
235
|
+
// The flagged events, each cut short: the first few, and how many more.
|
|
236
|
+
for (const e of r.flagged.slice(0, NOTICE_FLAGGED_SHOWN)) {
|
|
237
|
+
lines.push(` · [${e.at}]${e.source ? ` ${e.source}` : ''}${e.author ? ` · ${e.author}` : ''}: ${JSON.stringify(cut(oneLine(e.text), NOTICE_EVENT_CHARS))} (id ${e.id})`);
|
|
238
|
+
}
|
|
239
|
+
if (r.flagged.length > NOTICE_FLAGGED_SHOWN)
|
|
240
|
+
lines.push(` · and ${r.flagged.length - NOTICE_FLAGGED_SHOWN} more`);
|
|
241
|
+
}
|
|
242
|
+
lines.push(`${opts.dump === false ? 'suppression_stats shows' : 'suppression_stats and dump_suppressed show'} what a rule hid; wake_add_rule edits a rule, and wake_remove_rule removes one.`);
|
|
243
|
+
return lines.join('\n');
|
|
244
|
+
}
|
|
245
|
+
export class SuppressionReview {
|
|
246
|
+
deps;
|
|
247
|
+
settings;
|
|
248
|
+
now;
|
|
249
|
+
timer = null;
|
|
250
|
+
running = null;
|
|
251
|
+
stopped = false;
|
|
252
|
+
inFlight = new Set();
|
|
253
|
+
reviewedThrough;
|
|
254
|
+
retryFrom;
|
|
255
|
+
descriptions;
|
|
256
|
+
constructor(deps, options = {}) {
|
|
257
|
+
this.deps = deps;
|
|
258
|
+
this.settings = reviewSettings(options);
|
|
259
|
+
this.now = deps.now ?? Date.now;
|
|
260
|
+
const state = deps.statePath ? readState(deps.statePath) : null;
|
|
261
|
+
this.reviewedThrough = state?.reviewedThrough ?? this.now();
|
|
262
|
+
this.retryFrom = state?.retryFrom ?? new Map();
|
|
263
|
+
this.descriptions = state?.descriptions ?? new Map();
|
|
264
|
+
// Where the review starts is kept at once, so a restart before the first
|
|
265
|
+
// review still reviews from here.
|
|
266
|
+
if (!state)
|
|
267
|
+
this.saveState();
|
|
268
|
+
}
|
|
269
|
+
/** A rule's description as it stands when it hides a row: the one its rows are judged against later, though the rule be gone by then. */
|
|
270
|
+
noteRule(name, description) {
|
|
271
|
+
if (this.descriptions.get(name) === description)
|
|
272
|
+
return;
|
|
273
|
+
this.descriptions.set(name, description);
|
|
274
|
+
// Kept at once: a restart before the next review still judges the rows by it.
|
|
275
|
+
this.saveState();
|
|
276
|
+
}
|
|
277
|
+
get intervalMs() { return this.settings.intervalMs; }
|
|
278
|
+
get nextReviewAfter() { return this.reviewedThrough + this.settings.intervalMs; }
|
|
279
|
+
/** Schedule reviews: the first when the interval since the last review is up, and no sooner than a minute from now. */
|
|
280
|
+
start() {
|
|
281
|
+
if (this.stopped || this.timer)
|
|
282
|
+
return;
|
|
283
|
+
this.schedule(Math.max(FIRST_REVIEW_DELAY_MS, this.nextReviewAfter - this.now()));
|
|
284
|
+
}
|
|
285
|
+
stop() {
|
|
286
|
+
this.stopped = true;
|
|
287
|
+
if (this.timer)
|
|
288
|
+
clearTimeout(this.timer);
|
|
289
|
+
this.timer = null;
|
|
290
|
+
for (const controller of this.inFlight)
|
|
291
|
+
controller.abort();
|
|
292
|
+
}
|
|
293
|
+
schedule(delayMs) {
|
|
294
|
+
if (this.stopped)
|
|
295
|
+
return;
|
|
296
|
+
if (this.timer)
|
|
297
|
+
clearTimeout(this.timer);
|
|
298
|
+
this.timer = setTimeout(() => {
|
|
299
|
+
this.timer = null;
|
|
300
|
+
void this.runOnce()
|
|
301
|
+
.catch((error) => console.error('[gate] the suppression review failed:', error))
|
|
302
|
+
.finally(() => this.schedule(this.settings.intervalMs));
|
|
303
|
+
}, Math.min(delayMs, 2_147_483_647));
|
|
304
|
+
this.timer.unref?.();
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Review what was hidden since the last review, tell the agent, and record
|
|
308
|
+
* how far it reviewed. A call while a review runs gets that review's
|
|
309
|
+
* result. Null when no review ran: no agent is registered, the host isn't
|
|
310
|
+
* taking one now (mayRun, asked again before the agent is told), or the
|
|
311
|
+
* agent changed while the reviewer was asked; the next review covers the
|
|
312
|
+
* period. A review whose notice couldn't be written throws, and the next
|
|
313
|
+
* review covers its period again.
|
|
314
|
+
*/
|
|
315
|
+
runOnce() {
|
|
316
|
+
if (this.running)
|
|
317
|
+
return this.running;
|
|
318
|
+
this.running = this.review().finally(() => { this.running = null; });
|
|
319
|
+
return this.running;
|
|
320
|
+
}
|
|
321
|
+
async review() {
|
|
322
|
+
const agentName = this.deps.agentName();
|
|
323
|
+
if (!agentName || this.stopped || (this.deps.mayRun && !this.deps.mayRun()))
|
|
324
|
+
return null;
|
|
325
|
+
const fromMs = this.reviewedThrough;
|
|
326
|
+
const toMs = this.now();
|
|
327
|
+
const inForce = new Map(this.deps.rules().map((r) => [r.name, r]));
|
|
328
|
+
for (const rule of inForce.values())
|
|
329
|
+
this.descriptions.set(rule.name, rule.description);
|
|
330
|
+
// A rule the reviewer couldn't answer about last time is reviewed from
|
|
331
|
+
// where its unreviewed events begin.
|
|
332
|
+
const fromOf = (name) => Math.min(this.retryFrom.get(name) ?? fromMs, fromMs);
|
|
333
|
+
const earliest = [...this.retryFrom.values()].reduce((min, from) => Math.min(min, from), fromMs);
|
|
334
|
+
const byRule = new Map();
|
|
335
|
+
for (const record of this.deps.records(agentName, earliest, toMs)) {
|
|
336
|
+
if (Date.parse(record.at) < fromOf(record.rule))
|
|
337
|
+
continue;
|
|
338
|
+
const list = byRule.get(record.rule) ?? [];
|
|
339
|
+
list.push(record);
|
|
340
|
+
byRule.set(record.rule, list);
|
|
341
|
+
}
|
|
342
|
+
const rules = [];
|
|
343
|
+
for (const [name, records] of byRule) {
|
|
344
|
+
if (this.stopped)
|
|
345
|
+
return null;
|
|
346
|
+
const rule = inForce.get(name);
|
|
347
|
+
const description = rule?.description ?? this.descriptions.get(name);
|
|
348
|
+
const base = { rule: name, ...(description ? { description } : {}), inForce: rule !== undefined, suppressed: records.length };
|
|
349
|
+
if (!description) {
|
|
350
|
+
rules.push({ ...base, read: 0, verdict: 'unjudged', flagged: [] });
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
const sample = spread(records, this.settings.maxEventsPerRule);
|
|
354
|
+
rules.push(await this.judge(agentName, { name, description, ...(rule ?? {}) }, sample, records.length, { fromMs: fromOf(name), toMs }, base));
|
|
355
|
+
}
|
|
356
|
+
const summary = {
|
|
357
|
+
fromMs: rules.length > 0 ? rules.reduce((min, r) => Math.min(min, fromOf(r.rule)), Infinity) : fromMs, toMs, rules,
|
|
358
|
+
total: rules.reduce((n, r) => n + r.suppressed, 0),
|
|
359
|
+
flagged: rules.reduce((n, r) => n + r.flagged.length, 0),
|
|
360
|
+
};
|
|
361
|
+
// Stopped, quiesced, or the agent changed while the reviewer was asked:
|
|
362
|
+
// nothing is told and nothing recorded, so a later review takes this
|
|
363
|
+
// period again.
|
|
364
|
+
if (this.stopped || (this.deps.mayRun && !this.deps.mayRun()) || this.deps.agentName() !== agentName)
|
|
365
|
+
return null;
|
|
366
|
+
const tell = summary.total > 0 && (this.settings.notify === 'always' || summary.flagged > 0);
|
|
367
|
+
if (tell) {
|
|
368
|
+
this.deps.deliver(agentName, reviewNoticeText(summary, { dump: this.deps.dumpAvailable?.() ?? true }), summary.flagged > 0 && this.settings.wakeOnFlag, summary);
|
|
369
|
+
}
|
|
370
|
+
this.deps.emitTrace?.({
|
|
371
|
+
type: 'gate:suppression-review',
|
|
372
|
+
agentName, fromMs: earliest, toMs, total: summary.total, flagged: summary.flagged, delivered: tell,
|
|
373
|
+
rules: rules.map((r) => ({ rule: r.rule, suppressed: r.suppressed, read: r.read, verdict: r.verdict, flagged: r.flagged.length })),
|
|
374
|
+
});
|
|
375
|
+
for (const r of rules) {
|
|
376
|
+
if (r.verdict === 'flagged' || r.verdict === 'error') {
|
|
377
|
+
console.error(`[gate] suppression review: "${r.rule}" hid ${r.suppressed}, ${r.verdict}${r.verdict === 'flagged' ? ` ${r.flagged.length}` : ''}${r.note ? `: ${r.note}` : ''}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
this.reviewedThrough = toMs;
|
|
381
|
+
// The rules the reviewer couldn't answer about keep where their events
|
|
382
|
+
// begin; every other rule is reviewed through now.
|
|
383
|
+
for (const r of rules) {
|
|
384
|
+
// Kept for at most a week of events, so a reviewer that keeps failing doesn't read back without end.
|
|
385
|
+
if (r.verdict === 'error')
|
|
386
|
+
this.retryFrom.set(r.rule, Math.max(fromOf(r.rule), toMs - MAX_REVIEW_INTERVAL_MS));
|
|
387
|
+
else
|
|
388
|
+
this.retryFrom.delete(r.rule);
|
|
389
|
+
}
|
|
390
|
+
// Descriptions are kept for the rules in force and the ones with events
|
|
391
|
+
// still to review; the rest have nothing left to be judged.
|
|
392
|
+
// The rules in force read again now, so a rule added (and its rows
|
|
393
|
+
// noted) while the reviewer was asked keeps its description. One that's
|
|
394
|
+
// gone is dropped once nothing of it is left to judge: its rows were
|
|
395
|
+
// judged here, or it was in force when this review began and hid
|
|
396
|
+
// nothing in its period. One noted during this review is kept: its rows
|
|
397
|
+
// come in the next.
|
|
398
|
+
const nowInForce = new Set(this.deps.rules().map((r) => r.name));
|
|
399
|
+
for (const name of [...this.descriptions.keys()]) {
|
|
400
|
+
if (nowInForce.has(name) || this.retryFrom.has(name))
|
|
401
|
+
continue;
|
|
402
|
+
if (byRule.has(name) || inForce.has(name))
|
|
403
|
+
this.descriptions.delete(name);
|
|
404
|
+
}
|
|
405
|
+
this.saveState();
|
|
406
|
+
return summary;
|
|
407
|
+
}
|
|
408
|
+
async judge(agentName, rule, sample, hidden, period, base) {
|
|
409
|
+
const controller = new AbortController();
|
|
410
|
+
this.inFlight.add(controller);
|
|
411
|
+
const timer = setTimeout(() => controller.abort(), this.settings.timeoutMs);
|
|
412
|
+
timer.unref?.();
|
|
413
|
+
try {
|
|
414
|
+
const request = reviewRequest(rule, sample, hidden, period, this.settings);
|
|
415
|
+
const response = await this.deps.membraneFor(agentName).complete(request, { signal: controller.signal, formatter: new NativeFormatter() });
|
|
416
|
+
const usage = response.details?.usage;
|
|
417
|
+
if (usage)
|
|
418
|
+
this.deps.recordUsage?.(agentName, usage);
|
|
419
|
+
const text = response.content
|
|
420
|
+
.filter((b) => b.type === 'text')
|
|
421
|
+
.map((b) => b.text)
|
|
422
|
+
.join('\n');
|
|
423
|
+
const answer = parseReviewAnswer(text, sample.length);
|
|
424
|
+
if (!answer) {
|
|
425
|
+
return { ...base, read: sample.length, verdict: 'error', flagged: [], note: `its answer held no verdict (stop: ${response.stopReason})` };
|
|
426
|
+
}
|
|
427
|
+
const flagged = answer.flagged.map((n) => sample[n - 1]);
|
|
428
|
+
return {
|
|
429
|
+
...base, read: sample.length, verdict: flagged.length > 0 ? 'flagged' : 'fits', flagged,
|
|
430
|
+
...(answer.note ? { note: answer.note } : {}),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
const message = controller.signal.aborted && !this.stopped
|
|
435
|
+
? `no answer within ${Math.round(this.settings.timeoutMs / 1000)} s`
|
|
436
|
+
: cut(oneLine(error instanceof Error ? error.message : String(error)), 160);
|
|
437
|
+
return { ...base, read: 0, verdict: 'error', flagged: [], note: message };
|
|
438
|
+
}
|
|
439
|
+
finally {
|
|
440
|
+
clearTimeout(timer);
|
|
441
|
+
this.inFlight.delete(controller);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
saveState() {
|
|
445
|
+
const path = this.deps.statePath;
|
|
446
|
+
if (!path)
|
|
447
|
+
return;
|
|
448
|
+
try {
|
|
449
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
450
|
+
const temp = `${path}.${process.pid}.tmp`;
|
|
451
|
+
const state = {
|
|
452
|
+
version: 1, reviewedThrough: this.reviewedThrough,
|
|
453
|
+
retryFrom: Object.fromEntries(this.retryFrom), descriptions: Object.fromEntries(this.descriptions),
|
|
454
|
+
};
|
|
455
|
+
writeFileSync(temp, `${JSON.stringify(state, null, 2)}\n`);
|
|
456
|
+
renameSync(temp, path);
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
console.error(`[gate] the suppression review couldn't record its progress in ${path}, so a restart reviews from its start time:`, error);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=suppression-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppression-review.js","sourceRoot":"","sources":["../../../src/gate/suppression-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the agent's suppress rules have kept out of its context
|
|
3
|
+
* (`suppression_stats`), read from the stored rows themselves: each carries
|
|
4
|
+
* the record a suppress rule stamped on it as it arrived
|
|
5
|
+
* (`metadata.suppressed = { rule, eventType }`, the framework's
|
|
6
|
+
* suppressedRow). The rows are the record, so the counts cover every start
|
|
7
|
+
* of the host and follow the branch the store is on, and nothing beside
|
|
8
|
+
* them is kept.
|
|
9
|
+
*/
|
|
10
|
+
/** A stored row as these stats read it: the parts of context-manager's StoredMessage they use. */
|
|
11
|
+
export interface SuppressionStatsRow {
|
|
12
|
+
id: string;
|
|
13
|
+
timestamp: Date | number | string;
|
|
14
|
+
content: ReadonlyArray<{
|
|
15
|
+
type: string;
|
|
16
|
+
text?: unknown;
|
|
17
|
+
}>;
|
|
18
|
+
metadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** A rule in gate.json, as the stats name it. */
|
|
21
|
+
export interface SuppressRuleInForce {
|
|
22
|
+
name: string;
|
|
23
|
+
/** Events it suppressed since this process started (the gate's matchCount for it). */
|
|
24
|
+
sinceStart: number;
|
|
25
|
+
}
|
|
26
|
+
export interface SuppressionStatsOptions {
|
|
27
|
+
/** Only this rule's rows. */
|
|
28
|
+
rule?: string;
|
|
29
|
+
/** How many of each rule's newest rows to show, with a preview. Default 3, at most 20. */
|
|
30
|
+
recent?: number;
|
|
31
|
+
/** Only rows stored at or after this time (ms). */
|
|
32
|
+
sinceMs?: number;
|
|
33
|
+
}
|
|
34
|
+
/** One suppressed row, as the stats show it. */
|
|
35
|
+
export interface SuppressedEventShown {
|
|
36
|
+
id: string;
|
|
37
|
+
at: string;
|
|
38
|
+
eventType: string;
|
|
39
|
+
source?: string;
|
|
40
|
+
channel?: string;
|
|
41
|
+
author?: string;
|
|
42
|
+
preview: string;
|
|
43
|
+
}
|
|
44
|
+
/** One rule's stats. */
|
|
45
|
+
export interface RuleSuppressionStats {
|
|
46
|
+
rule: string;
|
|
47
|
+
/** Whether gate.json has a suppress rule of that name now. */
|
|
48
|
+
inForce: boolean;
|
|
49
|
+
/** Present for a rule in force: what it suppressed since this process started. */
|
|
50
|
+
sinceStart?: number;
|
|
51
|
+
/** Stored rows it suppressed (within `since`, when given). */
|
|
52
|
+
suppressed: number;
|
|
53
|
+
/** Their text, in characters. */
|
|
54
|
+
characters: number;
|
|
55
|
+
first?: string;
|
|
56
|
+
last?: string;
|
|
57
|
+
/** Rows by the server (or module source) they came from, the most first; past ten, the rest as "(others)". */
|
|
58
|
+
bySource: Record<string, number>;
|
|
59
|
+
/** Rows by the event type they arrived as. */
|
|
60
|
+
byEventType: Record<string, number>;
|
|
61
|
+
/** The newest rows, newest first. */
|
|
62
|
+
recent: SuppressedEventShown[];
|
|
63
|
+
}
|
|
64
|
+
export interface SuppressionStats {
|
|
65
|
+
rules: RuleSuppressionStats[];
|
|
66
|
+
/** Every stored suppressed row counted (within `since`, when given). */
|
|
67
|
+
total: number;
|
|
68
|
+
totalCharacters: number;
|
|
69
|
+
}
|
|
70
|
+
/** Longest preview shown, in characters. */
|
|
71
|
+
export declare const SUPPRESSION_PREVIEW_CHARS = 160;
|
|
72
|
+
/** Most recent rows shown per rule. */
|
|
73
|
+
export declare const MAX_RECENT = 20;
|
|
74
|
+
/** The record a row carries when a suppress rule took it, or undefined. */
|
|
75
|
+
export declare function suppressionRecordOf(metadata: Record<string, unknown> | undefined): {
|
|
76
|
+
rule: string;
|
|
77
|
+
eventType?: string;
|
|
78
|
+
source?: string;
|
|
79
|
+
} | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* The stats for `rows` (a message slot, oldest first), with every suppress
|
|
82
|
+
* rule in force listed even where it has hidden nothing yet. Rules in force
|
|
83
|
+
* come first, in gate.json's order; rules no longer in force follow, the
|
|
84
|
+
* most recently active first.
|
|
85
|
+
*/
|
|
86
|
+
export declare function suppressionStats(rows: Iterable<SuppressionStatsRow>, inForce: readonly SuppressRuleInForce[], opts?: SuppressionStatsOptions): SuppressionStats;
|
|
87
|
+
/** One suppressed row, as a dump or the review reads it: its text in full, any other block named. */
|
|
88
|
+
export interface SuppressedEventRecord {
|
|
89
|
+
id: string;
|
|
90
|
+
/** ISO 8601. */
|
|
91
|
+
at: string;
|
|
92
|
+
rule: string;
|
|
93
|
+
eventType: string;
|
|
94
|
+
source?: string;
|
|
95
|
+
channel?: string;
|
|
96
|
+
author?: string;
|
|
97
|
+
/** Its text blocks, joined; a block of another kind as `[image]`, `[audio]` and so on. */
|
|
98
|
+
text: string;
|
|
99
|
+
}
|
|
100
|
+
export interface SuppressedRecordsOptions {
|
|
101
|
+
rule?: string;
|
|
102
|
+
/** Rows stored at or after this time (ms). */
|
|
103
|
+
sinceMs?: number;
|
|
104
|
+
/** Rows stored before this time (ms). */
|
|
105
|
+
untilMs?: number;
|
|
106
|
+
}
|
|
107
|
+
/** The suppressed rows among `rows`, oldest first, their text in full; times are when each was stored. */
|
|
108
|
+
export declare function suppressedRecords(rows: Iterable<SuppressionStatsRow>, opts?: SuppressedRecordsOptions): SuppressedEventRecord[];
|
|
109
|
+
/** A dump's file formats: one JSON object a line, or a transcript to read. */
|
|
110
|
+
export type SuppressedDumpFormat = 'jsonl' | 'text';
|
|
111
|
+
/**
|
|
112
|
+
* A dump's file content, at most `maxBytes` (UTF-8): the newest records that
|
|
113
|
+
* fit, oldest first, and how many older ones were left out to fit. A
|
|
114
|
+
* transcript opens with a header naming what it holds (`title`, given how
|
|
115
|
+
* many it holds and the oldest's time) and, when some were left out, how many.
|
|
116
|
+
*/
|
|
117
|
+
export declare function renderSuppressedDump(records: readonly SuppressedEventRecord[], format: SuppressedDumpFormat, opts: {
|
|
118
|
+
maxBytes: number;
|
|
119
|
+
title: string | ((written: number, first: string) => string);
|
|
120
|
+
}): {
|
|
121
|
+
content: string;
|
|
122
|
+
written: number;
|
|
123
|
+
omitted: number;
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=suppression-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppression-stats.d.ts","sourceRoot":"","sources":["../../../src/gate/suppression-stats.ts"],"names":[],"mappings":"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"}
|