footprintjs 10.0.1 → 10.2.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/AGENTS.md +2 -1
- package/CLAUDE.md +61 -7
- package/README.md +136 -312
- package/dist/esm/index.d.ts +62 -2
- package/dist/esm/index.js +13 -6
- package/dist/esm/lib/attempt/anySignal.d.ts +19 -0
- package/dist/esm/lib/attempt/anySignal.js +39 -0
- package/dist/esm/lib/attempt/call.d.ts +88 -0
- package/dist/esm/lib/attempt/call.js +129 -0
- package/dist/esm/lib/attempt/category.d.ts +37 -0
- package/dist/esm/lib/attempt/category.js +131 -0
- package/dist/esm/lib/attempt/correlation.d.ts +95 -0
- package/dist/esm/lib/attempt/correlation.js +178 -0
- package/dist/esm/lib/attempt/deadline.d.ts +44 -0
- package/dist/esm/lib/attempt/deadline.js +101 -0
- package/dist/esm/lib/attempt/decision.d.ts +52 -0
- package/dist/esm/lib/attempt/decision.js +134 -0
- package/dist/esm/lib/attempt/effect.d.ts +76 -0
- package/dist/esm/lib/attempt/effect.js +160 -0
- package/dist/esm/lib/attempt/errors.d.ts +41 -0
- package/dist/esm/lib/attempt/errors.js +44 -0
- package/dist/esm/lib/attempt/index.d.ts +18 -0
- package/dist/esm/lib/attempt/index.js +15 -0
- package/dist/esm/lib/attempt/name.d.ts +21 -0
- package/dist/esm/lib/attempt/name.js +43 -0
- package/dist/esm/lib/attempt/observed.d.ts +66 -0
- package/dist/esm/lib/attempt/observed.js +171 -0
- package/dist/esm/lib/attempt/policy.d.ts +45 -0
- package/dist/esm/lib/attempt/policy.js +83 -0
- package/dist/esm/lib/attempt/record.d.ts +11 -0
- package/dist/esm/lib/attempt/record.js +24 -0
- package/dist/esm/lib/attempt/retryLoopContext.d.ts +18 -0
- package/dist/esm/lib/attempt/retryLoopContext.js +24 -0
- package/dist/esm/lib/attempt/retryLoopTypes.d.ts +18 -0
- package/dist/esm/lib/attempt/retryLoopTypes.js +2 -0
- package/dist/esm/lib/attempt/runner.d.ts +157 -0
- package/dist/esm/lib/attempt/runner.js +523 -0
- package/dist/esm/lib/attempt/standalone.d.ts +47 -0
- package/dist/esm/lib/attempt/standalone.js +126 -0
- package/dist/esm/lib/attempt/types.d.ts +453 -0
- package/dist/esm/lib/attempt/types.js +16 -0
- package/dist/esm/lib/budget/index.d.ts +9 -0
- package/dist/esm/lib/budget/index.js +9 -0
- package/dist/esm/lib/budget/timeBudget.d.ts +136 -0
- package/dist/esm/lib/budget/timeBudget.js +666 -0
- package/dist/esm/lib/builder/FlowChartBuilder.d.ts +88 -3
- package/dist/esm/lib/builder/FlowChartBuilder.js +199 -9
- package/dist/esm/lib/builder/retryLoop.d.ts +56 -0
- package/dist/esm/lib/builder/retryLoop.js +283 -0
- package/dist/esm/lib/builder/types.d.ts +35 -1
- package/dist/esm/lib/builder/types.js +1 -1
- package/dist/esm/lib/decide/decide.js +2 -2
- package/dist/esm/lib/decide/index.d.ts +1 -1
- package/dist/esm/lib/decide/index.js +2 -2
- package/dist/esm/lib/decide/types.d.ts +3 -0
- package/dist/esm/lib/decide/types.js +1 -8
- package/dist/esm/lib/engine/graph/StageNode.d.ts +11 -1
- package/dist/esm/lib/engine/graph/StageNode.js +1 -1
- package/dist/esm/lib/engine/graph/prefixNodeTree.js +5 -1
- package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
- package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
- package/dist/esm/lib/engine/handlers/ResumeEntry.js +3 -1
- package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
- package/dist/esm/lib/engine/handlers/StageRunner.d.ts +8 -1
- package/dist/esm/lib/engine/handlers/StageRunner.js +36 -9
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +24 -5
- package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
- package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
- package/dist/esm/lib/engine/handlers/stageError.d.ts +9 -0
- package/dist/esm/lib/engine/handlers/stageError.js +23 -1
- package/dist/esm/lib/engine/index.d.ts +2 -2
- package/dist/esm/lib/engine/index.js +1 -1
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +68 -40
- package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
- package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
- package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
- package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +61 -9
- package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
- package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
- package/dist/esm/lib/engine/narrative/formatting/sentences.d.ts +23 -0
- package/dist/esm/lib/engine/narrative/formatting/sentences.js +127 -1
- package/dist/esm/lib/engine/narrative/index.d.ts +2 -2
- package/dist/esm/lib/engine/narrative/index.js +1 -1
- package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +27 -21
- package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
- package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
- package/dist/esm/lib/engine/narrative/recorders/index.d.ts +1 -1
- package/dist/esm/lib/engine/narrative/recorders/index.js +1 -1
- package/dist/esm/lib/engine/narrative/types.d.ts +74 -5
- package/dist/esm/lib/engine/narrative/types.js +1 -1
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +194 -118
- package/dist/esm/lib/engine/traversalContext.d.ts +7 -2
- package/dist/esm/lib/engine/traversalContext.js +6 -3
- package/dist/esm/lib/engine/types.d.ts +52 -57
- package/dist/esm/lib/engine/types.js +1 -1
- package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
- package/dist/esm/lib/errors/terminalFailure.js +60 -0
- package/dist/esm/lib/{decide → filter}/evaluator.d.ts +7 -2
- package/dist/esm/lib/filter/evaluator.js +135 -0
- package/dist/esm/lib/ids/idempotencyKey.d.ts +14 -0
- package/dist/esm/lib/ids/idempotencyKey.js +24 -0
- package/dist/esm/lib/memory/StageContext.d.ts +123 -3
- package/dist/esm/lib/memory/StageContext.js +245 -4
- package/dist/esm/lib/memory/attention.d.ts +26 -0
- package/dist/esm/lib/memory/attention.js +171 -0
- package/dist/esm/lib/memory/borrowedMutation.d.ts +8 -0
- package/dist/esm/lib/memory/borrowedMutation.js +14 -1
- package/dist/esm/lib/memory/frameTypes.d.ts +38 -0
- package/dist/esm/lib/memory/frameTypes.js +3 -1
- package/dist/esm/lib/memory/redaction.d.ts +12 -0
- package/dist/esm/lib/memory/redaction.js +54 -5
- package/dist/esm/lib/pause/record.js +10 -1
- package/dist/esm/lib/pause/types.d.ts +19 -0
- package/dist/esm/lib/pause/types.js +17 -1
- package/dist/esm/lib/reactive/createTypedScope.js +3 -1
- package/dist/esm/lib/reactive/types.d.ts +36 -4
- package/dist/esm/lib/reactive/types.js +3 -1
- package/dist/esm/lib/recorder/AttemptRecorder.d.ts +141 -0
- package/dist/esm/lib/recorder/AttemptRecorder.js +412 -0
- package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +36 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.js +50 -2
- package/dist/esm/lib/recorder/EmitRecorder.d.ts +3 -0
- package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
- package/dist/esm/lib/recorder/InOutRecorder.d.ts +37 -1
- package/dist/esm/lib/recorder/InOutRecorder.js +75 -6
- package/dist/esm/lib/recorder/QualityRecorder.d.ts +32 -5
- package/dist/esm/lib/recorder/QualityRecorder.js +87 -29
- package/dist/esm/lib/recorder/TopologyRecorder.d.ts +35 -5
- package/dist/esm/lib/recorder/TopologyRecorder.js +76 -2
- package/dist/esm/lib/recorder/attemptMetricRows.d.ts +11 -0
- package/dist/esm/lib/recorder/attemptMetricRows.js +202 -0
- package/dist/esm/lib/recorder/attemptMetrics.d.ts +7 -0
- package/dist/esm/lib/recorder/attemptMetrics.js +165 -0
- package/dist/esm/lib/recorder/attemptMetricsTypes.d.ts +114 -0
- package/dist/esm/lib/recorder/attemptMetricsTypes.js +2 -0
- package/dist/esm/lib/recorder/attemptOTel.d.ts +78 -0
- package/dist/esm/lib/recorder/attemptOTel.js +107 -0
- package/dist/esm/lib/recorder/attemptSeries.d.ts +81 -0
- package/dist/esm/lib/recorder/attemptSeries.js +103 -0
- package/dist/esm/lib/recorder/hooks.d.ts +9 -0
- package/dist/esm/lib/recorder/hooks.js +4 -1
- package/dist/esm/lib/runner/DeferredObserverTier.js +13 -1
- package/dist/esm/lib/runner/ExecutionRuntime.d.ts +54 -6
- package/dist/esm/lib/runner/ExecutionRuntime.js +57 -5
- package/dist/esm/lib/runner/FlowChartExecutor.d.ts +46 -2
- package/dist/esm/lib/runner/FlowChartExecutor.js +330 -101
- package/dist/esm/lib/runner/RunnableChart.d.ts +6 -0
- package/dist/esm/lib/runner/RunnableChart.js +5 -1
- package/dist/esm/lib/runner/attach.d.ts +2 -1
- package/dist/esm/lib/runner/attach.js +8 -2
- package/dist/esm/lib/runner/checkpoint.js +3 -1
- package/dist/esm/lib/runner/deadline.d.ts +42 -0
- package/dist/esm/lib/runner/deadline.js +90 -0
- package/dist/esm/lib/runner/index.d.ts +3 -1
- package/dist/esm/lib/runner/index.js +2 -1
- package/dist/esm/lib/runner/options.d.ts +17 -0
- package/dist/esm/lib/runner/options.js +3 -1
- package/dist/esm/lib/runner/recordSink.d.ts +128 -0
- package/dist/esm/lib/runner/recordSink.js +296 -0
- package/dist/esm/lib/runner/resume.d.ts +3 -0
- package/dist/esm/lib/runner/resume.js +22 -2
- package/dist/esm/lib/runner/snapshot.d.ts +2 -2
- package/dist/esm/lib/runner/snapshot.js +6 -2
- package/dist/esm/lib/scope/ScopeFacade.d.ts +118 -4
- package/dist/esm/lib/scope/ScopeFacade.js +304 -7
- package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +17 -3
- package/dist/esm/lib/scope/recorders/DebugRecorder.js +79 -13
- package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +10 -0
- package/dist/esm/lib/scope/recorders/MetricRecorder.js +15 -2
- package/dist/esm/lib/scope/runtime.d.ts +3 -0
- package/dist/esm/lib/scope/runtime.js +1 -1
- package/dist/esm/lib/scope/types.d.ts +6 -0
- package/dist/esm/lib/scope/types.js +1 -1
- package/dist/esm/lib/sinks/fileSink.d.ts +135 -0
- package/dist/esm/lib/sinks/fileSink.js +387 -0
- package/dist/esm/recorders.d.ts +8 -2
- package/dist/esm/recorders.js +7 -1
- package/dist/esm/sinks.d.ts +23 -0
- package/dist/esm/sinks.js +23 -0
- package/dist/esm/trace.d.ts +2 -2
- package/dist/esm/trace.js +1 -1
- package/dist/index.js +77 -60
- package/dist/lib/attempt/anySignal.js +43 -0
- package/dist/lib/attempt/call.js +134 -0
- package/dist/lib/attempt/category.js +136 -0
- package/dist/lib/attempt/correlation.js +186 -0
- package/dist/lib/attempt/deadline.js +112 -0
- package/dist/lib/attempt/decision.js +139 -0
- package/dist/lib/attempt/effect.js +174 -0
- package/dist/lib/attempt/errors.js +49 -0
- package/dist/lib/attempt/index.js +26 -0
- package/dist/lib/attempt/name.js +48 -0
- package/dist/lib/attempt/observed.js +177 -0
- package/dist/lib/attempt/policy.js +92 -0
- package/dist/lib/attempt/record.js +29 -0
- package/dist/lib/attempt/retryLoopContext.js +31 -0
- package/dist/lib/attempt/retryLoopTypes.js +3 -0
- package/dist/lib/attempt/runner.js +530 -0
- package/dist/lib/attempt/standalone.js +130 -0
- package/dist/lib/attempt/types.js +17 -0
- package/dist/lib/budget/index.js +17 -0
- package/dist/lib/budget/timeBudget.js +674 -0
- package/dist/lib/builder/FlowChartBuilder.js +199 -9
- package/dist/lib/builder/retryLoop.js +287 -0
- package/dist/lib/builder/types.js +1 -1
- package/dist/lib/decide/decide.js +2 -2
- package/dist/lib/decide/index.js +2 -2
- package/dist/lib/decide/types.js +1 -8
- package/dist/lib/engine/graph/StageNode.js +1 -1
- package/dist/lib/engine/graph/prefixNodeTree.js +5 -1
- package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
- package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
- package/dist/lib/engine/handlers/ResumeEntry.js +3 -1
- package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
- package/dist/lib/engine/handlers/StageRunner.js +36 -9
- package/dist/lib/engine/handlers/SubflowExecutor.js +24 -5
- package/dist/lib/engine/handlers/commitStage.js +24 -5
- package/dist/lib/engine/handlers/stageError.js +26 -2
- package/dist/lib/engine/index.js +1 -1
- package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +67 -39
- package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
- package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +60 -8
- package/dist/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
- package/dist/lib/engine/narrative/formatting/sentences.js +131 -2
- package/dist/lib/engine/narrative/index.js +1 -1
- package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
- package/dist/lib/engine/narrative/recorders/index.js +1 -1
- package/dist/lib/engine/narrative/types.js +1 -1
- package/dist/lib/engine/traversal/FlowchartTraverser.js +192 -116
- package/dist/lib/engine/traversalContext.js +6 -3
- package/dist/lib/engine/types.js +1 -1
- package/dist/lib/errors/terminalFailure.js +64 -0
- package/dist/lib/filter/evaluator.js +139 -0
- package/dist/lib/ids/idempotencyKey.js +28 -0
- package/dist/lib/memory/StageContext.js +246 -5
- package/dist/lib/memory/attention.js +175 -0
- package/dist/lib/memory/borrowedMutation.js +16 -2
- package/dist/lib/memory/frameTypes.js +3 -1
- package/dist/lib/memory/redaction.js +54 -5
- package/dist/lib/pause/record.js +10 -1
- package/dist/lib/pause/types.js +17 -1
- package/dist/lib/reactive/createTypedScope.js +3 -1
- package/dist/lib/reactive/types.js +3 -1
- package/dist/lib/recorder/AttemptRecorder.js +417 -0
- package/dist/lib/recorder/ControlDepRecorder.js +50 -2
- package/dist/lib/recorder/EmitRecorder.js +1 -1
- package/dist/lib/recorder/InOutRecorder.js +75 -6
- package/dist/lib/recorder/QualityRecorder.js +87 -29
- package/dist/lib/recorder/TopologyRecorder.js +76 -2
- package/dist/lib/recorder/attemptMetricRows.js +209 -0
- package/dist/lib/recorder/attemptMetrics.js +174 -0
- package/dist/lib/recorder/attemptMetricsTypes.js +3 -0
- package/dist/lib/recorder/attemptOTel.js +111 -0
- package/dist/lib/recorder/attemptSeries.js +113 -0
- package/dist/lib/recorder/hooks.js +4 -1
- package/dist/lib/runner/DeferredObserverTier.js +13 -1
- package/dist/lib/runner/ExecutionRuntime.js +57 -5
- package/dist/lib/runner/FlowChartExecutor.js +330 -101
- package/dist/lib/runner/RunnableChart.js +5 -1
- package/dist/lib/runner/attach.js +8 -2
- package/dist/lib/runner/checkpoint.js +3 -1
- package/dist/lib/runner/deadline.js +94 -0
- package/dist/lib/runner/index.js +4 -2
- package/dist/lib/runner/options.js +3 -1
- package/dist/lib/runner/recordSink.js +302 -0
- package/dist/lib/runner/resume.js +22 -2
- package/dist/lib/runner/snapshot.js +6 -2
- package/dist/lib/scope/ScopeFacade.js +303 -6
- package/dist/lib/scope/recorders/DebugRecorder.js +79 -13
- package/dist/lib/scope/recorders/MetricRecorder.js +15 -2
- package/dist/lib/scope/runtime.js +1 -1
- package/dist/lib/scope/types.js +1 -1
- package/dist/lib/sinks/fileSink.js +392 -0
- package/dist/recorders.js +10 -2
- package/dist/sinks.js +32 -0
- package/dist/trace.js +1 -1
- package/dist/types/index.d.ts +62 -2
- package/dist/types/lib/attempt/anySignal.d.ts +19 -0
- package/dist/types/lib/attempt/call.d.ts +88 -0
- package/dist/types/lib/attempt/category.d.ts +37 -0
- package/dist/types/lib/attempt/correlation.d.ts +95 -0
- package/dist/types/lib/attempt/deadline.d.ts +44 -0
- package/dist/types/lib/attempt/decision.d.ts +52 -0
- package/dist/types/lib/attempt/effect.d.ts +76 -0
- package/dist/types/lib/attempt/errors.d.ts +41 -0
- package/dist/types/lib/attempt/index.d.ts +18 -0
- package/dist/types/lib/attempt/name.d.ts +21 -0
- package/dist/types/lib/attempt/observed.d.ts +66 -0
- package/dist/types/lib/attempt/policy.d.ts +45 -0
- package/dist/types/lib/attempt/record.d.ts +11 -0
- package/dist/types/lib/attempt/retryLoopContext.d.ts +18 -0
- package/dist/types/lib/attempt/retryLoopTypes.d.ts +18 -0
- package/dist/types/lib/attempt/runner.d.ts +157 -0
- package/dist/types/lib/attempt/standalone.d.ts +47 -0
- package/dist/types/lib/attempt/types.d.ts +453 -0
- package/dist/types/lib/budget/index.d.ts +9 -0
- package/dist/types/lib/budget/timeBudget.d.ts +136 -0
- package/dist/types/lib/builder/FlowChartBuilder.d.ts +88 -3
- package/dist/types/lib/builder/retryLoop.d.ts +56 -0
- package/dist/types/lib/builder/types.d.ts +35 -1
- package/dist/types/lib/decide/index.d.ts +1 -1
- package/dist/types/lib/decide/types.d.ts +3 -0
- package/dist/types/lib/engine/graph/StageNode.d.ts +11 -1
- package/dist/types/lib/engine/handlers/StageRunner.d.ts +8 -1
- package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
- package/dist/types/lib/engine/handlers/stageError.d.ts +9 -0
- package/dist/types/lib/engine/index.d.ts +2 -2
- package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
- package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
- package/dist/types/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
- package/dist/types/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
- package/dist/types/lib/engine/narrative/formatting/sentences.d.ts +23 -0
- package/dist/types/lib/engine/narrative/index.d.ts +2 -2
- package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +27 -21
- package/dist/types/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
- package/dist/types/lib/engine/narrative/recorders/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/types.d.ts +74 -5
- package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
- package/dist/types/lib/engine/traversalContext.d.ts +7 -2
- package/dist/types/lib/engine/types.d.ts +52 -57
- package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
- package/dist/types/lib/{decide → filter}/evaluator.d.ts +7 -2
- package/dist/types/lib/ids/idempotencyKey.d.ts +14 -0
- package/dist/types/lib/memory/StageContext.d.ts +123 -3
- package/dist/types/lib/memory/attention.d.ts +26 -0
- package/dist/types/lib/memory/borrowedMutation.d.ts +8 -0
- package/dist/types/lib/memory/frameTypes.d.ts +38 -0
- package/dist/types/lib/memory/redaction.d.ts +12 -0
- package/dist/types/lib/pause/types.d.ts +19 -0
- package/dist/types/lib/reactive/types.d.ts +36 -4
- package/dist/types/lib/recorder/AttemptRecorder.d.ts +141 -0
- package/dist/types/lib/recorder/ControlDepRecorder.d.ts +36 -2
- package/dist/types/lib/recorder/EmitRecorder.d.ts +3 -0
- package/dist/types/lib/recorder/InOutRecorder.d.ts +37 -1
- package/dist/types/lib/recorder/QualityRecorder.d.ts +32 -5
- package/dist/types/lib/recorder/TopologyRecorder.d.ts +35 -5
- package/dist/types/lib/recorder/attemptMetricRows.d.ts +11 -0
- package/dist/types/lib/recorder/attemptMetrics.d.ts +7 -0
- package/dist/types/lib/recorder/attemptMetricsTypes.d.ts +114 -0
- package/dist/types/lib/recorder/attemptOTel.d.ts +78 -0
- package/dist/types/lib/recorder/attemptSeries.d.ts +81 -0
- package/dist/types/lib/recorder/hooks.d.ts +9 -0
- package/dist/types/lib/runner/ExecutionRuntime.d.ts +54 -6
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +46 -2
- package/dist/types/lib/runner/RunnableChart.d.ts +6 -0
- package/dist/types/lib/runner/attach.d.ts +2 -1
- package/dist/types/lib/runner/deadline.d.ts +42 -0
- package/dist/types/lib/runner/index.d.ts +3 -1
- package/dist/types/lib/runner/options.d.ts +17 -0
- package/dist/types/lib/runner/recordSink.d.ts +128 -0
- package/dist/types/lib/runner/resume.d.ts +3 -0
- package/dist/types/lib/runner/snapshot.d.ts +2 -2
- package/dist/types/lib/scope/ScopeFacade.d.ts +118 -4
- package/dist/types/lib/scope/recorders/DebugRecorder.d.ts +17 -3
- package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +10 -0
- package/dist/types/lib/scope/runtime.d.ts +3 -0
- package/dist/types/lib/scope/types.d.ts +6 -0
- package/dist/types/lib/sinks/fileSink.d.ts +135 -0
- package/dist/types/recorders.d.ts +8 -2
- package/dist/types/sinks.d.ts +23 -0
- package/dist/types/trace.d.ts +2 -2
- package/package.json +20 -6
- package/dist/esm/lib/decide/evaluator.js +0 -130
- package/dist/lib/decide/evaluator.js +0 -134
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
* ```
|
|
60
60
|
*/
|
|
61
61
|
import type { EmitSourcePosition } from 'foottrace';
|
|
62
|
+
import type { RunCorrelation } from '../attempt/types.js';
|
|
62
63
|
import type { RecorderBundle } from './snapshot.js';
|
|
63
64
|
/**
|
|
64
65
|
* Event delivered to `EmitRecorder.onEmit`.
|
|
@@ -109,6 +110,8 @@ export interface EmitEvent {
|
|
|
109
110
|
* Absent on old/manual events and scopes without a bound engine log.
|
|
110
111
|
*/
|
|
111
112
|
readonly sourcePosition?: EmitSourcePosition;
|
|
113
|
+
/** The run's correlation (10.1) — as on every scope event (`RecorderContext.correlation`). Absent when none. */
|
|
114
|
+
readonly correlation?: RunCorrelation;
|
|
112
115
|
}
|
|
113
116
|
/**
|
|
114
117
|
* Pluggable observer for consumer-emitted structured events.
|
|
@@ -33,6 +33,18 @@
|
|
|
33
33
|
* (it means "in progress" or "paused"). The `getBoundary()` helper
|
|
34
34
|
* returns `{ entry, exit: undefined }` in that case.
|
|
35
35
|
*
|
|
36
|
+
* Attempts (10.1):
|
|
37
|
+
* An `exit` entry carries `attempts` — the count of attempts made inside
|
|
38
|
+
* the boundary, at any depth, by outcome, and how many series gave up —
|
|
39
|
+
* and `failedAttempts`, the failed / timed-out / aborted ones by name. Only
|
|
40
|
+
* series that retried, gave up or timed out count (`recorder/attemptSeries.ts ·
|
|
41
|
+
* isRetryEvidence`), so both fields are absent when nothing retried, and a
|
|
42
|
+
* boundary pair says what it cost to get through. An `entry` never carries
|
|
43
|
+
* them: the cost is known only at the exit — so a boundary that never
|
|
44
|
+
* exits (a run or subflow that failed, e.g. because a stage gave up, or a
|
|
45
|
+
* pause) carries no count; the attempts are then on the execution tree and
|
|
46
|
+
* the attempt-aware recorders (Topology, Debug, Quality).
|
|
47
|
+
*
|
|
36
48
|
* Redaction:
|
|
37
49
|
* Payload redaction is the engine's responsibility (`RedactionPolicy`).
|
|
38
50
|
* By the time payloads reach this recorder via `FlowSubflowEvent` or
|
|
@@ -63,7 +75,8 @@
|
|
|
63
75
|
* .filter((b) => b.subflowPath[1] === 'sf-agent'); // path[0] is the root
|
|
64
76
|
* ```
|
|
65
77
|
*/
|
|
66
|
-
import type { FlowRecorder, FlowRunEvent, FlowSubflowEvent } from '../engine/narrative/types.js';
|
|
78
|
+
import type { FlowAttemptEvent, FlowRecorder, FlowRunEvent, FlowSubflowEvent } from '../engine/narrative/types.js';
|
|
79
|
+
import type { AttemptOutcomeCounts, AttemptRef } from './attemptSeries.js';
|
|
67
80
|
export type InOutPhase = 'entry' | 'exit';
|
|
68
81
|
/** Synthetic id for the top-level run's boundary pair. */
|
|
69
82
|
export declare const ROOT_SUBFLOW_ID = "__root__";
|
|
@@ -111,6 +124,20 @@ export interface InOutEntry {
|
|
|
111
124
|
* Lens uses this to render the root pair as `user → run → user` instead of
|
|
112
125
|
* the regular subflow shape. */
|
|
113
126
|
readonly isRoot: boolean;
|
|
127
|
+
/** `phase: 'exit'` only, and only when something inside retried, gave up or timed out — see {@link InOutAttempts}. */
|
|
128
|
+
readonly attempts?: InOutAttempts;
|
|
129
|
+
/** With `attempts`: the attempts inside that failed, timed out or were aborted, in the order they ended. */
|
|
130
|
+
readonly failedAttempts?: readonly AttemptRef[];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* What it cost to get through a boundary: the attempts made inside it (at any depth) by series that retried, gave
|
|
134
|
+
* up or timed out — `count`, per outcome (`timeout` included), and how many of those series gave up (`exhausted`,
|
|
135
|
+
* `declined`, `no-time-left`).
|
|
136
|
+
*/
|
|
137
|
+
export interface InOutAttempts {
|
|
138
|
+
readonly count: number;
|
|
139
|
+
readonly byOutcome: AttemptOutcomeCounts;
|
|
140
|
+
readonly gaveUp: number;
|
|
114
141
|
}
|
|
115
142
|
export interface InOutRecorderOptions {
|
|
116
143
|
/** ScopeRecorder id. Defaults to `inout-N` (auto-incremented). */
|
|
@@ -132,11 +159,20 @@ export declare class InOutRecorder implements FlowRecorder {
|
|
|
132
159
|
readonly id: string;
|
|
133
160
|
/** 1:N ordered storage with per-step index (Convention 1 — composed). */
|
|
134
161
|
private readonly store;
|
|
162
|
+
/** The root run's attempts — every attempt is inside it. */
|
|
163
|
+
private rootAttempts;
|
|
164
|
+
/** Open subflow boundaries' attempts, by path-prefixed subflowId. */
|
|
165
|
+
private readonly openAttempts;
|
|
135
166
|
constructor(options?: InOutRecorderOptions);
|
|
136
167
|
onRunStart(event: FlowRunEvent): void;
|
|
137
168
|
onRunEnd(event: FlowRunEvent): void;
|
|
138
169
|
onSubflowEntry(event: FlowSubflowEvent): void;
|
|
139
170
|
onSubflowExit(event: FlowSubflowEvent): void;
|
|
171
|
+
/**
|
|
172
|
+
* Counts an attempt in the root boundary and in every open subflow boundary that contains the stage — the
|
|
173
|
+
* subflow the stage ran in is that subflow's id or below it.
|
|
174
|
+
*/
|
|
175
|
+
onAttempt(event: FlowAttemptEvent): void;
|
|
140
176
|
/** All entries in execution order (entry+exit interleaved). */
|
|
141
177
|
getBoundaries(): InOutEntry[];
|
|
142
178
|
/** Entry/exit pair for one chart execution.
|
|
@@ -10,6 +10,17 @@
|
|
|
10
10
|
* - **Accumulate**: progressive quality up to slider position
|
|
11
11
|
* - **Aggregate**: overall pipeline quality score
|
|
12
12
|
*
|
|
13
|
+
* Attempts (10.1): a stage whose retry series GAVE UP (exhausted, declined,
|
|
14
|
+
* no time left) or TIMED OUT is a quality drop at that stage — `drop:
|
|
15
|
+
* 'attempts'`, with the series' `attempts` summary and a factor naming why.
|
|
16
|
+
* A series that gave up never reached `onStageEnd` (the stage failed), so the
|
|
17
|
+
* recorder scores it itself: `0`, the floor, with the keys its last attempt
|
|
18
|
+
* read — which is what `qualityTrace()` walks to pair the drop with its
|
|
19
|
+
* causal parents. A series that timed out and recovered keeps the scoring
|
|
20
|
+
* function's score and gains the flag. Attempts reach a recorder on the FLOW
|
|
21
|
+
* channel (`onAttempt`): attach with `attachCombinedRecorder` to see them —
|
|
22
|
+
* `attachScopeRecorder` scores exactly as before.
|
|
23
|
+
*
|
|
13
24
|
* @example
|
|
14
25
|
* ```typescript
|
|
15
26
|
* const quality = new QualityRecorder((runtimeStageId, context) => {
|
|
@@ -30,6 +41,8 @@
|
|
|
30
41
|
* quality.getLowest(); // { runtimeStageId: 'call-llm#5', entry: { score: 0.7, ... } }
|
|
31
42
|
* ```
|
|
32
43
|
*/
|
|
44
|
+
import type { AttemptSummary } from '../attempt/types.js';
|
|
45
|
+
import type { FlowAttemptEvent } from '../engine/narrative/types.js';
|
|
33
46
|
import type { ReadEvent, ScopeRecorder, StageEvent, WriteEvent } from '../scope/types.js';
|
|
34
47
|
import type { RecorderOperation } from './RecorderOperation.js';
|
|
35
48
|
/** Per-step quality data stored by QualityRecorder. */
|
|
@@ -46,6 +59,10 @@ export interface QualityEntry {
|
|
|
46
59
|
keysRead: string[];
|
|
47
60
|
/** Keys written during this step (for backtracking). */
|
|
48
61
|
keysWritten: string[];
|
|
62
|
+
/** Present when the step's retry series gave up or timed out — a quality drop by attempts (10.1). */
|
|
63
|
+
drop?: 'attempts';
|
|
64
|
+
/** With `drop`: the series at a glance. */
|
|
65
|
+
attempts?: AttemptSummary;
|
|
49
66
|
}
|
|
50
67
|
/**
|
|
51
68
|
* Scoring function called at the end of each stage.
|
|
@@ -76,16 +93,26 @@ export declare class QualityRecorder implements ScopeRecorder {
|
|
|
76
93
|
/** 1:1 per-step storage (Convention 1 — composed, not inherited). */
|
|
77
94
|
private readonly store;
|
|
78
95
|
private readonly scoringFn;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Each execution in flight, by its OWN runtimeStageId (10.1) — every event owns its attribution, so parallel
|
|
98
|
+
* siblings never score under each other's id or with each other's keys (until 10.0 one shared "current stage"
|
|
99
|
+
* buffer did). A retried execution's entry restarts with each attempt: a series that gave up is scored with the
|
|
100
|
+
* keys its last attempt touched. Released at the stage's end, or when a drop consumes it.
|
|
101
|
+
*/
|
|
102
|
+
private readonly inFlight;
|
|
103
|
+
/** Per-series tallies of the series that retried, gave up or timed out. */
|
|
104
|
+
private readonly attemptBook;
|
|
84
105
|
constructor(scoringFn: QualityScoringFn, options?: QualityRecorderOptions);
|
|
85
106
|
onStageStart(event: StageEvent): void;
|
|
86
107
|
onRead(event: ReadEvent): void;
|
|
87
108
|
onWrite(event: WriteEvent): void;
|
|
88
109
|
onStageEnd(event: StageEvent): void;
|
|
110
|
+
/**
|
|
111
|
+
* A series that ended after giving up or timing out is a drop at its stage. `onAttempt` for the last attempt
|
|
112
|
+
* fires after that attempt's `onStageEnd` (when it returned), so a recovered series amends the scored entry; a
|
|
113
|
+
* series that gave up has none, and is scored here.
|
|
114
|
+
*/
|
|
115
|
+
onAttempt(event: FlowAttemptEvent): void;
|
|
89
116
|
/** Translate: quality entry for a specific runtimeStageId. */
|
|
90
117
|
getByKey(runtimeStageId: string): QualityEntry | undefined;
|
|
91
118
|
/** All per-step quality entries as a read-only Map (insertion-ordered). */
|
|
@@ -15,10 +15,16 @@
|
|
|
15
15
|
* three primitive channels, one live graph, queryable at any moment during
|
|
16
16
|
* or after a run.
|
|
17
17
|
*
|
|
18
|
-
* What it records —
|
|
18
|
+
* What it records — FOUR node kinds for complete composition coverage:
|
|
19
19
|
* 1. 'subflow' — via onSubflowEntry (a mounted subflow boundary)
|
|
20
20
|
* 2. 'fork-branch' — via onFork (one node per child, synthesized)
|
|
21
21
|
* 3. 'decision-branch' — via onDecision (the chosen branch, synthesized)
|
|
22
|
+
* 4. 'attempt-series' — via onAttempt (10.1): a stage execution that
|
|
23
|
+
* RETRIED, GAVE UP or TIMED OUT (`recorder/attemptSeries.ts · isRetryEvidence`), with its
|
|
24
|
+
* `attemptSummary` and its ordered `attempts`. A retry is a loop, so each
|
|
25
|
+
* retry decision is a self-edge of kind 'retry' on the node — the way
|
|
26
|
+
* onLoop draws 'loop-iteration'. A stage that ran once (with or without a
|
|
27
|
+
* policy) is no node, as before.
|
|
22
28
|
*
|
|
23
29
|
* When a fork-branch or decision-branch target IS ALSO a subflow, the
|
|
24
30
|
* subsequent onSubflowEntry creates a subflow CHILD of the synthetic node.
|
|
@@ -48,11 +54,13 @@
|
|
|
48
54
|
* topo.getSubflowNodes(); // only mounted subflows
|
|
49
55
|
* ```
|
|
50
56
|
*/
|
|
51
|
-
import type {
|
|
57
|
+
import type { AttemptSummary } from '../attempt/types.js';
|
|
58
|
+
import type { FlowAttemptEvent, FlowDecisionEvent, FlowForkEvent, FlowLoopEvent, FlowRecorder, FlowSubflowEvent } from '../engine/narrative/types.js';
|
|
59
|
+
import type { AttemptRef } from './attemptSeries.js';
|
|
52
60
|
/** The kind of composition unit a node represents. */
|
|
53
|
-
export type TopologyNodeKind = 'subflow' | 'fork-branch' | 'decision-branch';
|
|
61
|
+
export type TopologyNodeKind = 'subflow' | 'fork-branch' | 'decision-branch' | 'attempt-series';
|
|
54
62
|
/** How the traversal reached this node — drives consumer layout decisions. */
|
|
55
|
-
export type TopologyIncomingKind = 'root' | 'next' | 'fork-branch' | 'decision-branch' | 'loop-iteration';
|
|
63
|
+
export type TopologyIncomingKind = 'root' | 'next' | 'fork-branch' | 'decision-branch' | 'loop-iteration' | 'retry';
|
|
56
64
|
/** A composition-significant point in the graph. */
|
|
57
65
|
export interface TopologyNode {
|
|
58
66
|
/** Unique id. Subflows use their subflowId (with `#n` suffix on re-entry).
|
|
@@ -76,8 +84,16 @@ export interface TopologyNode {
|
|
|
76
84
|
/** runtimeStageId when the corresponding subflow exited. Only meaningful
|
|
77
85
|
* for kind='subflow'; fork/decision-branch nodes are instantaneous. */
|
|
78
86
|
exitedAt?: string;
|
|
79
|
-
/** Kind-specific extras: forkParent, decider, rationale, description. */
|
|
87
|
+
/** Kind-specific extras: forkParent, decider, rationale, description; stageId for an attempt series. */
|
|
80
88
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
89
|
+
/**
|
|
90
|
+
* kind='attempt-series' only: the series at a glance — equal to the stage's
|
|
91
|
+
* `StageSnapshot.attemptSummary`. Absent while the series is in flight (or
|
|
92
|
+
* when the run's signal cut its wait: no record says how it ended).
|
|
93
|
+
*/
|
|
94
|
+
readonly attemptSummary?: AttemptSummary;
|
|
95
|
+
/** kind='attempt-series' only: the series' attempts, in order. */
|
|
96
|
+
readonly attempts?: readonly AttemptRef[];
|
|
81
97
|
}
|
|
82
98
|
/** A traversal transition between two nodes. */
|
|
83
99
|
export interface TopologyEdge {
|
|
@@ -135,12 +151,26 @@ export declare class TopologyRecorder implements FlowRecorder {
|
|
|
135
151
|
* TopologyRecorder is supposed to expose.
|
|
136
152
|
*/
|
|
137
153
|
private readonly previousSubflowInScope;
|
|
154
|
+
/** Open subflow node id by its path-prefixed subflowId — where a stage's attempt series hangs. */
|
|
155
|
+
private readonly openSubflowByPath;
|
|
156
|
+
/** Per-series tallies of the series that are evidence (retried, gave up or timed out). */
|
|
157
|
+
private readonly attemptBook;
|
|
138
158
|
constructor(options?: TopologyRecorderOptions);
|
|
139
159
|
onSubflowEntry(event: FlowSubflowEvent): void;
|
|
140
160
|
onSubflowExit(event: FlowSubflowEvent): void;
|
|
141
161
|
onFork(event: FlowForkEvent): void;
|
|
142
162
|
onDecision(event: FlowDecisionEvent): void;
|
|
143
163
|
onLoop(event: FlowLoopEvent): void;
|
|
164
|
+
onAttempt(event: FlowAttemptEvent): void;
|
|
165
|
+
/**
|
|
166
|
+
* A new series node, under its parent: the pending fork-branch / decision-
|
|
167
|
+
* branch of the same name (a fork child or a chosen branch that is a plain
|
|
168
|
+
* stage), else the open subflow the stage runs in (read off its
|
|
169
|
+
* runtimeStageId — the stack top can be a parallel sibling), else the top
|
|
170
|
+
* level. One edge from
|
|
171
|
+
* the parent, as for every composition child.
|
|
172
|
+
*/
|
|
173
|
+
private placeSeries;
|
|
144
174
|
/** Called by the executor before each `run()` — resets all state. */
|
|
145
175
|
clear(): void;
|
|
146
176
|
/** Live snapshot of the composition graph. Safe during or after a run. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AttemptQuery, AttemptRow } from './attemptMetricsTypes.js';
|
|
2
|
+
/** Decode plain own data only; external data never gets to run getters or coercion hooks. */
|
|
3
|
+
export declare function ownDataRecord(value: unknown): Record<string, unknown> | undefined;
|
|
4
|
+
/** Read an external array window by descriptors, never by executing an index accessor or iterator. */
|
|
5
|
+
export declare function metricWindow(value: unknown, maxRows: number): {
|
|
6
|
+
values: unknown[];
|
|
7
|
+
omitted: number;
|
|
8
|
+
};
|
|
9
|
+
/** Invalid stored data is omitted and accounted, never copied as an arbitrary envelope. */
|
|
10
|
+
export declare function metricRow(value: unknown): AttemptRow | undefined;
|
|
11
|
+
export declare function matchesQuery(row: AttemptRow, query: AttemptQuery): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AttemptAggregate, AttemptMetricRef, AttemptRow, AttemptStorageStats, PhysicalAttemptRow } from './attemptMetricsTypes.js';
|
|
2
|
+
export declare const attemptRowKey: (row: AttemptRow) => string;
|
|
3
|
+
export declare const logicalKey: (runId: string, series: string, attempt: number) => string;
|
|
4
|
+
export declare const seriesKey: (runId: string, series: string) => string;
|
|
5
|
+
export declare function reference(row: PhysicalAttemptRow): AttemptMetricRef;
|
|
6
|
+
export declare function worst(rows: readonly PhysicalAttemptRow[], limit: number): AttemptMetricRef[];
|
|
7
|
+
export declare function aggregateAttempts(rows: readonly AttemptRow[], exemplars: number, storage: AttemptStorageStats): AttemptAggregate;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** Payload-free P7 rows and public metric projections. Store adapters receive named facts, never errors or keys. */
|
|
2
|
+
import type { AttemptId } from 'foottrace';
|
|
3
|
+
import type { RetryLoopCall, RetryLoopDecision } from '../attempt/retryLoopTypes.js';
|
|
4
|
+
import type { AttemptCategory, AttemptEffect, AttemptKind, AttemptNext, AttemptOutcome, AttemptReason } from '../attempt/types.js';
|
|
5
|
+
export interface AttemptMetricRef {
|
|
6
|
+
readonly id: AttemptId;
|
|
7
|
+
readonly series: string;
|
|
8
|
+
readonly runId: string;
|
|
9
|
+
readonly runtimeStageId: string;
|
|
10
|
+
readonly attemptKind: AttemptKind;
|
|
11
|
+
readonly retryLoop?: RetryLoopCall;
|
|
12
|
+
readonly target: string;
|
|
13
|
+
readonly traceId?: string;
|
|
14
|
+
readonly startedAt: number;
|
|
15
|
+
readonly durationMs: number;
|
|
16
|
+
readonly outcome: AttemptOutcome;
|
|
17
|
+
readonly category?: AttemptCategory;
|
|
18
|
+
readonly next: AttemptNext;
|
|
19
|
+
readonly reason: AttemptReason;
|
|
20
|
+
}
|
|
21
|
+
export interface PhysicalAttemptRow extends AttemptMetricRef {
|
|
22
|
+
readonly kind: 'attempt';
|
|
23
|
+
readonly attemptKind: AttemptKind;
|
|
24
|
+
readonly attempt: number;
|
|
25
|
+
readonly of?: number;
|
|
26
|
+
readonly effect?: AttemptEffect;
|
|
27
|
+
readonly retryLoop?: RetryLoopCall;
|
|
28
|
+
}
|
|
29
|
+
export interface AttemptDecisionRow extends RetryLoopDecision {
|
|
30
|
+
readonly kind: 'decision';
|
|
31
|
+
readonly runId: string;
|
|
32
|
+
readonly target: string;
|
|
33
|
+
readonly runtimeStageId: string;
|
|
34
|
+
readonly attemptId: AttemptId;
|
|
35
|
+
readonly startedAt: number;
|
|
36
|
+
}
|
|
37
|
+
export interface AttemptRunRow {
|
|
38
|
+
readonly kind: 'run';
|
|
39
|
+
readonly runId: string;
|
|
40
|
+
readonly startedAt: number;
|
|
41
|
+
readonly endedAt?: number;
|
|
42
|
+
readonly outcome: 'running' | 'ok' | 'failed' | 'paused';
|
|
43
|
+
}
|
|
44
|
+
export type AttemptRow = PhysicalAttemptRow | AttemptDecisionRow | AttemptRunRow;
|
|
45
|
+
export interface AttemptQuery {
|
|
46
|
+
readonly since?: number;
|
|
47
|
+
readonly until?: number;
|
|
48
|
+
readonly target?: string;
|
|
49
|
+
readonly runId?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface AttemptStore {
|
|
52
|
+
append(rows: readonly AttemptRow[]): void | Promise<void>;
|
|
53
|
+
read(query: AttemptQuery): Promise<readonly AttemptRow[]>;
|
|
54
|
+
/** Optional known retention accounting; omitted evidence must not appear complete. */
|
|
55
|
+
stats?(): {
|
|
56
|
+
readonly omittedRows: number;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export interface AttemptStorageStats {
|
|
60
|
+
readonly pending: number;
|
|
61
|
+
readonly failed: number;
|
|
62
|
+
readonly dropped: number;
|
|
63
|
+
readonly omittedRows: number;
|
|
64
|
+
readonly incomplete: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface AttemptStats {
|
|
67
|
+
readonly target: string;
|
|
68
|
+
readonly count: number;
|
|
69
|
+
readonly byKind: Record<AttemptKind, number>;
|
|
70
|
+
readonly byOutcome: Record<AttemptOutcome, number>;
|
|
71
|
+
readonly byCategory: Record<AttemptCategory, number>;
|
|
72
|
+
readonly retries: number;
|
|
73
|
+
readonly seriesRetried: number;
|
|
74
|
+
readonly gaveUp: number;
|
|
75
|
+
readonly effectUnknown: number;
|
|
76
|
+
readonly latencyMs: {
|
|
77
|
+
readonly p50: number;
|
|
78
|
+
readonly p90: number;
|
|
79
|
+
readonly p95: number;
|
|
80
|
+
readonly max: number;
|
|
81
|
+
readonly mean: number;
|
|
82
|
+
};
|
|
83
|
+
/** Sum of attempt durations (work time), which can overlap or nest; not elapsed run time. */
|
|
84
|
+
readonly budgetUsedMs: number;
|
|
85
|
+
readonly exemplars: {
|
|
86
|
+
readonly slowest: AttemptMetricRef[];
|
|
87
|
+
readonly timeout: AttemptMetricRef[];
|
|
88
|
+
readonly failed: AttemptMetricRef[];
|
|
89
|
+
readonly unknown: AttemptMetricRef[];
|
|
90
|
+
readonly gaveUp: AttemptMetricRef[];
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export interface AttemptRunStats {
|
|
94
|
+
readonly runId: string;
|
|
95
|
+
readonly attempts: number;
|
|
96
|
+
readonly retries: number;
|
|
97
|
+
readonly gaveUp: number;
|
|
98
|
+
readonly budgetUsedMs: number;
|
|
99
|
+
readonly budgetMs?: number;
|
|
100
|
+
readonly exemplars: AttemptMetricRef[];
|
|
101
|
+
readonly outcome: AttemptRunRow['outcome'] | 'incomplete';
|
|
102
|
+
}
|
|
103
|
+
export interface AttemptAggregate {
|
|
104
|
+
readonly byTarget: Map<string, AttemptStats>;
|
|
105
|
+
readonly byRun: Map<string, AttemptRunStats>;
|
|
106
|
+
readonly storage: AttemptStorageStats;
|
|
107
|
+
}
|
|
108
|
+
export interface AttemptRecorderOptions {
|
|
109
|
+
readonly exemplars?: number;
|
|
110
|
+
readonly maxRows?: number;
|
|
111
|
+
readonly maxPending?: number;
|
|
112
|
+
readonly storeTimeoutMs?: number;
|
|
113
|
+
readonly store?: AttemptStore;
|
|
114
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { AttemptStats, PhysicalAttemptRow } from './attemptMetricsTypes.js';
|
|
2
|
+
export declare function attemptOTel(rows: readonly PhysicalAttemptRow[], byTarget: ReadonlyMap<string, AttemptStats>, limit: number): {
|
|
3
|
+
resourceMetrics: {
|
|
4
|
+
resource: {
|
|
5
|
+
attributes: never[];
|
|
6
|
+
};
|
|
7
|
+
scopeMetrics: {
|
|
8
|
+
scope: {
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
metrics: ({
|
|
12
|
+
name: string;
|
|
13
|
+
unit: string;
|
|
14
|
+
description: string;
|
|
15
|
+
histogram: {
|
|
16
|
+
aggregationTemporality: number;
|
|
17
|
+
dataPoints: {
|
|
18
|
+
attributes: {
|
|
19
|
+
key: string;
|
|
20
|
+
value: {
|
|
21
|
+
stringValue: string;
|
|
22
|
+
};
|
|
23
|
+
}[];
|
|
24
|
+
startTimeUnixNano: string;
|
|
25
|
+
timeUnixNano: string;
|
|
26
|
+
count: string;
|
|
27
|
+
sum: number;
|
|
28
|
+
explicitBounds: number[];
|
|
29
|
+
bucketCounts: string[];
|
|
30
|
+
exemplars: {
|
|
31
|
+
traceId?: string | undefined;
|
|
32
|
+
asDouble: number;
|
|
33
|
+
timeUnixNano: string;
|
|
34
|
+
filteredAttributes: {
|
|
35
|
+
key: string;
|
|
36
|
+
value: {
|
|
37
|
+
stringValue: string;
|
|
38
|
+
};
|
|
39
|
+
}[];
|
|
40
|
+
}[];
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
43
|
+
sum?: undefined;
|
|
44
|
+
} | {
|
|
45
|
+
name: string;
|
|
46
|
+
unit: string;
|
|
47
|
+
sum: {
|
|
48
|
+
aggregationTemporality: number;
|
|
49
|
+
isMonotonic: boolean;
|
|
50
|
+
dataPoints: {
|
|
51
|
+
attributes: {
|
|
52
|
+
key: string;
|
|
53
|
+
value: {
|
|
54
|
+
stringValue: string;
|
|
55
|
+
};
|
|
56
|
+
}[];
|
|
57
|
+
startTimeUnixNano: string;
|
|
58
|
+
timeUnixNano: string;
|
|
59
|
+
asDouble: number;
|
|
60
|
+
exemplars: {
|
|
61
|
+
asDouble: number;
|
|
62
|
+
traceId?: string | undefined;
|
|
63
|
+
timeUnixNano: string;
|
|
64
|
+
filteredAttributes: {
|
|
65
|
+
key: string;
|
|
66
|
+
value: {
|
|
67
|
+
stringValue: string;
|
|
68
|
+
};
|
|
69
|
+
}[];
|
|
70
|
+
}[];
|
|
71
|
+
}[];
|
|
72
|
+
};
|
|
73
|
+
description?: undefined;
|
|
74
|
+
histogram?: undefined;
|
|
75
|
+
})[];
|
|
76
|
+
}[];
|
|
77
|
+
}[];
|
|
78
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recorder/attemptSeries.ts — what a RECORDER keeps of a series: the one evidence predicate, the stop that gave up, and a
|
|
3
|
+
* per-series tally rebuilt from `onAttempt` records (design §5.1, P1c).
|
|
4
|
+
*
|
|
5
|
+
* WHY one module: seven built-in recorders account for attempts, and each must agree on two questions — "is this
|
|
6
|
+
* series worth a row?" and "did it give up?" — or a Topology node and a boundary count would disagree about the
|
|
7
|
+
* same run. Asked here, once.
|
|
8
|
+
*
|
|
9
|
+
* THE predicate (`isRetryEvidence`): a series is evidence when it RETRIED (some attempt was followed by another),
|
|
10
|
+
* GAVE UP while a retry was possible (it stopped `exhausted`, `declined` or `no-time-left` with `of > 1`, §3.9), or
|
|
11
|
+
* TIMED OUT (an attempt ran out of its cap or the deadline — P1b's lone timeout is the incident's own shape). A
|
|
12
|
+
* policy stage that succeeded first time — or that paused or was aborted on its first attempt — is
|
|
13
|
+
* indistinguishable from a stage with no policy in every recorder row, so a chart in which nothing retried keeps
|
|
14
|
+
* those rows byte-identical (law 2). So is a LONE attempt (`of: 1`, recorded for every stage of a run with a
|
|
15
|
+
* deadline, P1b) that merely failed: a stage error like any other, so a deadline alone never multiplies rows.
|
|
16
|
+
*
|
|
17
|
+
* Records arrive in order within a series, so the predicate is decided at the series' FIRST record: attempt 1 is
|
|
18
|
+
* evidence iff it did not end the series quietly, and every later attempt is evidence by being one.
|
|
19
|
+
*
|
|
20
|
+
* L5 (`recorder/**`), beside the stores: it imports the attempt vocabulary's types only (the L0 leaf), so
|
|
21
|
+
* `recorder/` never takes a runtime edge into `attempt/` — whose runner reaches `decide/` and `scope/`, which
|
|
22
|
+
* import `recorder/` (a module cycle).
|
|
23
|
+
*/
|
|
24
|
+
import type { AttemptOutcome, AttemptRecord, AttemptSummary } from '../attempt/types.js';
|
|
25
|
+
/**
|
|
26
|
+
* One attempt, named — `series` (the stage execution's `runtimeStageId`) plus the 1-based `attempt`. The
|
|
27
|
+
* identity `AttemptRecord` carries until the engine stamps foottrace's attempt id (design §3.4).
|
|
28
|
+
*/
|
|
29
|
+
export interface AttemptRef {
|
|
30
|
+
readonly series: string;
|
|
31
|
+
readonly attempt: number;
|
|
32
|
+
}
|
|
33
|
+
/** Attempt counts per outcome — the shape `AttemptSummary` uses, without the series' end. */
|
|
34
|
+
export type AttemptOutcomeCounts = Readonly<Record<AttemptOutcome, number>>;
|
|
35
|
+
/** The series stopped on this record because retrying was given up (exhausted, declined or no time left). */
|
|
36
|
+
export declare function gaveUp(record: Pick<AttemptRecord, 'next' | 'reason'>): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The record belongs to a STAGE's series that retried, gave up or timed out — the one row predicate every recorder
|
|
39
|
+
* shares. A call's or an observed attempt (`scope.$call`, `observed()`, P2) is never a row here: these recorders keep
|
|
40
|
+
* one row per stage execution, and a call is counted per TARGET (the `attempts()` recorder, P7) — drawn as a stage's
|
|
41
|
+
* retry it would say the stage retried when only its call did.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isRetryEvidence(record: AttemptRecord): boolean;
|
|
44
|
+
/** Did the attempt itself fail — a failure, a timeout or the run's abort (not a success, not a pause)? */
|
|
45
|
+
export declare function attemptFailed(record: AttemptRecord): boolean;
|
|
46
|
+
/** The record's name. */
|
|
47
|
+
export declare function attemptRef(record: AttemptRecord): AttemptRef;
|
|
48
|
+
/**
|
|
49
|
+
* The path-prefixed id of the subflow an attempt's stage ran in (`'sf-outer/sf-inner'`), or `undefined` at the top
|
|
50
|
+
* level — read off the stage execution's `runtimeStageId` (the event's, else the series'), the one id that always
|
|
51
|
+
* carries it.
|
|
52
|
+
*/
|
|
53
|
+
export declare function subflowOfAttempt(event: {
|
|
54
|
+
readonly record: AttemptRecord;
|
|
55
|
+
readonly traversalContext?: {
|
|
56
|
+
readonly runtimeStageId: string;
|
|
57
|
+
};
|
|
58
|
+
}): string | undefined;
|
|
59
|
+
/** A zeroed per-outcome count. */
|
|
60
|
+
export declare function emptyOutcomeCounts(): Record<AttemptOutcome, number>;
|
|
61
|
+
/** What a recorder knows of one series so far. `summary` is present once the series ended. */
|
|
62
|
+
export interface AttemptSeriesState {
|
|
63
|
+
readonly series: string;
|
|
64
|
+
/** The series' attempts, in order. */
|
|
65
|
+
readonly attempts: readonly AttemptRef[];
|
|
66
|
+
/**
|
|
67
|
+
* The series at a glance — the same value the runner stamps on `StageSnapshot.attemptSummary`, rebuilt from the
|
|
68
|
+
* records. Absent while the last record says `retry`: the series is in flight, or the run's signal cut its wait
|
|
69
|
+
* (no record follows; only the execution tree knows how it ended).
|
|
70
|
+
*/
|
|
71
|
+
readonly summary?: AttemptSummary;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Per-series tallies, keyed by `series`, for the series that are evidence. `add` returns the series' state after
|
|
75
|
+
* the record, or `undefined` for a record that is not evidence (nothing to keep).
|
|
76
|
+
*/
|
|
77
|
+
export declare class AttemptSeriesBook {
|
|
78
|
+
private readonly bySeries;
|
|
79
|
+
add(record: AttemptRecord): AttemptSeriesState | undefined;
|
|
80
|
+
clear(): void;
|
|
81
|
+
}
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
*
|
|
31
31
|
* Pinned by test/lib/recorder/hooks.test.ts (the `@ts-expect-error` probes).
|
|
32
32
|
*/
|
|
33
|
+
import type { RunCorrelation } from '../attempt/types.js';
|
|
33
34
|
import type { FlowRecorder } from '../engine/narrative/types.js';
|
|
34
35
|
import type { ErrorEvent, ScopeRecorder } from '../scope/types.js';
|
|
35
36
|
import type { EmitRecorder } from './EmitRecorder.js';
|
|
@@ -174,6 +175,12 @@ export declare const HOOKS: {
|
|
|
174
175
|
};
|
|
175
176
|
readonly executorMade: false;
|
|
176
177
|
};
|
|
178
|
+
readonly onAttempt: {
|
|
179
|
+
readonly on: {
|
|
180
|
+
readonly flow: "FlowAttemptEvent";
|
|
181
|
+
};
|
|
182
|
+
readonly executorMade: false;
|
|
183
|
+
};
|
|
177
184
|
readonly onStageRetry: {
|
|
178
185
|
readonly on: {
|
|
179
186
|
readonly flow: "FlowStageRetryEvent";
|
|
@@ -240,6 +247,8 @@ export interface FailureSite {
|
|
|
240
247
|
readonly stageId: string;
|
|
241
248
|
readonly runtimeStageId: string;
|
|
242
249
|
readonly pipelineId: string;
|
|
250
|
+
/** The run's correlation, when the site's events carry one — the failure event carries it too. */
|
|
251
|
+
readonly correlation?: RunCorrelation;
|
|
243
252
|
}
|
|
244
253
|
/**
|
|
245
254
|
* THE scope-channel `onError` event for a recorder that threw in `hook` — built in ONE place
|