@plurnk/plurnk-service 1.16.4 → 1.17.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/.env.defaults +122 -246
- package/INSTALL.md +84 -138
- package/README.md +9 -5
- package/SPEC.md +1710 -1015
- package/dist/Paths.d.ts +2 -0
- package/dist/Paths.d.ts.map +1 -1
- package/dist/Paths.js +2 -0
- package/dist/Paths.js.map +1 -1
- package/dist/build-info.d.ts.map +1 -1
- package/dist/build-info.js +7 -1
- package/dist/build-info.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/content/body-preview.d.ts +8 -0
- package/dist/content/body-preview.d.ts.map +1 -0
- package/dist/content/body-preview.js +39 -0
- package/dist/content/body-preview.js.map +1 -0
- package/dist/content/byte-view.d.ts +1 -4
- package/dist/content/byte-view.d.ts.map +1 -1
- package/dist/content/byte-view.js.map +1 -1
- package/dist/content/edit-collision.d.ts.map +1 -1
- package/dist/content/edit-collision.js +3 -4
- package/dist/content/edit-collision.js.map +1 -1
- package/dist/content/line-anchors.d.ts +2 -2
- package/dist/content/line-anchors.d.ts.map +1 -1
- package/dist/content/line-anchors.js +4 -3
- package/dist/content/line-anchors.js.map +1 -1
- package/dist/content/line-selection.d.ts +9 -0
- package/dist/content/line-selection.d.ts.map +1 -0
- package/dist/content/line-selection.js +29 -0
- package/dist/content/line-selection.js.map +1 -0
- package/dist/content/matcher.d.ts +0 -1
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +2 -3
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/pattern-edits.d.ts +39 -0
- package/dist/content/pattern-edits.d.ts.map +1 -0
- package/dist/content/pattern-edits.js +121 -0
- package/dist/content/pattern-edits.js.map +1 -0
- package/dist/content/read-projector.d.ts +18 -9
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +132 -35
- package/dist/content/read-projector.js.map +1 -1
- package/dist/content/read-resolve.d.ts +3 -1
- package/dist/content/read-resolve.d.ts.map +1 -1
- package/dist/content/read-resolve.js +39 -7
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +3 -5
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +91 -83
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/BareBatchRunner.d.ts +6 -1
- package/dist/core/BareBatchRunner.d.ts.map +1 -1
- package/dist/core/BareBatchRunner.js +20 -5
- package/dist/core/BareBatchRunner.js.map +1 -1
- package/dist/core/BudgetReadout.d.ts +2 -3
- package/dist/core/BudgetReadout.d.ts.map +1 -1
- package/dist/core/BudgetReadout.js +23 -32
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/CapabilityPolicies.d.ts +3 -8
- package/dist/core/CapabilityPolicies.d.ts.map +1 -1
- package/dist/core/CapabilityPolicies.js +2 -28
- package/dist/core/CapabilityPolicies.js.map +1 -1
- package/dist/core/CapabilityResolver.d.ts +10 -10
- package/dist/core/CapabilityResolver.d.ts.map +1 -1
- package/dist/core/CapabilityResolver.js +87 -65
- package/dist/core/CapabilityResolver.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +14 -11
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +11 -12
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +99 -9
- package/dist/core/ClientInteractions.d.ts.map +1 -1
- package/dist/core/ClientInteractions.js +7 -0
- package/dist/core/ClientInteractions.js.map +1 -1
- package/dist/core/CoreSchemeServices.d.ts +13 -10
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +13 -5
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/DataStatementRunner.d.ts +2 -2
- package/dist/core/DataStatementRunner.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.js +36 -39
- package/dist/core/DataStatementRunner.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +19 -26
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +369 -219
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/Dispatcher.sql +66 -0
- package/dist/core/DurableStatement.d.ts.map +1 -1
- package/dist/core/DurableStatement.js +2 -1
- package/dist/core/DurableStatement.js.map +1 -1
- package/dist/core/EditMutations.d.ts +14 -18
- package/dist/core/EditMutations.d.ts.map +1 -1
- package/dist/core/EditMutations.js +211 -280
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/EditMutations.sql +15 -0
- package/dist/core/EditSequence.d.ts +13 -0
- package/dist/core/EditSequence.d.ts.map +1 -0
- package/dist/core/EditSequence.js +73 -0
- package/dist/core/EditSequence.js.map +1 -0
- package/dist/core/Engine.d.ts +17 -23
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +73 -163
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +0 -724
- package/dist/core/EntryAddressBinding.d.ts +7 -17
- package/dist/core/EntryAddressBinding.d.ts.map +1 -1
- package/dist/core/EntryAddressBinding.js +12 -72
- package/dist/core/EntryAddressBinding.js.map +1 -1
- package/dist/core/ExecutionOutputs.d.ts +9 -0
- package/dist/core/ExecutionOutputs.d.ts.map +1 -0
- package/dist/core/ExecutionOutputs.js +36 -0
- package/dist/core/ExecutionOutputs.js.map +1 -0
- package/dist/core/ExecutionOutputs.sql +13 -0
- package/dist/core/ExecutorRegistry.d.ts +7 -5
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +36 -32
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/HostPaths.d.ts +1 -0
- package/dist/core/HostPaths.d.ts.map +1 -1
- package/dist/core/HostPaths.js +4 -0
- package/dist/core/HostPaths.js.map +1 -1
- package/dist/core/InferenceCall.d.ts.map +1 -1
- package/dist/core/InferenceCall.js +1 -2
- package/dist/core/InferenceCall.js.map +1 -1
- package/dist/core/InferenceCall.sql +29 -0
- package/dist/core/KillHandler.d.ts +1 -0
- package/dist/core/KillHandler.d.ts.map +1 -1
- package/dist/core/KillHandler.js +24 -21
- package/dist/core/KillHandler.js.map +1 -1
- package/dist/core/LogBody.d.ts +8 -1
- package/dist/core/LogBody.d.ts.map +1 -1
- package/dist/core/LogBody.js +42 -11
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogEntryProjection.d.ts +1 -0
- package/dist/core/LogEntryProjection.d.ts.map +1 -1
- package/dist/core/LogEntryProjection.js +18 -10
- package/dist/core/LogEntryProjection.js.map +1 -1
- package/dist/core/LogVisibility.d.ts +1 -0
- package/dist/core/LogVisibility.d.ts.map +1 -1
- package/dist/core/LogVisibility.js +3 -0
- package/dist/core/LogVisibility.js.map +1 -1
- package/dist/core/LogWriter.d.ts +2 -3
- package/dist/core/LogWriter.d.ts.map +1 -1
- package/dist/core/LogWriter.js +25 -32
- package/dist/core/LogWriter.js.map +1 -1
- package/dist/core/LogWriter.sql +23 -0
- package/dist/core/LoopDriver.d.ts +11 -8
- package/dist/core/LoopDriver.d.ts.map +1 -1
- package/dist/core/LoopDriver.js +163 -189
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopDriver.sql +11 -0
- package/dist/core/LoopLifecycle.d.ts +32 -2
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +88 -4
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +145 -28
- package/dist/core/LoopPolicyReader.sql +6 -0
- package/dist/core/MembershipMaterialization.d.ts.map +1 -1
- package/dist/core/MembershipMaterialization.js +6 -28
- package/dist/core/MembershipMaterialization.js.map +1 -1
- package/dist/core/ModelCall.sql +70 -0
- package/dist/core/MutationEffects.d.ts +5 -3
- package/dist/core/MutationEffects.d.ts.map +1 -1
- package/dist/core/MutationEffects.js +10 -28
- package/dist/core/MutationEffects.js.map +1 -1
- package/dist/core/NativeContent.d.ts +6 -0
- package/dist/core/NativeContent.d.ts.map +1 -0
- package/dist/core/NativeContent.js +16 -0
- package/dist/core/NativeContent.js.map +1 -0
- package/dist/core/NativeContent.sql +6 -0
- package/dist/core/NoticeChannel.js +1 -1
- package/dist/core/NoticeChannel.js.map +1 -1
- package/dist/core/OperatorConfig.js +5 -5
- package/dist/core/OperatorConfig.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +8 -5
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +117 -81
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/PacketBuilder.sql +146 -0
- package/dist/core/PatternSelection.d.ts +28 -0
- package/dist/core/PatternSelection.d.ts.map +1 -0
- package/dist/core/PatternSelection.js +42 -0
- package/dist/core/PatternSelection.js.map +1 -0
- package/dist/core/ProblemLog.d.ts.map +1 -1
- package/dist/core/ProblemLog.js +0 -1
- package/dist/core/ProblemLog.js.map +1 -1
- package/dist/core/PromptFrames.d.ts +12 -0
- package/dist/core/PromptFrames.d.ts.map +1 -0
- package/dist/core/PromptFrames.js +28 -0
- package/dist/core/PromptFrames.js.map +1 -0
- package/dist/core/ProposalLifecycle.d.ts +0 -1
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +20 -19
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProposalLifecycle.sql +33 -0
- package/dist/core/ProviderInstantiate.d.ts +1 -1
- package/dist/core/ProviderInstantiate.d.ts.map +1 -1
- package/dist/core/ProviderInstantiate.js +7 -14
- package/dist/core/ProviderInstantiate.js.map +1 -1
- package/dist/core/ReasoningView.d.ts +9 -0
- package/dist/core/ReasoningView.d.ts.map +1 -0
- package/dist/core/ReasoningView.js +47 -0
- package/dist/core/ReasoningView.js.map +1 -0
- package/dist/core/ResourceBindings.d.ts +16 -0
- package/dist/core/ResourceBindings.d.ts.map +1 -0
- package/dist/core/ResourceBindings.js +45 -0
- package/dist/core/ResourceBindings.js.map +1 -0
- package/dist/core/ResourceMutations.d.ts +5 -8
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +6 -7
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.d.ts +2 -2
- package/dist/core/ResourceSelector.d.ts.map +1 -1
- package/dist/core/ResourceSelector.js +122 -62
- package/dist/core/ResourceSelector.js.map +1 -1
- package/dist/core/ResourceTransfers.d.ts +4 -2
- package/dist/core/ResourceTransfers.d.ts.map +1 -1
- package/dist/core/ResourceTransfers.js +95 -26
- package/dist/core/ResourceTransfers.js.map +1 -1
- package/dist/core/RuntimeWorker.d.ts +5 -0
- package/dist/core/RuntimeWorker.d.ts.map +1 -0
- package/dist/core/RuntimeWorker.js +10 -0
- package/dist/core/RuntimeWorker.js.map +1 -0
- package/dist/core/RuntimeWorker.sql +5 -0
- package/dist/core/SchemeRegistry.d.ts +12 -16
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +58 -84
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/StoredPacket.d.ts +6 -1
- package/dist/core/StoredPacket.d.ts.map +1 -1
- package/dist/core/StoredPacket.js +30 -10
- package/dist/core/StoredPacket.js.map +1 -1
- package/dist/core/StrikeRail.d.ts +9 -6
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +60 -113
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/StrikeRail.sql +12 -0
- package/dist/core/TerminalResult.d.ts +1 -1
- package/dist/core/TerminalResult.d.ts.map +1 -1
- package/dist/core/TerminalResult.js +2 -2
- package/dist/core/TerminalResult.js.map +1 -1
- package/dist/core/TokenCalibration.d.ts +1 -6
- package/dist/core/TokenCalibration.d.ts.map +1 -1
- package/dist/core/TokenCalibration.js +13 -9
- package/dist/core/TokenCalibration.js.map +1 -1
- package/dist/core/TokenCalibration.sql +15 -0
- package/dist/core/ToolInputSchema.d.ts +6 -0
- package/dist/core/ToolInputSchema.d.ts.map +1 -0
- package/dist/core/ToolInputSchema.js +43 -0
- package/dist/core/ToolInputSchema.js.map +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +76 -52
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/Turn.d.ts +5 -2
- package/dist/core/Turn.d.ts.map +1 -1
- package/dist/core/Turn.js +13 -11
- package/dist/core/Turn.js.map +1 -1
- package/dist/core/Turn.sql +25 -39
- package/dist/core/{SendBroadcastHandler.d.ts → TurnDispositionHandler.d.ts} +25 -17
- package/dist/core/TurnDispositionHandler.d.ts.map +1 -0
- package/dist/core/TurnDispositionHandler.js +198 -0
- package/dist/core/TurnDispositionHandler.js.map +1 -0
- package/dist/core/TurnMaterialization.d.ts +2 -3
- package/dist/core/TurnMaterialization.d.ts.map +1 -1
- package/dist/core/TurnMaterialization.js +40 -15
- package/dist/core/TurnMaterialization.js.map +1 -1
- package/dist/core/TurnMaterialization.sql +44 -0
- package/dist/core/TurnOps.d.ts.map +1 -1
- package/dist/core/TurnOps.js +8 -64
- package/dist/core/TurnOps.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +9 -12
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +232 -408
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/TurnRunner.sql +74 -0
- package/dist/core/TurnSources.sql +39 -0
- package/dist/core/WorkerControlAddress.d.ts +1 -0
- package/dist/core/WorkerControlAddress.d.ts.map +1 -1
- package/dist/core/WorkerControlAddress.js +5 -0
- package/dist/core/WorkerControlAddress.js.map +1 -1
- package/dist/core/WorkerControlHandler.d.ts +1 -3
- package/dist/core/WorkerControlHandler.d.ts.map +1 -1
- package/dist/core/WorkerControlHandler.js +41 -48
- package/dist/core/WorkerControlHandler.js.map +1 -1
- package/dist/core/WorkerName.d.ts +8 -6
- package/dist/core/WorkerName.d.ts.map +1 -1
- package/dist/core/WorkerName.js +33 -24
- package/dist/core/WorkerName.js.map +1 -1
- package/dist/core/WorkerName.sql +7 -10
- package/dist/core/WorkspaceGate.d.ts +1 -1
- package/dist/core/WorkspaceGate.d.ts.map +1 -1
- package/dist/core/WorkspaceGate.js +29 -6
- package/dist/core/WorkspaceGate.js.map +1 -1
- package/dist/core/ambient.sql +236 -0
- package/dist/core/attachments.d.ts +2 -1
- package/dist/core/attachments.d.ts.map +1 -1
- package/dist/core/attachments.js +5 -4
- package/dist/core/attachments.js.map +1 -1
- package/dist/core/caps/CapsResolve.d.ts +2 -3
- package/dist/core/caps/CapsResolve.d.ts.map +1 -1
- package/dist/core/caps/CapsResolve.js +5 -5
- package/dist/core/caps/CapsResolve.js.map +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
- package/dist/core/caps/DbChannelCaps.js +4 -6
- package/dist/core/caps/DbChannelCaps.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.d.ts +2 -1
- package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
- package/dist/core/caps/DbEntryCaps.js +11 -17
- package/dist/core/caps/DbEntryCaps.js.map +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
- package/dist/core/caps/DbNotifyCaps.js +3 -5
- package/dist/core/caps/DbNotifyCaps.js.map +1 -1
- package/dist/core/caps/DbProjectionCaps.js +1 -1
- package/dist/core/caps/DbProjectionCaps.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +5 -7
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +0 -2
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +4 -20
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js +4 -2
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/file-materialization.d.ts +4 -1
- package/dist/core/file-materialization.d.ts.map +1 -1
- package/dist/core/file-materialization.js +14 -0
- package/dist/core/file-materialization.js.map +1 -1
- package/dist/core/fork.d.ts +1 -6
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +9 -153
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +162 -185
- package/dist/core/git-env.d.ts +1 -0
- package/dist/core/git-env.d.ts.map +1 -1
- package/dist/core/git-env.js +39 -2
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +64 -48
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/git-state.js +25 -19
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/glob_match.d.ts +4 -0
- package/dist/core/glob_match.d.ts.map +1 -0
- package/dist/core/glob_match.js +7 -0
- package/dist/core/glob_match.js.map +1 -0
- package/dist/core/maintenance.sql +6 -0
- package/dist/core/mutation-types.d.ts +7 -28
- package/dist/core/mutation-types.d.ts.map +1 -1
- package/dist/core/packet-inject.d.ts.map +1 -1
- package/dist/core/packet-inject.js +2 -3
- package/dist/core/packet-inject.js.map +1 -1
- package/dist/core/packet-wire.d.ts +8 -6
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +131 -163
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +1 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +5 -12
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/scheme-types.d.ts +3 -3
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/scheme-types.js.map +1 -1
- package/dist/core/sha256.d.ts +4 -0
- package/dist/core/sha256.d.ts.map +1 -0
- package/dist/core/sha256.js +6 -0
- package/dist/core/sha256.js.map +1 -0
- package/dist/core/teaching.js +1 -1
- package/dist/core/teaching.js.map +1 -1
- package/dist/core/turn-scheduler.d.ts.map +1 -1
- package/dist/core/turn-scheduler.js +5 -18
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/turn-signals.d.ts +0 -6
- package/dist/core/turn-signals.d.ts.map +1 -1
- package/dist/core/turn-signals.js +1 -7
- package/dist/core/turn-signals.js.map +1 -1
- package/dist/core/worker-ops.sql +15 -22
- package/dist/core/workspace-settings.d.ts.map +1 -1
- package/dist/core/workspace-settings.js +18 -2
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/core/workspace-settings.sql +6 -0
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +27 -90
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestRender.d.ts.map +1 -1
- package/dist/digest/DigestRender.js +14 -54
- package/dist/digest/DigestRender.js.map +1 -1
- package/dist/digest/digest-rows.d.ts +10 -32
- package/dist/digest/digest-rows.d.ts.map +1 -1
- package/dist/digest/digest.sql +43 -18
- package/dist/schemes/Exec.d.ts +6 -12
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +256 -188
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +8 -6
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +33 -61
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/ExecutionInput.d.ts +12 -0
- package/dist/schemes/ExecutionInput.d.ts.map +1 -0
- package/dist/schemes/ExecutionInput.js +94 -0
- package/dist/schemes/ExecutionInput.js.map +1 -0
- package/dist/schemes/File.d.ts +5 -2
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +62 -92
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +84 -79
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +183 -15
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +3 -12
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/QuestionTool.d.ts +5 -0
- package/dist/schemes/QuestionTool.d.ts.map +1 -1
- package/dist/schemes/QuestionTool.js +6 -14
- package/dist/schemes/QuestionTool.js.map +1 -1
- package/dist/schemes/Skill.d.ts +12 -7
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +149 -21
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/TurnSource.d.ts +12 -0
- package/dist/schemes/TurnSource.d.ts.map +1 -0
- package/dist/schemes/TurnSource.js +116 -0
- package/dist/schemes/TurnSource.js.map +1 -0
- package/dist/schemes/Worker.d.ts +3 -3
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +61 -208
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +12 -15
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +63 -63
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +142 -46
- package/dist/schemes/_entry-find.d.ts +1 -3
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +111 -112
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +22 -14
- package/dist/schemes/_entry-fts.d.ts +14 -0
- package/dist/schemes/_entry-fts.d.ts.map +1 -0
- package/dist/schemes/_entry-fts.js +82 -0
- package/dist/schemes/_entry-fts.js.map +1 -0
- package/dist/schemes/_entry-fts.sql +31 -0
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +6 -14
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-graph.sql +29 -44
- package/dist/schemes/_entry-manifest.d.ts +2 -1
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +15 -12
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-manifest.sql +26 -0
- package/dist/schemes/_entry-ops.d.ts +3 -5
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +30 -43
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-ops.sql +5 -6
- package/dist/schemes/_entry-readable.d.ts +8 -0
- package/dist/schemes/_entry-readable.d.ts.map +1 -0
- package/dist/schemes/_entry-readable.js +38 -0
- package/dist/schemes/_entry-readable.js.map +1 -0
- package/dist/schemes/_entry-send.d.ts +1 -1
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +3 -3
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/_search-index.d.ts +1 -3
- package/dist/schemes/_search-index.d.ts.map +1 -1
- package/dist/schemes/_search-index.js +79 -110
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/_search-index.sql +30 -0
- package/dist/schemes/exec-runtime.d.ts +1 -1
- package/dist/schemes/exec-runtime.d.ts.map +1 -1
- package/dist/schemes/exec-runtime.js.map +1 -1
- package/dist/server/ClientReads.d.ts +2 -2
- package/dist/server/ClientReads.d.ts.map +1 -1
- package/dist/server/ClientReads.js +5 -8
- package/dist/server/ClientReads.js.map +1 -1
- package/dist/server/Daemon.d.ts +14 -21
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +135 -156
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +23 -21
- package/dist/server/DaemonModule.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +8 -21
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +278 -306
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/Functionality.d.ts +11 -12
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js +129 -101
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.d.ts +3 -5
- package/dist/server/FunctionalityManager.d.ts.map +1 -1
- package/dist/server/FunctionalityManager.js +20 -58
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +5 -4
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +24 -37
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/PlurnkSkill.d.ts +11 -0
- package/dist/server/PlurnkSkill.d.ts.map +1 -0
- package/dist/server/PlurnkSkill.js +41 -0
- package/dist/server/PlurnkSkill.js.map +1 -0
- package/dist/server/Retention.d.ts +22 -0
- package/dist/server/Retention.d.ts.map +1 -0
- package/dist/server/Retention.js +54 -0
- package/dist/server/Retention.js.map +1 -0
- package/dist/server/Retention.sql +36 -0
- package/dist/server/ServiceModules.d.ts +5 -0
- package/dist/server/ServiceModules.d.ts.map +1 -0
- package/dist/server/ServiceModules.js +10 -0
- package/dist/server/ServiceModules.js.map +1 -0
- package/dist/server/SkillsFunctionality.d.ts +14 -19
- package/dist/server/SkillsFunctionality.d.ts.map +1 -1
- package/dist/server/SkillsFunctionality.js +97 -104
- package/dist/server/SkillsFunctionality.js.map +1 -1
- package/dist/server/WorkerModelResolver.d.ts +4 -0
- package/dist/server/WorkerModelResolver.d.ts.map +1 -1
- package/dist/server/WorkerModelResolver.js +72 -39
- package/dist/server/WorkerModelResolver.js.map +1 -1
- package/dist/server/WorkspaceCapabilities.d.ts +21 -0
- package/dist/server/WorkspaceCapabilities.d.ts.map +1 -0
- package/dist/server/{WorkerCapabilities.js → WorkspaceCapabilities.js} +40 -40
- package/dist/server/WorkspaceCapabilities.js.map +1 -0
- package/dist/server/WorkspaceResidency.d.ts +36 -0
- package/dist/server/WorkspaceResidency.d.ts.map +1 -0
- package/dist/server/WorkspaceResidency.js +199 -0
- package/dist/server/WorkspaceResidency.js.map +1 -0
- package/dist/server/client-input.d.ts +1 -4
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +4 -45
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +4 -22
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/drain.sql +65 -42
- package/dist/server/envelope.d.ts +8 -0
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +9 -7
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +49 -13
- package/dist/server/lifecycle-recovery.sql +14 -17
- package/dist/server/logEntry.d.ts +1 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +4 -1
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +25 -1
- package/dist/server/loopDocs.d.ts +2 -2
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +38 -31
- package/dist/server/loopDocs.js.map +1 -1
- package/dist/server/loopDocs.sql +1 -3
- package/dist/server/model-catalog.d.ts.map +1 -1
- package/dist/server/model-catalog.js +2 -1
- package/dist/server/model-catalog.js.map +1 -1
- package/dist/server/model-route.d.ts +1 -1
- package/dist/server/model-route.d.ts.map +1 -1
- package/dist/server/model-route.js +4 -2
- package/dist/server/model-route.js.map +1 -1
- package/dist/server/seam-entry-read.sql +3 -4
- package/dist/server/seam-loop.sql +2 -9
- package/dist/server/workspace-capabilities.sql +19 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +5 -17
- package/dist/service.js.map +1 -1
- package/docs/members.md +83 -0
- package/docs/skills.md +50 -0
- package/migrations/001_workspaces.sql +53 -0
- package/migrations/002_workers.sql +183 -0
- package/migrations/003_loops.sql +326 -0
- package/migrations/004_inference.sql +360 -0
- package/migrations/005_entries.sql +207 -0
- package/migrations/006_log.sql +578 -0
- package/migrations/007_subscriptions.sql +175 -0
- package/migrations/008_interactions.sql +29 -0
- package/package.json +33 -40
- package/digest-sql/channel-dispositions/dispositions.sql +0 -15
- package/digest-sql/channel-state/state.sql +0 -6
- package/digest-sql/curation/curation.sql +0 -6
- package/digest-sql/derivations/derivations.sql +0 -4
- package/digest-sql/embeddings/embeddings.sql +0 -4
- package/digest-sql/entry-dispositions/dispositions.sql +0 -15
- package/digest-sql/entry-state/state.sql +0 -6
- package/digest-sql/token-counts/token-counts.sql +0 -2
- package/dist/core/EmbeddingCall.d.ts +0 -23
- package/dist/core/EmbeddingCall.d.ts.map +0 -1
- package/dist/core/EmbeddingCall.js +0 -149
- package/dist/core/EmbeddingCall.js.map +0 -1
- package/dist/core/OverflowTurn.d.ts +0 -11
- package/dist/core/OverflowTurn.d.ts.map +0 -1
- package/dist/core/OverflowTurn.js +0 -80
- package/dist/core/OverflowTurn.js.map +0 -1
- package/dist/core/Owner.d.ts +0 -8
- package/dist/core/Owner.d.ts.map +0 -1
- package/dist/core/Owner.js +0 -46
- package/dist/core/Owner.js.map +0 -1
- package/dist/core/SendBroadcastHandler.d.ts.map +0 -1
- package/dist/core/SendBroadcastHandler.js +0 -159
- package/dist/core/SendBroadcastHandler.js.map +0 -1
- package/dist/core/VectorPump.d.ts +0 -28
- package/dist/core/VectorPump.d.ts.map +0 -1
- package/dist/core/VectorPump.js +0 -130
- package/dist/core/VectorPump.js.map +0 -1
- package/dist/core/owner.sql +0 -11
- package/dist/core/worker-settings.d.ts +0 -10
- package/dist/core/worker-settings.d.ts.map +0 -1
- package/dist/core/worker-settings.js +0 -53
- package/dist/core/worker-settings.js.map +0 -1
- package/dist/schemes/_entry-chunk.d.ts +0 -14
- package/dist/schemes/_entry-chunk.d.ts.map +0 -1
- package/dist/schemes/_entry-chunk.js +0 -165
- package/dist/schemes/_entry-chunk.js.map +0 -1
- package/dist/schemes/_entry-semantic.d.ts +0 -63
- package/dist/schemes/_entry-semantic.d.ts.map +0 -1
- package/dist/schemes/_entry-semantic.js +0 -299
- package/dist/schemes/_entry-semantic.js.map +0 -1
- package/dist/schemes/_entry-semantic.sql +0 -99
- package/dist/schemes/cosine.d.ts +0 -4
- package/dist/schemes/cosine.d.ts.map +0 -1
- package/dist/schemes/cosine.js +0 -9
- package/dist/schemes/cosine.js.map +0 -1
- package/dist/server/WorkerCapabilities.d.ts +0 -21
- package/dist/server/WorkerCapabilities.d.ts.map +0 -1
- package/dist/server/WorkerCapabilities.js.map +0 -1
- package/dist/server/WorkerResidency.d.ts +0 -40
- package/dist/server/WorkerResidency.d.ts.map +0 -1
- package/dist/server/WorkerResidency.js +0 -283
- package/dist/server/WorkerResidency.js.map +0 -1
- package/dist/server/seam-log-read.sql +0 -21
- package/dist/server/worker-capabilities.sql +0 -28
- package/migrations/001_schema.sql +0 -2207
package/dist/core/TurnRunner.js
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
|
+
import { TurnDisposition } from "@plurnk/plurnk-contracts";
|
|
2
|
+
import NativeContent from "./NativeContent.js";
|
|
1
3
|
import { PathSyntax, PlurnkParser, PlurnkParseError, UNKNOWN_POSITION } from "@plurnk/plurnk-contracts";
|
|
2
4
|
import { setTimeout as delay } from "node:timers/promises";
|
|
3
5
|
import { aggregateProviderAccounting } from "@plurnk/plurnk-providers";
|
|
4
6
|
const comparePosition = (a, b) => a.line - b.line || a.column - b.column;
|
|
5
7
|
import Meta from "@plurnk/plurnk-meta";
|
|
6
|
-
import EntryCrud from "../schemes/_entry-crud.js";
|
|
7
8
|
import GitMembership from "./git-membership.js";
|
|
8
9
|
import { acceptedKinds } from "./attachments.js";
|
|
9
10
|
import GitState from "./git-state.js";
|
|
10
11
|
import WorkspaceSettings from "./workspace-settings.js";
|
|
11
|
-
import {
|
|
12
|
+
import { taskTiming } from "./LoopLifecycle.js";
|
|
13
|
+
import { generatedPathname, promptLoopPrefix } from "./plurnk-uri.js";
|
|
14
|
+
import PromptFrames from "./PromptFrames.js";
|
|
12
15
|
import { readFile } from "node:fs/promises";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
import { resolve as resolvePath } from "node:path";
|
|
17
|
+
import { homedir } from "node:os";
|
|
18
|
+
// {§operator-grammar} — an operator's own GBNF is a file path: absolute, `~`-relative, or
|
|
19
|
+
// relative to the daemon's working directory. The service ships no grammar profile, so a bare
|
|
20
|
+
// name (no separator) is refused by name rather than resolved against anything.
|
|
21
|
+
export const resolveOperatorGrammarPath = (value) => {
|
|
22
|
+
if (value === "~" || value.startsWith("~/"))
|
|
23
|
+
return resolvePath(homedir(), value.slice(2));
|
|
24
|
+
if (value.startsWith("/") || value.startsWith(".") || value.includes("/"))
|
|
25
|
+
return resolvePath(value);
|
|
26
|
+
throw new Error(`PLURNK_PROVIDERS_GBNF=${value} names a bundled grammar profile; the service ships none (#588). Give the path of a grammar file you wrote.`);
|
|
27
|
+
};
|
|
22
28
|
// Shared module imported by both Engine and bin/digest.ts, so wire
|
|
23
29
|
// projection and digest projection are structurally one function — no
|
|
24
30
|
// drift between wire and digest possible.
|
|
25
31
|
import PacketWire from "./packet-wire.js";
|
|
32
|
+
import ReasoningView from "./ReasoningView.js";
|
|
26
33
|
import Results, { OperationFailureError } from "./results.js";
|
|
27
34
|
import Turn from "./Turn.js";
|
|
28
35
|
import StoredPacket from "./StoredPacket.js";
|
|
@@ -30,39 +37,29 @@ import { observed, observedSync } from "../observe/spans.js";
|
|
|
30
37
|
import { GEN_AI_REQUEST_SPAN, genAiRequestOptions, settleGenAiResponse } from "../observe/genai.js";
|
|
31
38
|
import { PROVIDER_CALLS, recordCounter } from "../observe/metrics.js";
|
|
32
39
|
import ModelCall, { ModelCallPersistenceError, ProviderAccountingIntegrityError } from "./ModelCall.js";
|
|
33
|
-
import
|
|
40
|
+
import WorkerName from "./WorkerName.js";
|
|
34
41
|
import TurnOps from "./TurnOps.js";
|
|
35
42
|
import CapabilityPolicies from "./CapabilityPolicies.js";
|
|
36
43
|
import CapabilityResolver from "./CapabilityResolver.js";
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// the owner rides the owner_id column, the address carries only the loop coordinate.
|
|
40
|
-
const promptTarget = (loopSeq, promptOrdinal) => {
|
|
41
|
-
const storage = promptPathname(loopSeq, promptOrdinal);
|
|
44
|
+
// {§prompt-address}: the same literal address in every observer's packet.
|
|
45
|
+
const promptTarget = (workerName, storage) => {
|
|
42
46
|
return {
|
|
43
|
-
kind: "url", raw: `prompt://${storage}`,
|
|
47
|
+
kind: "url", raw: `prompt://${workerName}${storage}`,
|
|
44
48
|
scheme: "prompt", username: null, password: null,
|
|
45
|
-
hostname:
|
|
49
|
+
hostname: workerName, port: null,
|
|
46
50
|
pathname: storage, query: null, fragment: null,
|
|
47
51
|
};
|
|
48
52
|
};
|
|
49
53
|
const regexLiteral = (value) => value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
50
|
-
const workerCatalogTarget = (namespace
|
|
51
|
-
|
|
52
|
-
return null;
|
|
53
|
-
const leaf = availableNames.length === 0 || admittedNames.length === availableNames.length
|
|
54
|
-
? "*.md"
|
|
55
|
-
: admittedNames.length === 1
|
|
56
|
-
? `${admittedNames[0]}.md`
|
|
57
|
-
: `{${admittedNames.join(",")}}.md`;
|
|
58
|
-
const pathname = generatedPathname(`/${namespace}/${leaf}`);
|
|
54
|
+
const workerCatalogTarget = (namespace) => {
|
|
55
|
+
const pathname = generatedPathname(`/${namespace}/*.md`);
|
|
59
56
|
return {
|
|
60
57
|
kind: "url",
|
|
61
|
-
raw: `worker
|
|
58
|
+
raw: `worker://${pathname}`,
|
|
62
59
|
scheme: "worker",
|
|
63
60
|
username: null,
|
|
64
61
|
password: null,
|
|
65
|
-
hostname:
|
|
62
|
+
hostname: null,
|
|
66
63
|
port: null,
|
|
67
64
|
pathname,
|
|
68
65
|
query: null,
|
|
@@ -115,35 +112,12 @@ const readFilesItems = () => {
|
|
|
115
112
|
return normalizeFilesItems(Number.parseInt(raw, 10));
|
|
116
113
|
};
|
|
117
114
|
import { ProviderError, scopeEnvToAlias } from "@plurnk/plurnk-providers";
|
|
118
|
-
import { validateGbnf } from "@plurnk/gbnf";
|
|
119
115
|
import ProviderInstantiate from "./ProviderInstantiate.js";
|
|
120
116
|
import TurnMaterialization from "./TurnMaterialization.js";
|
|
121
117
|
import BareBatchRunner from "./BareBatchRunner.js";
|
|
122
|
-
import {
|
|
118
|
+
import { TURN_STATUS_IMPLICIT_CONTINUE } from "./turn-signals.js";
|
|
123
119
|
import AdmittedTurnExecutor from "./AdmittedTurnExecutor.js";
|
|
124
|
-
|
|
125
|
-
// template contributes a prefix that llama-server preserves in its response.
|
|
126
|
-
// The artifact names the alternate root that composes those bytes for evidence
|
|
127
|
-
// grading; arbitrary grammars without the declaration retain their transport root.
|
|
128
|
-
const grammarConstraint = (grammar) => {
|
|
129
|
-
const declarations = [...grammar.matchAll(/^# @plurnk-response-root ([A-Za-z][A-Za-z0-9-]*)$/gm)];
|
|
130
|
-
if (declarations.length === 0)
|
|
131
|
-
return { transport: grammar, response: grammar };
|
|
132
|
-
if (declarations.length !== 1)
|
|
133
|
-
throw new Error("GBNF constraint declares multiple @plurnk-response-root values");
|
|
134
|
-
const responseRoot = declarations[0][1];
|
|
135
|
-
if (!grammar.split("\n").some((line) => line.startsWith(`${responseRoot} ::=`))) {
|
|
136
|
-
throw new Error(`GBNF constraint declares missing response root ${responseRoot}`);
|
|
137
|
-
}
|
|
138
|
-
const roots = [...grammar.matchAll(/^root ::= ([A-Za-z][A-Za-z0-9-]*)$/gm)];
|
|
139
|
-
if (roots.length !== 1)
|
|
140
|
-
throw new Error("GBNF constraint must declare exactly one simple root");
|
|
141
|
-
return {
|
|
142
|
-
transport: grammar,
|
|
143
|
-
response: grammar.replace(roots[0][0], `root ::= ${responseRoot}`),
|
|
144
|
-
};
|
|
145
|
-
};
|
|
146
|
-
const TOKEN_BUDGET_OVERFLOW_HARD_DETAIL = "Context Token Budget Overflow: tokensActiveTotal exceeded tokensActiveMax, and the causal overflow turn could not make enough room.";
|
|
120
|
+
const TOKEN_BUDGET_OVERFLOW_HARD_DETAIL = "Context Token Budget Overflow: logTokensTotal exceeds logTokensMax; retained context cannot fit.";
|
|
147
121
|
const curationOverflowFailure = (pressure) => Results.failure("engine:context", "token-budget-overflow", 413, TOKEN_BUDGET_OVERFLOW_HARD_DETAIL, {}, {
|
|
148
122
|
usage: pressure.weight,
|
|
149
123
|
ceiling: pressure.budget,
|
|
@@ -202,7 +176,8 @@ export default class TurnRunner {
|
|
|
202
176
|
#warmWorkspace;
|
|
203
177
|
#dispatch;
|
|
204
178
|
#resolveWorkerProviderIdentity;
|
|
205
|
-
|
|
179
|
+
// {§operator-grammar} — one read per path per daemon; the file is the operator's and static.
|
|
180
|
+
#grammarCache = new Map();
|
|
206
181
|
#materialization;
|
|
207
182
|
#bareBatch;
|
|
208
183
|
#admitted;
|
|
@@ -228,7 +203,7 @@ export default class TurnRunner {
|
|
|
228
203
|
this.#warmWorkspace = warmWorkspace;
|
|
229
204
|
this.#dispatch = dispatch;
|
|
230
205
|
this.#resolveWorkerProviderIdentity = resolveWorkerProviderIdentity;
|
|
231
|
-
this.#materialization = new TurnMaterialization({ db: this.#db,
|
|
206
|
+
this.#materialization = new TurnMaterialization({ db: this.#db, weighContent: this.#weighContent });
|
|
232
207
|
this.#bareBatch = new BareBatchRunner({ db: this.#db, providerAttributions: this.#providerAttributions.bind(this), providerFailure: TurnRunner.#providerFailure });
|
|
233
208
|
this.#admitted = new AdmittedTurnExecutor({ db: this.#db, schemes: this.#schemes, notices: this.#notices, problems: this.#problems, dispatcher: this.#dispatcher, bareBatch: this.#bareBatch });
|
|
234
209
|
}
|
|
@@ -243,66 +218,31 @@ export default class TurnRunner {
|
|
|
243
218
|
workerId: args.workerId,
|
|
244
219
|
loopId: args.loopId,
|
|
245
220
|
packetCount: packetCount.count,
|
|
221
|
+
...taskTiming(packetCount),
|
|
246
222
|
});
|
|
247
223
|
}
|
|
248
|
-
// {§
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
TurnRunner.#railGapWarned.add(message);
|
|
255
|
-
process.stderr.write(`plurnk-engine: rail verdict unavailable — the configured grammar did not parse in @plurnk/gbnf (${message})\n`);
|
|
256
|
-
}
|
|
257
|
-
static #requireGrammarEvidence(response, allowWithheld) {
|
|
258
|
-
const evidence = response.grammarEvidence;
|
|
259
|
-
if (evidence === undefined) {
|
|
260
|
-
throw new Error("provider contract violation: configured GBNF response omitted grammar evidence");
|
|
261
|
-
}
|
|
262
|
-
const input = [...evidence.input];
|
|
263
|
-
if (!Number.isInteger(evidence.contentStart)
|
|
264
|
-
|| evidence.contentStart < 0
|
|
265
|
-
|| evidence.contentStart > input.length
|
|
266
|
-
|| typeof evidence.transported !== "boolean"
|
|
267
|
-
|| input.slice(evidence.contentStart).join("") !== response.assistant.content) {
|
|
268
|
-
throw new Error("provider contract violation: grammar evidence does not map exactly to assistant.content");
|
|
269
|
-
}
|
|
270
|
-
if (!allowWithheld && !evidence.transported) {
|
|
271
|
-
throw new Error("provider contract violation: configured GBNF was not transported outside explicit debug mode");
|
|
272
|
-
}
|
|
273
|
-
return evidence;
|
|
274
|
-
}
|
|
275
|
-
async #grammarConstraint(provider) {
|
|
276
|
-
// A real alias scopes its rail; an alias-free direct route uses the
|
|
277
|
-
// global provider configuration. Unrelated alias settings never apply.
|
|
278
|
-
// {§grammar-configuration-admission}
|
|
224
|
+
// {§operator-grammar} — the operator's grammar text for this provider, or undefined when
|
|
225
|
+
// none is configured. A real alias scopes its knob; an alias-free direct route uses the
|
|
226
|
+
// global provider configuration. Unrelated alias settings never apply
|
|
227
|
+
// ({§grammar-configuration-admission}). An unreadable file throws: a configured grammar
|
|
228
|
+
// never silently degrades.
|
|
229
|
+
async #operatorGrammar(provider) {
|
|
279
230
|
ProviderInstantiate.assertGrammarConfigurationScope(provider);
|
|
280
231
|
const alias = ProviderInstantiate.configurationAliasOf(provider);
|
|
281
232
|
const scoped = alias === undefined
|
|
282
233
|
? process.env
|
|
283
|
-
: scopeEnvToAlias(process.env, alias, [
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
]);
|
|
287
|
-
const variant = scoped.PLURNK_PROVIDERS_GBNF;
|
|
288
|
-
if (variant === undefined || variant === "" || variant === "0")
|
|
234
|
+
: scopeEnvToAlias(process.env, alias, ["PLURNK_PROVIDERS_GBNF"]);
|
|
235
|
+
const configured = scoped.PLURNK_PROVIDERS_GBNF;
|
|
236
|
+
if (configured === undefined || configured === "" || configured === "0")
|
|
289
237
|
return undefined;
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
&& scoped.PLURNK_PROVIDERS_GBNF_DEBUG !== "0";
|
|
293
|
-
const hit = this.#gbnfCache.get(variant);
|
|
238
|
+
const path = resolveOperatorGrammarPath(configured);
|
|
239
|
+
const hit = this.#grammarCache.get(path);
|
|
294
240
|
if (hit !== undefined)
|
|
295
|
-
return
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const path = resolveGrammarRailPath(variant);
|
|
301
|
-
const text = await readFile(path, "utf8"); // unresolvable/unreadable throws — a configured rail never silently degrades
|
|
302
|
-
const constraint = grammarConstraint(text);
|
|
303
|
-
this.#gbnfCache.set(variant, constraint);
|
|
304
|
-
process.stderr.write(`plurnk-engine: GBNF constraint: ${alias || "(bare)"} → ${variant} (${text.length} chars)\n`);
|
|
305
|
-
return { ...constraint, allowWithheld };
|
|
241
|
+
return hit;
|
|
242
|
+
const text = await readFile(path, "utf8");
|
|
243
|
+
this.#grammarCache.set(path, text);
|
|
244
|
+
process.stderr.write(`plurnk-engine: operator grammar: ${alias || "(bare)"} → ${path} (${text.length} chars)\n`);
|
|
245
|
+
return text;
|
|
306
246
|
}
|
|
307
247
|
// A lineage's no-parent root; a root worker resolves to itself. Fail hard
|
|
308
248
|
// when corruption leaves a worker without one. {§worker-primary}
|
|
@@ -342,10 +282,9 @@ export default class TurnRunner {
|
|
|
342
282
|
}
|
|
343
283
|
return { line, column };
|
|
344
284
|
}
|
|
345
|
-
// {§packet-attachment-parts}
|
|
346
|
-
//
|
|
347
|
-
|
|
348
|
-
async #wireMessages(packet, workspaceId, provider) {
|
|
285
|
+
// {§packet-attachment-parts}: native parts come from the READ's immutable snapshot,
|
|
286
|
+
// never from a source that may have changed since the observation.
|
|
287
|
+
async #wireMessages(packet, ctx, provider) {
|
|
349
288
|
const accepted = acceptedKinds(provider.inputModalities);
|
|
350
289
|
if (accepted.length === 0 || !(packet.attachments ?? []).some((attachment) => accepted.includes(attachment.kind))) {
|
|
351
290
|
return {
|
|
@@ -355,20 +294,14 @@ export default class TurnRunner {
|
|
|
355
294
|
}
|
|
356
295
|
const nativeInputs = new Set();
|
|
357
296
|
const messages = await PacketWire.wireMessages(packet, async (attachment) => {
|
|
358
|
-
const
|
|
359
|
-
const source = handler?.byteSource?.(attachment.pathname, { db: this.#db, workspaceId });
|
|
360
|
-
if (source === undefined)
|
|
361
|
-
return null;
|
|
362
|
-
const total = await source.size();
|
|
363
|
-
if (total === null || total === 0)
|
|
364
|
-
return null;
|
|
365
|
-
const bytes = await source.read(1, total);
|
|
297
|
+
const bytes = await NativeContent.read(ctx.db, attachment.contentHash);
|
|
366
298
|
nativeInputs.add(attachment.coordinate);
|
|
367
299
|
return bytes;
|
|
368
300
|
}, (kind) => accepted.includes(kind));
|
|
369
301
|
return { messages, nativeInputs: [...nativeInputs] };
|
|
370
302
|
}
|
|
371
|
-
async runTurn({ provider, childProvider = provider, messages, recap = "", workspaceId, workerId, loopId, signal, onDispatch, onSettled, turnNumber = 1, maxTurns = 50, invalidEmissionRecoveryEntryId, }) {
|
|
303
|
+
async runTurn({ provider, childProvider = provider, messages, recap = "", workspaceId, workerId, loopId, signal, onDispatch, onSettled, turnNumber = 1, maxTurns = 50, invalidEmissionRecoveryEntryId, allowUnobservedRetrievalCompletion = false, }) {
|
|
304
|
+
const workerName = await WorkerName.forId(this.#db, workerId);
|
|
372
305
|
const transientOpenLogEntryId = typeof invalidEmissionRecoveryEntryId === "number"
|
|
373
306
|
? invalidEmissionRecoveryEntryId
|
|
374
307
|
: null;
|
|
@@ -404,8 +337,8 @@ export default class TurnRunner {
|
|
|
404
337
|
createdTurnIds.push(initializationTurn.id);
|
|
405
338
|
const initializationPolicies = initializationTurn === null
|
|
406
339
|
? []
|
|
407
|
-
: (await CapabilityPolicies.layers(this.#db, workspaceId
|
|
408
|
-
const initializationAdmits = (statement) => this.#capabilities.allowsAcross(statement,
|
|
340
|
+
: (await CapabilityPolicies.layers(this.#db, workspaceId)).map((layer) => layer.policy);
|
|
341
|
+
const initializationAdmits = (statement) => this.#capabilities.allowsAcross(statement, workspaceId, initializationPolicies);
|
|
409
342
|
let modelTurn = initializationTurn === null
|
|
410
343
|
? await Turn.open(this.#db, { loopId, producer: "model", kind: "inference" })
|
|
411
344
|
: null;
|
|
@@ -421,109 +354,68 @@ export default class TurnRunner {
|
|
|
421
354
|
// Threaded per turn, never engine state, so concurrent loops on
|
|
422
355
|
// different providers each read their own honest tokenizer values.
|
|
423
356
|
const systemContext = (contextTurnId) => ({
|
|
424
|
-
db: this.#db, workspaceId, workerId,
|
|
357
|
+
db: this.#db, workspaceId, workerId, loopId, turnId: contextTurnId,
|
|
425
358
|
writer: "_plurnk",
|
|
426
359
|
signal: this.#loopSignal(loopId),
|
|
427
360
|
streamEventNotify: this.#streamEventNotify,
|
|
428
361
|
wakeWorkerNotify: this.#wakeWorkerNotify,
|
|
429
362
|
weigh: this.#weighContent,
|
|
430
363
|
mimetypes: this.#mimetypes,
|
|
431
|
-
defaultChannelFor: (s) => this.#schemes.defaultChannelFor(s,
|
|
364
|
+
defaultChannelFor: (s) => this.#schemes.defaultChannelFor(s, workspaceId),
|
|
432
365
|
pushNotice: (notice) => this.#notices.push(workspaceId, workerId, loopId, notice),
|
|
433
|
-
requestInteraction: (request) => this.#interactions.request(request, { workspaceId, workerId, loopId, turnId: contextTurnId },
|
|
366
|
+
requestInteraction: (request, signal = this.#loopSignal(loopId)) => this.#interactions.request(request, { workspaceId, workerId, loopId, turnId: contextTurnId }, signal),
|
|
434
367
|
});
|
|
435
368
|
let systemCtx = systemContext(initializationTurn?.id ?? modelTurn.id);
|
|
436
369
|
// {§prompt-entry} — the prompt entry exists before any turn of the loop
|
|
437
|
-
// runs
|
|
438
|
-
//
|
|
439
|
-
// per loop, decided by that row).
|
|
370
|
+
// runs; its `prompt` log row is published to the model turn below (one
|
|
371
|
+
// durable publication per loop, decided by that row).
|
|
440
372
|
const promptPublication = turnNumber === 1 && loopRow?.prompt_published === 0
|
|
441
373
|
&& typeof loopRow.prompt === "string" && loopRow.prompt.length > 0
|
|
442
374
|
? {
|
|
443
375
|
content: loopRow.prompt,
|
|
444
376
|
source: loopRow.prompt_source,
|
|
445
|
-
path: promptTarget(
|
|
377
|
+
path: promptTarget(workerName, await PromptFrames.write(systemCtx, {
|
|
378
|
+
loopSequence: loopRow.sequence, ordinal: 1, content: loopRow.prompt,
|
|
379
|
+
source: loopRow.prompt_source, pathname: loopRow.prompt_pathname,
|
|
380
|
+
openPaths: assertOpenPaths(JSON.parse(loopRow.open_paths), `Loop ${loopId} open_paths`),
|
|
381
|
+
})),
|
|
446
382
|
openPaths: assertOpenPaths(JSON.parse(loopRow.open_paths), `Loop ${loopId} open_paths`),
|
|
447
383
|
}
|
|
448
384
|
: null;
|
|
449
|
-
if (promptPublication !== null) {
|
|
450
|
-
const entry = {
|
|
451
|
-
channels: { body: { content: promptPublication.content, mimetype: "text/markdown" } },
|
|
452
|
-
attributes: {
|
|
453
|
-
openPaths: promptPublication.openPaths,
|
|
454
|
-
...(promptPublication.source === null ? {} : { source: promptPublication.source }),
|
|
455
|
-
},
|
|
456
|
-
};
|
|
457
|
-
await EntryCrud.writeEntry({ authority: "", pathname: promptPublication.path.pathname }, entry, systemCtx, "prompt", workerId);
|
|
458
|
-
}
|
|
459
385
|
const initializationStatements = [];
|
|
460
386
|
// {§worker-initialization-entry} — the worker's first turn is the worked
|
|
461
|
-
// example itself:
|
|
462
|
-
// and an ordinary terminal SEND.
|
|
387
|
+
// example itself: the actual orienting operations and an ordinary TASK.
|
|
463
388
|
if (initializationTurn !== null) {
|
|
464
|
-
const plan = {
|
|
465
|
-
op: "PLAN", delimiter: "", annotation: "Determinations and Decisions must be persisted as `memory` items.",
|
|
466
|
-
target: null, metadata: null, lineMarker: null,
|
|
467
|
-
body: [
|
|
468
|
-
{
|
|
469
|
-
content: "Discover the tooling available and survey the workspace file root.",
|
|
470
|
-
status: "in_progress",
|
|
471
|
-
},
|
|
472
|
-
],
|
|
473
|
-
position: UNKNOWN_POSITION,
|
|
474
|
-
};
|
|
475
|
-
initializationStatements.push(plan);
|
|
476
|
-
// {§worker-initialization-entry} — the prompt is archived into the
|
|
477
|
-
// worker's private space: the worked COPY specimen, and the private
|
|
478
|
-
// space shown as scratch. An append onto an absent entry creates it.
|
|
479
|
-
// Authored first among the operations because it executes first
|
|
480
|
-
// ({§op-mode-phases}: Mutate precedes Observe).
|
|
481
|
-
if (promptPublication !== null) {
|
|
482
|
-
const archive = {
|
|
483
|
-
op: "COPY", delimiter: "", annotation: null,
|
|
484
|
-
source: { target: promptPublication.path, metadata: null, lineMarker: null },
|
|
485
|
-
destination: {
|
|
486
|
-
target: { kind: "url", raw: "worker://~/prompts.md", scheme: "worker", username: null, password: null, hostname: "~", port: null, pathname: "/prompts.md", query: null, fragment: null },
|
|
487
|
-
metadata: null,
|
|
488
|
-
lineMarker: { marks: [-1] },
|
|
489
|
-
},
|
|
490
|
-
position: UNKNOWN_POSITION,
|
|
491
|
-
};
|
|
492
|
-
initializationStatements.push(archive);
|
|
493
|
-
}
|
|
494
389
|
// {§turn0-agents-stunt} — the project AGENTS.md (materialized by LoopDocs as
|
|
495
|
-
// worker
|
|
390
|
+
// worker:///_plurnk/agents.md) gets one foisted READ on the worker's first
|
|
496
391
|
// loop, so local repo guidance is visible turn-0 content. Global policy
|
|
497
392
|
// stays in the system prompt; nothing else is force-read.
|
|
498
393
|
if (workerFirstInference) {
|
|
499
394
|
const agentsEntry = await this.#db.crud_find_workspace_entry.get({
|
|
500
395
|
workspace_id: workspaceId,
|
|
501
|
-
owner_id: workerId,
|
|
502
396
|
scheme: "worker",
|
|
503
397
|
authority: "",
|
|
504
398
|
pathname: generatedPathname("/agents.md"),
|
|
505
399
|
});
|
|
506
400
|
if (agentsEntry !== undefined) {
|
|
507
401
|
const agentsTarget = {
|
|
508
|
-
kind: "url", raw: "worker
|
|
509
|
-
username: null, password: null, hostname:
|
|
402
|
+
kind: "url", raw: "worker:///_plurnk/agents.md", scheme: "worker",
|
|
403
|
+
username: null, password: null, hostname: null, port: null,
|
|
510
404
|
pathname: generatedPathname("/agents.md"), query: null, fragment: null,
|
|
511
405
|
};
|
|
512
406
|
const agentsRead = {
|
|
513
|
-
op: "READ",
|
|
514
|
-
metadata: null, lineMarker: null, body: null, position: UNKNOWN_POSITION,
|
|
407
|
+
op: "READ", aside: null, target: agentsTarget,
|
|
408
|
+
metadata: null, lineMarker: null, matcher: null, body: null, position: UNKNOWN_POSITION,
|
|
515
409
|
};
|
|
516
410
|
initializationStatements.push(agentsRead);
|
|
517
411
|
}
|
|
518
412
|
}
|
|
519
413
|
}
|
|
520
414
|
// The persistent search-index pass (_search-index.maintain) attaches
|
|
521
|
-
// every readable entry/log projection to complete graph/FTS
|
|
415
|
+
// every readable entry/log projection to complete graph/FTS derivations.
|
|
522
416
|
// NOT an action: no log entry, no sequence slot,
|
|
523
417
|
// not dispatched. There is no materialized manifest entry — the catalog
|
|
524
418
|
// is served on demand by FIND: recursive when asked, shallow-mapped below.
|
|
525
|
-
// {§semantic-embed-dedup} — one pass-wide semantic plan binds every
|
|
526
|
-
// chunk counter to the derivation identity it produces.
|
|
527
419
|
// SPEC {§membership} D4/D5 — git-ls-files workspace membership, resolved at
|
|
528
420
|
// prompt-composition (EMI is eager + exhaustive — git is the only bound). When the
|
|
529
421
|
// workspace's project_root is a git working tree, tracked files are
|
|
@@ -550,7 +442,7 @@ export default class TurnRunner {
|
|
|
550
442
|
// Turn-0 catalog preview (PLURNK_SERVICE_FILES_ITEMS, {§actor-boundary-catalog-preview}):
|
|
551
443
|
// Eight bodyless FIND surveys in the worker's packetless initialization turn establish the Agent
|
|
552
444
|
// Skills, the plurnk references, the enabled tools, agents, and members, then the project, commons,
|
|
553
|
-
// and
|
|
445
|
+
// and named scratch, in that order.
|
|
554
446
|
// Their `init` classification lets the model curate this opening survey as one log set.
|
|
555
447
|
if (initializationTurn !== null) {
|
|
556
448
|
// {§operator-config-workspace-files-items} — workspace filesItems replaces the env default.
|
|
@@ -560,81 +452,49 @@ export default class TurnRunner {
|
|
|
560
452
|
const catalogSchemes = await this.#db.engine_scheme_catalog_summary.all({ workspace_id: workspaceId });
|
|
561
453
|
const fileItems = catalogSchemes.find(({ scheme }) => scheme === "file")?.shallow_items ?? 0;
|
|
562
454
|
const fileCap = filesItems > 0 && fileItems > 0 ? Math.min(filesItems, fileItems) : null;
|
|
563
|
-
// {§tools-resource-materialization} —
|
|
564
|
-
//
|
|
565
|
-
// `### EXEC0` headings: one row per tool — heading, annotation,
|
|
566
|
-
// signature — paged like every survey. No document is delivered
|
|
567
|
-
// unasked; per-target child documents do not exist.
|
|
455
|
+
// {§tools-resource-materialization} — expanded families project complete
|
|
456
|
+
// invocation blocks, paged through ordinary FIND result ranges.
|
|
568
457
|
const registry = this.#executors();
|
|
569
|
-
const
|
|
570
|
-
const
|
|
571
|
-
const prefix = generatedPathname(`/${namespace}/`);
|
|
572
|
-
return [...new Set(references.flatMap(({ pathname }) => {
|
|
573
|
-
if (!pathname.startsWith(prefix) || !pathname.endsWith(".md"))
|
|
574
|
-
return [];
|
|
575
|
-
const name = pathname.slice(prefix.length, -3);
|
|
576
|
-
return name.includes("/") ? [] : [name];
|
|
577
|
-
}))].toSorted();
|
|
578
|
-
};
|
|
579
|
-
const schemeExamples = new Map(this.#schemes.examples(workerId).map(({ name, source }) => [name, source]));
|
|
580
|
-
const runtimeAdmitted = (runtime) => {
|
|
581
|
-
const tools = registry?.toolRegistry(runtime, workerId);
|
|
582
|
-
return tools === null || tools === undefined
|
|
583
|
-
? this.#capabilities.allowsRuntimeAcross(runtime, null, workerId, initializationPolicies)
|
|
584
|
-
: tools.tools.some((tool) => this.#capabilities.allowsRuntimeAcross(runtime, tool.target, workerId, initializationPolicies));
|
|
585
|
-
};
|
|
586
|
-
const referenceAdmitted = (namespace, name) => {
|
|
587
|
-
const entry = registry?.entry(name, workerId);
|
|
588
|
-
const entryNamespace = entry?.resourcesPath === "/tools" ? "tools" : "plurnk";
|
|
589
|
-
if (entry !== undefined && entryNamespace === namespace)
|
|
590
|
-
return runtimeAdmitted(name);
|
|
591
|
-
const source = schemeExamples.get(name);
|
|
592
|
-
return source === undefined
|
|
593
|
-
|| this.#capabilities.allowsExampleAcross(source, workerId, initializationPolicies);
|
|
594
|
-
};
|
|
595
|
-
const plurnkReferences = referenceNames("plurnk");
|
|
596
|
-
const toolReferences = referenceNames("tools");
|
|
597
|
-
const plurnkCatalog = workerCatalogTarget("plurnk", plurnkReferences, plurnkReferences.filter((name) => referenceAdmitted("plurnk", name)));
|
|
598
|
-
const toolsCatalog = workerCatalogTarget("tools", toolReferences, toolReferences.filter((name) => referenceAdmitted("tools", name)));
|
|
458
|
+
const plurnkCatalog = workerCatalogTarget("plurnk");
|
|
459
|
+
const toolsCatalog = workerCatalogTarget("tools");
|
|
599
460
|
const toolExpansions = [];
|
|
600
|
-
for (const tag of registry?.availableRuntimes(
|
|
601
|
-
const entry = registry?.entry(tag,
|
|
461
|
+
for (const tag of registry?.availableRuntimes(workspaceId) ?? []) {
|
|
462
|
+
const entry = registry?.entry(tag, workspaceId);
|
|
602
463
|
if (entry?.resourcesPath !== "/tools" || entry.expandTools !== true)
|
|
603
464
|
continue;
|
|
604
|
-
const tools = registry?.toolRegistry(tag,
|
|
605
|
-
const admittedTools = tools?.tools.filter((tool) => this.#capabilities.allowsRuntimeAcross(tag, tool.target,
|
|
465
|
+
const tools = registry?.toolRegistry(tag, workspaceId);
|
|
466
|
+
const admittedTools = tools?.tools.filter((tool) => this.#capabilities.allowsRuntimeAcross(tag, tool.target, workspaceId, initializationPolicies)) ?? [];
|
|
606
467
|
if (admittedTools.length === 0)
|
|
607
468
|
continue;
|
|
608
|
-
const
|
|
609
|
-
?
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
: "^### EXEC0 .*\\n.*$";
|
|
469
|
+
const targetFilter = tools !== null && tools !== undefined && admittedTools.length !== tools.tools.length
|
|
470
|
+
? " \\((?:" + admittedTools.map((tool) => regexLiteral(PathSyntax.escapeTarget(tool.target))).join("|") + ")\\)"
|
|
471
|
+
: " ";
|
|
472
|
+
const pattern = "^(\x60{3,})" + regexLiteral(tag) + targetFilter + "[^\\n]*?(?:\\1|\\n[\\s\\S]*?\\n\\1)$";
|
|
613
473
|
toolExpansions.push({
|
|
614
474
|
statement: {
|
|
615
|
-
op: "FIND",
|
|
616
|
-
target: { kind: "url", raw: `worker
|
|
475
|
+
op: "FIND", aside: null,
|
|
476
|
+
target: { kind: "url", raw: `worker:///_plurnk/tools/${tag}.md`, scheme: "worker", username: null, password: null, hostname: null, port: null, pathname: generatedPathname(`/tools/${tag}.md`), query: null, fragment: null },
|
|
617
477
|
metadata: null,
|
|
618
|
-
|
|
619
|
-
lineMarker: null, position: UNKNOWN_POSITION,
|
|
478
|
+
matcher: { dialect: "regex", raw: `/${pattern.replaceAll("/", "\\/")}/m`, pattern, flags: "m" },
|
|
479
|
+
body: null, lineMarker: null, position: UNKNOWN_POSITION,
|
|
620
480
|
},
|
|
621
481
|
});
|
|
622
482
|
}
|
|
623
483
|
const surveys = [
|
|
624
484
|
{
|
|
625
485
|
statement: {
|
|
626
|
-
op: "FIND",
|
|
627
|
-
target: { kind: "url", raw: "
|
|
486
|
+
op: "FIND", aside: null,
|
|
487
|
+
target: { kind: "url", raw: "skill://*/SKILL.md", scheme: "skill", username: null, password: null, hostname: "*", port: null, pathname: "/SKILL.md", query: null, fragment: null },
|
|
628
488
|
metadata: null,
|
|
629
|
-
body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
489
|
+
matcher: null, body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
630
490
|
},
|
|
631
491
|
},
|
|
632
492
|
...(plurnkCatalog === null ? [] : [{
|
|
633
493
|
statement: {
|
|
634
|
-
op: "FIND",
|
|
494
|
+
op: "FIND", aside: null,
|
|
635
495
|
target: plurnkCatalog,
|
|
636
496
|
metadata: null,
|
|
637
|
-
body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
497
|
+
matcher: null, body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
638
498
|
},
|
|
639
499
|
}]),
|
|
640
500
|
...(toolsCatalog === null ? [] : [{
|
|
@@ -645,10 +505,10 @@ export default class TurnRunner {
|
|
|
645
505
|
// PLURNK_MCP_EXPANDED add a second survey of their complete
|
|
646
506
|
// tool tree.
|
|
647
507
|
statement: {
|
|
648
|
-
op: "FIND",
|
|
508
|
+
op: "FIND", aside: null,
|
|
649
509
|
target: toolsCatalog,
|
|
650
510
|
metadata: null,
|
|
651
|
-
body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
511
|
+
matcher: null, body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
652
512
|
},
|
|
653
513
|
}]),
|
|
654
514
|
...toolExpansions,
|
|
@@ -657,27 +517,28 @@ export default class TurnRunner {
|
|
|
657
517
|
// alias level; each row's summary is the agent's identity line,
|
|
658
518
|
// the exact card stays pullable through READ a2a://<alias>.
|
|
659
519
|
statement: {
|
|
660
|
-
op: "FIND",
|
|
661
|
-
target: { kind: "url", raw: "worker
|
|
520
|
+
op: "FIND", aside: null,
|
|
521
|
+
target: { kind: "url", raw: "worker:///_plurnk/agents/*.md", scheme: "worker", username: null, password: null, hostname: null, port: null, pathname: generatedPathname("/agents/*.md"), query: null, fragment: null },
|
|
662
522
|
metadata: null,
|
|
663
|
-
body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
523
|
+
matcher: null, body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
664
524
|
},
|
|
665
525
|
},
|
|
666
526
|
{
|
|
667
527
|
// {§members-projection} — enabled members definitions survey at alias
|
|
668
528
|
// level; each row's summary is what its glob resolved to.
|
|
669
529
|
statement: {
|
|
670
|
-
op: "FIND",
|
|
671
|
-
target: { kind: "url", raw: "worker
|
|
530
|
+
op: "FIND", aside: null,
|
|
531
|
+
target: { kind: "url", raw: "worker:///_plurnk/members/*.md", scheme: "worker", username: null, password: null, hostname: null, port: null, pathname: generatedPathname("/members/*.md"), query: null, fragment: null },
|
|
672
532
|
metadata: null,
|
|
673
|
-
body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
533
|
+
matcher: null, body: null, lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
674
534
|
},
|
|
675
535
|
},
|
|
676
536
|
{
|
|
677
537
|
statement: {
|
|
678
|
-
op: "FIND",
|
|
538
|
+
op: "FIND", aside: "project root member files",
|
|
679
539
|
target: { kind: "local", raw: "*" },
|
|
680
540
|
metadata: null,
|
|
541
|
+
matcher: null,
|
|
681
542
|
body: null,
|
|
682
543
|
lineMarker: fileCap === null ? null : { marks: [1, fileCap] },
|
|
683
544
|
position: UNKNOWN_POSITION,
|
|
@@ -685,37 +546,52 @@ export default class TurnRunner {
|
|
|
685
546
|
},
|
|
686
547
|
{
|
|
687
548
|
statement: {
|
|
688
|
-
op: "FIND",
|
|
549
|
+
op: "FIND", aside: "shared worker Extended Context",
|
|
689
550
|
target: { kind: "url", raw: "worker:///*", scheme: "worker", username: null, password: null, hostname: null, port: null, pathname: "/*", query: null, fragment: null },
|
|
690
551
|
metadata: null,
|
|
691
|
-
body: null, lineMarker: null, position: UNKNOWN_POSITION,
|
|
552
|
+
matcher: null, body: null, lineMarker: null, position: UNKNOWN_POSITION,
|
|
692
553
|
},
|
|
693
554
|
},
|
|
694
555
|
{
|
|
695
556
|
statement: {
|
|
696
|
-
op: "FIND",
|
|
697
|
-
target: { kind: "url", raw:
|
|
557
|
+
op: "FIND", aside: "private worker Extended Context",
|
|
558
|
+
target: { kind: "url", raw: `worker://${workerName}/*`, scheme: "worker", username: null, password: null, hostname: workerName, port: null, pathname: "/*", query: null, fragment: null },
|
|
698
559
|
metadata: null,
|
|
699
|
-
body: null, lineMarker: null, position: UNKNOWN_POSITION,
|
|
560
|
+
matcher: null, body: null, lineMarker: null, position: UNKNOWN_POSITION,
|
|
700
561
|
},
|
|
701
562
|
},
|
|
702
563
|
];
|
|
703
|
-
initializationStatements.push(...surveys.map(({ statement }) => statement));
|
|
564
|
+
initializationStatements.push(...surveys.map(({ statement }) => statement).filter(({ target }) => this.#schemes.get(target?.kind === "url" ? target.scheme : "file", workspaceId) !== undefined));
|
|
704
565
|
}
|
|
705
|
-
const
|
|
706
|
-
op: "
|
|
707
|
-
|
|
708
|
-
body: { raw: "Next: Address the prompt.", json: null },
|
|
566
|
+
const task = {
|
|
567
|
+
op: "TASK", aside: null, target: null, metadata: null, lineMarker: null,
|
|
568
|
+
body: [{ content: "Address the prompt.", status: "in_progress" }],
|
|
709
569
|
position: UNKNOWN_POSITION,
|
|
710
570
|
};
|
|
711
|
-
|
|
571
|
+
const pathname = `/${loopRow.sequence}/${initializationTurn.sequence}`;
|
|
572
|
+
await Turn.recordSource(this.#db, initializationTurn.id, "reasoning", ReasoningView.initialSource());
|
|
573
|
+
// {§reasoning-initial-read} — the pattern READ needs a text/plain projection to run the regex.
|
|
574
|
+
const pluck = await this.#mimetypes.getHandler("text/plain") !== null;
|
|
575
|
+
const reasoningRead = ReasoningView.initialRead(provider, loopRow.sequence, initializationTurn.sequence, pluck);
|
|
576
|
+
if (reasoningRead !== null)
|
|
577
|
+
initializationStatements.push(reasoningRead);
|
|
578
|
+
initializationStatements.push({
|
|
579
|
+
op: "READ", aside: "inspect this turn's emission", matcher: null, body: null, metadata: null,
|
|
580
|
+
target: {
|
|
581
|
+
kind: "url", raw: `ops://${pathname}`, scheme: "ops", pathname,
|
|
582
|
+
username: null, password: null, hostname: null, port: null, query: null, fragment: null,
|
|
583
|
+
},
|
|
584
|
+
lineMarker: { marks: [1, -1] }, position: UNKNOWN_POSITION,
|
|
585
|
+
});
|
|
586
|
+
// {§prompt-entry} — the prompt reaches the model as its `prompt` row in the first
|
|
587
|
+
// model turn; initialization does not READ it a second time.
|
|
588
|
+
initializationStatements.push(task);
|
|
712
589
|
const admittedInitializationStatements = initializationStatements.filter(initializationAdmits);
|
|
713
590
|
const source = TurnOps.renderInternal(admittedInitializationStatements);
|
|
714
591
|
const admitted = TurnOps.parseInternal(source);
|
|
715
592
|
const result = await this.executeAdmittedTurn({
|
|
716
593
|
statements: admitted,
|
|
717
594
|
source,
|
|
718
|
-
sourceFolded: false,
|
|
719
595
|
origin: "_plurnk",
|
|
720
596
|
workspaceId,
|
|
721
597
|
workerId,
|
|
@@ -728,7 +604,7 @@ export default class TurnRunner {
|
|
|
728
604
|
onSettled,
|
|
729
605
|
});
|
|
730
606
|
if (result.status !== TURN_STATUS_IMPLICIT_CONTINUE) {
|
|
731
|
-
throw new Error(`initialization
|
|
607
|
+
throw new Error(`initialization TASK returned ${result.status}; expected ${TURN_STATUS_IMPLICIT_CONTINUE}`);
|
|
732
608
|
}
|
|
733
609
|
}
|
|
734
610
|
// Initialization is a complete preceding turn, not a set of rows
|
|
@@ -767,7 +643,7 @@ export default class TurnRunner {
|
|
|
767
643
|
const loopSeq = loopSeqRow?.sequence ?? loopId;
|
|
768
644
|
const prefix = promptLoopPrefix(loopSeq);
|
|
769
645
|
const undelivered = (await this.#db.drain_undelivered_prompts_for_loop.all({
|
|
770
|
-
|
|
646
|
+
worker_id: workerId,
|
|
771
647
|
pattern: `${prefix}%`,
|
|
772
648
|
prefix_len: prefix.length,
|
|
773
649
|
loop_id: loopId,
|
|
@@ -778,13 +654,12 @@ export default class TurnRunner {
|
|
|
778
654
|
if (attributes.openPaths !== undefined) {
|
|
779
655
|
turnOpenPaths.push(...assertOpenPaths(attributes.openPaths, `Prompt ${injectedRow.pathname} openPaths`));
|
|
780
656
|
}
|
|
781
|
-
const ordinal = Number(injectedRow.pathname.split("/").filter(Boolean).at(-1));
|
|
782
657
|
const promptLogId = await this.#materialization.writePromptLog({
|
|
783
658
|
workerId,
|
|
784
659
|
loopId,
|
|
785
660
|
turnId,
|
|
786
661
|
sequence: nextActionIndex++,
|
|
787
|
-
target: promptTarget(
|
|
662
|
+
target: promptTarget(workerName, injectedRow.pathname),
|
|
788
663
|
content: injectedRow.content,
|
|
789
664
|
source: promptSourceFromAttributes(attributes, `Prompt ${injectedRow.pathname} attributes`),
|
|
790
665
|
});
|
|
@@ -798,7 +673,7 @@ export default class TurnRunner {
|
|
|
798
673
|
for (const raw of turnOpenPaths) {
|
|
799
674
|
const pathname = raw.startsWith("/") ? raw : `/${raw}`;
|
|
800
675
|
const fileRead = {
|
|
801
|
-
op: "READ",
|
|
676
|
+
op: "READ", aside: null, lineMarker: null, matcher: null,
|
|
802
677
|
target: {
|
|
803
678
|
kind: "url", raw: `file://${pathname}`, scheme: "file",
|
|
804
679
|
username: null, password: null, hostname: null, port: null,
|
|
@@ -821,7 +696,7 @@ export default class TurnRunner {
|
|
|
821
696
|
// the subsequent turn. The terminal output then surfaces initially visible via the stream-delta path.
|
|
822
697
|
await this.#reapTurnScopedStreams(workerId);
|
|
823
698
|
nextActionIndex += await this.#materialization.materializeEnvironmentDeltas({ workspaceId, workerId, loopId, turnId, fromSequence: nextActionIndex });
|
|
824
|
-
nextActionIndex += await this.#materialization.materializeStreamDeltas({ workerId, loopId, turnId, fromSequence: nextActionIndex });
|
|
699
|
+
nextActionIndex += await this.#materialization.materializeStreamDeltas({ workspaceId, workerId, loopId, turnId, fromSequence: nextActionIndex });
|
|
825
700
|
// The post-reconciliation Git snapshot above is threaded into the packet
|
|
826
701
|
// and every budget rebuild; overflow never shells again.
|
|
827
702
|
// Notices are non-terminal observations, never operation-failure truth.
|
|
@@ -832,6 +707,7 @@ export default class TurnRunner {
|
|
|
832
707
|
// queries log_entries scoped to the worker — the prompt entry just
|
|
833
708
|
// written (if turn 1) is part of that query result.
|
|
834
709
|
let promptProjection = "automatic";
|
|
710
|
+
const loopSeq = (await this.#db.engine_loop_sequence.get({ loop_id: loopId }))?.sequence ?? loopId;
|
|
835
711
|
const buildPacket = () => this.#packets.buildRequestPacket({
|
|
836
712
|
initialMessages: messages,
|
|
837
713
|
recap,
|
|
@@ -844,63 +720,35 @@ export default class TurnRunner {
|
|
|
844
720
|
notices,
|
|
845
721
|
transientOpenLogEntryId,
|
|
846
722
|
promptProjection,
|
|
723
|
+
turnId,
|
|
847
724
|
});
|
|
848
725
|
let requestPacket = await buildPacket();
|
|
849
|
-
// {§
|
|
850
|
-
//
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
const
|
|
854
|
-
if (
|
|
855
|
-
const
|
|
856
|
-
await Turn.
|
|
857
|
-
const internalStatements = [
|
|
858
|
-
OverflowTurn.planStatement(),
|
|
859
|
-
...kills.map(({ statement }) => statement),
|
|
860
|
-
OverflowTurn.sendStatement(),
|
|
861
|
-
];
|
|
862
|
-
const source = TurnOps.renderInternal(internalStatements);
|
|
863
|
-
const admitted = TurnOps.parseInternal(source);
|
|
864
|
-
const executed = await this.executeAdmittedTurn({
|
|
865
|
-
statements: admitted,
|
|
866
|
-
source,
|
|
867
|
-
sourceFolded: true,
|
|
868
|
-
origin: "_plurnk",
|
|
869
|
-
workspaceId,
|
|
870
|
-
workerId,
|
|
871
|
-
loopId,
|
|
872
|
-
turnId,
|
|
873
|
-
fromSequence: nextActionIndex,
|
|
874
|
-
failOnOperationError: true,
|
|
875
|
-
signal: this.#loopSignal(loopId),
|
|
876
|
-
onDispatch,
|
|
877
|
-
onSettled,
|
|
878
|
-
});
|
|
879
|
-
if (executed.status !== TURN_STATUS_IMPLICIT_CONTINUE) {
|
|
880
|
-
throw new Error(`overflow SEND returned ${executed.status}; expected ${TURN_STATUS_IMPLICIT_CONTINUE}`);
|
|
881
|
-
}
|
|
882
|
-
const rebuilt = await buildPacket();
|
|
883
|
-
const remaining = this.#packets.curationOverflow(rebuilt, provider);
|
|
884
|
-
const curationFailure = kills.length === 0 || remaining !== null
|
|
885
|
-
? curationOverflowFailure(remaining ?? pressure)
|
|
886
|
-
: undefined;
|
|
726
|
+
// {§context-output-admission} — output admission changes no operation
|
|
727
|
+
// outcome, authored inventory, or turn identity.
|
|
728
|
+
if (await this.#packets.admitOutput(requestPacket, turnId))
|
|
729
|
+
requestPacket = await buildPacket();
|
|
730
|
+
const remaining = this.#packets.curationOverflow(requestPacket);
|
|
731
|
+
if (remaining !== null) {
|
|
732
|
+
const curationFailure = curationOverflowFailure(remaining);
|
|
733
|
+
await Turn.complete(this.#db, turnId, curationFailure.status);
|
|
887
734
|
return {
|
|
888
735
|
createdTurnIds,
|
|
889
736
|
turnId,
|
|
890
|
-
producer: "
|
|
891
|
-
kind: "
|
|
892
|
-
status: curationFailure
|
|
737
|
+
producer: "model",
|
|
738
|
+
kind: "inference",
|
|
739
|
+
status: curationFailure.status,
|
|
893
740
|
outcomes: [],
|
|
894
741
|
fingerprint: "",
|
|
895
742
|
capacityHardStop: false,
|
|
896
743
|
providerParked: false,
|
|
897
744
|
steerStruck: false,
|
|
745
|
+
emptyTurn: false,
|
|
898
746
|
emissionAttempts: 0,
|
|
899
747
|
emissionExhausted: false,
|
|
900
|
-
|
|
748
|
+
curationFailure,
|
|
901
749
|
};
|
|
902
750
|
}
|
|
903
|
-
let materializedRequest = await this.#wireMessages(requestPacket,
|
|
751
|
+
let materializedRequest = await this.#wireMessages(requestPacket, systemCtx, provider);
|
|
904
752
|
let modelMessages = materializedRequest.messages;
|
|
905
753
|
let nativeInputs = materializedRequest.nativeInputs;
|
|
906
754
|
// Curation pressure and provider generation are independent. The
|
|
@@ -908,8 +756,6 @@ export default class TurnRunner {
|
|
|
908
756
|
let response;
|
|
909
757
|
let splitResponse;
|
|
910
758
|
let railGrammar;
|
|
911
|
-
let railResponseGrammar;
|
|
912
|
-
let railAllowWithheld = false;
|
|
913
759
|
let railEvidence;
|
|
914
760
|
let emissionAttempts = 0;
|
|
915
761
|
let providerCallInFlight = false;
|
|
@@ -928,7 +774,6 @@ export default class TurnRunner {
|
|
|
928
774
|
const providerSignal = this.#loopSignal(loopId) ?? signal;
|
|
929
775
|
// {§client-metadata}
|
|
930
776
|
const { client } = await WorkspaceSettings.read(this.#db, workspaceId);
|
|
931
|
-
const loopSeq = (await this.#db.engine_loop_sequence.get({ loop_id: loopId }))?.sequence ?? loopId;
|
|
932
777
|
const providerIdentity = await this.#resolveWorkerProviderIdentity(workerId);
|
|
933
778
|
const { workerId: providerWorkerId, primaryWorkerId } = providerIdentity;
|
|
934
779
|
const classifyProviderAttempt = async (id, attemptSplit, emissionAttempt, accepted) => {
|
|
@@ -947,7 +792,7 @@ export default class TurnRunner {
|
|
|
947
792
|
if (promptProjection === "automatic") {
|
|
948
793
|
promptProjection = "withheld";
|
|
949
794
|
const candidate = await buildPacket();
|
|
950
|
-
const candidateRequest = await this.#wireMessages(candidate,
|
|
795
|
+
const candidateRequest = await this.#wireMessages(candidate, systemCtx, provider);
|
|
951
796
|
if (JSON.stringify(candidateRequest.messages) !== JSON.stringify(baselineMessages)) {
|
|
952
797
|
requestPacket = candidate;
|
|
953
798
|
materializedRequest = candidateRequest;
|
|
@@ -963,12 +808,9 @@ export default class TurnRunner {
|
|
|
963
808
|
// {§turn-lifecycle}: bracket the complete provider-attempt window with liveness notices.
|
|
964
809
|
if (!signal?.aborted)
|
|
965
810
|
this.#notices.push(workspaceId, workerId, loopId, { source: "engine:turn", kind: "turn_awaiting_model", level: "info", message: "awaiting model response" });
|
|
966
|
-
|
|
967
|
-
railGrammar = railConstraint?.transport;
|
|
968
|
-
railResponseGrammar = railConstraint?.response;
|
|
969
|
-
railAllowWithheld = railConstraint?.allowWithheld ?? false;
|
|
811
|
+
railGrammar = await this.#operatorGrammar(provider);
|
|
970
812
|
const attemptLimit = readEmissionAttempts();
|
|
971
|
-
const strikeStreak = this.#strikes.streak(loopId);
|
|
813
|
+
const strikeStreak = await this.#strikes.streak(loopId);
|
|
972
814
|
// {§turn-accounting-notice} (#465) — every physical exchange this turn pays
|
|
973
815
|
// for, successes and failed calls alike, so the completion notice carries
|
|
974
816
|
// the exact settled wire spend.
|
|
@@ -1059,6 +901,7 @@ export default class TurnRunner {
|
|
|
1059
901
|
completedResponse = await observed(// {§observability-boundary}
|
|
1060
902
|
GEN_AI_REQUEST_SPAN, { model: provider.model, attempt: modelCallSequence }, async (span) => {
|
|
1061
903
|
try {
|
|
904
|
+
await this.#packets.recordObservations(requestPacket);
|
|
1062
905
|
const generated = await provider.generate({
|
|
1063
906
|
messages: modelMessages,
|
|
1064
907
|
workerId: providerWorkerId,
|
|
@@ -1116,7 +959,7 @@ export default class TurnRunner {
|
|
|
1116
959
|
// {§provider-interrupted-attempt} — the interrupted response stays durable
|
|
1117
960
|
// as an unaccepted attempt; it is never admitted or replayed.
|
|
1118
961
|
await currentModelCall.observeResponse(error.attempt, failure, nativeInputs);
|
|
1119
|
-
await classifyProviderAttempt(providerAttemptId, this.#splitResponse(error.attempt), currentEmissionAttempt, false);
|
|
962
|
+
await classifyProviderAttempt(providerAttemptId, this.#splitResponse(error.attempt, this.#executors()?.availableRuntimes(workspaceId) ?? []), currentEmissionAttempt, false);
|
|
1120
963
|
}
|
|
1121
964
|
else {
|
|
1122
965
|
await currentModelCall.fail(failure, error.capacity ?? null);
|
|
@@ -1166,7 +1009,7 @@ export default class TurnRunner {
|
|
|
1166
1009
|
// Include the durable recovery signal in the replacement
|
|
1167
1010
|
// request while preserving the selected recovery posture.
|
|
1168
1011
|
requestPacket = await buildPacket();
|
|
1169
|
-
materializedRequest = await this.#wireMessages(requestPacket,
|
|
1012
|
+
materializedRequest = await this.#wireMessages(requestPacket, systemCtx, provider);
|
|
1170
1013
|
modelMessages = materializedRequest.messages;
|
|
1171
1014
|
nativeInputs = materializedRequest.nativeInputs;
|
|
1172
1015
|
continue;
|
|
@@ -1187,10 +1030,8 @@ export default class TurnRunner {
|
|
|
1187
1030
|
response = completedResponse;
|
|
1188
1031
|
turnWireAccounting.push(...completedResponse.accounting);
|
|
1189
1032
|
await currentModelCall.observeResponse(completedResponse, null, nativeInputs);
|
|
1190
|
-
railEvidence = railGrammar === undefined
|
|
1191
|
-
|
|
1192
|
-
: TurnRunner.#requireGrammarEvidence(completedResponse, railAllowWithheld);
|
|
1193
|
-
splitResponse = this.#splitResponse(completedResponse);
|
|
1033
|
+
railEvidence = railGrammar === undefined ? undefined : completedResponse.grammarEvidence;
|
|
1034
|
+
splitResponse = this.#splitResponse(completedResponse, this.#executors()?.availableRuntimes(workspaceId) ?? []);
|
|
1194
1035
|
await classifyProviderAttempt(attemptRow.id, splitResponse, attempt, splitResponse.emissionValid);
|
|
1195
1036
|
if (splitResponse.emissionValid)
|
|
1196
1037
|
break;
|
|
@@ -1235,7 +1076,7 @@ export default class TurnRunner {
|
|
|
1235
1076
|
if (err instanceof ProviderError && err.attempt !== undefined) {
|
|
1236
1077
|
response = err.attempt;
|
|
1237
1078
|
await providerModelCall.observeResponse(response, failure, nativeInputs);
|
|
1238
|
-
splitResponse = this.#splitResponse(response);
|
|
1079
|
+
splitResponse = this.#splitResponse(response, this.#executors()?.availableRuntimes(workspaceId) ?? []);
|
|
1239
1080
|
await classifyProviderAttempt(providerAttemptId, splitResponse, currentEmissionAttempt, false);
|
|
1240
1081
|
}
|
|
1241
1082
|
else {
|
|
@@ -1244,10 +1085,9 @@ export default class TurnRunner {
|
|
|
1244
1085
|
emissionAttempts = currentEmissionAttempt;
|
|
1245
1086
|
}
|
|
1246
1087
|
// {§turn-never-blank} — a ProviderError means no completed exchange exists.
|
|
1247
|
-
// Persist its exact RFC 9457 result before propagating it. Grammar
|
|
1248
|
-
//
|
|
1249
|
-
//
|
|
1250
|
-
// provider failure. Close the
|
|
1088
|
+
// Persist its exact RFC 9457 result before propagating it. Grammar transport
|
|
1089
|
+
// evidence exists only on completed responses ({§operator-grammar}).
|
|
1090
|
+
// Cancellation is lifecycle truth, not a provider failure. Close the
|
|
1251
1091
|
// attempted turn without inventing an assistant response, then let
|
|
1252
1092
|
// runLoop/Daemon settle the exact 504/499 loop result.
|
|
1253
1093
|
if (providerSignal?.aborted) {
|
|
@@ -1256,7 +1096,8 @@ export default class TurnRunner {
|
|
|
1256
1096
|
workspaceId, workerId, loopId, turnId,
|
|
1257
1097
|
evidence: {
|
|
1258
1098
|
packet: StoredPacket.stringify(requestPacket),
|
|
1259
|
-
|
|
1099
|
+
sections: StoredPacket.sections(requestPacket),
|
|
1100
|
+
usageCurationBudget: this.#packets.curationBudgetFor(requestPacket),
|
|
1260
1101
|
finishReason: splitResponse?.callMetadata.finishReason ?? null,
|
|
1261
1102
|
model: splitResponse?.callMetadata.model ?? provider.model,
|
|
1262
1103
|
meta: JSON.stringify(response?.meta ?? {}),
|
|
@@ -1281,7 +1122,8 @@ export default class TurnRunner {
|
|
|
1281
1122
|
workspaceId, workerId, loopId, turnId,
|
|
1282
1123
|
evidence: {
|
|
1283
1124
|
packet: StoredPacket.stringify(requestPacket),
|
|
1284
|
-
|
|
1125
|
+
sections: StoredPacket.sections(requestPacket),
|
|
1126
|
+
usageCurationBudget: this.#packets.curationBudgetFor(requestPacket),
|
|
1285
1127
|
finishReason: splitResponse?.callMetadata.finishReason ?? null,
|
|
1286
1128
|
model: splitResponse?.callMetadata.model ?? provider.model,
|
|
1287
1129
|
meta: JSON.stringify(response?.meta ?? {}),
|
|
@@ -1308,6 +1150,7 @@ export default class TurnRunner {
|
|
|
1308
1150
|
capacityHardStop: false, providerParked: true,
|
|
1309
1151
|
providerFailure: recorded.result,
|
|
1310
1152
|
steerStruck: false,
|
|
1153
|
+
emptyTurn: false,
|
|
1311
1154
|
emissionAttempts,
|
|
1312
1155
|
emissionExhausted: false,
|
|
1313
1156
|
};
|
|
@@ -1325,6 +1168,7 @@ export default class TurnRunner {
|
|
|
1325
1168
|
providerParked: false,
|
|
1326
1169
|
capacityFailure: recorded.result,
|
|
1327
1170
|
steerStruck: false,
|
|
1171
|
+
emptyTurn: false,
|
|
1328
1172
|
emissionAttempts,
|
|
1329
1173
|
emissionExhausted: false,
|
|
1330
1174
|
};
|
|
@@ -1347,6 +1191,7 @@ export default class TurnRunner {
|
|
|
1347
1191
|
providerParked: false,
|
|
1348
1192
|
providerFailure: recorded.result,
|
|
1349
1193
|
steerStruck: false,
|
|
1194
|
+
emptyTurn: false,
|
|
1350
1195
|
emissionAttempts,
|
|
1351
1196
|
emissionExhausted: false,
|
|
1352
1197
|
};
|
|
@@ -1357,6 +1202,9 @@ export default class TurnRunner {
|
|
|
1357
1202
|
throw new Error("provider attempt loop completed without a response");
|
|
1358
1203
|
}
|
|
1359
1204
|
const emissionModelCallId = providerModelCall.id;
|
|
1205
|
+
if (splitResponse.packetAssistant.reasoning?.length) {
|
|
1206
|
+
await Turn.recordSource(this.#db, turnId, "reasoning", splitResponse.packetAssistant.reasoning, { modelCallId: emissionModelCallId });
|
|
1207
|
+
}
|
|
1360
1208
|
if (!splitResponse.emissionValid) {
|
|
1361
1209
|
// {§invalid-emission-attempts} Every exhaustion publishes the raw final
|
|
1362
1210
|
// response and its recovery fact; {§engine-rails} Contract Strikes rule
|
|
@@ -1370,9 +1218,6 @@ export default class TurnRunner {
|
|
|
1370
1218
|
turnId,
|
|
1371
1219
|
sequence: nextActionIndex,
|
|
1372
1220
|
modelCallId: emissionModelCallId,
|
|
1373
|
-
...(response.assistant.reasoningEncrypted?.length
|
|
1374
|
-
? { reasoningItems: response.assistant.reasoningEncrypted }
|
|
1375
|
-
: {}),
|
|
1376
1221
|
});
|
|
1377
1222
|
// {§invalid-emission-attempts} — the informed turn carries the parser's own
|
|
1378
1223
|
// diagnostic and position: the model sees WHY, not only that it was refused.
|
|
@@ -1405,7 +1250,8 @@ export default class TurnRunner {
|
|
|
1405
1250
|
workspaceId, workerId, loopId, turnId,
|
|
1406
1251
|
evidence: {
|
|
1407
1252
|
packet: StoredPacket.stringify(requestPacket),
|
|
1408
|
-
|
|
1253
|
+
sections: StoredPacket.sections(requestPacket),
|
|
1254
|
+
usageCurationBudget: this.#packets.curationBudgetFor(requestPacket),
|
|
1409
1255
|
finishReason: splitResponse.callMetadata.finishReason,
|
|
1410
1256
|
model: splitResponse.callMetadata.model,
|
|
1411
1257
|
meta: JSON.stringify(response.meta ?? {}),
|
|
@@ -1423,6 +1269,7 @@ export default class TurnRunner {
|
|
|
1423
1269
|
capacityHardStop: false,
|
|
1424
1270
|
providerParked: false,
|
|
1425
1271
|
steerStruck: false,
|
|
1272
|
+
emptyTurn: false,
|
|
1426
1273
|
emissionAttempts,
|
|
1427
1274
|
emissionExhausted: true,
|
|
1428
1275
|
...(rejectedModelEntryId === undefined ? {} : { rejectedModelEntryId }),
|
|
@@ -1434,9 +1281,22 @@ export default class TurnRunner {
|
|
|
1434
1281
|
for (const notice of parseNotices) {
|
|
1435
1282
|
this.#notices.push(workspaceId, workerId, loopId, notice);
|
|
1436
1283
|
}
|
|
1284
|
+
// {§empty-turn} — a response cut at the output allowance with nothing admitted names the
|
|
1285
|
+
// cut, so the model reads the ceiling, never a parser symptom (#478).
|
|
1286
|
+
if (splitResponse.emptyTurn && callMetadata.finishReason === "length") {
|
|
1287
|
+
const cut = allowanceCutMessage(callMetadata.finishReason, response.capacity.responseMax ?? provider.outputBudget);
|
|
1288
|
+
if (cut !== null) {
|
|
1289
|
+
this.#notices.push(workspaceId, workerId, loopId, {
|
|
1290
|
+
source: "engine:turn",
|
|
1291
|
+
kind: "output_truncated",
|
|
1292
|
+
level: "warn",
|
|
1293
|
+
message: `${cut}; no operations were performed`,
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1437
1297
|
// Non-fatal provider transport notices on an accepted turn. Forward each
|
|
1438
1298
|
// Notice with a content-offset `line:col`;
|
|
1439
|
-
// the model resolves it against its own emission — READ
|
|
1299
|
+
// the model resolves it against its own emission — READ ops:///<loop>/<turn> at the
|
|
1440
1300
|
// cited lines ({§turn-ops-entry}) — not an embedded snippet that would duplicate the emission.
|
|
1441
1301
|
for (const notice of response.notices ?? []) {
|
|
1442
1302
|
const located = typeof notice.position === "number"
|
|
@@ -1461,45 +1321,12 @@ export default class TurnRunner {
|
|
|
1461
1321
|
level: "warn",
|
|
1462
1322
|
});
|
|
1463
1323
|
}
|
|
1464
|
-
//
|
|
1465
|
-
//
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
if (railResponseGrammar === undefined)
|
|
1471
|
-
throw new Error("configured GBNF has no response grammar");
|
|
1472
|
-
let verdict = null;
|
|
1473
|
-
try {
|
|
1474
|
-
verdict = validateGbnf(railResponseGrammar, railEvidence.input);
|
|
1475
|
-
}
|
|
1476
|
-
catch (cause) {
|
|
1477
|
-
TurnRunner.#warnRailVerdictGapOnce(cause.message);
|
|
1478
|
-
}
|
|
1479
|
-
railKeys = {
|
|
1480
|
-
railsAttached: railEvidence.transported ? "client" : "withheld",
|
|
1481
|
-
railsVerdict: verdict?.status ?? "unverifiable",
|
|
1482
|
-
};
|
|
1483
|
-
if (verdict !== null && verdict.status !== "accept" && allowanceCut === null) {
|
|
1484
|
-
const contentPosition = verdict.pos >= railEvidence.contentStart
|
|
1485
|
-
? verdict.pos - railEvidence.contentStart
|
|
1486
|
-
: null;
|
|
1487
|
-
const located = contentPosition === null
|
|
1488
|
-
? null
|
|
1489
|
-
: this.#offsetToLineColumn(packetAssistant.content, contentPosition);
|
|
1490
|
-
this.#notices.push(workspaceId, workerId, loopId, {
|
|
1491
|
-
source: "engine:rails",
|
|
1492
|
-
kind: "grammar_unenforced",
|
|
1493
|
-
message: verdict.status === "reject"
|
|
1494
|
-
? `emission rejects the grammar at raw code point ${verdict.pos}`
|
|
1495
|
-
: `emission is an incomplete grammar sentence (ends at raw code point ${verdict.pos})`,
|
|
1496
|
-
level: "warn",
|
|
1497
|
-
...(located === null
|
|
1498
|
-
? {}
|
|
1499
|
-
: { position: { type: "content-offset", line: located.line, column: located.column } }),
|
|
1500
|
-
});
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1324
|
+
// {§operator-grammar} — transport evidence only: the turn records whether the operator's
|
|
1325
|
+
// grammar reached the wire. Nothing grades the response against it; the parser's
|
|
1326
|
+
// admission is the one verdict (#588).
|
|
1327
|
+
const railKeys = railGrammar === undefined
|
|
1328
|
+
? undefined
|
|
1329
|
+
: { railsAttached: railEvidence?.transported === true ? "client" : "withheld" };
|
|
1503
1330
|
// Attach the admitted inference evidence. The turn remains open until
|
|
1504
1331
|
// the producer-neutral admitted-turn executor settles every operation
|
|
1505
1332
|
// and its exact source artifact.
|
|
@@ -1508,11 +1335,12 @@ export default class TurnRunner {
|
|
|
1508
1335
|
workspaceId, workerId, loopId, turnId,
|
|
1509
1336
|
evidence: {
|
|
1510
1337
|
packet: StoredPacket.stringify(packet),
|
|
1511
|
-
|
|
1338
|
+
sections: StoredPacket.sections(packet),
|
|
1339
|
+
usageCurationBudget: this.#packets.curationBudgetFor(requestPacket), // {§tokenomics-client-gauge}
|
|
1512
1340
|
finishReason: callMetadata.finishReason,
|
|
1513
1341
|
model: callMetadata.model,
|
|
1514
|
-
// Opaque provider metadata plus
|
|
1515
|
-
// {§meta-passthrough}, {§
|
|
1342
|
+
// Opaque provider metadata plus the grammar transport key.
|
|
1343
|
+
// {§meta-passthrough}, {§operator-grammar}
|
|
1516
1344
|
meta: JSON.stringify({ ...(response.meta ?? {}), ...(railKeys ?? {}) }),
|
|
1517
1345
|
},
|
|
1518
1346
|
});
|
|
@@ -1520,15 +1348,10 @@ export default class TurnRunner {
|
|
|
1520
1348
|
// narrows the operator ceiling before the admitted program reaches the
|
|
1521
1349
|
// shared executor.
|
|
1522
1350
|
const maxCommands = Math.min(readMaxCommands(), (await WorkspaceSettings.read(this.#db, workspaceId)).maxCommands ?? Number.POSITIVE_INFINITY);
|
|
1523
|
-
const reasoningItems = response.assistant.reasoningEncrypted?.length
|
|
1524
|
-
? response.assistant.reasoningEncrypted
|
|
1525
|
-
: undefined;
|
|
1526
1351
|
const executed = await this.executeAdmittedTurn({
|
|
1527
1352
|
statements: packetAssistant.ops,
|
|
1528
1353
|
source: splitResponse.sourceBacked ? packetAssistant.content : null,
|
|
1529
|
-
sourceFolded: true,
|
|
1530
1354
|
sourceModelCallId: emissionModelCallId,
|
|
1531
|
-
...(reasoningItems !== undefined ? { sourceReasoningItems: reasoningItems } : {}),
|
|
1532
1355
|
origin: "model",
|
|
1533
1356
|
workspaceId,
|
|
1534
1357
|
workerId,
|
|
@@ -1536,8 +1359,9 @@ export default class TurnRunner {
|
|
|
1536
1359
|
turnId,
|
|
1537
1360
|
fromSequence: nextActionIndex,
|
|
1538
1361
|
maxCommands,
|
|
1539
|
-
|
|
1362
|
+
allowUnobservedRetrievalCompletion,
|
|
1540
1363
|
recoverableParseErrors,
|
|
1364
|
+
emptyTurn: splitResponse.emptyTurn,
|
|
1541
1365
|
bare: {
|
|
1542
1366
|
provider: childProvider,
|
|
1543
1367
|
primaryWorkerId,
|
|
@@ -1560,6 +1384,7 @@ export default class TurnRunner {
|
|
|
1560
1384
|
capacityHardStop: false,
|
|
1561
1385
|
providerParked: false,
|
|
1562
1386
|
steerStruck: executed.steerStruck,
|
|
1387
|
+
emptyTurn: executed.emptyTurn,
|
|
1563
1388
|
emissionAttempts,
|
|
1564
1389
|
emissionExhausted: false,
|
|
1565
1390
|
};
|
|
@@ -1592,13 +1417,11 @@ export default class TurnRunner {
|
|
|
1592
1417
|
// its assistant payload to skip the parse roundtrip. The wire Provider
|
|
1593
1418
|
// contract has no `ops` field; only Mock exposes one. Real providers
|
|
1594
1419
|
// always take the parse path because their `assistant.ops` is undefined.
|
|
1595
|
-
#splitResponse(response) {
|
|
1420
|
+
#splitResponse(response, executors = []) {
|
|
1596
1421
|
const { assistant } = response;
|
|
1597
1422
|
const preParsedOps = assistant.ops;
|
|
1598
1423
|
const ops = [];
|
|
1599
|
-
//
|
|
1600
|
-
// client as a log entry. No special hoisting into the reasoning field. Only
|
|
1601
|
-
// structured operations are executable; interstitial text is not an operation.
|
|
1424
|
+
// Only structured operations are executable; interstitial text is not an operation.
|
|
1602
1425
|
// Full PlurnkParseError context is preserved on rejected attempt evidence;
|
|
1603
1426
|
// warnings remain admissible Notices. {§parse-diagnostics}
|
|
1604
1427
|
const parseErrors = [];
|
|
@@ -1611,7 +1434,9 @@ export default class TurnRunner {
|
|
|
1611
1434
|
// {§observability-boundary} — the parse is observed without its input;
|
|
1612
1435
|
// only the resulting statement count is attributable.
|
|
1613
1436
|
const parsed = observedSync("contracts.parse", {}, (span) => {
|
|
1614
|
-
|
|
1437
|
+
// {§fence-heading-in-body} {§interstitial-fence} — the executors this workspace can run
|
|
1438
|
+
// are heading tags to the parser; anything else tagged is a code block.
|
|
1439
|
+
const result = PlurnkParser.parse(assistant.content, { executors });
|
|
1615
1440
|
span.setAttribute("statements", result.items.filter((item) => item.kind === "statement").length);
|
|
1616
1441
|
return result;
|
|
1617
1442
|
});
|
|
@@ -1637,7 +1462,7 @@ export default class TurnRunner {
|
|
|
1637
1462
|
});
|
|
1638
1463
|
}
|
|
1639
1464
|
else {
|
|
1640
|
-
parseErrors.push({ message: err.message, line: err.line, column: err.column, source: err.source });
|
|
1465
|
+
parseErrors.push({ message: err.message, line: err.line, column: err.column, source: err.source, ...(err.code === undefined ? {} : { code: err.code }) });
|
|
1641
1466
|
}
|
|
1642
1467
|
}
|
|
1643
1468
|
else {
|
|
@@ -1655,25 +1480,23 @@ export default class TurnRunner {
|
|
|
1655
1480
|
}
|
|
1656
1481
|
}
|
|
1657
1482
|
const sourceStatementCount = ops.filter(({ position }) => position.line > 0).length;
|
|
1658
|
-
const
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
?
|
|
1664
|
-
: undefined;
|
|
1665
|
-
const recoveredSend = terminalSend?.position.line === 0;
|
|
1666
|
-
// {§turn-shape} — PLAN is a SHOULD: a turn without one is complete once it ends in a
|
|
1667
|
-
// terminal SEND, and the recoverable window then starts at the turn's first statement.
|
|
1668
|
-
const recoverableParseErrors = terminalSend !== undefined && !hasUnparsedTail
|
|
1669
|
-
? parseErrors.filter((error) => (error.message === PlurnkParser.MISSING_SEND
|
|
1670
|
-
|| ((plan === undefined || comparePosition(error, plan.position) > 0)
|
|
1671
|
-
&& (recoveredSend || comparePosition(error, terminalSend.position) < 0)))).toSorted(comparePosition)
|
|
1483
|
+
const dispositions = ops.filter(TurnDisposition.is);
|
|
1484
|
+
const trustworthyBoundary = dispositions.length <= 1 && !hasUnparsedTail;
|
|
1485
|
+
// {§turn-shape} — bounded operation errors are recoverable and ride with the
|
|
1486
|
+
// admitted program; document-boundary failures still reject it.
|
|
1487
|
+
const recoverableParseErrors = trustworthyBoundary
|
|
1488
|
+
? parseErrors.filter((error) => error.code !== "invalid-turn-structure").toSorted(comparePosition)
|
|
1672
1489
|
: [];
|
|
1490
|
+
// {§empty-turn} — no operation and no other hard error: admitted as an empty turn, never
|
|
1491
|
+
// resampled; its advisories ({§bare-heading-advisory}) ride as notices.
|
|
1492
|
+
const emptyTurn = preParsedOps === undefined
|
|
1493
|
+
&& trustworthyBoundary
|
|
1494
|
+
&& sourceStatementCount === 0
|
|
1495
|
+
&& parseErrors.every((error) => error.message === PlurnkParser.NO_VALID_OPERATION);
|
|
1673
1496
|
const emissionValid = preParsedOps !== undefined
|
|
1674
|
-
||
|
|
1497
|
+
|| emptyTurn
|
|
1498
|
+
|| (trustworthyBoundary
|
|
1675
1499
|
&& sourceStatementCount > 0
|
|
1676
|
-
&& !hasUnparsedTail
|
|
1677
1500
|
&& recoverableParseErrors.length === parseErrors.length);
|
|
1678
1501
|
const reasoning = assistant.reasoning ?? null;
|
|
1679
1502
|
return {
|
|
@@ -1681,18 +1504,19 @@ export default class TurnRunner {
|
|
|
1681
1504
|
sourceBacked: preParsedOps === undefined,
|
|
1682
1505
|
callMetadata: { finishReason: assistant.finishReason, model: assistant.model },
|
|
1683
1506
|
parseErrors,
|
|
1684
|
-
recoverableParseErrors: emissionValid ? recoverableParseErrors : [],
|
|
1507
|
+
recoverableParseErrors: emissionValid && !emptyTurn ? recoverableParseErrors : [],
|
|
1508
|
+
emptyTurn,
|
|
1685
1509
|
parseNotices,
|
|
1686
1510
|
// The ANTLR model-turn parser is authoritative. At least one source
|
|
1687
|
-
// operation
|
|
1688
|
-
//
|
|
1689
|
-
//
|
|
1511
|
+
// operation is required; TASK omission continues silently. Bounded
|
|
1512
|
+
// statement failures become durable operation results.
|
|
1513
|
+
// Boundary loss and an unparsed tail still reject
|
|
1690
1514
|
// wholesale. Pre-parsed ops are Mock's trusted test seam.
|
|
1691
1515
|
emissionValid,
|
|
1692
1516
|
};
|
|
1693
1517
|
}
|
|
1694
1518
|
// #note12 — plugin reference docs are materialized beneath
|
|
1695
|
-
// worker
|
|
1519
|
+
// worker:///_plurnk/plurnk/ by LoopDocs.
|
|
1696
1520
|
// {§exec-poll} — EXEC `<0>` is turn-scoped: abort the worker's open turn-scoped streams via their
|
|
1697
1521
|
// owning scheme (the same registry-routed abort the total reap uses). Called at each pre-turn
|
|
1698
1522
|
// before the turn's own spawns, so every open turn-scoped sub here is from a prior turn — it
|