@sema-agent/client-core 0.77.0 → 0.77.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -1
- package/README.md +5 -4
- package/dist/abortableSleep.d.ts +0 -28
- package/dist/abortableSleep.js +0 -28
- package/dist/adapt/arms.d.ts +0 -46
- package/dist/adapt/arms.js +9 -544
- package/dist/adapt/ids.d.ts +0 -58
- package/dist/adapt/ids.js +0 -63
- package/dist/adapt/instanceLedger.d.ts +0 -25
- package/dist/adapt/instanceLedger.js +0 -20
- package/dist/adapt/panelTasks.d.ts +0 -69
- package/dist/adapt/panelTasks.js +0 -95
- package/dist/adapt/textSegmentAuthority.d.ts +1 -137
- package/dist/adapt/textSegmentAuthority.js +0 -54
- package/dist/adapt/textStream.d.ts +0 -252
- package/dist/adapt/textStream.js +2 -281
- package/dist/adapt/toolCards.d.ts +0 -46
- package/dist/adapt/toolCards.js +0 -23
- package/dist/adapt/turnFlags.d.ts +0 -54
- package/dist/adapt/turnFlags.js +1 -17
- package/dist/adapt/wireShapes.d.ts +0 -92
- package/dist/adapt/wireShapes.js +0 -83
- package/dist/adapt.d.ts +0 -55
- package/dist/adapt.js +1 -120
- package/dist/adapter/activeRunSelfHeal.d.ts +22 -515
- package/dist/adapter/activeRunSelfHeal.js +10 -625
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -305
- package/dist/adapter/downstream/eventToSdkMessage.js +2 -867
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -314
- package/dist/adapter/downstream/terminalToSdkResult.js +13 -560
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +0 -95
- package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -31
- package/dist/adapter/runStream.d.ts +0 -206
- package/dist/adapter/runStream.js +6 -596
- package/dist/adapter/types.d.ts +0 -111
- package/dist/adapter/types.js +0 -29
- package/dist/agentSession/backgroundView.d.ts +0 -106
- package/dist/agentSession/backgroundView.js +3 -49
- package/dist/agentSession/contract.d.ts +0 -98
- package/dist/agentSession/contract.js +0 -12
- package/dist/agentsWireCaps.d.ts +0 -72
- package/dist/agentsWireCaps.js +4 -72
- package/dist/approvalsStreamLiveCapability.d.ts +0 -25
- package/dist/approvalsStreamLiveCapability.js +0 -31
- package/dist/argvFlagValue.d.ts +0 -33
- package/dist/argvFlagValue.js +3 -35
- package/dist/attachmentsWireCaps.d.ts +0 -127
- package/dist/attachmentsWireCaps.js +0 -144
- package/dist/autoModeUnavailable.d.ts +0 -120
- package/dist/autoModeUnavailable.js +0 -144
- package/dist/classifierStatus.d.ts +0 -72
- package/dist/classifierStatus.js +0 -167
- package/dist/classifierVerdictWire.d.ts +0 -54
- package/dist/classifierVerdictWire.js +0 -133
- package/dist/clientContextWireCaps.d.ts +0 -37
- package/dist/clientContextWireCaps.js +0 -36
- package/dist/clientSlice.d.ts +0 -63
- package/dist/clientSlice.js +0 -45
- package/dist/cloudConfigWireCaps.d.ts +0 -86
- package/dist/cloudConfigWireCaps.js +2 -65
- package/dist/compensations.d.ts +0 -52
- package/dist/compensations.js +2 -63
- package/dist/controlRouter.d.ts +2 -208
- package/dist/controlRouter.js +1 -129
- package/dist/coreValuePorts.d.ts +0 -84
- package/dist/coreValuePorts.js +0 -29
- package/dist/decideReceipt.d.ts +0 -110
- package/dist/decideReceipt.js +0 -84
- package/dist/detachWire.d.ts +0 -130
- package/dist/detachWire.js +1 -130
- package/dist/deviceExecutorManagementCapability.d.ts +2 -35
- package/dist/deviceExecutorManagementCapability.js +1 -37
- package/dist/diagnostics.d.ts +0 -8
- package/dist/diagnostics.js +0 -8
- package/dist/diff/patch.d.ts +0 -17
- package/dist/diff/patch.js +0 -19
- package/dist/effectiveFacts.d.ts +0 -40
- package/dist/effectiveFacts.js +0 -22
- package/dist/effortWire.d.ts +0 -11
- package/dist/effortWire.js +0 -12
- package/dist/engineAgentPanelStore.d.ts +0 -169
- package/dist/engineAgentPanelStore.js +13 -293
- package/dist/engineCapReader.d.ts +0 -62
- package/dist/engineCapReader.js +1 -43
- package/dist/engineCapsCache.d.ts +0 -177
- package/dist/engineCapsCache.js +0 -199
- package/dist/engineCapsGenerationGuard.d.ts +0 -2
- package/dist/engineCapsGenerationGuard.js +0 -11
- package/dist/engineErrorCodes.d.ts +1 -316
- package/dist/engineErrorCodes.js +0 -427
- package/dist/engineHttpTools.d.ts +0 -29
- package/dist/engineHttpTools.js +0 -29
- package/dist/engineIdentity.d.ts +0 -83
- package/dist/engineIdentity.js +0 -88
- package/dist/engineInlineTaskStats.d.ts +0 -57
- package/dist/engineInlineTaskStats.js +1 -42
- package/dist/engineNoticeCodes.d.ts +0 -190
- package/dist/engineNoticeCodes.js +0 -182
- package/dist/engineSessionParam.d.ts +0 -30
- package/dist/engineSessionParam.js +0 -52
- package/dist/engineToolLabelStore.d.ts +0 -29
- package/dist/engineToolLabelStore.js +0 -31
- package/dist/engineWireSdk.d.ts +0 -90
- package/dist/engineWireSdk.js +0 -74
- package/dist/engineWireTarget.d.ts +0 -14
- package/dist/engineWireTarget.js +0 -39
- package/dist/env/localeGeo.d.ts +0 -12
- package/dist/env/localeGeo.js +2 -77
- package/dist/env/localeTag.d.ts +0 -34
- package/dist/env/localeTag.js +0 -32
- package/dist/env/uiLanguage.d.ts +0 -13
- package/dist/env/uiLanguage.js +0 -25
- package/dist/envFlag.d.ts +0 -37
- package/dist/envFlag.js +0 -40
- package/dist/executionLaneCapability.d.ts +0 -48
- package/dist/executionLaneCapability.js +0 -54
- package/dist/finalVerifyWire.d.ts +0 -67
- package/dist/finalVerifyWire.js +3 -43
- package/dist/fleet/fleetLedger.d.ts +0 -308
- package/dist/fleet/fleetLedger.js +10 -429
- package/dist/fleet/fleetProjection.d.ts +0 -240
- package/dist/fleet/fleetProjection.js +0 -189
- package/dist/fleet/fleetRowAgentType.d.ts +0 -6
- package/dist/fleet/fleetRowAgentType.js +1 -32
- package/dist/fleet/workflowSizeWarning.d.ts +0 -47
- package/dist/fleet/workflowSizeWarning.js +1 -46
- package/dist/fleetAgentPanelProjection.d.ts +0 -48
- package/dist/fleetAgentPanelProjection.js +8 -173
- package/dist/fleetTaskDesc.d.ts +0 -39
- package/dist/fleetTaskDesc.js +0 -69
- package/dist/forkWireCaps.d.ts +0 -23
- package/dist/forkWireCaps.js +1 -24
- package/dist/gateOutcome.d.ts +0 -140
- package/dist/gateOutcome.js +0 -85
- package/dist/gateVocabulary.d.ts +0 -114
- package/dist/gateVocabulary.js +1 -161
- package/dist/goalStopHook.d.ts +0 -127
- package/dist/goalStopHook.js +0 -178
- package/dist/headlessPermissionModeWire.d.ts +0 -76
- package/dist/headlessPermissionModeWire.js +1 -155
- package/dist/headlessReconnectWire.d.ts +0 -84
- package/dist/headlessReconnectWire.js +13 -67
- package/dist/hitl/approvalDecisionNoteAudit.d.ts +0 -49
- package/dist/hitl/approvalDecisionNoteAudit.js +0 -56
- package/dist/hitl/approvalOutcomeNote.d.ts +0 -2
- package/dist/hitl/approvalOutcomeNote.js +0 -20
- package/dist/hitl/approvalResolution.d.ts +0 -113
- package/dist/hitl/approvalResolution.js +0 -66
- package/dist/hitl/approvalsFeed.d.ts +0 -183
- package/dist/hitl/approvalsFeed.js +12 -243
- package/dist/hitl/armedGateRegistry.d.ts +0 -55
- package/dist/hitl/armedGateRegistry.js +0 -146
- package/dist/hitl/askGateWire.d.ts +0 -86
- package/dist/hitl/askGateWire.js +1 -95
- package/dist/hitl/askParkRowRouting.d.ts +0 -123
- package/dist/hitl/askParkRowRouting.js +1 -89
- package/dist/hitl/crashConverged.d.ts +0 -148
- package/dist/hitl/crashConverged.js +0 -214
- package/dist/hitl/editedRuleTextPrecheck.d.ts +0 -109
- package/dist/hitl/editedRuleTextPrecheck.js +0 -71
- package/dist/hitl/frameRouter.d.ts +0 -134
- package/dist/hitl/frameRouter.js +6 -378
- package/dist/hitl/gateIdentity.d.ts +0 -39
- package/dist/hitl/gateIdentity.js +0 -41
- package/dist/hitl/gateLedger.d.ts +0 -267
- package/dist/hitl/gateLedger.js +0 -121
- package/dist/hitl/hitlBridge.d.ts +7 -431
- package/dist/hitl/hitlBridge.js +7 -476
- package/dist/hitl/hitlHostSurface.d.ts +0 -150
- package/dist/hitl/hitlHostSurface.js +0 -169
- package/dist/hitl/livePendingAsk.d.ts +0 -91
- package/dist/hitl/livePendingAsk.js +0 -74
- package/dist/hitl/localAllowRule.d.ts +0 -62
- package/dist/hitl/localAllowRule.js +1 -33
- package/dist/hitl/parkOwnership.d.ts +0 -56
- package/dist/hitl/parkOwnership.js +0 -22
- package/dist/hitl/parkResolver.d.ts +3 -88
- package/dist/hitl/parkResolver.js +8 -349
- package/dist/hitl/parkRowBirthWait.d.ts +2 -26
- package/dist/hitl/parkRowBirthWait.js +3 -93
- package/dist/hitl/persistedRulesWire.d.ts +13 -358
- package/dist/hitl/persistedRulesWire.js +0 -310
- package/dist/hitl/planReviewWire.d.ts +4 -176
- package/dist/hitl/planReviewWire.js +9 -312
- package/dist/hitl/resumeRunningCard.d.ts +0 -105
- package/dist/hitl/resumeRunningCard.js +0 -105
- package/dist/hitl/sessionPolicyWire.d.ts +11 -191
- package/dist/hitl/sessionPolicyWire.js +0 -149
- package/dist/hitl/suspendedReopen.d.ts +3 -24
- package/dist/hitl/suspendedReopen.js +0 -14
- package/dist/hitl/toolApprovalWire.d.ts +5 -1308
- package/dist/hitl/toolApprovalWire.js +5 -945
- package/dist/hooksWireCaps.d.ts +0 -38
- package/dist/hooksWireCaps.js +0 -190
- package/dist/host.d.ts +0 -105
- package/dist/host.js +0 -33
- package/dist/hostEnv.d.ts +0 -14
- package/dist/hostEnv.js +0 -13
- package/dist/imagesWireCaps.d.ts +0 -21
- package/dist/imagesWireCaps.js +0 -22
- package/dist/index.d.ts +0 -134
- package/dist/index.js +0 -476
- package/dist/interactiveHalt.d.ts +5 -153
- package/dist/interactiveHalt.js +0 -111
- package/dist/interactiveToolsWire.d.ts +0 -62
- package/dist/interactiveToolsWire.js +1 -67
- package/dist/leaderConflict.d.ts +0 -59
- package/dist/leaderConflict.js +0 -48
- package/dist/limitsWire.d.ts +0 -125
- package/dist/limitsWire.js +2 -120
- package/dist/liveInitToolFace.d.ts +0 -77
- package/dist/liveInitToolFace.js +1 -109
- package/dist/liveModelCatalog.d.ts +0 -52
- package/dist/liveModelCatalog.js +0 -48
- package/dist/liveQuestionStore.d.ts +0 -87
- package/dist/liveQuestionStore.js +1 -56
- package/dist/mcpLiveness.d.ts +0 -151
- package/dist/mcpLiveness.js +0 -122
- package/dist/mcpPanel.d.ts +0 -104
- package/dist/mcpPanel.js +0 -49
- package/dist/mcpReconnect.d.ts +0 -58
- package/dist/mcpReconnect.js +1 -69
- package/dist/mcpWireCaps.d.ts +0 -55
- package/dist/mcpWireCaps.js +1 -13
- package/dist/memoryComplianceCapability.d.ts +3 -57
- package/dist/memoryComplianceCapability.js +0 -57
- package/dist/memoryEntriesWire.d.ts +6 -198
- package/dist/memoryEntriesWire.js +0 -144
- package/dist/memoryOriginCapability.d.ts +3 -53
- package/dist/memoryOriginCapability.js +0 -50
- package/dist/memorySpecWire.d.ts +0 -116
- package/dist/memorySpecWire.js +0 -150
- package/dist/model/catalog.d.ts +0 -111
- package/dist/model/catalog.js +0 -87
- package/dist/model/catalogLoader.d.ts +0 -114
- package/dist/model/catalogLoader.js +2 -139
- package/dist/model/modelSupplyRules.d.ts +1 -55
- package/dist/model/modelSupplyRules.js +0 -62
- package/dist/model/providerAuth.d.ts +0 -103
- package/dist/model/providerAuth.js +2 -38
- package/dist/model/providerCatalog.d.ts +0 -45
- package/dist/model/providerCatalog.js +0 -37
- package/dist/model/providerPresets.d.ts +0 -33
- package/dist/model/providerPresets.js +2 -91
- package/dist/model/tierVocabulary.d.ts +0 -31
- package/dist/model/tierVocabulary.js +0 -27
- package/dist/modelBudgetRule.d.ts +0 -39
- package/dist/modelBudgetRule.js +0 -39
- package/dist/modelCapabilityProbe.d.ts +0 -175
- package/dist/modelCapabilityProbe.js +0 -147
- package/dist/modelWireCaps.d.ts +0 -13
- package/dist/modelWireCaps.js +0 -13
- package/dist/notifications.d.ts +0 -233
- package/dist/notifications.js +14 -492
- package/dist/oneShotWireCaps.d.ts +0 -34
- package/dist/oneShotWireCaps.js +0 -35
- package/dist/ownKey.d.ts +0 -33
- package/dist/ownKey.js +0 -33
- package/dist/panelRunningHistory.d.ts +0 -28
- package/dist/panelRunningHistory.js +0 -43
- package/dist/peerFrames.d.ts +0 -71
- package/dist/peerFrames.js +0 -168
- package/dist/peerLaneCapability.d.ts +0 -44
- package/dist/peerLaneCapability.js +0 -52
- package/dist/permissionRuleIssue.d.ts +0 -30
- package/dist/permissionRuleIssue.js +0 -78
- package/dist/permissionRulesWriteCapability.d.ts +0 -46
- package/dist/permissionRulesWriteCapability.js +0 -54
- package/dist/permissionWireCaps.d.ts +0 -37
- package/dist/permissionWireCaps.js +0 -37
- package/dist/postureKnob.d.ts +0 -71
- package/dist/postureKnob.js +0 -86
- package/dist/principalWire.d.ts +0 -17
- package/dist/principalWire.js +0 -17
- package/dist/printToolResultFrame.d.ts +0 -100
- package/dist/printToolResultFrame.js +0 -33
- package/dist/promptProfileWireCaps.d.ts +0 -13
- package/dist/promptProfileWireCaps.js +0 -13
- package/dist/readFacePosture.d.ts +0 -43
- package/dist/readFacePosture.js +0 -46
- package/dist/request/printNotification.d.ts +0 -20
- package/dist/request/printNotification.js +0 -55
- package/dist/request/taskRequest.d.ts +0 -249
- package/dist/request/taskRequest.js +10 -496
- package/dist/resumeRefusalCopy.d.ts +0 -136
- package/dist/resumeRefusalCopy.js +1 -117
- package/dist/retainBackgroundWireCaps.d.ts +0 -48
- package/dist/retainBackgroundWireCaps.js +0 -48
- package/dist/retryStatus.d.ts +2 -221
- package/dist/retryStatus.js +0 -107
- package/dist/rewindWireCaps.d.ts +0 -27
- package/dist/rewindWireCaps.js +0 -24
- package/dist/runCancelContext.d.ts +1 -20
- package/dist/runCancelContext.js +0 -34
- package/dist/runTerminal.d.ts +0 -273
- package/dist/runTerminal.js +0 -177
- package/dist/sandboxWire.d.ts +0 -38
- package/dist/sandboxWire.js +0 -82
- package/dist/scenarioWire.d.ts +0 -60
- package/dist/scenarioWire.js +0 -68
- package/dist/scratchpadWireCaps.d.ts +0 -11
- package/dist/scratchpadWireCaps.js +0 -32
- package/dist/sdkWireTransit.d.ts +0 -38
- package/dist/sdkWireTransit.js +0 -30
- package/dist/seam.d.ts +18 -853
- package/dist/seam.js +0 -52
- package/dist/seatContract.d.ts +0 -555
- package/dist/seatContract.js +5 -304
- package/dist/selfOrchestrationDenial.d.ts +0 -189
- package/dist/selfOrchestrationDenial.js +0 -162
- package/dist/selfOrchestrationWireCaps.d.ts +0 -38
- package/dist/selfOrchestrationWireCaps.js +0 -38
- package/dist/sessionMap.d.ts +0 -60
- package/dist/sessionMap.js +0 -37
- package/dist/sessionMemoryStatus.d.ts +11 -114
- package/dist/sessionMemoryStatus.js +0 -112
- package/dist/sessionModelLatch.d.ts +0 -29
- package/dist/sessionModelLatch.js +0 -40
- package/dist/sessionPolicyCapability.d.ts +3 -53
- package/dist/sessionPolicyCapability.js +0 -52
- package/dist/sessionSlot.d.ts +0 -26
- package/dist/sessionSlot.js +0 -17
- package/dist/skillsWireCaps.d.ts +0 -87
- package/dist/skillsWireCaps.js +0 -38
- package/dist/sqlEngineCapability.d.ts +0 -118
- package/dist/sqlEngineCapability.js +0 -134
- package/dist/sseIdleTriage.d.ts +0 -79
- package/dist/sseIdleTriage.js +1 -80
- package/dist/steering.d.ts +0 -54
- package/dist/steering.js +0 -63
- package/dist/subagent/engineCompactWire.d.ts +0 -34
- package/dist/subagent/engineCompactWire.js +4 -134
- package/dist/subagent/engineDelegatedPrompt.d.ts +0 -31
- package/dist/subagent/engineDelegatedPrompt.js +1 -103
- package/dist/subagent/engineRowStopGate.d.ts +0 -20
- package/dist/subagent/engineRowStopGate.js +0 -49
- package/dist/subagent/engineSubagentOutput.d.ts +0 -7
- package/dist/subagent/engineSubagentOutput.js +1 -51
- package/dist/subagent/engineSubagentResume.d.ts +2 -279
- package/dist/subagent/engineSubagentResume.js +2 -129
- package/dist/subagent/engineSubagentSteer.d.ts +0 -26
- package/dist/subagent/engineSubagentSteer.js +0 -63
- package/dist/subagent/engineSubagentTail.d.ts +0 -38
- package/dist/subagent/engineSubagentTail.js +2 -110
- package/dist/subagent/engineTaskHandleWire.d.ts +11 -65
- package/dist/subagent/engineTaskHandleWire.js +20 -131
- package/dist/subagent/subagentOwnerAbsence.d.ts +0 -2
- package/dist/subagent/subagentOwnerAbsence.js +0 -25
- package/dist/subagentContentStore.d.ts +3 -260
- package/dist/subagentContentStore.js +7 -540
- package/dist/systemReminderTag.d.ts +0 -49
- package/dist/systemReminderTag.js +0 -61
- package/dist/toolResult.d.ts +1 -211
- package/dist/toolResult.js +1 -358
- package/dist/toolRoster.d.ts +0 -140
- package/dist/toolRoster.js +0 -66
- package/dist/typePins.d.ts +0 -46
- package/dist/types/engineState.d.ts +0 -71
- package/dist/types/engineState.js +0 -16
- package/dist/ultracodeWireCaps.d.ts +0 -75
- package/dist/ultracodeWireCaps.js +0 -92
- package/dist/unrefTimer.d.ts +0 -27
- package/dist/webSearchBackendCapability.d.ts +0 -72
- package/dist/webSearchBackendCapability.js +0 -79
- package/dist/webSearchWireCaps.d.ts +0 -37
- package/dist/webSearchWireCaps.js +0 -34
- package/dist/websearch/searchProviderPresets.d.ts +0 -81
- package/dist/websearch/searchProviderPresets.js +0 -27
- package/dist/wireErrorTriage.d.ts +4 -160
- package/dist/wireErrorTriage.js +0 -171
- package/dist/wireRefusalCopy.d.ts +0 -28
- package/dist/wireRefusalCopy.js +0 -28
- package/dist/workflow.d.ts +0 -40
- package/dist/workflow.js +0 -52
- package/dist/workflowClient.d.ts +0 -122
- package/dist/workflowClient.js +8 -360
- package/dist/workflowMonitor.d.ts +2 -72
- package/dist/workflowMonitor.js +0 -26
- package/dist/writeProtectionCapability.d.ts +0 -112
- package/dist/writeProtectionCapability.js +0 -109
- package/docs/INTEGRATION-CLIENTS.md +62 -1
- package/package.json +1 -1
package/dist/hitl/frameRouter.js
CHANGED
|
@@ -2,59 +2,15 @@ import { hostLog } from '../host.js';
|
|
|
2
2
|
import { isToolApprovalGate, toolNameIsFsWrite, toolNameIsShellExec, isToolApprovalFrame, isFromSubagent, surfaceToolApprovalFrameAndRespond, } from './toolApprovalWire.js';
|
|
3
3
|
import { classifierDenyFromToolEnd } from '../classifierVerdictWire.js';
|
|
4
4
|
import { GATE_PARKED_ERROR_CODE } from '../engineErrorCodes.js';
|
|
5
|
-
// 0.60.0(engine ≥7.64.0 / sdk 8.4.0):终局/park 读数的单一读器(两代字节 → 一个带标因由)。
|
|
6
5
|
import { readRunTerminal, runTerminalCode, runTerminalGateKind, runTerminalGateToolName } from '../runTerminal.js';
|
|
7
6
|
import { surfaceForCurrentSession } from './hitlHostSurface.js';
|
|
8
|
-
/**
|
|
9
|
-
* CC `utils/messages.ts` 的 `REJECT_MESSAGE` **逐字**(B7 搬迁差分 2)。deny 后重放 tool_end 的
|
|
10
|
-
* render 面 stamp 用 —— vendored `renderToolUseRejectedMessage` 渲 `User rejected <op> to <path>`。
|
|
11
|
-
* 🔴 pure 门 B7 段:包内冻结字面量(无条件)+ 壳树全树扫描「每一处声明都逐字节相同」(壳树缺席=跳过)。
|
|
12
|
-
*/
|
|
13
7
|
export const HITL_REJECT_MESSAGE = "The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed.";
|
|
14
8
|
function rejectMessageForRender() {
|
|
15
9
|
return HITL_REJECT_MESSAGE;
|
|
16
10
|
}
|
|
17
|
-
/**
|
|
18
|
-
* CC `utils/messages.ts` 的 `INTERRUPT_MESSAGE_FOR_TOOL_USE` **逐字**(件 B,#323 症状②,2026-08-25)。
|
|
19
|
-
*
|
|
20
|
-
* 🔴 CC 语料直证的两条事实(壳侧勘察,cli `src/utils/messages.ts:216-217` 逐字节同):
|
|
21
|
-
* ① `"Operation aborted"` 在 CC 只在 transport 层 throw,**从不上屏** —— 它是我们这条引擎链
|
|
22
|
-
* 特有的产物,渲成红 `Error: Operation aborted` 是 CC 里根本不存在的形;
|
|
23
|
-
* ② CC 的**唯一**中断呈现形就是本串:壳的 `UserToolErrorMessage` 对
|
|
24
|
-
* `content.includes(INTERRUPT_MESSAGE_FOR_TOOL_USE)` 渲 dim `Interrupted`(CC 2.1.223 逐字判据)。
|
|
25
|
-
* ⇒ 用户中断批的 tool_result 文案在**呈现向**归一到本串,三端就天然拿到 CC 的 Interrupted 形,
|
|
26
|
-
* 不必各自再抄一份「Operation aborted 也算中断」的手工判据(那正是漂移温床)。
|
|
27
|
-
* 🔴 **呈现向,不是模型面**:本包这条链是转录/渲染链;喂回模型的那一份由引擎自己的 wire 承载,
|
|
28
|
-
* 这里一个字节都不碰它。
|
|
29
|
-
*/
|
|
30
11
|
export const HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE = '[Request interrupted by user for tool use]';
|
|
31
|
-
/**
|
|
32
|
-
* run 被**取消**的终态短码(server cancel settle 契约:`runs.cancel` → run SETTLES to `failed` +
|
|
33
|
-
* `errorCode:"cancelled"`;成文见本包 `controlRouter.ts` cancel 段与 `docs/INTEGRATION-CLIENTS.md`
|
|
34
|
-
* 的 cancel/deny 对照行 ——「ack 带 `errorCode:"cancelled"`」)。
|
|
35
|
-
*/
|
|
36
12
|
const RUN_CANCELLED_ERROR_CODE = 'cancelled';
|
|
37
|
-
/**
|
|
38
|
-
* core 对**被 gate park 的那个 call**(gate 主角)铸的 tool_end 载体(逐字;desktop session-host
|
|
39
|
-
* 真引擎实测同款)。HOLD 谓词锚它做**精确等值** —— 普通工具错的输出是各自的错误文案,永不进 HOLD。
|
|
40
|
-
*
|
|
41
|
-
* 🔴 **勘误(件⑤,2026-08-22,[4970] 真机取证)**:此处原话是「core 对被 gate/**连坐** abort 的
|
|
42
|
-
* call **恒**铸这一串」——对连坐的旁观者**不成立**。core 5.52.0 dist 直证两个短路点两种文案:
|
|
43
|
-
* gate 主角走 abort 早退 = 本串;**执行前被连坐**的旁观者 = `"operation aborted before execution"`
|
|
44
|
-
* (小写 + 后缀)。所以本串只是判据的**兜底臂**(旧 core 唯一的信号),主锚是机读码
|
|
45
|
-
* `gate.parked`——见 {@link isEngineAbortToolEnd}。
|
|
46
|
-
*/
|
|
47
13
|
export const ENGINE_ABORT_TOOL_RESULT = 'Operation aborted';
|
|
48
|
-
/**
|
|
49
|
-
* tool_end.output 的文本归一(P0 案B,2026-08-03,server 6.0.0 wire 实测):sync leg 的毒化帧
|
|
50
|
-
* `output` 不再是裸 string,而是 content-block 数组 `[{"type":"text","text":"Operation aborted"}]`
|
|
51
|
-
* (8790 裸引擎 POST /v1/tasks/stream 逐帧记录字节形)。abort 标记的**等值锚**必须先归一再比,
|
|
52
|
-
* 否则 6.0.0 下 hold-poison 臂全盲:毒化帧当场上屏 + generic-close 记 ended ⇒ decide 后重放的
|
|
53
|
-
* 真收口帧被 isEnded 早退去重 —— 「按 Yes 屏幕永远停在 Error: Operation aborted」整案复发。
|
|
54
|
-
* 只归一**判定**,帧本身一个字节不改;等值语义不放宽([2084]①-b 收窄仍然成立,负控见 gate ⑩)。
|
|
55
|
-
* 🆕 [C93] 公面导出(0.17.1):web/desktop 被点名「两端务必接」的同款归一各自手抄=漂移温床,
|
|
56
|
-
* 导出做单一真源;签名不变,加导出=additive。
|
|
57
|
-
*/
|
|
58
14
|
export function toolEndOutputText(output) {
|
|
59
15
|
if (typeof output === 'string')
|
|
60
16
|
return output;
|
|
@@ -68,38 +24,12 @@ export function toolEndOutputText(output) {
|
|
|
68
24
|
}
|
|
69
25
|
return parts.length > 0 ? parts.join('') : undefined;
|
|
70
26
|
}
|
|
71
|
-
// ── gate 词汇(两把刀共享)──────────────────────────────────────────────────────────────────────
|
|
72
|
-
/** 工具名是不是 AskUserQuestion(空白/下划线/连字符与大小写都不敏感)。
|
|
73
|
-
* **宽口**:帧上的 `toolName` 位是 UNTRUSTED 的任意值,判据自己吃 `unknown`,本模块内部用。 */
|
|
74
27
|
function isAskToolLoose(name) {
|
|
75
28
|
return typeof name === 'string' && name.replace(/[\s_-]+/g, '').toLowerCase() === 'askuserquestion';
|
|
76
29
|
}
|
|
77
|
-
/** 上者的**窄口**(`findPendingForTask` 的 gate 过滤谓词签名)—— 出境的那一版不吃 `unknown`:
|
|
78
|
-
* 边界层的 unknown 在本模块里窄化完再跨模块(typeshape 门 B2 的纪律)。 */
|
|
79
30
|
export function isAskTool(toolName) {
|
|
80
31
|
return isAskToolLoose(toolName);
|
|
81
32
|
}
|
|
82
|
-
/**
|
|
83
|
-
* 「这个**工具名**归 gate 管」的判据(#110 修,2026-08-02)。
|
|
84
|
-
*
|
|
85
|
-
* ⚠️ 它只是 park 判定的**名字腿**对位件,不是全部 —— park 判定 `isToolApprovalGate` 还有一条
|
|
86
|
-
* 一等 kind 腿(`gate.kind==='tool_approval'`,放行任意 toolName),名字面上没有对位物。
|
|
87
|
-
* tool_end 手柄用的是下面的 `isGatedToolEnd`(名字腿 ∪ abort 标记腿),两者的集合关系与理由
|
|
88
|
-
* 写在那个函数的头注里([2393] hitl-F1)。本函数还被 `routeToolStart` 用来决定「要不要记 args /
|
|
89
|
-
* 要不要跟 `lastFsOrShellGatedCallId`」,那两件事本来就只对名字识别得出的族成立。
|
|
90
|
-
*
|
|
91
|
-
* 🔴 它必须与 park 判定的**名字腿**(`isAskTool` / `toolNameIsFsWrite` / `toolNameIsShellExec`)
|
|
92
|
-
* 覆盖同一个集合 —— 两边不同集就是 [paired-mechanisms-must-share-premise] 那种「park 认得出、
|
|
93
|
-
* HOLD 认不出」的半场病:[2150] S1 给 park 判定加了 `toolNameIsShellExec`(Bash/shell 类进 gate 了),但
|
|
94
|
-
* tool_end 手柄的 HOLD/REJECT 谓词还停在 `isAskTool || toolNameIsFsWrite` ——
|
|
95
|
-
* 于是 Bash 的 durable gate 走到这里就两件事同时出错:
|
|
96
|
-
* ① park 期的毒化帧(`tool_end{isError:true, output:"Operation aborted"}`)没被 HOLD,
|
|
97
|
-
* **当场上屏**;用户按了 Yes、命令也真跑了,屏幕上却永远停在 `Error: Operation aborted`;
|
|
98
|
-
* ② 更狠的是紧接着的 `markEnded(toolCallId)` —— resume 后引擎重放的**真** tool_end
|
|
99
|
-
* 被手柄开头的 `isEnded` 早退静默去重,真结果一帧都上不了屏。
|
|
100
|
-
* 附带第三件:deny 腿的 `User rejected …` 文案对 Bash 同样进不去,用户看到的是引擎原文。
|
|
101
|
-
* 证据链见 cli 仓 design/cli-164 T4-A(硬 oracle=磁盘状态:按 Yes 后 printf +504ms 真落盘)。
|
|
102
|
-
*/
|
|
103
33
|
function isGatedToolName(name) {
|
|
104
34
|
if (isAskToolLoose(name))
|
|
105
35
|
return true;
|
|
@@ -107,130 +37,25 @@ function isGatedToolName(name) {
|
|
|
107
37
|
return false;
|
|
108
38
|
return toolNameIsFsWrite(name) || toolNameIsShellExec(name);
|
|
109
39
|
}
|
|
110
|
-
/** 这个 gate 的**主角属 fs 写 / shell 执行族**吗(`gateLedger.noteParkGate` 的准入判据)。
|
|
111
|
-
* 🔴 主语是 **gate 本体**的 toolName(park 的 `checkpointGate`/`gate`),不是某张 tool_end
|
|
112
|
-
* 帧的 —— 拿「本 turn 有哪些 gate-capable 工具」当准入证正是 v1 名字锚那条病的同形残留。 */
|
|
113
40
|
function isFsOrShellToolName(name) {
|
|
114
41
|
return typeof name === 'string' && (toolNameIsFsWrite(name) || toolNameIsShellExec(name));
|
|
115
42
|
}
|
|
116
|
-
/**
|
|
117
|
-
* core 对**因 gate park 而中止**的 call 铸的机读短码(`tool_end.errorCode`,core ≥5.9.0)。
|
|
118
|
-
*
|
|
119
|
-
* 🔴 **契约,不是巧合**(core 官方答复 [4973]):两个 abort 短路点(gate 主角 / 执行前被连坐的
|
|
120
|
-
* 旁观者)**消费同一个分类席**,而 park 提交**先于** abort 发射 —— 铸点读那一席时无竞态,
|
|
121
|
-
* 于是主角与旁观者**恒**同席同码。所以本码可以当**主锚**用,而不是「我们在消费侧观察到它总在」
|
|
122
|
-
* 那种推断。SDK 的 `Event_tool_end.errorCode` 声明处也逐字点名这个码 =「门把这次调用 park 了」;
|
|
123
|
-
* 供给点见 core 5.52.0 dist `prepare-task` 的 `abortResultDetails: () => ({ code: "gate.parked" })`。
|
|
124
|
-
*
|
|
125
|
-
* 🔴 开集里的**具名一员**,不是前缀族:判据只认这一个码。放宽成「有 errorCode 就算」会把
|
|
126
|
-
* `path_not_in_root` 这类普通工具错拖进 HOLD —— 那正是 [2084]①-b 收窄掉的病(真错迟到上屏)。
|
|
127
|
-
* 常驻反证:hitl 门 F11-d(表外码的普通工具错必须**零滞后**上屏,判据锚在帧的**位置**上)。
|
|
128
|
-
*
|
|
129
|
-
* 🔴 **在场 ≠ 这次 park 有 call 身份**([4973]③):plan-review / resource-slice 这类不持有 call
|
|
130
|
-
* 的 park 照样带本码,但诚实缺席 call id。所以本判据只锚 errorCode,**不**顺手去锚任何 id —— 锚了
|
|
131
|
-
* 就等于把那几族 park 的连坐帧判成「认不出」。(core 5.55 的 `tool_end.gatedCallId` **顶层键**
|
|
132
|
-
* 到货后可用于「折叠归组」那一面,与本判据是两件事,跟车另批。)
|
|
133
|
-
*/
|
|
134
|
-
// 🔴 **单源**(0.60.0):字面量收编进 `engineErrorCodes.GATE_PARKED_ERROR_CODE` —— 本文件的连坐/中断
|
|
135
|
-
// 判据与 `gateOutcome.isGateParkedToolEnd`(端的「这次调用没在这里结算」第二形谓词)读同一个常量。
|
|
136
|
-
// 两处各写一份必漂,而漂的那一天两边会对同一帧给出相反的判决。
|
|
137
43
|
const ENGINE_GATE_PARKED_ERROR_CODE = GATE_PARKED_ERROR_CODE;
|
|
138
|
-
/**
|
|
139
|
-
* 「这一帧是**引擎因 gate 而中止**的毒化帧」——双判据 OR(件⑤,2026-08-22,[4970] G1 端到端 RED)。
|
|
140
|
-
*
|
|
141
|
-
* 🔴 病形(test 线真机取证:真 server 7.41.0 + 真 Postgres,1 Bash 待审批 + 2 并行 WebFetch):
|
|
142
|
-
* 判据原来只有下面第②条(精确串),而 core 的**两个短路点产两种串**——
|
|
143
|
-
* · gate 主角(`agent-loop` abort 早退,dist 两处)= `"Operation aborted"`(精确);
|
|
144
|
-
* · **同批被连坐的旁观者**(执行前短路)= `"operation aborted before execution"`(小写 + 后缀)。
|
|
145
|
-
* ⇒ 判据对旁观者**恰好全不命中**:它们的毒化帧根本没进 HOLD(当场上屏 + 被 generic-close 记
|
|
146
|
-
* `markEnded`,resume 后重放的真结果被静默去重),而 #324 的连坐机读位在真实现网**一次都没出现过**。
|
|
147
|
-
* 本文件旧注写的「core 对被 gate/连坐 abort 的 call **恒**铸这一串」对旁观者不成立,已按实证撤回。
|
|
148
|
-
*
|
|
149
|
-
* 两臂各自的适用域(都**不**放宽成模糊匹配):
|
|
150
|
-
* ① **主锚** `errorCode === "gate.parked"`([4973] 契约:双短路点同席恒铸)—— 机读位,
|
|
151
|
-
* 两种文案都覆盖,core ≥5.9.0 起在场;
|
|
152
|
-
* ② **兜底** 输出等于 {@link ENGINE_ABORT_TOOL_RESULT} —— 覆盖两类:老 core(还没有 errorCode
|
|
153
|
-
* 这个位)**以及** core 现役唯一**不铸**本码的那一条臂 —— **post-hook signal re-check**
|
|
154
|
-
* ([4973]②:工具**已经执行完**、hook 之后签核那一拍才发现 abort,历来铸的 abort 结果
|
|
155
|
-
* 不带 details ⇒ 无 errorCode)。这条臂正是双判据设计成立的理由:少了兜底臂,它整条落空。
|
|
156
|
-
* 🔴 缺席不反推:两臂都不命中 = 这一帧没有「因 gate 中止」的任何证据,照旧走普通收口
|
|
157
|
-
* (老 core + 变体串就落在这一格 —— 诚实缺席,不靠猜文案家族把普通工具错也收进来)。
|
|
158
|
-
*
|
|
159
|
-
* 🔴 **两串族不会被上游合并**([4973],core 显式拒绝改串向,**不是**「core 待修」):两条串各自
|
|
160
|
-
* 承的是真语义 —— `"Operation aborted"` = **执行中被中止**,`"operation aborted before execution"`
|
|
161
|
-
* = **从未执行**。消费端要的是「归不归 gate 管」这个判定,那件事归机读码;文案面归 core 的语义面,
|
|
162
|
-
* 两者不该互相迁就。
|
|
163
|
-
*/
|
|
164
44
|
function isEngineAbortToolEnd(ev) {
|
|
165
45
|
if (ev.errorCode === ENGINE_GATE_PARKED_ERROR_CODE)
|
|
166
46
|
return true;
|
|
167
47
|
return toolEndOutputText(ev.output) === ENGINE_ABORT_TOOL_RESULT;
|
|
168
48
|
}
|
|
169
|
-
/**
|
|
170
|
-
* 「这一帧 tool_end 归 gate 管」的判据 —— 上面那条**名字腿**加一条 kind 腿的替身([2393] hitl-F1,
|
|
171
|
-
* 2026-08-02)。
|
|
172
|
-
*
|
|
173
|
-
* 🔴 为什么名字腿一条不够(上面那句「必须覆盖同一个集合」在 kind 腿上的反例):park 判定
|
|
174
|
-
* `isToolApprovalGate` 有**两条**腿 —— 名字族(ask / fs 写三件 / Bash)与**一等 kind**
|
|
175
|
-
* (`gate.kind === 'tool_approval'`,`toolApprovalWire.isFsApprovalGate` 首行)。后者放行**任意**
|
|
176
|
-
* toolName:server 对名单外的工具出一等 kind 审批 park 时,park 侧认、tool_end 侧的名字腿认不出,
|
|
177
|
-
* 于是 #110 那三件事在这类 gate 上原样重演一遍(毒化帧上屏 / `markEnded` 吃掉重放的真结果 /
|
|
178
|
-
* deny 的 CC 文案进不去)。
|
|
179
|
-
*
|
|
180
|
-
* 🔴 为什么不能在名字腿里补 kind:`tool_end` 帧上**根本没有 kind 位** —— gate 的 kind 只在
|
|
181
|
-
* `done{suspended}.checkpointGate` / `suspended.gate` 上,而那两帧**晚于**毒化 tool_end 到达
|
|
182
|
-
* (park 帧序:tool_start → tool_end(毒化)→ done{suspended})。「park 时按 callId 打标、
|
|
183
|
-
* tool_end 时读台账」这条路对**这一帧**来得太晚。帧面上唯一可读的信号是引擎铸的 abort 标记
|
|
184
|
-
* ({@link isEngineAbortToolEnd} 的**双判据**:机读码 `gate.parked` ∪ 那条确切串 —— 件⑤ 之前
|
|
185
|
-
* 这里只有后者,而 core 对**旁观者**铸的是另一种文案,见该函数头注),所以本判据 =
|
|
186
|
-
* 名字腿 ∪ abort 标记腿。
|
|
187
|
-
*
|
|
188
|
-
* 🔴 集合关系(说清楚,别让下一棒再以为两边逐字相等):本判据是 park 判定的**超集**(它还会盖到
|
|
189
|
-
* 被同 turn 连坐 abort 的非 gate call)。方向是有意的,且不对称成立 —— 多盖一帧的代价是那一帧
|
|
190
|
-
* **晚**上屏(HOLD 的帧在模型推进 / 终帧 / fail-soft 三处必被 flush,一帧都不会丢),而少盖一帧
|
|
191
|
-
* 的代价是用户按了 Yes 却只看到 `Error: Operation aborted`。顺带把连坐 abort 的 call 从
|
|
192
|
-
* `markEnded` 里救出来:它们本来也会在 resume 后被模型重发,而旧码已把它们记成已收口。
|
|
193
|
-
* ⚠️ 普通工具错(非 abort 标记)照旧**不进** HOLD —— [2084]①-b 的收窄没有被放宽,负控 F1-c 钉着。
|
|
194
|
-
*/
|
|
195
49
|
function isGatedToolEnd(ev) {
|
|
196
50
|
if (isGatedToolName(ev.toolName))
|
|
197
51
|
return true;
|
|
198
|
-
return isEngineAbortToolEnd(ev);
|
|
52
|
+
return isEngineAbortToolEnd(ev);
|
|
199
53
|
}
|
|
200
|
-
/**
|
|
201
|
-
* 上者的**窄口**,只给 ②`deny-stamp-next` 那条**位置性**判据用(件⑤ 的臂间掩蔽面,异源复审四审
|
|
202
|
-
* finding①)。
|
|
203
|
-
*
|
|
204
|
-
* 🔴 为什么这一条不能用超集谓词:deny stamp 是**一次性的全局记号**(同步审批帧腿 deny 且 callId
|
|
205
|
-
* 关联不上时才武装),语义是「**下一张** gated 报错帧就是那张门的收口帧」——**谁先到谁消费**。
|
|
206
|
-
* 件⑤ 把 abort 标记腿放宽到认 `gate.parked` 之后,同批被连坐的**旁观者**(WebFetch 之流)也成了
|
|
207
|
-
* 「gated 报错帧」:它先到就把记号吃掉、被改写成「用户拒绝了」并记 ended(它 resume 后的真结果
|
|
208
|
-
* 还会被去重),而真正被拒的那个 call 拿到的是引擎原文 —— 正是 [2393] hitl-F1 要修的那个用户面,
|
|
209
|
-
* 方向还反了。连坐帧带的是「我被 gate 连累中止」,**不是**「我就是那张被拒的门」,所以它没资格
|
|
210
|
-
* 认领一个**位置性**的身份记号。
|
|
211
|
-
* ⇒ 本判据 = 件⑤ **之前**的那一版(名字腿 ∪ 确切串),逐字保留;新加的连坐码臂**刻意不进来**。
|
|
212
|
-
* (确切串腿理论上也可能是一条正在执行中被连坐的帧 —— 那是本记号自带的既有近似,与件⑤ 无关,
|
|
213
|
-
* 不在本批放宽也不在本批收紧。)
|
|
214
|
-
*/
|
|
215
54
|
function isDenyStampCandidate(ev) {
|
|
216
55
|
if (isGatedToolName(ev.toolName))
|
|
217
56
|
return true;
|
|
218
57
|
return toolEndOutputText(ev.output) === ENGINE_ABORT_TOOL_RESULT;
|
|
219
58
|
}
|
|
220
|
-
/**
|
|
221
|
-
* done 帧的 park 门读数(0.60.0:判据从退役的 `status:"suspended"` + `checkpointGate` 两个平面键
|
|
222
|
-
* 换成带标因由 `terminal.paused` —— 读法单源 {@link readRunTerminal},本文件零平面键直读)。
|
|
223
|
-
*
|
|
224
|
-
* 🔴 两条 park 臂共用**一次**读取:此前两个谓词各自把 result 强转一遍再各判一次 `status`,
|
|
225
|
-
* 两处的窄读域一旦分叉就会出现「ask 臂认得、fs 臂认不得」的半场(paired-mechanisms 病形)。
|
|
226
|
-
* 返回 `null` = 这一帧不是 park(或连 taskId 都读不出 ⇒ 两条臂本来就都驱动不了)。
|
|
227
|
-
*
|
|
228
|
-
* ⚠️ **修前那条 `status === 'suspended'` 前置条件去哪了**(如实交代,不是漏掉):因由形下 park 只带
|
|
229
|
-
* 门,「哪个 park 读作 suspended、哪个读作 needs_review」由**引擎的 pause registry** 决定、不再
|
|
230
|
-
* 出现在这条 wire 上。而那条前置条件真正在挡的是**复核族 park**(plan_review / dry_run_review /
|
|
231
|
-
* needs_review 门)——它们本来就过不了下面两个门谓词(复核门不带 toolName,`isAskToolLoose`
|
|
232
|
-
* 与 `isToolApprovalGate` 两条都判 false)⇒ 语义由**更精确的**门种判据原样承接,不是放宽。
|
|
233
|
-
*/
|
|
234
59
|
function parkGateOf(result) {
|
|
235
60
|
const read = readRunTerminal(result);
|
|
236
61
|
if (read === null || read.kind !== 'paused')
|
|
@@ -239,62 +64,25 @@ function parkGateOf(result) {
|
|
|
239
64
|
if (typeof taskId !== 'string' || taskId.length === 0)
|
|
240
65
|
return null;
|
|
241
66
|
const toolName = runTerminalGateToolName(read);
|
|
242
|
-
// Ask gate 恒先判(问答 overlay 原路)。
|
|
243
67
|
if (isAskToolLoose(toolName))
|
|
244
68
|
return { taskId, gate: 'ask', toolName };
|
|
245
|
-
// 工具审批 park([816] 放宽腿 + [2150] Bash 半场):门指 fs 写三件 / Bash / 一等
|
|
246
|
-
// kind==='tool_approval'(超集谓词 isToolApprovalGate,decide 腿对两族同构、卡形归壳分发)。
|
|
247
69
|
if (isToolApprovalGate({ kind: runTerminalGateKind(read), toolName }))
|
|
248
70
|
return { taskId, gate: 'fs', toolName };
|
|
249
71
|
return null;
|
|
250
72
|
}
|
|
251
|
-
/**
|
|
252
|
-
* park 帧上的**待批 call 身份**(server ≥7.41.0;[4914] 施工帖逐字:数据源 = checkpoint 本体的
|
|
253
|
-
* `pendingAction.toolCallId`,投影到 **`done{suspended}` 的 result 顶层**与 durable **`suspended`
|
|
254
|
-
* 事件**的 `gate` **旁**,两处同键同义)。两个 park 腿各读各的载体,判据是同一只。
|
|
255
|
-
*
|
|
256
|
-
* 🔴 UNTRUSTED wire 值:只认**非空串**,其余(缺席 / 非串 / 空串)一律诚实缺席 —— tool-less park
|
|
257
|
-
* (resource_limit / plan_review / task_done)按契约本来就没有这个键,而一个坏值被当成身份用
|
|
258
|
-
* 会去摘一条不存在的扣留帧(等于什么都没摘,但把「判不出」的保守臂骗过去了)。
|
|
259
|
-
*/
|
|
260
73
|
function parkGatedCallId(src) {
|
|
261
74
|
const v = src?.toolCallId;
|
|
262
75
|
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
263
76
|
}
|
|
264
|
-
/** 台账里那份 gated `tool_start` 当拍的 args 快照(UNTRUSTED,只搬运不解释)。 */
|
|
265
77
|
function argsOfGatedStart(led, callId) {
|
|
266
78
|
if (callId === undefined)
|
|
267
79
|
return undefined;
|
|
268
80
|
return led.gatedStartArgs().get(callId);
|
|
269
81
|
}
|
|
270
|
-
// ── [2084]① 扣留帧「模型推进即放行」(2026-07-30;同日 web 复审纠偏收窄触发集)────────────────
|
|
271
|
-
//
|
|
272
|
-
// HOLD 只护 park 窗口。放行触发集 = host-lane **模型推进**帧:text_delta/reasoning_delta/
|
|
273
|
-
// tool_start —— park 路径上这三种在 done{suspended} 之前不会出现,真错路径上下一轮必来其一。
|
|
274
|
-
// 🔴 turn_end 明确**不在**触发集(初版在,web 复审真机轨迹逮红):core agent-loop 的 turn_end
|
|
275
|
-
// emit 在 executeToolCalls 之后**无 abort/suspend 守卫**(邻臂都有,唯此一处没有)⇒ 真 park
|
|
276
|
-
// 的帧序是 tool_end(毒化)→ message_committed → turn_end → done{suspended},turn_end 若放行
|
|
277
|
-
// 会把毒化帧漏上屏,且 flushHeld 的 ended 记账让 decide 后重放的解答帧被当已收口丢弃
|
|
278
|
-
// (真实答案卡永不出现)。代价 = turn 末尾无后续推进帧的 abort 形帧等到终帧 flush,与修前同。
|
|
279
|
-
// parentToolCallId 在场 = sub-agent 行帧,park 期间孙代照常说话,不算 host 推进(负控①C)。
|
|
280
|
-
// (普通工具错自 [2084]①-b 谓词收窄后根本不进 HOLD,零滞后不依赖本触发集。)
|
|
281
|
-
/** 这一帧是不是「host lane 的模型推进」= 扣留帧的放行信号。 */
|
|
282
82
|
export function isHostProgressFrame(ev) {
|
|
283
83
|
return ((ev.type === 'text_delta' || ev.type === 'reasoning_delta' || ev.type === 'tool_start') &&
|
|
284
84
|
ev.parentToolCallId === undefined);
|
|
285
85
|
}
|
|
286
|
-
// ── 件 B(#323 症状②):用户中断批的呈现向文案归一 ────────────────────────────────────────────
|
|
287
|
-
/**
|
|
288
|
-
* 这次 flush 的**出口**带不带「用户要停」的证据。两条腿各自是**结构事实**,都不是猜:
|
|
289
|
-
* ① **wire 终帧腿**:`failed.errorCode === "cancelled"`(server cancel settle 契约)/ durable 腿
|
|
290
|
-
* 同码骑在 `done.result.errorCode` 上(终态投影表 `terminalToSdkResult` 头注的同一格)。
|
|
291
|
-
* 壳侧实证:Esc 的默认臂之外还有一发 best-effort `POST /v1/runs/:id/cancel`,run 就是这么
|
|
292
|
-
* 结算的 —— 所以「这一批 abort 帧属于一次取消」在 wire 上有据可查。
|
|
293
|
-
* ② **宿主腿**:`ctx.signal.aborted`。这个 signal 是宿主的 turn 中断信号,壳侧唯一 abort 源是
|
|
294
|
-
* 用户按 Esc(`abortController.abort('user-cancel')`),web/desktop 同位。它是**宿主事实**
|
|
295
|
-
* 而非帧事实,所以只在**收口出口**读(源流已经走完/终帧已到),不在流中途读。
|
|
296
|
-
* 🔴 两腿都不命中 ⇒ 没有中断证据 ⇒ 文案一个字节不改(诚实缺席,不靠猜)。
|
|
297
|
-
*/
|
|
298
86
|
function isUserInterruptTerminalOrSignal(ev, signal) {
|
|
299
87
|
if (signal?.aborted === true)
|
|
300
88
|
return true;
|
|
@@ -304,23 +92,10 @@ function isUserInterruptTerminalOrSignal(ev, signal) {
|
|
|
304
92
|
return ev.errorCode === RUN_CANCELLED_ERROR_CODE;
|
|
305
93
|
}
|
|
306
94
|
if (ev.type === 'done') {
|
|
307
|
-
// 0.60.0:cancel settle 的码在因由形下**结构上属于失败臂**(`terminal.failed.code`);扁平形
|
|
308
|
-
// 回放的历史行仍把它平铺在 `errorCode` 上 —— 两代都由 `runTerminalCode` 归一。
|
|
309
95
|
return runTerminalCode(readRunTerminal(ev.result)) === RUN_CANCELLED_ERROR_CODE;
|
|
310
96
|
}
|
|
311
97
|
return false;
|
|
312
98
|
}
|
|
313
|
-
/**
|
|
314
|
-
* 呈现向改写的**帧级**准入(与出口级证据合取)。三条,全是不放宽的精确判据:
|
|
315
|
-
* ① 文案**精确等于** {@link ENGINE_ABORT_TOOL_RESULT}(6.0.0 的块数组形先经 `toolEndOutputText`
|
|
316
|
-
* 归一)—— `"operation aborted before execution"`(连坐旁观者:从未执行)与
|
|
317
|
-
* `interrupted_never_started` 族**刻意不进本臂**:core 显式拒绝合并两串向([4973]),
|
|
318
|
-
* 两串各承真语义,它们各自的文案/折叠语义已在别处成立,并进来 = 把两个语义压成一个。
|
|
319
|
-
* ② `errorCode !== "gate.parked"`:机读位在场时,**门语义帧一票否决** —— 那是「门把这次调用
|
|
320
|
-
* park 了」,不是「用户按了 Esc」。⚠️ 这一票**只在 ①/② 两腿证据下投**:见
|
|
321
|
-
* `allowGateParked` 与 {@link flushHeldWithInterruptRewrite} 头注的两模判词。
|
|
322
|
-
* ③ `isError === true`:呈现向的中断形长在报错卡那一路(壳 `UserToolErrorMessage` 的判据位)。
|
|
323
|
-
*/
|
|
324
99
|
function isUserInterruptRewritable(ev, allowGateParked) {
|
|
325
100
|
if (ev.isError !== true)
|
|
326
101
|
return false;
|
|
@@ -329,30 +104,7 @@ function isUserInterruptRewritable(ev, allowGateParked) {
|
|
|
329
104
|
}
|
|
330
105
|
return toolEndOutputText(ev.output) === ENGINE_ABORT_TOOL_RESULT;
|
|
331
106
|
}
|
|
332
|
-
/**
|
|
333
|
-
* `led.flushHeld()` 的**唯一**排水出口包装:用户中断批把毒化帧的 `output` 归一成 CC 的中断形
|
|
334
|
-
* ({@link HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE}),其余一切原样。
|
|
335
|
-
*
|
|
336
|
-
* ── 判词(两模,别合并;方向一律 fail-safe:证据不足就走原路)──────────────────────────────
|
|
337
|
-
* · **模 A —— 纯用户中断批**(证据 = cancel 终帧码 / 宿主 `signal.aborted`):要求 **本批零 park
|
|
338
|
-
* 登记**(`hasBatchPark() === false`),且帧上 `errorCode !== "gate.parked"`。两道门都是同一件事
|
|
339
|
-
* 的两个面 ——「这一批背后没有任何门」才谈得上纯中断;有门而我们只看见 abort 帧 = 判不出,不改。
|
|
340
|
-
* · **模 B —— 门被用户中断**(证据 = {@link HeldFlushInterruptEvidence.gateAbortedByUser}):
|
|
341
|
-
* park 在场是**前提**而不是障碍,所以模 A 的两道门在这一模下**都让位** —— 包括
|
|
342
|
-
* `gate.parked` 那一票。理由:该码回答的是「这次调用为什么中止 =被门 park 了」,回答不了
|
|
343
|
-
* 「这一批为什么收场 = 用户按了 Esc」,两者正交;拿它做否决会把这一格里**最该显形的那张
|
|
344
|
-
* 主角卡**留成红 `Error: Operation aborted`(真机复现:审批卡挂着按 Esc,主角与连坐帧同文案)。
|
|
345
|
-
* 🔴 **gate deny 语义零变**:deny 走的是 `decided` 分支(→ 续流重放 → `denied-call`/`deny-stamp-next`
|
|
346
|
-
* 两臂 stamp CC REJECT 文案),那两臂排在 hold-poison **之前**、帧根本不进扣留表,本包装够不着。
|
|
347
|
-
* fail-soft 的其余原因(no_pending / 传输失败 / hop 用尽)三腿全不命中 ⇒ 诚实红照旧。
|
|
348
|
-
*
|
|
349
|
-
* 🔴 **只改 `output` 一个键**:`isError` / `errorCode` / `toolCallId` / `toolName` / `gate` /
|
|
350
|
-
* `delivered` / `gatedCallId` / `structured` 以及 `flushHeld` 自己盖的
|
|
351
|
-
* `_sema_collateral_abort` 机读位全部原样过境(展开赋值只覆盖 `output`)—— 端侧的连坐折叠锚的是
|
|
352
|
-
* 机读位不是文案,所以折叠语义不受影响,只是被折那一行的正文换成了 CC 中断形。
|
|
353
|
-
*/
|
|
354
107
|
export function* flushHeldWithInterruptRewrite(led, evidence) {
|
|
355
|
-
// 🔴 读位必须在 flushHeld **之前**求值:那一拍尾部 `retireBatchState()` 会把批级计数清零。
|
|
356
108
|
const gateAborted = evidence.gateAbortedByUser === true;
|
|
357
109
|
const rewrite = gateAborted
|
|
358
110
|
? true
|
|
@@ -365,11 +117,6 @@ export function* flushHeldWithInterruptRewrite(led, evidence) {
|
|
|
365
117
|
yield { ...ev, output: HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE };
|
|
366
118
|
}
|
|
367
119
|
}
|
|
368
|
-
/**
|
|
369
|
-
* 🔴 **有序**(承重):分类器批3([907])的注释原文 = 「结构性识别(core 机器签名)优先于 fs
|
|
370
|
-
* HOLD/REJECT 分支(签名比"fs 写报错"更特定;分类器 deny 从不产 tool_approval 帧,denied /
|
|
371
|
-
* denyStamp 与之互斥)」。顺序作为数据写在这里,下方加载期断言把它与 `TOOL_END_ARMS` 钉死。
|
|
372
|
-
*/
|
|
373
120
|
const TOOL_END_ARM_ORDER = [
|
|
374
121
|
'classifier-deny',
|
|
375
122
|
'deny-stamp-next',
|
|
@@ -377,15 +124,8 @@ const TOOL_END_ARM_ORDER = [
|
|
|
377
124
|
'hold-poison',
|
|
378
125
|
'generic-close',
|
|
379
126
|
];
|
|
380
|
-
/**
|
|
381
|
-
* tool_end 的**有序**臂表:自上而下第一个返回动作的臂胜出。顺序 = 原文 5 条分支的书写顺序,
|
|
382
|
-
* 由 `TOOL_END_ARM_ORDER` + 下方加载期断言锁死(改这张表的顺序必须同批改那张表)。
|
|
383
|
-
* 🔴 表尾 `generic-close` 是**无条件**兜底臂 —— 给它加早退条件 = tool_end 会被整帧静默丢弃。
|
|
384
|
-
*/
|
|
385
127
|
const TOOL_END_ARMS = [
|
|
386
128
|
{
|
|
387
|
-
// ① 分类器 deny 裁决帧:副作用 = CC 207 通知行 + Recent Denials 记账;render 面 stamp 去
|
|
388
|
-
// system-reminder 包裹渲裁决原文(render-only,模型面原文不动)。
|
|
389
129
|
id: 'classifier-deny',
|
|
390
130
|
run(ev, callId, led) {
|
|
391
131
|
if (ev.isError !== true || led.isDenied(callId))
|
|
@@ -395,14 +135,6 @@ const TOOL_END_ARMS = [
|
|
|
395
135
|
return undefined;
|
|
396
136
|
led.markEnded(callId);
|
|
397
137
|
led.dropHeld(callId);
|
|
398
|
-
// L-69⑨(0.52.0):把**这一只 call 的现场**一并交给宿主 —— 修前只给 `toolName`,于是端的
|
|
399
|
-
// Recent Denials 三行同名(三条被拒的 Bash 一个样)、retry 粒度只能落到「整个工具」。
|
|
400
|
-
// 🔴 args 是 **UNTRUSTED** wire 值:本层原样搬运(不渲不截不消毒),展示消毒归端。
|
|
401
|
-
// 🔴 args 取自**在飞表**(`noteStart`,每张 tool_start 都记、有界、收口即删)——`gatedStartArgs`
|
|
402
|
-
// 在这里读不到:分类器 deny 的工具通常**没被 gate**(引擎侧分类器直接 block,一张
|
|
403
|
-
// tool_approval 帧都不出),那张表里根本没有它。
|
|
404
|
-
// 🔴 缺席不铸键(`exactOptionalPropertyTypes`):台账里没有 ⇒ `ctx` 只带 `toolCallId`,
|
|
405
|
-
// 端读到的是诚实缺席,不是「args 是 undefined」。
|
|
406
138
|
const startArgs = led.startArgs().get(callId);
|
|
407
139
|
surfaceForCurrentSession()?.surfaceClassifierDeny(typeof ev.toolName === 'string' ? ev.toolName : 'tool', verdict, { toolCallId: callId, ...(startArgs !== undefined ? { args: startArgs } : {}) });
|
|
408
140
|
hostLog('debug', `liveHitlAskWire: classifier deny verdict on ${callId} (${String(ev.toolName)}) — labeled render + notice`);
|
|
@@ -410,14 +142,8 @@ const TOOL_END_ARMS = [
|
|
|
410
142
|
},
|
|
411
143
|
},
|
|
412
144
|
{
|
|
413
|
-
// ② 同步帧腿 deny 且 callId 没关联上:下一张 gated 报错帧即该 gate 的收口帧,stamp REJECT 文案。
|
|
414
|
-
// #110:stamp 也要盖 shell —— 否则按 No 时用户看到的是引擎原文 `Operation aborted`。
|
|
415
|
-
// [2393] hitl-F1:改用 `isGatedToolEnd`(名字腿 ∪ abort 标记腿)—— 一等 kind gate 的
|
|
416
|
-
// 收口帧名字腿认不出,不盖它 = 用户按了 No 却看到引擎原文。
|
|
417
145
|
id: 'deny-stamp-next',
|
|
418
146
|
run(ev, callId, led) {
|
|
419
|
-
// 🔴 窄口(件⑤/四审 finding①):这条记号是**一次性 + 位置性**的,超集谓词会让连坐旁观者
|
|
420
|
-
// 抢走它 —— 理由见 `isDenyStampCandidate` 头注。
|
|
421
147
|
if (ev.isError !== true || !isDenyStampCandidate(ev) || led.isDenied(callId))
|
|
422
148
|
return undefined;
|
|
423
149
|
if (!led.takeDenyStamp())
|
|
@@ -428,7 +154,6 @@ const TOOL_END_ARMS = [
|
|
|
428
154
|
},
|
|
429
155
|
},
|
|
430
156
|
{
|
|
431
|
-
// ③ 三选卡 No:重放的报错帧 stamp REJECT 文案 → vendored 卡渲 `User rejected <op> to <path>`。
|
|
432
157
|
id: 'denied-call',
|
|
433
158
|
run(ev, callId, led) {
|
|
434
159
|
if (ev.isError !== true || !isGatedToolEnd(ev))
|
|
@@ -441,33 +166,17 @@ const TOOL_END_ARMS = [
|
|
|
441
166
|
},
|
|
442
167
|
},
|
|
443
168
|
{
|
|
444
|
-
// ④ [2084]①-b HOLD 谓词收窄(2026-07-30,desktop 复审建议采纳):park 毒化帧的载体是**确切的
|
|
445
|
-
// 引擎 abort 标记**(core 对被 gate/连坐 abort 的 call 铸 `tool_end{isError:true,
|
|
446
|
-
// output:"Operation aborted"}`;desktop session-host 2026-07-29 对真引擎实测同款)。普通
|
|
447
|
-
// 工具错(old_string 不命中/read-gate 拒绝…)输出是各自的错误文案,**根本不该进 HOLD**
|
|
448
|
-
// —— 收窄后它们零滞后直达转录(落到 ⑤ 通用收口),不再依赖「推进信号放行」。
|
|
449
169
|
id: 'hold-poison',
|
|
450
170
|
run(ev, callId, led) {
|
|
451
171
|
if (ev.isError !== true || !isGatedToolEnd(ev))
|
|
452
172
|
return undefined;
|
|
453
|
-
// 件⑤(2026-08-22,[4970] 真机 RED):判据 = `isEngineAbortToolEnd` 的**双判据**(机读码
|
|
454
|
-
// `gate.parked` ∪ 那条确切串)。此前只有后者,而 core 对**被连坐的旁观者**铸的是
|
|
455
|
-
// `"operation aborted before execution"` —— 于是连坐帧恰好全不进 HOLD(当场上屏 + 被 ⑤ 臂
|
|
456
|
-
// 记 ended 吃掉重放的真结果),#324 的机读位在现网一次都没出现过。适用域与不放宽的理由
|
|
457
|
-
// 见该函数头注;6.0.0 wire 的 content-block 数组形由 `toolEndOutputText` 归一后仍做精确等值。
|
|
458
173
|
if (!isEngineAbortToolEnd(ev))
|
|
459
174
|
return undefined;
|
|
460
|
-
// #324 换锚(2026-08-22):这一拍**不判出身**。durable park 腿的帧序是
|
|
461
|
-
// `tool_start → tool_end(毒化) → done{suspended}` —— gate 身份晚于本帧到达,此刻任何判词
|
|
462
|
-
// 都是猜的(名字腿猜法被双向证伪:一等 kind gate 的主角判成连坐、同族兄弟两个都判成主角)。
|
|
463
|
-
// 出身改在 `flushHeld` 当拍按**已登记的主角身份**求值,判据供给见 `gateLedger.noteGateSubject`。
|
|
464
175
|
led.hold(callId, ev);
|
|
465
|
-
return { kind: 'skip' };
|
|
176
|
+
return { kind: 'skip' };
|
|
466
177
|
},
|
|
467
178
|
},
|
|
468
179
|
{
|
|
469
|
-
// ⑤ 通用收口(**无条件命中**,兜底臂):正常收口(重放的 isError:false 解答帧)赢;已作答的
|
|
470
|
-
// gate 在这里把真实答案 stamp 回 `structured`,否则卡片渲成结果不可用。
|
|
471
180
|
id: 'generic-close',
|
|
472
181
|
run(ev, callId, led) {
|
|
473
182
|
led.markEnded(callId);
|
|
@@ -475,15 +184,12 @@ const TOOL_END_ARMS = [
|
|
|
475
184
|
const answered = led.answerFor(callId);
|
|
476
185
|
if (answered && ev.isError !== true && ev.structured === undefined) {
|
|
477
186
|
led.dropAnswer(callId);
|
|
478
|
-
return { kind: 'yield', events: [{ ...ev, structured: answered }] };
|
|
187
|
+
return { kind: 'yield', events: [{ ...ev, structured: answered }] };
|
|
479
188
|
}
|
|
480
189
|
return { kind: 'yield', events: [ev] };
|
|
481
190
|
},
|
|
482
191
|
},
|
|
483
192
|
];
|
|
484
|
-
// 🔴 顺序锁(SPLIT-12 硬约束):注册表化把「顺序」从代码位置搬成了数据,于是顺序本身需要一条断言。
|
|
485
|
-
// 加载期求值 —— 重排 `TOOL_END_ARMS` 而没同批改 `TOOL_END_ARM_ORDER` 的那次 import 当场抛,
|
|
486
|
-
// 而不是等到某个 Bash gate 的毒化帧在用户屏上停住才发现。
|
|
487
193
|
{
|
|
488
194
|
const actual = TOOL_END_ARMS.map(a => a.id).join(' > ');
|
|
489
195
|
const expected = TOOL_END_ARM_ORDER.join(' > ');
|
|
@@ -493,35 +199,14 @@ const TOOL_END_ARMS = [
|
|
|
493
199
|
'改顺序必须同批改 TOOL_END_ARM_ORDER 并说明为什么新顺序仍然对。');
|
|
494
200
|
}
|
|
495
201
|
}
|
|
496
|
-
// ── 帧手柄 ────────────────────────────────────────────────────────────────────────────────────
|
|
497
202
|
async function routeToolApprovalFrame(ev, ctx) {
|
|
498
|
-
// ── server 1.191 同步帧腿([830]①):`tool_approval` 帧 → 三选卡 → respond ────────────────
|
|
499
|
-
// 引擎此刻同步阻塞在帧上(fail-closed:无 respond/TTL 5min/abort ⇒ deny),await 卡决断安全。
|
|
500
|
-
// 帧是 HITL 词汇非 AgentEvent arm——两种帧都不外泄到渲染管道。
|
|
501
203
|
const { led, deps } = ctx;
|
|
502
204
|
if (ev.type === 'tool_approval_complete')
|
|
503
|
-
return { kind: 'skip' };
|
|
504
|
-
// 🔴 #324:本臂**刻意不给连坐判别子供证**(异源对抗复审四轮的收口,2026-08-22)。
|
|
505
|
-
// 帧只证明「本 turn 出现过一张 gate」,证明不了「**这一批** abort 帧属于它」—— 那张 gate
|
|
506
|
-
// 可能早已正常收口(零毒化帧 ⇒ 零扣留表 ⇒ 一次 flush 都不跑),证却会活到下一批派错判词。
|
|
507
|
-
// 三条实测假阳(旧 server 双主角 / 零 HOLD 审批证跨批 / 历史身份跨批)都出自帧腿取证。
|
|
508
|
-
// 判别子只认 park(归属可结构性证明,见 `gateLedger.noteParkGate` 头注);同步帧腿一律
|
|
509
|
-
// 不标 —— 诚实缺席,登记在 §3z 已知局限。
|
|
205
|
+
return { kind: 'skip' };
|
|
510
206
|
if (!deps.respondToolApproval) {
|
|
511
207
|
hostLog('debug', `liveHitlAskWire: tool_approval frame ${ev.approvalId} but no respond wire — engine self-settles (TTL deny)`);
|
|
512
208
|
return { kind: 'skip' };
|
|
513
209
|
}
|
|
514
|
-
// 补验批 askq 案定谳(2026-07-23,[1534],引擎 dist 逐坐标读定):core 的 durable
|
|
515
|
-
// question policy 对 AskUserQuestion 出 action:"ask",本意让 durable gate park(suspended
|
|
516
|
-
// → 下方 bridge 弹卡收答);但 core suspendAsk 的退位条件(safety 缺席 + onAsk 在场)
|
|
517
|
-
// 把问题门也抢进了同步审批帧腿(壳为 fs 写权限三选卡开的 TOOL_APPROVAL_ENABLED)——同步帧
|
|
518
|
-
// 二值 respond 装不下「答案」,链路死锁:deny=模型误信问题已展示原地等;allow=执行工具
|
|
519
|
-
// 本体炸 durable 装配的 onQuestion 占位(QUESTION_AWAITS_RESUME)。此处取两害之轻恒 allow:
|
|
520
|
-
// 模型收到明确错误后退化成正文提问,用户尚可下一条消息作答(deny 形连这条退化路都没有)。
|
|
521
|
-
// 承重域收敛史([1543]§一 cli 注意):core 1.375 修 question gate 恒 park(健康路),
|
|
522
|
-
// 1.376 又断了降级路(checkpoint pre-commit/put 失败 fallback 改 typed refusal)与继承链
|
|
523
|
-
// 两臂——1.376+ 下 ask 工具在任何路径都不再出 tool_approval 帧,本分支唯一剩余承重
|
|
524
|
-
// = 旧引擎(<1.375)兼容,askq pty fence @1.375+ 已四门全绿实证([1542])。
|
|
525
210
|
if (isAskToolLoose(ev.toolName)) {
|
|
526
211
|
try {
|
|
527
212
|
await deps.respondToolApproval(ev.approvalId, 'allow', {
|
|
@@ -534,18 +219,11 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
534
219
|
}
|
|
535
220
|
return { kind: 'skip' };
|
|
536
221
|
}
|
|
537
|
-
// [1535]/server 1.258:子代的审批帧(broker 腿浮到宿主流,判别=fromSubagent 显式键
|
|
538
|
-
// core 1.378 优先/sourceTaskId 在场性兜底)——子代的 tool_start 不在宿主行流上,绝不把
|
|
539
|
-
// 宿主自己的 pending fs call 关联给它(args 会错配成宿主的 diff、deny 会误标宿主 call 的
|
|
540
|
-
// REJECT 收口)。args 从帧上取,deny 收口归子代 lane 自理。
|
|
541
222
|
const fromSubagent = isFromSubagent(ev);
|
|
542
223
|
hostLog('debug', `liveHitlAskWire: tool_approval frame ${ev.approvalId} tool=${String(ev.toolName)}${fromSubagent ? ` from-subagent=${String(ev.sourceTaskId ?? ev.sourceAgentName ?? 'explicit')}` : ''}`);
|
|
543
224
|
const gatedCallId = !fromSubagent ? led.lastPendingFsCall() : undefined;
|
|
544
|
-
// FIX①(2026-08-07):产物是 `{decision, ack?}` —— ack 上的 `rememberApplied`/`updatedInputForwarded`
|
|
545
|
-
// 由 toolApprovalWire 就地收敛成宿主通知(本路由只认决断词,不重复解释 ack)。
|
|
546
225
|
const outcome = await surfaceToolApprovalFrameAndRespond(ev, deps.respondToolApproval, argsOfGatedStart(led, gatedCallId), ctx.signal, deps.approvalLane);
|
|
547
226
|
const { decision } = outcome;
|
|
548
|
-
// 0.74.1(CC-68):结局交回宿主(fail-soft:宿主的回调 bug 不许拆流)。
|
|
549
227
|
if (deps.onToolApprovalOutcome !== undefined) {
|
|
550
228
|
try {
|
|
551
229
|
const out = deps.onToolApprovalOutcome(ev, outcome);
|
|
@@ -556,12 +234,10 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
556
234
|
}
|
|
557
235
|
}
|
|
558
236
|
catch (e) {
|
|
559
|
-
// 宿主回调的异常不许拆帧路由;留痕走 hostLog。
|
|
560
237
|
hostLog('debug', `liveHitlAskWire: onToolApprovalOutcome threw: ${String(e).slice(0, 160)}`);
|
|
561
238
|
}
|
|
562
239
|
}
|
|
563
240
|
if (decision === 'deny' && !fromSubagent) {
|
|
564
|
-
// 该 call 的报错收口帧 stamp REJECT 文案(vendored `User rejected <op> to <path>` 卡)。
|
|
565
241
|
if (gatedCallId !== undefined)
|
|
566
242
|
led.markDenied(gatedCallId);
|
|
567
243
|
else
|
|
@@ -570,25 +246,13 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
570
246
|
return { kind: 'skip' };
|
|
571
247
|
}
|
|
572
248
|
function routeToolStart(ev, callId, led) {
|
|
573
|
-
// L-69⑨(0.52.0):**所有** tool_start 都留一份 args 快照(有界在飞表,收口即删)。
|
|
574
|
-
// 🔴 与下面那张 gated 表刻意**不合表**:「表里有」绝不等于「被 gate 过」——两张表的成员关系、
|
|
575
|
-
// 生命周期、容量纪律都不同(逐条理由见 `gateLedger.ts` 的 `noteStart` 头注)。
|
|
576
|
-
// 这一份服务的是分类器 deny 这类**没走 gate**的收口现场(gated 表里根本没有它们)。
|
|
577
|
-
// 🔴 **必须排在 `markStarted` 闸之前**(异源对抗复审 R1 finding② 采纳):那道闸是**渲染**去重
|
|
578
|
-
// (durable 重放的已渲 call 不再上屏),而记账不是渲染。排在闸之后 ⇒ 重放帧一律早退 ⇒
|
|
579
|
-
// `noteStart` 的「先删再写」刷新在**生产路径上永远走不到**,只有直调台账的测试碰得着;
|
|
580
|
-
// 而重放恰恰是被有界表淘汰过的那些 call 唯一一次把快照拿回来的机会。
|
|
581
249
|
led.noteStart(callId, ev);
|
|
582
250
|
if (!led.markStarted(callId))
|
|
583
|
-
return { kind: 'skip' };
|
|
251
|
+
return { kind: 'skip' };
|
|
584
252
|
if (isGatedToolName(ev.toolName)) {
|
|
585
|
-
// #110:Bash 也要记 args —— 卡片渲染要拿到 `command`,不记则 shell gate 的卡面空着。
|
|
586
253
|
led.noteGatedStart(callId, ev);
|
|
587
254
|
if (typeof ev.toolName === 'string' && toolNameIsFsWrite(ev.toolName))
|
|
588
255
|
led.pushFsCall(callId);
|
|
589
|
-
// REF-CC-034:`park.gate==='fs'` 分支覆盖 fs 写 + shell 执行两族(isToolApprovalGate
|
|
590
|
-
// 超集谓词)——`lastFsOrShellGatedCallId` 两族都要跟,否则 Bash gate 的已决断身份
|
|
591
|
-
// 候选恒 undefined。与 `pushFsCall` 不同,它不在 tool_end 到达时清空(见台账声明处注)。
|
|
592
256
|
if (typeof ev.toolName === 'string' && (toolNameIsFsWrite(ev.toolName) || toolNameIsShellExec(ev.toolName))) {
|
|
593
257
|
led.noteFsOrShellGate(callId);
|
|
594
258
|
}
|
|
@@ -597,35 +261,20 @@ function routeToolStart(ev, callId, led) {
|
|
|
597
261
|
}
|
|
598
262
|
function routeToolEnd(ev, callId, led) {
|
|
599
263
|
if (led.isEnded(callId)) {
|
|
600
|
-
// L-69⑨(0.52.0):已收口的 call **无论走哪条路**都不该留在在飞表里。这一行是上面
|
|
601
|
-
// 「noteStart 排在渲染去重闸之前」的对偶:durable 重放会把 start 再送一遍(于是快照被重新
|
|
602
|
-
// 加回来),而重放的 end 在这里早退 ⇒ 少了这一行,那一条就要一直挂到被容量淘汰为止。
|
|
603
264
|
led.dropStartArgs(callId);
|
|
604
|
-
return { kind: 'skip' };
|
|
265
|
+
return { kind: 'skip' };
|
|
605
266
|
}
|
|
606
267
|
led.dropFsCall(callId);
|
|
607
268
|
for (const arm of TOOL_END_ARMS) {
|
|
608
269
|
const action = arm.run(ev, callId, led);
|
|
609
270
|
if (action) {
|
|
610
|
-
// L-69⑨(0.52.0):在飞窗到此为止 —— 收口帧已经判完(臂**在这一行之前**跑,分类器 deny 臂
|
|
611
|
-
// 因此还读得到 args),这一条快照从此没有消费者。
|
|
612
|
-
// 🔴 释放点必须在**臂之后**:挪到循环之前 ⇒ deny 臂拿到的恒是缺席(修前形);挪到 `return`
|
|
613
|
-
// 的调用方 ⇒ 五条臂各自 return,释放就要抄五遍(而漏抄的那条就是泄漏点)。
|
|
614
271
|
led.dropStartArgs(callId);
|
|
615
272
|
return action;
|
|
616
273
|
}
|
|
617
274
|
}
|
|
618
|
-
// 不可达:兜底臂 generic-close 无条件命中。真走到这里 = 有人给它加了早退条件,
|
|
619
|
-
// 那样 tool_end 会被整帧静默丢弃(用户看不到任何收口),必须当场喊出来而不是 `skip`。
|
|
620
275
|
throw new Error('frameRouter: tool_end 有序臂全部落空 —— generic-close 不再是无条件兜底臂');
|
|
621
276
|
}
|
|
622
277
|
function routeSuspended(ev, ctx) {
|
|
623
|
-
// durable leg 的 park arm(续流中模型再次提问/再次撞写权限)。gate 只带 kind/toolName,
|
|
624
|
-
// payload 走 approvals。
|
|
625
|
-
// 🔴 两条 park 臂都要登记(判别子的归属证据只认 park)—— ask park 自己用不到兜底腿,
|
|
626
|
-
// 但它必须把**上一张** gate 的准入证清掉,否则旧证会让兜底把一个 Bash 连坐帧反认成主角、
|
|
627
|
-
// 再把真正的 ask 主角 stamp 掉(对抗复审实测 `ask-main=STAMP`)。
|
|
628
|
-
// [4914]:durable `suspended` 事件的待批 call 身份就挂在 `gate` **旁**(不是 gate 里)。
|
|
629
278
|
const gatedCallId = parkGatedCallId(ev);
|
|
630
279
|
if (ev.gate && isAskToolLoose(ev.gate.toolName) && ctx.taskId.current) {
|
|
631
280
|
ctx.led.noteParkGate({ fsOrShellFamily: false });
|
|
@@ -634,32 +283,21 @@ function routeSuspended(ev, ctx) {
|
|
|
634
283
|
if (ev.gate &&
|
|
635
284
|
isToolApprovalGate(ev.gate) &&
|
|
636
285
|
ctx.taskId.current) {
|
|
637
|
-
// 准入证:park 的 gate 本体属 fs/shell 族(kind-only gate 的 toolName 在族外 ⇒ 不发证)。
|
|
638
286
|
ctx.led.noteParkGate({ fsOrShellFamily: isFsOrShellToolName(ev.gate.toolName) });
|
|
639
287
|
return { kind: 'park', gate: 'fs', ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
|
|
640
288
|
}
|
|
641
|
-
// 其余 gate:透传。⚠️ ADAPTER-F8 注纠(2026-08-02):原文写「eventToSdkMessage 出 null」——
|
|
642
|
-
// 那个返回形已随 REF-CC-058 退役,今天它出的是 `EventProjection` 三态,永不是 null;本臂的
|
|
643
|
-
// 帧走到投影器时落 `none/hitl_out_of_slice`(HITL 登记是 run driver 的活,不在投影切片内)。
|
|
644
289
|
return { kind: 'yield', events: [ev] };
|
|
645
290
|
}
|
|
646
291
|
function routeDone(ev, ctx) {
|
|
647
292
|
const { led } = ctx;
|
|
648
|
-
// [4914]:sync 腿的待批 call 身份在 `done{suspended}` 的 **result 顶层**(与 checkpointId 同位)。
|
|
649
293
|
const gatedCallId = parkGatedCallId(ev.result);
|
|
650
|
-
// 两条 park 臂都登记(理由同 routeSuspended)。
|
|
651
294
|
const park = parkGateOf(ev.result);
|
|
652
295
|
if (park !== null) {
|
|
653
296
|
ctx.taskId.current = ctx.taskId.current ?? park.taskId;
|
|
654
|
-
// 准入证:主语是**门本体**的 toolName,不是任何 tool_end 帧的(ask 臂恒 false —— 问答门不属
|
|
655
|
-
// fs/shell 族)。
|
|
656
297
|
led.noteParkGate({ fsOrShellFamily: park.gate === 'fs' && isFsOrShellToolName(park.toolName) });
|
|
657
298
|
return { kind: 'park', gate: park.gate, pendingDone: ev, ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
|
|
658
299
|
}
|
|
659
|
-
// 真错(非 gate)的 Ask tool_end 此刻诚实渲染;件 B:纯用户中断批在这个出口把文案归一成 CC 中断形。
|
|
660
300
|
const events = [...flushHeldWithInterruptRewrite(led, { terminal: ev, signal: ctx.signal })];
|
|
661
|
-
// durable 终帧的 result.taskId === sessionId(引擎 durable quirk)会让 captureSessionId 跳过
|
|
662
|
-
// rewind 绑定 —— 用 sync leg 捕的真 handle 修正回去。
|
|
663
301
|
const r = ev.result;
|
|
664
302
|
const realTaskId = ctx.taskId.current;
|
|
665
303
|
if (realTaskId && r && r.taskId === r.sessionId && r.taskId !== realTaskId) {
|
|
@@ -670,18 +308,9 @@ function routeDone(ev, ctx) {
|
|
|
670
308
|
}
|
|
671
309
|
return { kind: 'end', events };
|
|
672
310
|
}
|
|
673
|
-
/**
|
|
674
|
-
* 一帧 → 一个处置。手柄的**先后**与原文逐条同序:tool_approval 帧 → tool_start → tool_end →
|
|
675
|
-
* suspended → done → failed → 透传。
|
|
676
|
-
*/
|
|
677
311
|
export async function routeFrame(ev, ctx) {
|
|
678
312
|
const { led } = ctx;
|
|
679
313
|
if (isToolApprovalFrame(ev)) {
|
|
680
|
-
// #51: `ToolApprovalFrame` frames are documented as NOT part of the
|
|
681
|
-
// `AgentEvent` union (a separate SSE wire vocabulary riding the same
|
|
682
|
-
// stream) — intersecting the type-predicate's asserted type with the
|
|
683
|
-
// unrelated `AgentEvent` union collapses every arm to `never`. Local
|
|
684
|
-
// rebind restores the real (already-checked) shape.
|
|
685
314
|
const frame = ev;
|
|
686
315
|
return await routeToolApprovalFrame(frame, ctx);
|
|
687
316
|
}
|
|
@@ -693,7 +322,6 @@ export async function routeFrame(ev, ctx) {
|
|
|
693
322
|
return routeSuspended(ev, ctx);
|
|
694
323
|
if (ev.type === 'done')
|
|
695
324
|
return routeDone(ev, ctx);
|
|
696
|
-
// 件 B:cancel settle 的终帧(`failed{errorCode:"cancelled"}`)就是「用户要停」的 wire 证据。
|
|
697
325
|
if (ev.type === 'failed') {
|
|
698
326
|
return { kind: 'end', events: [...flushHeldWithInterruptRewrite(led, { terminal: ev, signal: ctx.signal }), ev] };
|
|
699
327
|
}
|