@smthrs/harness 0.0.0-stage → 1.0.0-rc.4
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/CHANGELOG.md +387 -0
- package/LICENSE +21 -0
- package/README.md +138 -2
- package/dist/cjs/AgentEvent.d.ts +3092 -0
- package/dist/cjs/AgentEvent.d.ts.map +1 -0
- package/dist/cjs/AgentEvent.js +1116 -0
- package/dist/cjs/AgentEvent.js.map +7 -0
- package/dist/cjs/CallLedger.d.ts +378 -0
- package/dist/cjs/CallLedger.d.ts.map +1 -0
- package/dist/cjs/CallLedger.js +240 -0
- package/dist/cjs/CallLedger.js.map +7 -0
- package/dist/cjs/Cell.d.ts +774 -0
- package/dist/cjs/Cell.d.ts.map +1 -0
- package/dist/cjs/Cell.js +431 -0
- package/dist/cjs/Cell.js.map +7 -0
- package/dist/cjs/CellCalls.d.ts +115 -0
- package/dist/cjs/CellCalls.d.ts.map +1 -0
- package/dist/cjs/CellCalls.js +98 -0
- package/dist/cjs/CellCalls.js.map +7 -0
- package/dist/cjs/CellHistory.d.ts +102 -0
- package/dist/cjs/CellHistory.d.ts.map +1 -0
- package/dist/cjs/CellHistory.js +54 -0
- package/dist/cjs/CellHistory.js.map +7 -0
- package/dist/cjs/CellTurn.d.ts +1071 -0
- package/dist/cjs/CellTurn.d.ts.map +1 -0
- package/dist/cjs/CellTurn.js +2618 -0
- package/dist/cjs/CellTurn.js.map +7 -0
- package/dist/cjs/CellValidation.d.ts +94 -0
- package/dist/cjs/CellValidation.d.ts.map +1 -0
- package/dist/cjs/CellValidation.js +218 -0
- package/dist/cjs/CellValidation.js.map +7 -0
- package/dist/cjs/Compaction.d.ts +158 -0
- package/dist/cjs/Compaction.d.ts.map +1 -0
- package/dist/cjs/Compaction.js +189 -0
- package/dist/cjs/Compaction.js.map +7 -0
- package/dist/cjs/CompletionClaim.d.ts +801 -0
- package/dist/cjs/CompletionClaim.d.ts.map +1 -0
- package/dist/cjs/CompletionClaim.js +303 -0
- package/dist/cjs/CompletionClaim.js.map +7 -0
- package/dist/cjs/ContextWindow.d.ts +435 -0
- package/dist/cjs/ContextWindow.d.ts.map +1 -0
- package/dist/cjs/ContextWindow.js +319 -0
- package/dist/cjs/ContextWindow.js.map +7 -0
- package/dist/cjs/EngineLike.d.ts +546 -0
- package/dist/cjs/EngineLike.d.ts.map +1 -0
- package/dist/cjs/EngineLike.js +114 -0
- package/dist/cjs/EngineLike.js.map +7 -0
- package/dist/cjs/ExternalTranscript.d.ts +349 -0
- package/dist/cjs/ExternalTranscript.d.ts.map +1 -0
- package/dist/cjs/ExternalTranscript.js +826 -0
- package/dist/cjs/ExternalTranscript.js.map +7 -0
- package/dist/cjs/FailedCall.d.ts +132 -0
- package/dist/cjs/FailedCall.d.ts.map +1 -0
- package/dist/cjs/FailedCall.js +53 -0
- package/dist/cjs/FailedCall.js.map +7 -0
- package/dist/cjs/FlowBinding.d.ts +289 -0
- package/dist/cjs/FlowBinding.d.ts.map +1 -0
- package/dist/cjs/FlowBinding.js +251 -0
- package/dist/cjs/FlowBinding.js.map +7 -0
- package/dist/cjs/HarnessError.d.ts +57 -0
- package/dist/cjs/HarnessError.d.ts.map +1 -0
- package/dist/cjs/HarnessError.js +75 -0
- package/dist/cjs/HarnessError.js.map +7 -0
- package/dist/cjs/Judgement.d.ts +289 -0
- package/dist/cjs/Judgement.d.ts.map +1 -0
- package/dist/cjs/Judgement.js +240 -0
- package/dist/cjs/Judgement.js.map +7 -0
- package/dist/cjs/Monitor.d.ts +374 -0
- package/dist/cjs/Monitor.d.ts.map +1 -0
- package/dist/cjs/Monitor.js +233 -0
- package/dist/cjs/Monitor.js.map +7 -0
- package/dist/cjs/NarrowedCheck.d.ts +523 -0
- package/dist/cjs/NarrowedCheck.d.ts.map +1 -0
- package/dist/cjs/NarrowedCheck.js +263 -0
- package/dist/cjs/NarrowedCheck.js.map +7 -0
- package/dist/cjs/Notifications.d.ts +42 -0
- package/dist/cjs/Notifications.d.ts.map +1 -0
- package/dist/cjs/Notifications.js +177 -0
- package/dist/cjs/Notifications.js.map +7 -0
- package/dist/cjs/Plan.d.ts +127 -0
- package/dist/cjs/Plan.d.ts.map +1 -0
- package/dist/cjs/Plan.js +77 -0
- package/dist/cjs/Plan.js.map +7 -0
- package/dist/cjs/QuickJSSandbox.d.ts +151 -0
- package/dist/cjs/QuickJSSandbox.d.ts.map +1 -0
- package/dist/cjs/QuickJSSandbox.js +987 -0
- package/dist/cjs/QuickJSSandbox.js.map +7 -0
- package/dist/cjs/Relevance.d.ts +213 -0
- package/dist/cjs/Relevance.d.ts.map +1 -0
- package/dist/cjs/Relevance.js +183 -0
- package/dist/cjs/Relevance.js.map +7 -0
- package/dist/cjs/Sandbox.d.ts +637 -0
- package/dist/cjs/Sandbox.d.ts.map +1 -0
- package/dist/cjs/Sandbox.js +260 -0
- package/dist/cjs/Sandbox.js.map +7 -0
- package/dist/cjs/Steering.d.ts +464 -0
- package/dist/cjs/Steering.d.ts.map +1 -0
- package/dist/cjs/Steering.js +153 -0
- package/dist/cjs/Steering.js.map +7 -0
- package/dist/cjs/StructuredOutput.d.ts +252 -0
- package/dist/cjs/StructuredOutput.d.ts.map +1 -0
- package/dist/cjs/StructuredOutput.js +266 -0
- package/dist/cjs/StructuredOutput.js.map +7 -0
- package/dist/cjs/Sufficiency.d.ts +195 -0
- package/dist/cjs/Sufficiency.d.ts.map +1 -0
- package/dist/cjs/Sufficiency.js +110 -0
- package/dist/cjs/Sufficiency.js.map +7 -0
- package/dist/cjs/Supervisor.d.ts +719 -0
- package/dist/cjs/Supervisor.d.ts.map +1 -0
- package/dist/cjs/Supervisor.js +313 -0
- package/dist/cjs/Supervisor.js.map +7 -0
- package/dist/cjs/Tokens.d.ts +86 -0
- package/dist/cjs/Tokens.d.ts.map +1 -0
- package/dist/cjs/Tokens.js +72 -0
- package/dist/cjs/Tokens.js.map +7 -0
- package/dist/cjs/Transcript.d.ts +171 -0
- package/dist/cjs/Transcript.d.ts.map +1 -0
- package/dist/cjs/Transcript.js +342 -0
- package/dist/cjs/Transcript.js.map +7 -0
- package/dist/cjs/TruncatedOutput.d.ts +186 -0
- package/dist/cjs/TruncatedOutput.d.ts.map +1 -0
- package/dist/cjs/TruncatedOutput.js +143 -0
- package/dist/cjs/TruncatedOutput.js.map +7 -0
- package/dist/cjs/UnmovedTree.d.ts +113 -0
- package/dist/cjs/UnmovedTree.d.ts.map +1 -0
- package/dist/cjs/UnmovedTree.js +38 -0
- package/dist/cjs/UnmovedTree.js.map +7 -0
- package/dist/cjs/UnresolvedFailure.d.ts +196 -0
- package/dist/cjs/UnresolvedFailure.d.ts.map +1 -0
- package/dist/cjs/UnresolvedFailure.js +77 -0
- package/dist/cjs/UnresolvedFailure.js.map +7 -0
- package/dist/cjs/VacuousVerification.d.ts +237 -0
- package/dist/cjs/VacuousVerification.d.ts.map +1 -0
- package/dist/cjs/VacuousVerification.js +91 -0
- package/dist/cjs/VacuousVerification.js.map +7 -0
- package/dist/cjs/VariablesPanel.d.ts +117 -0
- package/dist/cjs/VariablesPanel.d.ts.map +1 -0
- package/dist/cjs/VariablesPanel.js +108 -0
- package/dist/cjs/VariablesPanel.js.map +7 -0
- package/dist/cjs/index.d.ts +172 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +99 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/bytes.d.ts +36 -0
- package/dist/cjs/internal/bytes.d.ts.map +1 -0
- package/dist/cjs/internal/bytes.js +57 -0
- package/dist/cjs/internal/bytes.js.map +7 -0
- package/dist/cjs/internal/cellPrompt.d.ts +122 -0
- package/dist/cjs/internal/cellPrompt.d.ts.map +1 -0
- package/dist/cjs/internal/cellPrompt.js +146 -0
- package/dist/cjs/internal/cellPrompt.js.map +7 -0
- package/dist/cjs/internal/compactable.d.ts +44 -0
- package/dist/cjs/internal/compactable.d.ts.map +1 -0
- package/dist/cjs/internal/compactable.js +56 -0
- package/dist/cjs/internal/compactable.js.map +7 -0
- package/dist/cjs/internal/compactionMarks.d.ts +278 -0
- package/dist/cjs/internal/compactionMarks.d.ts.map +1 -0
- package/dist/cjs/internal/compactionMarks.js +212 -0
- package/dist/cjs/internal/compactionMarks.js.map +7 -0
- package/dist/cjs/internal/demandText.d.ts +95 -0
- package/dist/cjs/internal/demandText.d.ts.map +1 -0
- package/dist/cjs/internal/demandText.js +70 -0
- package/dist/cjs/internal/demandText.js.map +7 -0
- package/dist/cjs/internal/elide.d.ts +109 -0
- package/dist/cjs/internal/elide.d.ts.map +1 -0
- package/dist/cjs/internal/elide.js +59 -0
- package/dist/cjs/internal/elide.js.map +7 -0
- package/dist/cjs/internal/frame.d.ts +463 -0
- package/dist/cjs/internal/frame.d.ts.map +1 -0
- package/dist/cjs/internal/frame.js +514 -0
- package/dist/cjs/internal/frame.js.map +7 -0
- package/dist/cjs/internal/nonNegativeSafeInt.d.ts +20 -0
- package/dist/cjs/internal/nonNegativeSafeInt.d.ts.map +1 -0
- package/dist/cjs/internal/nonNegativeSafeInt.js +29 -0
- package/dist/cjs/internal/nonNegativeSafeInt.js.map +7 -0
- package/dist/cjs/internal/paidUsage.d.ts +52 -0
- package/dist/cjs/internal/paidUsage.d.ts.map +1 -0
- package/dist/cjs/internal/paidUsage.js +70 -0
- package/dist/cjs/internal/paidUsage.js.map +7 -0
- package/dist/cjs/internal/printChannel.d.ts +233 -0
- package/dist/cjs/internal/printChannel.d.ts.map +1 -0
- package/dist/cjs/internal/printChannel.js +165 -0
- package/dist/cjs/internal/printChannel.js.map +7 -0
- package/dist/cjs/internal/printsObservation.d.ts +26 -0
- package/dist/cjs/internal/printsObservation.d.ts.map +1 -0
- package/dist/cjs/internal/printsObservation.js +27 -0
- package/dist/cjs/internal/printsObservation.js.map +7 -0
- package/dist/cjs/internal/refusal.d.ts +40 -0
- package/dist/cjs/internal/refusal.d.ts.map +1 -0
- package/dist/cjs/internal/refusal.js +45 -0
- package/dist/cjs/internal/refusal.js.map +7 -0
- package/dist/cjs/internal/supervision.d.ts +174 -0
- package/dist/cjs/internal/supervision.d.ts.map +1 -0
- package/dist/cjs/internal/supervision.js +402 -0
- package/dist/cjs/internal/supervision.js.map +7 -0
- package/dist/cjs/internal/unfinishedWork.d.ts +99 -0
- package/dist/cjs/internal/unfinishedWork.d.ts.map +1 -0
- package/dist/cjs/internal/unfinishedWork.js +80 -0
- package/dist/cjs/internal/unfinishedWork.js.map +7 -0
- package/dist/cjs/internal/unobservedCall.d.ts +112 -0
- package/dist/cjs/internal/unobservedCall.d.ts.map +1 -0
- package/dist/cjs/internal/unobservedCall.js +345 -0
- package/dist/cjs/internal/unobservedCall.js.map +7 -0
- package/dist/cjs/internal/untrustedData.d.ts +14 -0
- package/dist/cjs/internal/untrustedData.d.ts.map +1 -0
- package/dist/cjs/internal/untrustedData.js +30 -0
- package/dist/cjs/internal/untrustedData.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/AgentEvent.d.ts +3092 -0
- package/dist/esm/AgentEvent.d.ts.map +1 -0
- package/dist/esm/AgentEvent.js +1610 -0
- package/dist/esm/AgentEvent.js.map +1 -0
- package/dist/esm/CallLedger.d.ts +378 -0
- package/dist/esm/CallLedger.d.ts.map +1 -0
- package/dist/esm/CallLedger.js +506 -0
- package/dist/esm/CallLedger.js.map +1 -0
- package/dist/esm/Cell.d.ts +774 -0
- package/dist/esm/Cell.d.ts.map +1 -0
- package/dist/esm/Cell.js +772 -0
- package/dist/esm/Cell.js.map +1 -0
- package/dist/esm/CellCalls.d.ts +115 -0
- package/dist/esm/CellCalls.d.ts.map +1 -0
- package/dist/esm/CellCalls.js +97 -0
- package/dist/esm/CellCalls.js.map +1 -0
- package/dist/esm/CellHistory.d.ts +102 -0
- package/dist/esm/CellHistory.d.ts.map +1 -0
- package/dist/esm/CellHistory.js +91 -0
- package/dist/esm/CellHistory.js.map +1 -0
- package/dist/esm/CellTurn.d.ts +1071 -0
- package/dist/esm/CellTurn.d.ts.map +1 -0
- package/dist/esm/CellTurn.js +3410 -0
- package/dist/esm/CellTurn.js.map +1 -0
- package/dist/esm/CellValidation.d.ts +94 -0
- package/dist/esm/CellValidation.d.ts.map +1 -0
- package/dist/esm/CellValidation.js +335 -0
- package/dist/esm/CellValidation.js.map +1 -0
- package/dist/esm/Compaction.d.ts +158 -0
- package/dist/esm/Compaction.d.ts.map +1 -0
- package/dist/esm/Compaction.js +216 -0
- package/dist/esm/Compaction.js.map +1 -0
- package/dist/esm/CompletionClaim.d.ts +801 -0
- package/dist/esm/CompletionClaim.d.ts.map +1 -0
- package/dist/esm/CompletionClaim.js +833 -0
- package/dist/esm/CompletionClaim.js.map +1 -0
- package/dist/esm/ContextWindow.d.ts +435 -0
- package/dist/esm/ContextWindow.d.ts.map +1 -0
- package/dist/esm/ContextWindow.js +427 -0
- package/dist/esm/ContextWindow.js.map +1 -0
- package/dist/esm/EngineLike.d.ts +546 -0
- package/dist/esm/EngineLike.d.ts.map +1 -0
- package/dist/esm/EngineLike.js +218 -0
- package/dist/esm/EngineLike.js.map +1 -0
- package/dist/esm/ExternalTranscript.d.ts +349 -0
- package/dist/esm/ExternalTranscript.d.ts.map +1 -0
- package/dist/esm/ExternalTranscript.js +985 -0
- package/dist/esm/ExternalTranscript.js.map +1 -0
- package/dist/esm/FailedCall.d.ts +132 -0
- package/dist/esm/FailedCall.d.ts.map +1 -0
- package/dist/esm/FailedCall.js +131 -0
- package/dist/esm/FailedCall.js.map +1 -0
- package/dist/esm/FlowBinding.d.ts +289 -0
- package/dist/esm/FlowBinding.d.ts.map +1 -0
- package/dist/esm/FlowBinding.js +376 -0
- package/dist/esm/FlowBinding.js.map +1 -0
- package/dist/esm/HarnessError.d.ts +57 -0
- package/dist/esm/HarnessError.d.ts.map +1 -0
- package/dist/esm/HarnessError.js +85 -0
- package/dist/esm/HarnessError.js.map +1 -0
- package/dist/esm/Judgement.d.ts +289 -0
- package/dist/esm/Judgement.d.ts.map +1 -0
- package/dist/esm/Judgement.js +305 -0
- package/dist/esm/Judgement.js.map +1 -0
- package/dist/esm/Monitor.d.ts +374 -0
- package/dist/esm/Monitor.d.ts.map +1 -0
- package/dist/esm/Monitor.js +370 -0
- package/dist/esm/Monitor.js.map +1 -0
- package/dist/esm/NarrowedCheck.d.ts +523 -0
- package/dist/esm/NarrowedCheck.d.ts.map +1 -0
- package/dist/esm/NarrowedCheck.js +612 -0
- package/dist/esm/NarrowedCheck.js.map +1 -0
- package/dist/esm/Notifications.d.ts +42 -0
- package/dist/esm/Notifications.d.ts.map +1 -0
- package/dist/esm/Notifications.js +215 -0
- package/dist/esm/Notifications.js.map +1 -0
- package/dist/esm/Plan.d.ts +127 -0
- package/dist/esm/Plan.d.ts.map +1 -0
- package/dist/esm/Plan.js +97 -0
- package/dist/esm/Plan.js.map +1 -0
- package/dist/esm/QuickJSSandbox.d.ts +151 -0
- package/dist/esm/QuickJSSandbox.d.ts.map +1 -0
- package/dist/esm/QuickJSSandbox.js +1364 -0
- package/dist/esm/QuickJSSandbox.js.map +1 -0
- package/dist/esm/Relevance.d.ts +213 -0
- package/dist/esm/Relevance.d.ts.map +1 -0
- package/dist/esm/Relevance.js +254 -0
- package/dist/esm/Relevance.js.map +1 -0
- package/dist/esm/Sandbox.d.ts +637 -0
- package/dist/esm/Sandbox.d.ts.map +1 -0
- package/dist/esm/Sandbox.js +464 -0
- package/dist/esm/Sandbox.js.map +1 -0
- package/dist/esm/Steering.d.ts +464 -0
- package/dist/esm/Steering.d.ts.map +1 -0
- package/dist/esm/Steering.js +193 -0
- package/dist/esm/Steering.js.map +1 -0
- package/dist/esm/StructuredOutput.d.ts +252 -0
- package/dist/esm/StructuredOutput.d.ts.map +1 -0
- package/dist/esm/StructuredOutput.js +430 -0
- package/dist/esm/StructuredOutput.js.map +1 -0
- package/dist/esm/Sufficiency.d.ts +195 -0
- package/dist/esm/Sufficiency.d.ts.map +1 -0
- package/dist/esm/Sufficiency.js +207 -0
- package/dist/esm/Sufficiency.js.map +1 -0
- package/dist/esm/Supervisor.d.ts +719 -0
- package/dist/esm/Supervisor.d.ts.map +1 -0
- package/dist/esm/Supervisor.js +575 -0
- package/dist/esm/Supervisor.js.map +1 -0
- package/dist/esm/Tokens.d.ts +86 -0
- package/dist/esm/Tokens.d.ts.map +1 -0
- package/dist/esm/Tokens.js +92 -0
- package/dist/esm/Tokens.js.map +1 -0
- package/dist/esm/Transcript.d.ts +171 -0
- package/dist/esm/Transcript.d.ts.map +1 -0
- package/dist/esm/Transcript.js +424 -0
- package/dist/esm/Transcript.js.map +1 -0
- package/dist/esm/TruncatedOutput.d.ts +186 -0
- package/dist/esm/TruncatedOutput.d.ts.map +1 -0
- package/dist/esm/TruncatedOutput.js +257 -0
- package/dist/esm/TruncatedOutput.js.map +1 -0
- package/dist/esm/UnmovedTree.d.ts +113 -0
- package/dist/esm/UnmovedTree.d.ts.map +1 -0
- package/dist/esm/UnmovedTree.js +90 -0
- package/dist/esm/UnmovedTree.js.map +1 -0
- package/dist/esm/UnresolvedFailure.d.ts +196 -0
- package/dist/esm/UnresolvedFailure.d.ts.map +1 -0
- package/dist/esm/UnresolvedFailure.js +218 -0
- package/dist/esm/UnresolvedFailure.js.map +1 -0
- package/dist/esm/VacuousVerification.d.ts +237 -0
- package/dist/esm/VacuousVerification.d.ts.map +1 -0
- package/dist/esm/VacuousVerification.js +245 -0
- package/dist/esm/VacuousVerification.js.map +1 -0
- package/dist/esm/VariablesPanel.d.ts +117 -0
- package/dist/esm/VariablesPanel.d.ts.map +1 -0
- package/dist/esm/VariablesPanel.js +142 -0
- package/dist/esm/VariablesPanel.js.map +1 -0
- package/dist/esm/index.d.ts +172 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +172 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/bytes.d.ts +36 -0
- package/dist/esm/internal/bytes.d.ts.map +1 -0
- package/dist/esm/internal/bytes.js +70 -0
- package/dist/esm/internal/bytes.js.map +1 -0
- package/dist/esm/internal/cellPrompt.d.ts +122 -0
- package/dist/esm/internal/cellPrompt.d.ts.map +1 -0
- package/dist/esm/internal/cellPrompt.js +276 -0
- package/dist/esm/internal/cellPrompt.js.map +1 -0
- package/dist/esm/internal/compactable.d.ts +44 -0
- package/dist/esm/internal/compactable.d.ts.map +1 -0
- package/dist/esm/internal/compactable.js +71 -0
- package/dist/esm/internal/compactable.js.map +1 -0
- package/dist/esm/internal/compactionMarks.d.ts +278 -0
- package/dist/esm/internal/compactionMarks.d.ts.map +1 -0
- package/dist/esm/internal/compactionMarks.js +317 -0
- package/dist/esm/internal/compactionMarks.js.map +1 -0
- package/dist/esm/internal/demandText.d.ts +95 -0
- package/dist/esm/internal/demandText.d.ts.map +1 -0
- package/dist/esm/internal/demandText.js +128 -0
- package/dist/esm/internal/demandText.js.map +1 -0
- package/dist/esm/internal/elide.d.ts +109 -0
- package/dist/esm/internal/elide.d.ts.map +1 -0
- package/dist/esm/internal/elide.js +123 -0
- package/dist/esm/internal/elide.js.map +1 -0
- package/dist/esm/internal/frame.d.ts +463 -0
- package/dist/esm/internal/frame.d.ts.map +1 -0
- package/dist/esm/internal/frame.js +861 -0
- package/dist/esm/internal/frame.js.map +1 -0
- package/dist/esm/internal/nonNegativeSafeInt.d.ts +20 -0
- package/dist/esm/internal/nonNegativeSafeInt.d.ts.map +1 -0
- package/dist/esm/internal/nonNegativeSafeInt.js +20 -0
- package/dist/esm/internal/nonNegativeSafeInt.js.map +1 -0
- package/dist/esm/internal/paidUsage.d.ts +52 -0
- package/dist/esm/internal/paidUsage.d.ts.map +1 -0
- package/dist/esm/internal/paidUsage.js +72 -0
- package/dist/esm/internal/paidUsage.js.map +1 -0
- package/dist/esm/internal/printChannel.d.ts +233 -0
- package/dist/esm/internal/printChannel.d.ts.map +1 -0
- package/dist/esm/internal/printChannel.js +376 -0
- package/dist/esm/internal/printChannel.js.map +1 -0
- package/dist/esm/internal/printsObservation.d.ts +26 -0
- package/dist/esm/internal/printsObservation.d.ts.map +1 -0
- package/dist/esm/internal/printsObservation.js +29 -0
- package/dist/esm/internal/printsObservation.js.map +1 -0
- package/dist/esm/internal/refusal.d.ts +40 -0
- package/dist/esm/internal/refusal.d.ts.map +1 -0
- package/dist/esm/internal/refusal.js +47 -0
- package/dist/esm/internal/refusal.js.map +1 -0
- package/dist/esm/internal/supervision.d.ts +174 -0
- package/dist/esm/internal/supervision.d.ts.map +1 -0
- package/dist/esm/internal/supervision.js +485 -0
- package/dist/esm/internal/supervision.js.map +1 -0
- package/dist/esm/internal/unfinishedWork.d.ts +99 -0
- package/dist/esm/internal/unfinishedWork.d.ts.map +1 -0
- package/dist/esm/internal/unfinishedWork.js +85 -0
- package/dist/esm/internal/unfinishedWork.js.map +1 -0
- package/dist/esm/internal/unobservedCall.d.ts +112 -0
- package/dist/esm/internal/unobservedCall.d.ts.map +1 -0
- package/dist/esm/internal/unobservedCall.js +501 -0
- package/dist/esm/internal/unobservedCall.js.map +1 -0
- package/dist/esm/internal/untrustedData.d.ts +14 -0
- package/dist/esm/internal/untrustedData.d.ts.map +1 -0
- package/dist/esm/internal/untrustedData.js +15 -0
- package/dist/esm/internal/untrustedData.js.map +1 -0
- package/docs/README.md +129 -0
- package/docs/api.md +1869 -0
- package/docs/concepts.md +238 -0
- package/docs/external-transcripts.md +245 -0
- package/docs/guides/bind-flows.md +167 -0
- package/docs/guides/drive-the-loop.md +265 -0
- package/docs/guides/run-cells.md +262 -0
- package/docs/guides/workerd.md +144 -0
- package/docs/installation.md +69 -0
- package/docs/quickstart.md +121 -0
- package/docs/reference.md +954 -0
- package/docs/troubleshooting.md +177 -0
- package/package.json +463 -3
- package/src/AgentEvent.ts +1772 -0
- package/src/CallLedger.ts +560 -0
- package/src/Cell.ts +926 -0
- package/src/CellCalls.ts +198 -0
- package/src/CellHistory.ts +128 -0
- package/src/CellTurn.ts +4450 -0
- package/src/CellValidation.ts +382 -0
- package/src/Compaction.ts +330 -0
- package/src/CompletionClaim.ts +1013 -0
- package/src/ContextWindow.ts +669 -0
- package/src/EngineLike.ts +614 -0
- package/src/ExternalTranscript.ts +1142 -0
- package/src/FailedCall.ts +163 -0
- package/src/FlowBinding.ts +603 -0
- package/src/HarnessError.ts +98 -0
- package/src/Judgement.ts +526 -0
- package/src/Monitor.ts +579 -0
- package/src/NarrowedCheck.ts +694 -0
- package/src/Notifications.ts +262 -0
- package/src/Plan.ts +113 -0
- package/src/QuickJSSandbox.ts +1557 -0
- package/src/Relevance.ts +352 -0
- package/src/Sandbox.ts +908 -0
- package/src/Steering.ts +405 -0
- package/src/StructuredOutput.ts +484 -0
- package/src/Sufficiency.ts +247 -0
- package/src/Supervisor.ts +798 -0
- package/src/Tokens.ts +108 -0
- package/src/Transcript.ts +513 -0
- package/src/TruncatedOutput.ts +297 -0
- package/src/UnmovedTree.ts +121 -0
- package/src/UnresolvedFailure.ts +240 -0
- package/src/VacuousVerification.ts +280 -0
- package/src/VariablesPanel.ts +165 -0
- package/src/index.ts +204 -0
- package/src/internal/bytes.ts +70 -0
- package/src/internal/cellPrompt.ts +337 -0
- package/src/internal/compactable.ts +76 -0
- package/src/internal/compactionMarks.ts +454 -0
- package/src/internal/demandText.ts +145 -0
- package/src/internal/elide.ts +130 -0
- package/src/internal/frame.ts +1178 -0
- package/src/internal/nonNegativeSafeInt.ts +24 -0
- package/src/internal/paidUsage.ts +90 -0
- package/src/internal/printChannel.ts +434 -0
- package/src/internal/printsObservation.ts +31 -0
- package/src/internal/refusal.ts +53 -0
- package/src/internal/supervision.ts +652 -0
- package/src/internal/unfinishedWork.ts +123 -0
- package/src/internal/unobservedCall.ts +536 -0
- package/src/internal/untrustedData.ts +19 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The call ledger: what this run has already asked, rendered every frame.
|
|
3
|
+
*
|
|
4
|
+
* A cell's results are durable, but they are invisible to the next model turn
|
|
5
|
+
* unless the cell that made them happened to copy them into `context`. A cell
|
|
6
|
+
* is authored blind — the model writes the whole program before it sees any of
|
|
7
|
+
* its results — so copying is a guess made before the answer exists, and the
|
|
8
|
+
* rational response is to split one logical step across two frames: one frame
|
|
9
|
+
* to fetch, one to look. Thirty-one percent of the frames in one graded wave
|
|
10
|
+
* made no flow call at all, and the justifications they volunteered name the
|
|
11
|
+
* cause outright: "loaded the durable investigation results so the next frame
|
|
12
|
+
* can edit without repeating repository reads".
|
|
13
|
+
*
|
|
14
|
+
* This ledger removes the guess. Every settled call of the run contributes one
|
|
15
|
+
* line the harness derives on its own — ordinal, flow, what the call was about,
|
|
16
|
+
* whether it settled ok, and a structural digest of what came back — so a model
|
|
17
|
+
* can see what it has already asked without asking again. It carries no
|
|
18
|
+
* payloads: a line says `stdout=4096b`, never the four kilobytes.
|
|
19
|
+
*
|
|
20
|
+
* A call that *writes* gets two things more, because a repeated write is a
|
|
21
|
+
* different failure from a repeated read. The line says so and says how many
|
|
22
|
+
* bytes the call carried, and a write whose flow and input an earlier write
|
|
23
|
+
* already settled names that earlier one. The r95repl lane is why:
|
|
24
|
+
* `sympy__sympy-13878` applied one 4,789-byte patch five times across five
|
|
25
|
+
* frames, reverting the file between each, and nothing in the run's own record
|
|
26
|
+
* of itself said that the second application was the first one again. It spent
|
|
27
|
+
* 649 seconds and $1.20, the slowest instance in an arm whose median was 121 s.
|
|
28
|
+
* This is visibility and not a gate: re-applying is sometimes exactly right —
|
|
29
|
+
* the run had genuinely reverted the tree — and the exact-match refusal the
|
|
30
|
+
* truncated-write guard already carries is what stands between a run and a
|
|
31
|
+
* destructive repeat.
|
|
32
|
+
*
|
|
33
|
+
* It is a sibling of `NarrowedCheck` and `TruncatedOutput`: run-scoped
|
|
34
|
+
* controller state, bounded, journal-derivable, and interpreting nothing about
|
|
35
|
+
* any flow, tool, or repository.
|
|
36
|
+
*
|
|
37
|
+
* @since 0.1.0
|
|
38
|
+
*/
|
|
39
|
+
import * as Digest from "@smthrs/core/Digest";
|
|
40
|
+
import * as CanonicalJson from "@smthrs/model/CanonicalJson";
|
|
41
|
+
import { Effect, Schema } from "effect";
|
|
42
|
+
import * as elide from "./internal/elide.js";
|
|
43
|
+
import { NonNegativeSafeInt } from "./internal/nonNegativeSafeInt.js";
|
|
44
|
+
import * as NarrowedCheck from "./NarrowedCheck.js";
|
|
45
|
+
/**
|
|
46
|
+
* How many settled calls the rendered ledger carries, newest last.
|
|
47
|
+
*
|
|
48
|
+
* Thirty is above the whole call count of every round this harness has ever
|
|
49
|
+
* completed at or near par — the five golfed instances settle 7 to 25 calls —
|
|
50
|
+
* and it is a third of the call count of the worst recorded round, so a run
|
|
51
|
+
* that has genuinely lost the thread is shown its recent history rather than
|
|
52
|
+
* its whole one. Each line is bounded, so the section is bounded.
|
|
53
|
+
*
|
|
54
|
+
* @category constants
|
|
55
|
+
* @since 0.1.0
|
|
56
|
+
* @slop
|
|
57
|
+
*/
|
|
58
|
+
export const bound = 30;
|
|
59
|
+
/**
|
|
60
|
+
* How much of one call's subject or result digest a line may quote.
|
|
61
|
+
*
|
|
62
|
+
* @category constants
|
|
63
|
+
* @since 0.1.0
|
|
64
|
+
* @slop
|
|
65
|
+
*/
|
|
66
|
+
export const width = 120;
|
|
67
|
+
/**
|
|
68
|
+
* How many leaves of a result the digest may name.
|
|
69
|
+
*
|
|
70
|
+
* @category constants
|
|
71
|
+
* @since 0.1.0
|
|
72
|
+
* @slop
|
|
73
|
+
*/
|
|
74
|
+
export const members = 6;
|
|
75
|
+
/**
|
|
76
|
+
* How many levels below a result's own the digest descends.
|
|
77
|
+
*
|
|
78
|
+
* Five, because that is where a batched judgement keeps its answers. A
|
|
79
|
+
* `classify` batch answers under `results[].answers.<question>.value`, which
|
|
80
|
+
* is five levels down, and a digest that stopped above it reported
|
|
81
|
+
* `results=[4]` about a call that had answered four questions. Measured on the
|
|
82
|
+
* live seat over the three refused completions this bound was raised for:
|
|
83
|
+
* with `results=[4]` the narrow question read `invented` 0.86, 0.87 and 0.86;
|
|
84
|
+
* with the leaves named it read 0.11, 0.11 and 0.10. Below five the same
|
|
85
|
+
* states read 0.24 to 0.49, because naming the first member of a batch says
|
|
86
|
+
* what one state answered and the claim is about all of them.
|
|
87
|
+
*
|
|
88
|
+
* It is a depth and not a size: {@link resultWidth} is what keeps the line
|
|
89
|
+
* bounded, and {@link members} is what keeps a wide result from taking it
|
|
90
|
+
* over.
|
|
91
|
+
*
|
|
92
|
+
* @category constants
|
|
93
|
+
* @since 0.1.0
|
|
94
|
+
* @slop
|
|
95
|
+
*/
|
|
96
|
+
export const depth = 5;
|
|
97
|
+
/**
|
|
98
|
+
* How many distinct values one leaf may report before the rest are counted.
|
|
99
|
+
*
|
|
100
|
+
* A leaf folded across a batch takes one value per member, and what a reader
|
|
101
|
+
* needs from it is the spread: four states that all answered `true`, or three
|
|
102
|
+
* that answered `true` and one that did not. Three distinct values say that;
|
|
103
|
+
* a fourth says only that the leaf varies, which the count already said.
|
|
104
|
+
*
|
|
105
|
+
* @category constants
|
|
106
|
+
* @since 0.1.0
|
|
107
|
+
* @slop
|
|
108
|
+
*/
|
|
109
|
+
export const distinct = 3;
|
|
110
|
+
/**
|
|
111
|
+
* How much of one call's result digest a line may quote.
|
|
112
|
+
*
|
|
113
|
+
* Wider than {@link width} because a digest is a list of leaves and a name is
|
|
114
|
+
* one term. It is the bound the brake's receipt is held to as well: the
|
|
115
|
+
* digest travels twice, once in the state section this module renders and
|
|
116
|
+
* once as `CompletionClaim.Evidence.callsRun`'s `resultSummary`, and both are
|
|
117
|
+
* the same string. Three hundred and twenty bytes holds the six leaves
|
|
118
|
+
* {@link members} allows at the path lengths {@link depth} produces, and caps
|
|
119
|
+
* the ledger's whole contribution to a frame at thirty lines of it.
|
|
120
|
+
*
|
|
121
|
+
* @category constants
|
|
122
|
+
* @since 0.1.0
|
|
123
|
+
* @slop
|
|
124
|
+
*/
|
|
125
|
+
export const resultWidth = 320;
|
|
126
|
+
const clip = (text, limit) => elide.head(text, limit, "clipped");
|
|
127
|
+
/**
|
|
128
|
+
* One settled call, as one line of the run's history.
|
|
129
|
+
*
|
|
130
|
+
* @category models
|
|
131
|
+
* @since 0.1.0
|
|
132
|
+
* @slop
|
|
133
|
+
*/
|
|
134
|
+
export class Entry extends Schema.Class("flows/harness/CallLedger/Entry")({
|
|
135
|
+
/** The call's one-based position in the run's whole settled sequence. */
|
|
136
|
+
ordinal: NonNegativeSafeInt,
|
|
137
|
+
/** The flow the call named. */
|
|
138
|
+
flow: Schema.String,
|
|
139
|
+
/** What the call was about; see {@link subject}. */
|
|
140
|
+
subject: Schema.String,
|
|
141
|
+
/** Whether the call settled successfully. This is not the exit status. */
|
|
142
|
+
ok: Schema.Boolean,
|
|
143
|
+
/** The structural digest of what came back; see {@link digest}. */
|
|
144
|
+
digest: Schema.String,
|
|
145
|
+
/**
|
|
146
|
+
* The whole of what came back, in bytes of canonical JSON.
|
|
147
|
+
*
|
|
148
|
+
* Stated on every line, because a line is an index entry and the size is what
|
|
149
|
+
* says how much the name it points at is holding.
|
|
150
|
+
*/
|
|
151
|
+
bytes: NonNegativeSafeInt.pipe(Schema.withConstructorDefault(Effect.succeed(0)), Schema.withDecodingDefaultKey(Effect.succeed(0))),
|
|
152
|
+
/**
|
|
153
|
+
* Whether this call reached the engine declaring that it changes the tree.
|
|
154
|
+
*
|
|
155
|
+
* A mutation is the one kind of call whose repetition is never compliance.
|
|
156
|
+
* Re-issuing a read costs bytes; re-issuing the check that failed is what rule
|
|
157
|
+
* 7 asks for; re-applying a hunk means the run either lost its own edit or
|
|
158
|
+
* undid it, and either way it is about to make a change it has already made.
|
|
159
|
+
* So the line says which calls wrote, and {@link render} points a repeated
|
|
160
|
+
* write back at the write it repeats.
|
|
161
|
+
*/
|
|
162
|
+
mutates: Schema.Boolean.pipe(Schema.withConstructorDefault(Effect.succeed(false)), Schema.withDecodingDefaultKey(Effect.succeed(false))),
|
|
163
|
+
/**
|
|
164
|
+
* The bytes this call carried into the tree, for a call that declares a write.
|
|
165
|
+
*
|
|
166
|
+
* It is the longest string in the call's input — a `write`'s content, an
|
|
167
|
+
* `edit`'s replacement, a patch — measured the same flow-agnostic way
|
|
168
|
+
* `TruncatedOutput` measures a payload, and it is **not** a measured delta of
|
|
169
|
+
* the workspace. The harness has no per-call delta to report: its one honest
|
|
170
|
+
* measurement is `EngineLike.observe`, which covers a whole frame and counts
|
|
171
|
+
* paths rather than bytes. Stating the payload says what the call was, which
|
|
172
|
+
* is what makes two applications of one 4,789-byte patch legible as the same
|
|
173
|
+
* act; claiming a delta would say what the tree did, which this number does
|
|
174
|
+
* not know.
|
|
175
|
+
*
|
|
176
|
+
* The number is the payload and not the call: `sympy__sympy-13878` sent a
|
|
177
|
+
* 4,789-byte patch inside a 4,965-byte input, and it is the patch this reports,
|
|
178
|
+
* because the patch is the part two calls have in common.
|
|
179
|
+
*/
|
|
180
|
+
payloadBytes: NonNegativeSafeInt.pipe(Schema.withConstructorDefault(Effect.succeed(0)), Schema.withDecodingDefaultKey(Effect.succeed(0))),
|
|
181
|
+
/**
|
|
182
|
+
* The digest of this call's flow and input together.
|
|
183
|
+
*
|
|
184
|
+
* Held rather than rendered: it is what lets a later identical write name the
|
|
185
|
+
* earlier one, and it is a digest so the ledger stays small enough to live in
|
|
186
|
+
* journaled controller state.
|
|
187
|
+
*/
|
|
188
|
+
signature: Schema.String.pipe(Schema.withConstructorDefault(Effect.succeed("")), Schema.withDecodingDefaultKey(Effect.succeed("")))
|
|
189
|
+
}) {
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The run's settled calls, oldest first and bounded to {@link bound}.
|
|
193
|
+
*
|
|
194
|
+
* @category models
|
|
195
|
+
* @since 0.1.0
|
|
196
|
+
* @slop
|
|
197
|
+
*/
|
|
198
|
+
export const Ledger = Schema.Array(Entry).pipe(Schema.withConstructorDefault(Effect.succeed([])), Schema.withDecodingDefaultKey(Effect.succeed([])));
|
|
199
|
+
/**
|
|
200
|
+
* What one call was about: the first term of its input that names a target.
|
|
201
|
+
*
|
|
202
|
+
* `NarrowedCheck` already owns the lexer and the target/condition split, so a
|
|
203
|
+
* path, a test id, a dotted module name, or the file inside a shell command is
|
|
204
|
+
* picked out without this module knowing what any of those are. `names` is its
|
|
205
|
+
* stricter reading of a target, because a subject nobody can recognize is worse
|
|
206
|
+
* than no subject at all. An input with no such term is quoted whole instead,
|
|
207
|
+
* clipped — a grep that targets only a glob is named by its own pattern and
|
|
208
|
+
* root, which is what makes the line recognizable at all.
|
|
209
|
+
*
|
|
210
|
+
* @category conversions
|
|
211
|
+
* @since 0.1.0
|
|
212
|
+
* @slop
|
|
213
|
+
*/
|
|
214
|
+
export const subject = (input) => clip(sole(input) ?? CanonicalJson.stringify(input), width);
|
|
215
|
+
/**
|
|
216
|
+
* The one target an input names, or nothing when it names none or several.
|
|
217
|
+
*
|
|
218
|
+
* {@link target} takes the first, which is the right reading of a call about
|
|
219
|
+
* one thing and the wrong reading of a call about many. A `classify` batch
|
|
220
|
+
* over four files lexes four paths and was named by the first of them, so its
|
|
221
|
+
* line read `classify notes/n1.txt`: a call about four states, named after
|
|
222
|
+
* one of them, with the question it asked nowhere on the line. An input that
|
|
223
|
+
* names several targets is quoted whole instead, clipped, which is where the
|
|
224
|
+
* question is. Measured with the leaves of the result named either way, on
|
|
225
|
+
* the live seat over three refused completions: named after one state the
|
|
226
|
+
* narrow question read `invented` 0.73, 0.64 and 0.70; quoted whole it read
|
|
227
|
+
* 0.11, 0.11 and 0.10.
|
|
228
|
+
*
|
|
229
|
+
* Distinct, not total: a patch that names one path on every hunk header names
|
|
230
|
+
* one target, and it is the target.
|
|
231
|
+
*
|
|
232
|
+
* @category conversions
|
|
233
|
+
* @since 0.1.0
|
|
234
|
+
* @slop
|
|
235
|
+
*/
|
|
236
|
+
export const sole = (value) => {
|
|
237
|
+
const named = new Set(NarrowedCheck.lex(value).filter(NarrowedCheck.names));
|
|
238
|
+
const [only] = named;
|
|
239
|
+
return named.size === 1 ? only : undefined;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* The first term of a value that names a target, or nothing.
|
|
243
|
+
*
|
|
244
|
+
* Split out of {@link subject} because a write's target is not always in its
|
|
245
|
+
* input. Usually it is, even inside a blob: the lexer reads a patch's own text,
|
|
246
|
+
* so `sympy__sympy-13878`'s five applications each named
|
|
247
|
+
* `sympy/stats/crv_types.py` off the `*** Update File:` line. The split is for
|
|
248
|
+
* the write whose input names nothing a lexer can find — a patch that only adds
|
|
249
|
+
* a file, an input that carries bytes and a handle — where the result is the one
|
|
250
|
+
* place a path appears at all: `modified: ["sympy/stats/crv_types.py"]`. A line
|
|
251
|
+
* that named such a write by its payload's first hundred bytes said nothing a
|
|
252
|
+
* reader could match against the next one.
|
|
253
|
+
*
|
|
254
|
+
* @category conversions
|
|
255
|
+
* @since 0.1.0
|
|
256
|
+
* @slop
|
|
257
|
+
*/
|
|
258
|
+
export const target = (value) => NarrowedCheck.lex(value).find(NarrowedCheck.names);
|
|
259
|
+
const encoder = new TextEncoder();
|
|
260
|
+
const scalar = (value) => {
|
|
261
|
+
if (typeof value === "string")
|
|
262
|
+
return `${encoder.encode(value).byteLength}b`;
|
|
263
|
+
if (Array.isArray(value))
|
|
264
|
+
return `[${value.length}]`;
|
|
265
|
+
if (value !== null && typeof value === "object")
|
|
266
|
+
return "{…}";
|
|
267
|
+
return String(value);
|
|
268
|
+
};
|
|
269
|
+
const leafly = (value) => value === null || typeof value !== "object";
|
|
270
|
+
/** Whether a value reports itself whole: a scalar, or an array of them. */
|
|
271
|
+
const counted = (value) => leafly(value) || (Array.isArray(value) && (value.length === 0 || value.every(leafly)));
|
|
272
|
+
/**
|
|
273
|
+
* Folds one result's leaves into the path each sits at and the values that
|
|
274
|
+
* path took, in the order the walk met them.
|
|
275
|
+
*
|
|
276
|
+
* An array is walked into one path rather than one path per index: the members
|
|
277
|
+
* of a batch answer the same question, so `results[].ok` is one leaf that took
|
|
278
|
+
* four values and not four leaves that took one each. That is what makes a
|
|
279
|
+
* four-state judgement fit a line.
|
|
280
|
+
*/
|
|
281
|
+
const leaves = (value, path, into, left) => {
|
|
282
|
+
const took = (rendered) => {
|
|
283
|
+
const seen = into.get(path);
|
|
284
|
+
if (seen === undefined)
|
|
285
|
+
into.set(path, [rendered]);
|
|
286
|
+
else
|
|
287
|
+
seen.push(rendered);
|
|
288
|
+
};
|
|
289
|
+
if (counted(value) || left === 0)
|
|
290
|
+
return took(scalar(value));
|
|
291
|
+
if (Array.isArray(value)) {
|
|
292
|
+
for (const item of value)
|
|
293
|
+
leaves(item, `${path}[]`, into, left - 1);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const record = value;
|
|
297
|
+
const keys = Object.keys(record).sort();
|
|
298
|
+
// `{}` and not `{…}`: nothing was elided, the record is empty, and a reader
|
|
299
|
+
// that cannot tell those apart reads an empty result as a hidden one.
|
|
300
|
+
if (keys.length === 0)
|
|
301
|
+
return took("{}");
|
|
302
|
+
for (const key of keys)
|
|
303
|
+
leaves(record[key], path === "" ? key : `${path}.${key}`, into, left - 1);
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* What one leaf reported, across however many members it was folded over.
|
|
307
|
+
*
|
|
308
|
+
* Distinct values, each with how many members took it, capped at
|
|
309
|
+
* {@link distinct}. A leaf one member deep reports its value alone, which is
|
|
310
|
+
* what every unbatched result in this ledger reported before folding existed.
|
|
311
|
+
*/
|
|
312
|
+
const spread = (values) => {
|
|
313
|
+
const tally = new Map();
|
|
314
|
+
for (const value of values)
|
|
315
|
+
tally.set(value, (tally.get(value) ?? 0) + 1);
|
|
316
|
+
const all = [...tally.entries()];
|
|
317
|
+
const named = all.slice(0, distinct).map(([value, count]) => count === 1 ? value : `${value}×${count}`);
|
|
318
|
+
const rest = all.length - named.length;
|
|
319
|
+
return [...named, ...(rest > 0 ? [`+${rest} more`] : [])].join(" ");
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* The one-line structural digest of what a call returned.
|
|
323
|
+
*
|
|
324
|
+
* Counts and statuses, never payloads: a leaf that is a string reports its
|
|
325
|
+
* byte length, an array of scalars reports its length, and a number or boolean
|
|
326
|
+
* (an exit code, a truncation flag, a judgement) reports itself. Leaves are
|
|
327
|
+
* named by their path in canonical key order and capped at {@link members}, so
|
|
328
|
+
* the same result always renders the same line and a result with fifty leaves
|
|
329
|
+
* cannot take the frame over.
|
|
330
|
+
*
|
|
331
|
+
* It descends {@link depth} levels, and an array of records folds into one
|
|
332
|
+
* path per leaf with the values its members took, because the alternative was
|
|
333
|
+
* measured and it was the defect. A `classify` batch returns its judgements
|
|
334
|
+
* under `results[].answers.<question>.value`; a digest that named only the
|
|
335
|
+
* result's own keys reported `results=[4]`, which records that four answers
|
|
336
|
+
* arrived and not one of them. The completion brake reads this string as its
|
|
337
|
+
* receipt for work that reports no exit status, so a run that judged four
|
|
338
|
+
* files and said so was refused for reporting a result nothing recorded. See
|
|
339
|
+
* {@link depth} for the readings either way.
|
|
340
|
+
*
|
|
341
|
+
* @category conversions
|
|
342
|
+
* @since 0.1.0
|
|
343
|
+
* @slop
|
|
344
|
+
*/
|
|
345
|
+
export const digest = (value) => {
|
|
346
|
+
if (counted(value))
|
|
347
|
+
return clip(scalar(value), resultWidth);
|
|
348
|
+
const found = new Map();
|
|
349
|
+
leaves(value, "", found, depth);
|
|
350
|
+
const paths = [...found.keys()];
|
|
351
|
+
// The root has no name, so a result with nothing under it reports its own
|
|
352
|
+
// shape rather than an empty name bound to it.
|
|
353
|
+
const named = paths.slice(0, members).map((path) => path === "" ? spread(found.get(path)) : `${path}=${spread(found.get(path))}`);
|
|
354
|
+
const rest = paths.length - named.length;
|
|
355
|
+
return clip([...named, ...(rest > 0 ? [`+${rest} more`] : [])].join(" "), resultWidth);
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* The bytes one call carried into the tree: the longest string in its input.
|
|
359
|
+
*
|
|
360
|
+
* Flow-agnostic on purpose, and the same walk `TruncatedOutput` uses to find the
|
|
361
|
+
* payload of a call it has never heard of. A `write` carries its content, an
|
|
362
|
+
* `edit` its replacement, `apply_patch` its patch, and every one of them is the
|
|
363
|
+
* longest string the input holds. A mutating call with no string at all — a
|
|
364
|
+
* revert that names only a path — carries nothing and says zero.
|
|
365
|
+
*
|
|
366
|
+
* @category conversions
|
|
367
|
+
* @since 0.1.0
|
|
368
|
+
* @slop
|
|
369
|
+
*/
|
|
370
|
+
export const payload = (input) => {
|
|
371
|
+
if (typeof input === "string")
|
|
372
|
+
return encoder.encode(input).byteLength;
|
|
373
|
+
if (Array.isArray(input))
|
|
374
|
+
return input.reduce((widest, item) => Math.max(widest, payload(item)), 0);
|
|
375
|
+
if (input === null || typeof input !== "object")
|
|
376
|
+
return 0;
|
|
377
|
+
return Object.values(input).reduce((widest, item) => Math.max(widest, payload(item)), 0);
|
|
378
|
+
};
|
|
379
|
+
/**
|
|
380
|
+
* Records one settled call.
|
|
381
|
+
*
|
|
382
|
+
* A call that failed carries what the flow said about the failure, because that
|
|
383
|
+
* text — an anchor near-miss, a missing path — is the whole content of the
|
|
384
|
+
* result and is otherwise seen only by a cell that thought to catch it.
|
|
385
|
+
*
|
|
386
|
+
* Every one of the four rendered fields is bounded, the flow name included. A
|
|
387
|
+
* name that matches no descriptor still settles — as a failure saying so — and
|
|
388
|
+
* the name is whatever the cell passed to `ctx.call`, which is a value the model
|
|
389
|
+
* writes. `ctx.call("Z".repeat(50000), {})` is one short line of JavaScript, and
|
|
390
|
+
* without this bound it put fifty kilobytes into durable controller state and
|
|
391
|
+
* into every remaining frame's prompt, thirty times over at the ledger's bound.
|
|
392
|
+
* A real flow name is far under {@link width}, so the clip is invisible to every
|
|
393
|
+
* call that names something callable.
|
|
394
|
+
*
|
|
395
|
+
* @category constructors
|
|
396
|
+
* @since 0.1.0
|
|
397
|
+
* @slop
|
|
398
|
+
*/
|
|
399
|
+
export const entry = (ordinal, call) => {
|
|
400
|
+
// `?? null` because a host can settle a call with no value at all: the
|
|
401
|
+
// contract says `Json`, an implementation that returns nothing says
|
|
402
|
+
// `undefined`, and canonical JSON refuses it. The ledger reports what the
|
|
403
|
+
// cell saw, which for such a call is `null`.
|
|
404
|
+
const whole = CanonicalJson.stringify(call.ok ? call.value ?? null : { failed: call.message ?? "failed" });
|
|
405
|
+
const mutates = call.mutates === true;
|
|
406
|
+
return new Entry({
|
|
407
|
+
ordinal,
|
|
408
|
+
flow: clip(call.flow, width),
|
|
409
|
+
// A write whose input names nothing is named by what came back, because a
|
|
410
|
+
// patch carries its paths in its own text and hands them back as a list.
|
|
411
|
+
// A write is named by the first target it holds, wherever it holds it: a
|
|
412
|
+
// patch names one file per hunk header and every one of them is a target
|
|
413
|
+
// this write has, so {@link sole} would refuse a two-file patch a name.
|
|
414
|
+
subject: mutates
|
|
415
|
+
? clip(target(call.input) ?? target(call.value) ?? CanonicalJson.stringify(call.input), width)
|
|
416
|
+
: subject(call.input),
|
|
417
|
+
ok: call.ok,
|
|
418
|
+
digest: call.ok ? digest(call.value) : clip(call.message ?? "failed", width),
|
|
419
|
+
bytes: encoder.encode(whole).byteLength,
|
|
420
|
+
mutates,
|
|
421
|
+
payloadBytes: mutates ? payload(call.input) : 0,
|
|
422
|
+
signature: mutates ? Digest.digest(CanonicalJson.stringify([call.flow, call.input])) : ""
|
|
423
|
+
});
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* How many calls this run has settled, given a ledger some of whose lines have
|
|
427
|
+
* aged out.
|
|
428
|
+
*
|
|
429
|
+
* The ledger holds at most {@link bound} lines, so its length stops being the
|
|
430
|
+
* run's call count as soon as it fills. The newest entry's ordinal is the count
|
|
431
|
+
* and does not, which is why ordinals are stored rather than rendered from an
|
|
432
|
+
* index.
|
|
433
|
+
*
|
|
434
|
+
* @category conversions
|
|
435
|
+
* @since 0.1.0
|
|
436
|
+
* @slop
|
|
437
|
+
*/
|
|
438
|
+
export const settled = (ledger) => ledger.length === 0 ? 0 : ledger[ledger.length - 1].ordinal;
|
|
439
|
+
/**
|
|
440
|
+
* Folds one frame's settled calls into the run's ledger, newest last.
|
|
441
|
+
*
|
|
442
|
+
* Ordinals continue the run's own sequence, so the numbers a model reads stay
|
|
443
|
+
* the numbers the journal would give the same calls after older lines have aged
|
|
444
|
+
* out of the bound.
|
|
445
|
+
*
|
|
446
|
+
* The ledger is an index, not a store: what a call returned is under the name
|
|
447
|
+
* the cell bound it to, and it is that index the golf report credits with
|
|
448
|
+
* deleting a whole frame class.
|
|
449
|
+
*
|
|
450
|
+
* @category combinators
|
|
451
|
+
* @since 0.1.0
|
|
452
|
+
* @slop
|
|
453
|
+
*/
|
|
454
|
+
export const remember = (known, made) => {
|
|
455
|
+
const before = settled(known);
|
|
456
|
+
const all = [...known, ...made.map((call, index) => entry(before + index + 1, call))];
|
|
457
|
+
return all.length <= bound ? all : all.slice(all.length - bound);
|
|
458
|
+
};
|
|
459
|
+
/**
|
|
460
|
+
* Renders the ledger for the state section, or nothing when there is no call
|
|
461
|
+
* to list.
|
|
462
|
+
*
|
|
463
|
+
* `since` is the newest ordinal an earlier section in the window already
|
|
464
|
+
* listed. The window keeps every frame's section (see `CellTurn`), so a later
|
|
465
|
+
* section lists only the calls settled after it; zero lists the whole ledger.
|
|
466
|
+
*
|
|
467
|
+
* @category conversions
|
|
468
|
+
* @since 0.1.0
|
|
469
|
+
* @slop
|
|
470
|
+
*/
|
|
471
|
+
export const render = (ledger, since = 0) => {
|
|
472
|
+
const listed = ledger.filter((line) => line.ordinal > since);
|
|
473
|
+
if (listed.length === 0)
|
|
474
|
+
return undefined;
|
|
475
|
+
const total = settled(ledger);
|
|
476
|
+
const elided = total - ledger.length;
|
|
477
|
+
const heading = since > 0
|
|
478
|
+
? `Calls this run has settled since the last list (${listed.length} of ${total}), oldest first. You have already asked these — read them here instead of asking again:`
|
|
479
|
+
: elided === 0
|
|
480
|
+
? `Calls this run has settled (${total}), oldest first. You have already asked these — read them here instead of asking again:`
|
|
481
|
+
: `Calls this run has settled (${total}), oldest first; the ${elided} oldest are not listed. You have already asked these — read them here instead of asking again:`;
|
|
482
|
+
// Where each write's signature was first settled, so a repeat can name it.
|
|
483
|
+
// First rather than most recent: the run wants the call it has already made,
|
|
484
|
+
// and the earliest one is the one every later copy repeats.
|
|
485
|
+
const first = new Map();
|
|
486
|
+
for (const line of ledger) {
|
|
487
|
+
if (line.mutates && !first.has(line.signature))
|
|
488
|
+
first.set(line.signature, line);
|
|
489
|
+
}
|
|
490
|
+
const lines = listed.map((line) => {
|
|
491
|
+
const repeated = line.mutates ? first.get(line.signature) : undefined;
|
|
492
|
+
const again = repeated === undefined || repeated.ordinal === line.ordinal
|
|
493
|
+
? ""
|
|
494
|
+
: ` — the same write as ${repeated.ordinal}, which ${repeated.ok ? "succeeded" : "failed"}`;
|
|
495
|
+
const wrote = line.mutates ? `WROTE ${line.payloadBytes}b, ` : "";
|
|
496
|
+
return `${line.ordinal}. ${line.flow} ${line.subject} — ${wrote}${line.ok ? "ok" : "FAILED"}${again}: ${line.digest} (${line.bytes}b)`;
|
|
497
|
+
});
|
|
498
|
+
// Only where the run has actually written something: teaching about a marker
|
|
499
|
+
// nothing on the page carries costs a frame's worth of reading for nothing.
|
|
500
|
+
const writes = first.size === 0
|
|
501
|
+
? ""
|
|
502
|
+
: "\nA line marked `WROTE` changed the tree, with the bytes it carried. One that names an earlier write made a change this run had already made: read what happened after the first one before making it a third time.";
|
|
503
|
+
const trailer = "\nThese are an index, not the results: what each call returned is still under the name your cell bound it to. Read the name; do not issue the call again.";
|
|
504
|
+
return `${heading}\n${lines.join("\n")}${trailer}${writes}`;
|
|
505
|
+
};
|
|
506
|
+
//# sourceMappingURL=CallLedger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallLedger.js","sourceRoot":"","sources":["../../src/CallLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,MAAM,MAAM,qBAAqB,CAAA;AAC7C,OAAO,KAAK,aAAa,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,CAAA;AAEvB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA;AAExB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAA;AAExB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAA;AAEtB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAA;AAEzB;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAA;AAE9B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAA;AAExF;;;;;;GAMG;AACH,MAAM,OAAO,KAAM,SAAQ,MAAM,CAAC,KAAK,CAAQ,gCAAgC,CAAC,CAAC;IAC/E,yEAAyE;IACzE,OAAO,EAAE,kBAAkB;IAC3B,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC,OAAO;IAClB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB;;;;;OAKG;IACH,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAC5B,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAChD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CACjD;IACD;;;;;;;;;OASG;IACH,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAC1B,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EACpD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CACrD;IACD;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,EAAE,kBAAkB,CAAC,IAAI,CACnC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAChD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CACjD;IACD;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAC3B,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EACjD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAClD;CACF,CAAC;CAAG;AAEL;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAC5C,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAuB,EAAE,CAAC,CAAC,EACvE,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAuB,EAAE,CAAC,CAAC,CACxE,CAAA;AAWD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAkB,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;AAEjH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAkB,EAAsB,EAAE;IAC7D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3E,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;IACpB,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5C,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAsB,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;AAEpH,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAEjC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAU,EAAE;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,CAAA;IAC5E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAA;IACpD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC7D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAA;AAEvF,2EAA2E;AAC3E,MAAM,OAAO,GAAG,CAAC,KAAc,EAAW,EAAE,CAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AAExF;;;;;;;;GAQG;AACH,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,IAAY,EAAE,IAAgC,EAAE,IAAY,EAAQ,EAAE;IACxG,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC3B,IAAI,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;;YAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC1B,CAAC,CAAA;IACD,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;QACnE,OAAM;IACR,CAAC;IACD,MAAM,MAAM,GAAG,KAA8C,CAAA;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IACvC,4EAA4E;IAC5E,sEAAsE;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,CAAA;IACxC,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAE,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;AACpG,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,CAAC,MAA6B,EAAU,EAAE;IACvD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAA;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACzE,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC,CAAA;IACvG,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IACtC,OAAO,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACrE,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAU,EAAE;IACnD,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAA;IAC9C,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAC/B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IAC/B,0EAA0E;IAC1E,+CAA+C;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjD,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,EAAE,CAC/E,CAAA;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IACxC,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAA;AACxF,CAAC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAkB,EAAU,EAAE;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,CAAA;IACtE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,MAAM,CAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3G,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAA;IACzD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAClG,CAAC,CAAA;AAmBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,IAAgB,EAAS,EAAE;IAChE,uEAAuE;IACvE,oEAAoE;IACpE,0EAA0E;IAC1E,6CAA6C;IAC7C,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAA;IAC1G,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAA;IACrC,OAAO,IAAI,KAAK,CAAC;QACf,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;QAC5B,0EAA0E;QAC1E,yEAAyE;QACzE,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,OAAO,EAAE,OAAO;YACd,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;YAC9F,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QACvB,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,KAAK,CAAC;QAC5E,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU;QACvC,OAAO;QACP,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;KAC1F,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,OAAO,CAAA;AAE/G;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,IAA+B,EAAU,EAAE;IACjF,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IACrF,OAAO,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAA;AAClE,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,KAAK,GAAG,CAAC,EAAsB,EAAE;IACtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,CAAA;IAC5D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7B,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAA;IACpC,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC;QACvB,CAAC,CAAC,mDAAmD,MAAM,CAAC,MAAM,OAAO,KAAK,yFAAyF;QACvK,CAAC,CAAC,MAAM,KAAK,CAAC;YACd,CAAC,CAAC,+BAA+B,KAAK,yFAAyF;YAC/H,CAAC,CAAC,+BAA+B,KAAK,wBAAwB,MAAM,gGAAgG,CAAA;IACtK,2EAA2E;IAC3E,6EAA6E;IAC7E,4DAA4D;IAC5D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAiB,CAAA;IACtC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IACjF,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACrE,MAAM,KAAK,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;YACvE,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,wBAAwB,QAAQ,CAAC,OAAO,WAAW,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QACjE,OAAO,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,MAAM,KAAK,GAC7D,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QACnB,GAAG,KAAK,KAAK,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,IAAI,CAAA;IAC7C,CAAC,CAAC,CAAA;IACF,6EAA6E;IAC7E,4EAA4E;IAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC;QAC7B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,qNAAqN,CAAA;IACzN,MAAM,OAAO,GACX,2JAA2J,CAAA;IAC7J,OAAO,GAAG,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;AAC7D,CAAC,CAAA","sourcesContent":["/**\n * The call ledger: what this run has already asked, rendered every frame.\n *\n * A cell's results are durable, but they are invisible to the next model turn\n * unless the cell that made them happened to copy them into `context`. A cell\n * is authored blind — the model writes the whole program before it sees any of\n * its results — so copying is a guess made before the answer exists, and the\n * rational response is to split one logical step across two frames: one frame\n * to fetch, one to look. Thirty-one percent of the frames in one graded wave\n * made no flow call at all, and the justifications they volunteered name the\n * cause outright: \"loaded the durable investigation results so the next frame\n * can edit without repeating repository reads\".\n *\n * This ledger removes the guess. Every settled call of the run contributes one\n * line the harness derives on its own — ordinal, flow, what the call was about,\n * whether it settled ok, and a structural digest of what came back — so a model\n * can see what it has already asked without asking again. It carries no\n * payloads: a line says `stdout=4096b`, never the four kilobytes.\n *\n * A call that *writes* gets two things more, because a repeated write is a\n * different failure from a repeated read. The line says so and says how many\n * bytes the call carried, and a write whose flow and input an earlier write\n * already settled names that earlier one. The r95repl lane is why:\n * `sympy__sympy-13878` applied one 4,789-byte patch five times across five\n * frames, reverting the file between each, and nothing in the run's own record\n * of itself said that the second application was the first one again. It spent\n * 649 seconds and $1.20, the slowest instance in an arm whose median was 121 s.\n * This is visibility and not a gate: re-applying is sometimes exactly right —\n * the run had genuinely reverted the tree — and the exact-match refusal the\n * truncated-write guard already carries is what stands between a run and a\n * destructive repeat.\n *\n * It is a sibling of `NarrowedCheck` and `TruncatedOutput`: run-scoped\n * controller state, bounded, journal-derivable, and interpreting nothing about\n * any flow, tool, or repository.\n *\n * @since 0.1.0\n */\n\nimport * as Digest from \"@smthrs/core/Digest\"\nimport * as CanonicalJson from \"@smthrs/model/CanonicalJson\"\nimport { Effect, Schema } from \"effect\"\nimport * as elide from \"./internal/elide.ts\"\nimport { NonNegativeSafeInt } from \"./internal/nonNegativeSafeInt.ts\"\nimport * as NarrowedCheck from \"./NarrowedCheck.ts\"\n\n/**\n * How many settled calls the rendered ledger carries, newest last.\n *\n * Thirty is above the whole call count of every round this harness has ever\n * completed at or near par — the five golfed instances settle 7 to 25 calls —\n * and it is a third of the call count of the worst recorded round, so a run\n * that has genuinely lost the thread is shown its recent history rather than\n * its whole one. Each line is bounded, so the section is bounded.\n *\n * @category constants\n * @since 0.1.0\n * @slop\n */\nexport const bound = 30\n\n/**\n * How much of one call's subject or result digest a line may quote.\n *\n * @category constants\n * @since 0.1.0\n * @slop\n */\nexport const width = 120\n\n/**\n * How many leaves of a result the digest may name.\n *\n * @category constants\n * @since 0.1.0\n * @slop\n */\nexport const members = 6\n\n/**\n * How many levels below a result's own the digest descends.\n *\n * Five, because that is where a batched judgement keeps its answers. A\n * `classify` batch answers under `results[].answers.<question>.value`, which\n * is five levels down, and a digest that stopped above it reported\n * `results=[4]` about a call that had answered four questions. Measured on the\n * live seat over the three refused completions this bound was raised for:\n * with `results=[4]` the narrow question read `invented` 0.86, 0.87 and 0.86;\n * with the leaves named it read 0.11, 0.11 and 0.10. Below five the same\n * states read 0.24 to 0.49, because naming the first member of a batch says\n * what one state answered and the claim is about all of them.\n *\n * It is a depth and not a size: {@link resultWidth} is what keeps the line\n * bounded, and {@link members} is what keeps a wide result from taking it\n * over.\n *\n * @category constants\n * @since 0.1.0\n * @slop\n */\nexport const depth = 5\n\n/**\n * How many distinct values one leaf may report before the rest are counted.\n *\n * A leaf folded across a batch takes one value per member, and what a reader\n * needs from it is the spread: four states that all answered `true`, or three\n * that answered `true` and one that did not. Three distinct values say that;\n * a fourth says only that the leaf varies, which the count already said.\n *\n * @category constants\n * @since 0.1.0\n * @slop\n */\nexport const distinct = 3\n\n/**\n * How much of one call's result digest a line may quote.\n *\n * Wider than {@link width} because a digest is a list of leaves and a name is\n * one term. It is the bound the brake's receipt is held to as well: the\n * digest travels twice, once in the state section this module renders and\n * once as `CompletionClaim.Evidence.callsRun`'s `resultSummary`, and both are\n * the same string. Three hundred and twenty bytes holds the six leaves\n * {@link members} allows at the path lengths {@link depth} produces, and caps\n * the ledger's whole contribution to a frame at thirty lines of it.\n *\n * @category constants\n * @since 0.1.0\n * @slop\n */\nexport const resultWidth = 320\n\nconst clip = (text: string, limit: number): string => elide.head(text, limit, \"clipped\")\n\n/**\n * One settled call, as one line of the run's history.\n *\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport class Entry extends Schema.Class<Entry>(\"flows/harness/CallLedger/Entry\")({\n /** The call's one-based position in the run's whole settled sequence. */\n ordinal: NonNegativeSafeInt,\n /** The flow the call named. */\n flow: Schema.String,\n /** What the call was about; see {@link subject}. */\n subject: Schema.String,\n /** Whether the call settled successfully. This is not the exit status. */\n ok: Schema.Boolean,\n /** The structural digest of what came back; see {@link digest}. */\n digest: Schema.String,\n /**\n * The whole of what came back, in bytes of canonical JSON.\n *\n * Stated on every line, because a line is an index entry and the size is what\n * says how much the name it points at is holding.\n */\n bytes: NonNegativeSafeInt.pipe(\n Schema.withConstructorDefault(Effect.succeed(0)),\n Schema.withDecodingDefaultKey(Effect.succeed(0))\n ),\n /**\n * Whether this call reached the engine declaring that it changes the tree.\n *\n * A mutation is the one kind of call whose repetition is never compliance.\n * Re-issuing a read costs bytes; re-issuing the check that failed is what rule\n * 7 asks for; re-applying a hunk means the run either lost its own edit or\n * undid it, and either way it is about to make a change it has already made.\n * So the line says which calls wrote, and {@link render} points a repeated\n * write back at the write it repeats.\n */\n mutates: Schema.Boolean.pipe(\n Schema.withConstructorDefault(Effect.succeed(false)),\n Schema.withDecodingDefaultKey(Effect.succeed(false))\n ),\n /**\n * The bytes this call carried into the tree, for a call that declares a write.\n *\n * It is the longest string in the call's input — a `write`'s content, an\n * `edit`'s replacement, a patch — measured the same flow-agnostic way\n * `TruncatedOutput` measures a payload, and it is **not** a measured delta of\n * the workspace. The harness has no per-call delta to report: its one honest\n * measurement is `EngineLike.observe`, which covers a whole frame and counts\n * paths rather than bytes. Stating the payload says what the call was, which\n * is what makes two applications of one 4,789-byte patch legible as the same\n * act; claiming a delta would say what the tree did, which this number does\n * not know.\n *\n * The number is the payload and not the call: `sympy__sympy-13878` sent a\n * 4,789-byte patch inside a 4,965-byte input, and it is the patch this reports,\n * because the patch is the part two calls have in common.\n */\n payloadBytes: NonNegativeSafeInt.pipe(\n Schema.withConstructorDefault(Effect.succeed(0)),\n Schema.withDecodingDefaultKey(Effect.succeed(0))\n ),\n /**\n * The digest of this call's flow and input together.\n *\n * Held rather than rendered: it is what lets a later identical write name the\n * earlier one, and it is a digest so the ledger stays small enough to live in\n * journaled controller state.\n */\n signature: Schema.String.pipe(\n Schema.withConstructorDefault(Effect.succeed(\"\")),\n Schema.withDecodingDefaultKey(Effect.succeed(\"\"))\n )\n}) {}\n\n/**\n * The run's settled calls, oldest first and bounded to {@link bound}.\n *\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport const Ledger = Schema.Array(Entry).pipe(\n Schema.withConstructorDefault(Effect.succeed<ReadonlyArray<Entry>>([])),\n Schema.withDecodingDefaultKey(Effect.succeed<ReadonlyArray<Entry>>([]))\n)\n\n/**\n * The run's settled calls, oldest first and bounded to {@link bound}.\n *\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport type Ledger = typeof Ledger.Type\n\n/**\n * What one call was about: the first term of its input that names a target.\n *\n * `NarrowedCheck` already owns the lexer and the target/condition split, so a\n * path, a test id, a dotted module name, or the file inside a shell command is\n * picked out without this module knowing what any of those are. `names` is its\n * stricter reading of a target, because a subject nobody can recognize is worse\n * than no subject at all. An input with no such term is quoted whole instead,\n * clipped — a grep that targets only a glob is named by its own pattern and\n * root, which is what makes the line recognizable at all.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const subject = (input: Schema.Json): string => clip(sole(input) ?? CanonicalJson.stringify(input), width)\n\n/**\n * The one target an input names, or nothing when it names none or several.\n *\n * {@link target} takes the first, which is the right reading of a call about\n * one thing and the wrong reading of a call about many. A `classify` batch\n * over four files lexes four paths and was named by the first of them, so its\n * line read `classify notes/n1.txt`: a call about four states, named after\n * one of them, with the question it asked nowhere on the line. An input that\n * names several targets is quoted whole instead, clipped, which is where the\n * question is. Measured with the leaves of the result named either way, on\n * the live seat over three refused completions: named after one state the\n * narrow question read `invented` 0.73, 0.64 and 0.70; quoted whole it read\n * 0.11, 0.11 and 0.10.\n *\n * Distinct, not total: a patch that names one path on every hunk header names\n * one target, and it is the target.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const sole = (value: Schema.Json): string | undefined => {\n const named = new Set(NarrowedCheck.lex(value).filter(NarrowedCheck.names))\n const [only] = named\n return named.size === 1 ? only : undefined\n}\n\n/**\n * The first term of a value that names a target, or nothing.\n *\n * Split out of {@link subject} because a write's target is not always in its\n * input. Usually it is, even inside a blob: the lexer reads a patch's own text,\n * so `sympy__sympy-13878`'s five applications each named\n * `sympy/stats/crv_types.py` off the `*** Update File:` line. The split is for\n * the write whose input names nothing a lexer can find — a patch that only adds\n * a file, an input that carries bytes and a handle — where the result is the one\n * place a path appears at all: `modified: [\"sympy/stats/crv_types.py\"]`. A line\n * that named such a write by its payload's first hundred bytes said nothing a\n * reader could match against the next one.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const target = (value: Schema.Json): string | undefined => NarrowedCheck.lex(value).find(NarrowedCheck.names)\n\nconst encoder = new TextEncoder()\n\nconst scalar = (value: unknown): string => {\n if (typeof value === \"string\") return `${encoder.encode(value).byteLength}b`\n if (Array.isArray(value)) return `[${value.length}]`\n if (value !== null && typeof value === \"object\") return \"{…}\"\n return String(value)\n}\n\nconst leafly = (value: unknown): boolean => value === null || typeof value !== \"object\"\n\n/** Whether a value reports itself whole: a scalar, or an array of them. */\nconst counted = (value: unknown): boolean =>\n leafly(value) || (Array.isArray(value) && (value.length === 0 || value.every(leafly)))\n\n/**\n * Folds one result's leaves into the path each sits at and the values that\n * path took, in the order the walk met them.\n *\n * An array is walked into one path rather than one path per index: the members\n * of a batch answer the same question, so `results[].ok` is one leaf that took\n * four values and not four leaves that took one each. That is what makes a\n * four-state judgement fit a line.\n */\nconst leaves = (value: Schema.Json, path: string, into: Map<string, Array<string>>, left: number): void => {\n const took = (rendered: string) => {\n const seen = into.get(path)\n if (seen === undefined) into.set(path, [rendered])\n else seen.push(rendered)\n }\n if (counted(value) || left === 0) return took(scalar(value))\n if (Array.isArray(value)) {\n for (const item of value) leaves(item, `${path}[]`, into, left - 1)\n return\n }\n const record = value as Readonly<Record<string, Schema.Json>>\n const keys = Object.keys(record).sort()\n // `{}` and not `{…}`: nothing was elided, the record is empty, and a reader\n // that cannot tell those apart reads an empty result as a hidden one.\n if (keys.length === 0) return took(\"{}\")\n for (const key of keys) leaves(record[key]!, path === \"\" ? key : `${path}.${key}`, into, left - 1)\n}\n\n/**\n * What one leaf reported, across however many members it was folded over.\n *\n * Distinct values, each with how many members took it, capped at\n * {@link distinct}. A leaf one member deep reports its value alone, which is\n * what every unbatched result in this ledger reported before folding existed.\n */\nconst spread = (values: ReadonlyArray<string>): string => {\n const tally = new Map<string, number>()\n for (const value of values) tally.set(value, (tally.get(value) ?? 0) + 1)\n const all = [...tally.entries()]\n const named = all.slice(0, distinct).map(([value, count]) => count === 1 ? value : `${value}×${count}`)\n const rest = all.length - named.length\n return [...named, ...(rest > 0 ? [`+${rest} more`] : [])].join(\" \")\n}\n\n/**\n * The one-line structural digest of what a call returned.\n *\n * Counts and statuses, never payloads: a leaf that is a string reports its\n * byte length, an array of scalars reports its length, and a number or boolean\n * (an exit code, a truncation flag, a judgement) reports itself. Leaves are\n * named by their path in canonical key order and capped at {@link members}, so\n * the same result always renders the same line and a result with fifty leaves\n * cannot take the frame over.\n *\n * It descends {@link depth} levels, and an array of records folds into one\n * path per leaf with the values its members took, because the alternative was\n * measured and it was the defect. A `classify` batch returns its judgements\n * under `results[].answers.<question>.value`; a digest that named only the\n * result's own keys reported `results=[4]`, which records that four answers\n * arrived and not one of them. The completion brake reads this string as its\n * receipt for work that reports no exit status, so a run that judged four\n * files and said so was refused for reporting a result nothing recorded. See\n * {@link depth} for the readings either way.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const digest = (value: Schema.Json): string => {\n if (counted(value)) return clip(scalar(value), resultWidth)\n const found = new Map<string, Array<string>>()\n leaves(value, \"\", found, depth)\n const paths = [...found.keys()]\n // The root has no name, so a result with nothing under it reports its own\n // shape rather than an empty name bound to it.\n const named = paths.slice(0, members).map((path) =>\n path === \"\" ? spread(found.get(path)!) : `${path}=${spread(found.get(path)!)}`\n )\n const rest = paths.length - named.length\n return clip([...named, ...(rest > 0 ? [`+${rest} more`] : [])].join(\" \"), resultWidth)\n}\n\n/**\n * The bytes one call carried into the tree: the longest string in its input.\n *\n * Flow-agnostic on purpose, and the same walk `TruncatedOutput` uses to find the\n * payload of a call it has never heard of. A `write` carries its content, an\n * `edit` its replacement, `apply_patch` its patch, and every one of them is the\n * longest string the input holds. A mutating call with no string at all — a\n * revert that names only a path — carries nothing and says zero.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const payload = (input: Schema.Json): number => {\n if (typeof input === \"string\") return encoder.encode(input).byteLength\n if (Array.isArray(input)) return input.reduce<number>((widest, item) => Math.max(widest, payload(item)), 0)\n if (input === null || typeof input !== \"object\") return 0\n return Object.values(input).reduce<number>((widest, item) => Math.max(widest, payload(item)), 0)\n}\n\n/**\n * One settled call, as the controller observed it.\n *\n * @category models\n * @since 0.1.0\n * @slop\n */\nexport interface Settlement {\n readonly flow: string\n readonly input: Schema.Json\n readonly ok: boolean\n readonly value: Schema.Json\n readonly message?: string | undefined\n /** Whether the call reached the engine declaring a write; see {@link Entry.mutates}. */\n readonly mutates?: boolean | undefined\n}\n\n/**\n * Records one settled call.\n *\n * A call that failed carries what the flow said about the failure, because that\n * text — an anchor near-miss, a missing path — is the whole content of the\n * result and is otherwise seen only by a cell that thought to catch it.\n *\n * Every one of the four rendered fields is bounded, the flow name included. A\n * name that matches no descriptor still settles — as a failure saying so — and\n * the name is whatever the cell passed to `ctx.call`, which is a value the model\n * writes. `ctx.call(\"Z\".repeat(50000), {})` is one short line of JavaScript, and\n * without this bound it put fifty kilobytes into durable controller state and\n * into every remaining frame's prompt, thirty times over at the ledger's bound.\n * A real flow name is far under {@link width}, so the clip is invisible to every\n * call that names something callable.\n *\n * @category constructors\n * @since 0.1.0\n * @slop\n */\nexport const entry = (ordinal: number, call: Settlement): Entry => {\n // `?? null` because a host can settle a call with no value at all: the\n // contract says `Json`, an implementation that returns nothing says\n // `undefined`, and canonical JSON refuses it. The ledger reports what the\n // cell saw, which for such a call is `null`.\n const whole = CanonicalJson.stringify(call.ok ? call.value ?? null : { failed: call.message ?? \"failed\" })\n const mutates = call.mutates === true\n return new Entry({\n ordinal,\n flow: clip(call.flow, width),\n // A write whose input names nothing is named by what came back, because a\n // patch carries its paths in its own text and hands them back as a list.\n // A write is named by the first target it holds, wherever it holds it: a\n // patch names one file per hunk header and every one of them is a target\n // this write has, so {@link sole} would refuse a two-file patch a name.\n subject: mutates\n ? clip(target(call.input) ?? target(call.value) ?? CanonicalJson.stringify(call.input), width)\n : subject(call.input),\n ok: call.ok,\n digest: call.ok ? digest(call.value) : clip(call.message ?? \"failed\", width),\n bytes: encoder.encode(whole).byteLength,\n mutates,\n payloadBytes: mutates ? payload(call.input) : 0,\n signature: mutates ? Digest.digest(CanonicalJson.stringify([call.flow, call.input])) : \"\"\n })\n}\n\n/**\n * How many calls this run has settled, given a ledger some of whose lines have\n * aged out.\n *\n * The ledger holds at most {@link bound} lines, so its length stops being the\n * run's call count as soon as it fills. The newest entry's ordinal is the count\n * and does not, which is why ordinals are stored rather than rendered from an\n * index.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const settled = (ledger: Ledger): number => ledger.length === 0 ? 0 : ledger[ledger.length - 1]!.ordinal\n\n/**\n * Folds one frame's settled calls into the run's ledger, newest last.\n *\n * Ordinals continue the run's own sequence, so the numbers a model reads stay\n * the numbers the journal would give the same calls after older lines have aged\n * out of the bound.\n *\n * The ledger is an index, not a store: what a call returned is under the name\n * the cell bound it to, and it is that index the golf report credits with\n * deleting a whole frame class.\n *\n * @category combinators\n * @since 0.1.0\n * @slop\n */\nexport const remember = (known: Ledger, made: ReadonlyArray<Settlement>): Ledger => {\n const before = settled(known)\n const all = [...known, ...made.map((call, index) => entry(before + index + 1, call))]\n return all.length <= bound ? all : all.slice(all.length - bound)\n}\n\n/**\n * Renders the ledger for the state section, or nothing when there is no call\n * to list.\n *\n * `since` is the newest ordinal an earlier section in the window already\n * listed. The window keeps every frame's section (see `CellTurn`), so a later\n * section lists only the calls settled after it; zero lists the whole ledger.\n *\n * @category conversions\n * @since 0.1.0\n * @slop\n */\nexport const render = (ledger: Ledger, since = 0): string | undefined => {\n const listed = ledger.filter((line) => line.ordinal > since)\n if (listed.length === 0) return undefined\n const total = settled(ledger)\n const elided = total - ledger.length\n const heading = since > 0\n ? `Calls this run has settled since the last list (${listed.length} of ${total}), oldest first. You have already asked these — read them here instead of asking again:`\n : elided === 0\n ? `Calls this run has settled (${total}), oldest first. You have already asked these — read them here instead of asking again:`\n : `Calls this run has settled (${total}), oldest first; the ${elided} oldest are not listed. You have already asked these — read them here instead of asking again:`\n // Where each write's signature was first settled, so a repeat can name it.\n // First rather than most recent: the run wants the call it has already made,\n // and the earliest one is the one every later copy repeats.\n const first = new Map<string, Entry>()\n for (const line of ledger) {\n if (line.mutates && !first.has(line.signature)) first.set(line.signature, line)\n }\n const lines = listed.map((line) => {\n const repeated = line.mutates ? first.get(line.signature) : undefined\n const again = repeated === undefined || repeated.ordinal === line.ordinal\n ? \"\"\n : ` — the same write as ${repeated.ordinal}, which ${repeated.ok ? \"succeeded\" : \"failed\"}`\n const wrote = line.mutates ? `WROTE ${line.payloadBytes}b, ` : \"\"\n return `${line.ordinal}. ${line.flow} ${line.subject} — ${wrote}${\n line.ok ? \"ok\" : \"FAILED\"\n }${again}: ${line.digest} (${line.bytes}b)`\n })\n // Only where the run has actually written something: teaching about a marker\n // nothing on the page carries costs a frame's worth of reading for nothing.\n const writes = first.size === 0\n ? \"\"\n : \"\\nA line marked `WROTE` changed the tree, with the bytes it carried. One that names an earlier write made a change this run had already made: read what happened after the first one before making it a third time.\"\n const trailer =\n \"\\nThese are an index, not the results: what each call returned is still under the name your cell bound it to. Read the name; do not issue the call again.\"\n return `${heading}\\n${lines.join(\"\\n\")}${trailer}${writes}`\n}\n"]}
|