@sema-agent/client-core 0.77.1 → 0.78.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/CHANGELOG.md +42 -1
- package/README.md +6 -5
- 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 +3 -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 +23 -371
- package/dist/hitl/persistedRulesWire.js +62 -329
- 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 +0 -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 +1 -249
- package/dist/request/taskRequest.js +20 -498
- 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 +6 -67
- package/dist/subagent/engineTaskHandleWire.js +0 -126
- 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 +78 -5
- package/package.json +3 -3
|
@@ -1,89 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* src/sema/headlessPermissionModeWire.ts — SEMA_HEADLESS_PERMISSION_MODE 部署旋钮
|
|
3
|
-
* (clay 拍板 2026-07-16:TB/bench 场景 headless `-p` 统一垫 bypassPermissions,对齐 CC bench 实跑的
|
|
4
|
-
* --dangerously-skip-permissions 姿势;落地形态 = 环境变量部署旋钮,产品缺省语义不动)。
|
|
5
|
-
*
|
|
6
|
-
* gap-check 现状(2026-07-16,db3c72f):
|
|
7
|
-
* · `--permission-mode <mode>` CLI flag 存在(main.tsx:1042,choices = PERMISSION_MODES + 'manual'),
|
|
8
|
-
* `--dangerously-skip-permissions` 亦在;但两者在 headless `-p` 车道【都不进 TaskRequest】——
|
|
9
|
-
* seamQueryEngine.ask 自建请求从不 stamp permissionMode(交互 REPL 走 seamQuery →
|
|
10
|
-
* permissionWireCaps.permissionModeField,print/headless 从不 stamp = server absent-mode)。
|
|
11
|
-
* · 即:今天 `-p` 的权限面全靠 server 对 absent-mode 的缺省解释([830]① server 1.191 五模式解释层,
|
|
12
|
-
* absent 不挂门)。core [885] 残余建议:显式垫,防未来缺省变化让 TB 静默变盘。
|
|
13
|
-
*
|
|
14
|
-
* 语义(件2 拍板逐字):
|
|
15
|
-
* 优先级:CLI flag 显式值 > SEMA_HEADLESS_PERMISSION_MODE env > 现状 absent-mode(env 是缺省态的
|
|
16
|
-
* 垫层,flag 恒赢——flag 在场时 env 完全不看,即使 flag 值不在 wire 词表内)。
|
|
17
|
-
* 值域 = 壳既有 wire permissionMode 词表(permissionWireCaps.PermissionMode:default / plan /
|
|
18
|
-
* acceptEdits / bypassPermissions / auto——分类器批3 [907] server 五模式表,server ≥1.209 认
|
|
19
|
-
* "auto")。非法 env 值 ⇒ 一次性 warn + 回落现状,绝不 fail 启动。
|
|
20
|
-
* stamp 规则([2713] 最小刀改形,2026-08-05;双复审补 dontAsk 归一同日):
|
|
21
|
-
* · flag 来源:显式表态一律显式 stamp——wire 五词直 stamp,`default` 走 stampDefault 显式垫
|
|
22
|
-
* (旧形 default 不 stamp ⇒ server 侧 `settings.permissions.defaultMode` 恒缺席 ⇒
|
|
23
|
-
* `deriveSettingsPolicy` 早退返回 `{}` ⇒ **按模式派生的那套门一个不铸**,print 车道 ask 门
|
|
24
|
-
* 断链根因。⚠️ 本模块只对**这一个量**负责:body 里有没有 `permissionMode`。[2713] 写的
|
|
25
|
-
* 「applyTaskSettings 整跳」是那条链的简写,它成不成立还要看 body.settings 里有没有别的
|
|
26
|
-
* parsed 字段 —— 那是 server 的控制流,会随 server 改版漂,别在本注释里复述第二遍,要查就去
|
|
27
|
-
* 读 server task-settings.ts);壳内部词(`manual`=CC default 别名、`dontAsk`=壳侧最严
|
|
28
|
-
* 「ask⇒deny」模式)经 SHELL_INTERNAL_MODE_TO_WIRE 归一到 wire 词 `default` 后 stamp
|
|
29
|
-
* (方向纪律与三条残余记账见该常量 doc);归一表外的值仍不 stamp = 回落部署基线。
|
|
30
|
-
* ⚠️ 版本界(逐值核过 server CHANGELOG 与 cli scripts/lib/engine-pin.mjs,2026-08-05):
|
|
31
|
-
* `shellGate` 与 fs 写 ask 门曾同吃这道断链;server #153([2713] 分单②)把
|
|
32
|
-
* MANUAL_MODE_SHELL_GATE 升到 `applyRuntimeGovernance` 无条件施加,该修**发在 server 7.1.0**,
|
|
33
|
-
* 而当日 `ENGINE_PIN = '7.0.0'` —— **发货引擎上两门仍同断**,本 stamp 两门都决定。等 pin 抬到
|
|
34
|
-
* ≥7.1.0,shellGate 就与本字段在不在场无关,本 stamp 只再决定 fs 写 ask 门。
|
|
35
|
-
* 别把这段读成「现在只剩 fsWrite」,也别读成「shellGate 永远归我管」——它是随 pin 移动的界。
|
|
36
|
-
* · env 来源:五词全部显式 stamp(含 `default`——env 是"显式垫层"旋钮,设了就是要显式语义,
|
|
37
|
-
* 不再依赖 server absent-mode 缺省解释;server 1.191 对显式 "default" 走 manual ask 门解释)。
|
|
38
|
-
* 车道纪律:`resolveHeadlessPermissionMode`(本模块的 stamp 决策口)只被 seamQueryEngine.ask
|
|
39
|
-
* (headless `-p`)调用;交互 REPL(seamQuery)一根毛不动——单测的 lane proof 锚的正是**这个符号
|
|
40
|
-
* 名**,不是模块名。⚠️ 「本模块只被 seamQueryEngine import」是**错的**(旧注释遗留,双复审查出):
|
|
41
|
-
* `interactiveToolsWire.ts:45` 也 import 本模块的 `permissionModeFromArgv`(REF-CC-dup-10 收编,
|
|
42
|
-
* 两个 headless 旋钮共用同一份 argv 读法)——那是纯 argv 解析器,不碰 stamp 决策,车道纪律不破。
|
|
43
|
-
*/
|
|
44
1
|
import { type PermissionMode, type PermissionModeField } from './permissionWireCaps.js';
|
|
45
2
|
import { type EnvLike } from './hostEnv.js';
|
|
46
|
-
/** 部署旋钮 env 键名(settings.json env 块 → 1a-envseed → process.env 同车道)。 */
|
|
47
3
|
export declare const HEADLESS_PERMISSION_MODE_ENV = "SEMA_HEADLESS_PERMISSION_MODE";
|
|
48
4
|
export declare const HEADLESS_PERMISSION_WIRE_MODES: readonly PermissionMode[];
|
|
49
|
-
/**
|
|
50
|
-
* 归一表的**唯一取值口**(#164 [2760]② wire 面三面同拍,2026-08-06):壳内部模式词 → wire 词;
|
|
51
|
-
* 表外词与 undefined 恒等透传(未表态不制造表态)。两个消费方共用同一张表(单表纪律,禁抄写):
|
|
52
|
-
* · headless flag 支(本模块 resolveHeadlessPermissionMode);
|
|
53
|
-
* · 壳交互车道(seamQuery 在 permissionModeField stamp 前归一——修前交互车道 `dontAsk` 落
|
|
54
|
-
* permissionModeField 表外支不 stamp ⇒ 引擎侧 absent-mode 一个门不铸,与底栏「don't ask on」
|
|
55
|
-
* 指示相反;归一后 stamp `default` ⇒ 引擎铸 ask 门,ask 到壳后由壳侧 dontAsk 决策臂
|
|
56
|
-
* (ask⇒deny)落地,与 CC 单进程语义对位)。
|
|
57
|
-
* 方向纪律与三条残余记账见上方表 doc,本函数不另立口径。
|
|
58
|
-
*/
|
|
59
5
|
export declare function normalizeShellPermissionModeForWire(mode: string | undefined): string | undefined;
|
|
60
6
|
export type HeadlessPermissionResolution = {
|
|
61
|
-
/** 直接展开进 TaskRequest 的字段({} = 不 stamp,现状 absent-mode)。 */
|
|
62
7
|
fields: PermissionModeField;
|
|
63
8
|
source: 'flag' | 'env' | 'default' | 'absent';
|
|
64
|
-
/** 非法 env 值的告警文案(调用层一次性打 stderr)。 */
|
|
65
9
|
warning?: string;
|
|
66
10
|
};
|
|
67
|
-
/**
|
|
68
|
-
* argv 里的 `--permission-mode <v>` / `--permission-mode=<v>`(后者/后出现者赢,commander 同语义)与
|
|
69
|
-
* `--dangerously-skip-permissions`(= bypassPermissions;`--permission-mode` 在场时让位)。
|
|
70
|
-
* 返回 undefined = flag 车道未显式表态。
|
|
71
|
-
*
|
|
72
|
-
* REF-CC-143(dup-07)收编:`--permission-mode` 的取值改吃共用 lastFlagValue(argvFlagValue.ts,
|
|
73
|
-
* `onMissingValue:'latch-previous'`)——旧手写循环对「某一次 occurrence 缺值」的处置是跳过这一次、
|
|
74
|
-
* 锁存(latch)住之前已经取到的合法值,不是把整个旗塌缩成「从没写过」(`--permission-mode plan
|
|
75
|
-
* --permission-mode` 的旧行为是 `mode==='plan'`,不是 `undefined`)。共用叶的缺省策略
|
|
76
|
-
* (`'invalidate'`,sandboxWire/scenarioWire 用)会把这个情形塌缩成「有旗无值」,与本函数原有语义
|
|
77
|
-
* 不符,所以本调用点显式传 `'latch-previous'` 保住旧行为——这才是任务书说的「各调用方保持自己现有
|
|
78
|
-
* 对缺值的处置」(wave1 回炉修复,blocker:此前误用了共用叶的 invalidate 缺省,详见 commit 记账)。
|
|
79
|
-
* `--dangerously-skip-permissions` 的存在性判别不属于「取某旗最后值」这个不变量,单独一个小循环即
|
|
80
|
-
* 可,零重复。
|
|
81
|
-
*/
|
|
82
11
|
export declare function permissionModeFromArgv(argv: readonly string[]): string | undefined;
|
|
83
|
-
/**
|
|
84
|
-
* 解析 headless `-p` 的 permissionMode stamp。纯函数除告警 latch(同值只警一次)。
|
|
85
|
-
* 调用方(seamQueryEngine.ask)live-gated:mock/pty 车道永不经过这里。
|
|
86
|
-
*/
|
|
87
12
|
export declare function resolveHeadlessPermissionMode(argv: readonly string[], env?: EnvLike): HeadlessPermissionResolution;
|
|
88
|
-
/** 测试钩子:重置一次性告警 latch。 */
|
|
89
13
|
export declare function _resetHeadlessPermissionModeWireForTest(): void;
|
|
@@ -1,152 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* src/sema/headlessPermissionModeWire.ts — SEMA_HEADLESS_PERMISSION_MODE 部署旋钮
|
|
3
|
-
* (clay 拍板 2026-07-16:TB/bench 场景 headless `-p` 统一垫 bypassPermissions,对齐 CC bench 实跑的
|
|
4
|
-
* --dangerously-skip-permissions 姿势;落地形态 = 环境变量部署旋钮,产品缺省语义不动)。
|
|
5
|
-
*
|
|
6
|
-
* gap-check 现状(2026-07-16,db3c72f):
|
|
7
|
-
* · `--permission-mode <mode>` CLI flag 存在(main.tsx:1042,choices = PERMISSION_MODES + 'manual'),
|
|
8
|
-
* `--dangerously-skip-permissions` 亦在;但两者在 headless `-p` 车道【都不进 TaskRequest】——
|
|
9
|
-
* seamQueryEngine.ask 自建请求从不 stamp permissionMode(交互 REPL 走 seamQuery →
|
|
10
|
-
* permissionWireCaps.permissionModeField,print/headless 从不 stamp = server absent-mode)。
|
|
11
|
-
* · 即:今天 `-p` 的权限面全靠 server 对 absent-mode 的缺省解释([830]① server 1.191 五模式解释层,
|
|
12
|
-
* absent 不挂门)。core [885] 残余建议:显式垫,防未来缺省变化让 TB 静默变盘。
|
|
13
|
-
*
|
|
14
|
-
* 语义(件2 拍板逐字):
|
|
15
|
-
* 优先级:CLI flag 显式值 > SEMA_HEADLESS_PERMISSION_MODE env > 现状 absent-mode(env 是缺省态的
|
|
16
|
-
* 垫层,flag 恒赢——flag 在场时 env 完全不看,即使 flag 值不在 wire 词表内)。
|
|
17
|
-
* 值域 = 壳既有 wire permissionMode 词表(permissionWireCaps.PermissionMode:default / plan /
|
|
18
|
-
* acceptEdits / bypassPermissions / auto——分类器批3 [907] server 五模式表,server ≥1.209 认
|
|
19
|
-
* "auto")。非法 env 值 ⇒ 一次性 warn + 回落现状,绝不 fail 启动。
|
|
20
|
-
* stamp 规则([2713] 最小刀改形,2026-08-05;双复审补 dontAsk 归一同日):
|
|
21
|
-
* · flag 来源:显式表态一律显式 stamp——wire 五词直 stamp,`default` 走 stampDefault 显式垫
|
|
22
|
-
* (旧形 default 不 stamp ⇒ server 侧 `settings.permissions.defaultMode` 恒缺席 ⇒
|
|
23
|
-
* `deriveSettingsPolicy` 早退返回 `{}` ⇒ **按模式派生的那套门一个不铸**,print 车道 ask 门
|
|
24
|
-
* 断链根因。⚠️ 本模块只对**这一个量**负责:body 里有没有 `permissionMode`。[2713] 写的
|
|
25
|
-
* 「applyTaskSettings 整跳」是那条链的简写,它成不成立还要看 body.settings 里有没有别的
|
|
26
|
-
* parsed 字段 —— 那是 server 的控制流,会随 server 改版漂,别在本注释里复述第二遍,要查就去
|
|
27
|
-
* 读 server task-settings.ts);壳内部词(`manual`=CC default 别名、`dontAsk`=壳侧最严
|
|
28
|
-
* 「ask⇒deny」模式)经 SHELL_INTERNAL_MODE_TO_WIRE 归一到 wire 词 `default` 后 stamp
|
|
29
|
-
* (方向纪律与三条残余记账见该常量 doc);归一表外的值仍不 stamp = 回落部署基线。
|
|
30
|
-
* ⚠️ 版本界(逐值核过 server CHANGELOG 与 cli scripts/lib/engine-pin.mjs,2026-08-05):
|
|
31
|
-
* `shellGate` 与 fs 写 ask 门曾同吃这道断链;server #153([2713] 分单②)把
|
|
32
|
-
* MANUAL_MODE_SHELL_GATE 升到 `applyRuntimeGovernance` 无条件施加,该修**发在 server 7.1.0**,
|
|
33
|
-
* 而当日 `ENGINE_PIN = '7.0.0'` —— **发货引擎上两门仍同断**,本 stamp 两门都决定。等 pin 抬到
|
|
34
|
-
* ≥7.1.0,shellGate 就与本字段在不在场无关,本 stamp 只再决定 fs 写 ask 门。
|
|
35
|
-
* 别把这段读成「现在只剩 fsWrite」,也别读成「shellGate 永远归我管」——它是随 pin 移动的界。
|
|
36
|
-
* · env 来源:五词全部显式 stamp(含 `default`——env 是"显式垫层"旋钮,设了就是要显式语义,
|
|
37
|
-
* 不再依赖 server absent-mode 缺省解释;server 1.191 对显式 "default" 走 manual ask 门解释)。
|
|
38
|
-
* 车道纪律:`resolveHeadlessPermissionMode`(本模块的 stamp 决策口)只被 seamQueryEngine.ask
|
|
39
|
-
* (headless `-p`)调用;交互 REPL(seamQuery)一根毛不动——单测的 lane proof 锚的正是**这个符号
|
|
40
|
-
* 名**,不是模块名。⚠️ 「本模块只被 seamQueryEngine import」是**错的**(旧注释遗留,双复审查出):
|
|
41
|
-
* `interactiveToolsWire.ts:45` 也 import 本模块的 `permissionModeFromArgv`(REF-CC-dup-10 收编,
|
|
42
|
-
* 两个 headless 旋钮共用同一份 argv 读法)——那是纯 argv 解析器,不碰 stamp 决策,车道纪律不破。
|
|
43
|
-
*/
|
|
44
1
|
import { permissionModeField } from './permissionWireCaps.js';
|
|
45
2
|
import { hostEnv } from './hostEnv.js';
|
|
46
3
|
import { lastFlagValue } from './argvFlagValue.js';
|
|
47
|
-
/** 部署旋钮 env 键名(settings.json env 块 → 1a-envseed → process.env 同车道)。 */
|
|
48
4
|
export const HEADLESS_PERMISSION_MODE_ENV = 'SEMA_HEADLESS_PERMISSION_MODE';
|
|
49
|
-
/** wire 词表(permissionWireCaps.PermissionMode 的运行时镜像;大小写敏感——与 CC flag choices 一致)。
|
|
50
|
-
* 'auto'(分类器批3,[907]):server ≥1.209 五模式表认;老 server coerce 未知词 → "default" 只紧不松。 */
|
|
51
5
|
const HEADLESS_PERMISSION_WIRE_MODE_TUPLE = ['default', 'plan', 'acceptEdits', 'bypassPermissions', 'auto'];
|
|
52
|
-
/**
|
|
53
|
-
* 🔴 [2006] B-CC-2(2026-07-29):`readonly PermissionMode[]` 的注解只保证「元素合法」,**从不保证
|
|
54
|
-
* 穷举** —— server 五模式表加第六个词、`PermissionMode` 跟了而这张运行时镜像没跟 ⇒ 编译期全绿,
|
|
55
|
-
* 而那个词从 env 旋钮走进来会被判非法、一次性 warn 后**静默回落**(部署以为设了、实际没设)。
|
|
56
|
-
* 补「类型 → 常量」那半边;之前的看守只有 `length > 0 && includes('plan')`(对这个方向零判别力)。
|
|
57
|
-
* `Covers`(REF-CC-145/dup-12,P3 wave1 卡C-argv)改吃共用叶 typePins.ts——四份逐字重复钉之一。
|
|
58
|
-
*/
|
|
59
6
|
const _headlessPermissionModePins = [true, true];
|
|
60
7
|
void _headlessPermissionModePins;
|
|
61
8
|
export const HEADLESS_PERMISSION_WIRE_MODES = HEADLESS_PERMISSION_WIRE_MODE_TUPLE;
|
|
62
|
-
/**
|
|
63
|
-
* 壳内部模式词 → wire 词的归一表(**壳内映射,勿改 server 五词表**)。大小写敏感,与 commander
|
|
64
|
-
* `--permission-mode` 的 choices 同口径;表外词照原样交给 permissionModeField 双支自处置。
|
|
65
|
-
*
|
|
66
|
-
* · `manual` = CC 2.1.207 对内部 `default` 的**输入别名**(壳 `normalizePermissionModeAlias`
|
|
67
|
-
* 同一张表:`mode === 'manual' ? 'default' : mode`,枚举本身不含 manual 成员)。
|
|
68
|
-
* · `dontAsk` = 壳侧**最严**模式:`permissions.ts` 把 `behavior==='ask'` 整个改判成 `'deny'`
|
|
69
|
-
* (DONT_ASK_REJECT_MESSAGE),且它在 `INTERNAL_PERMISSION_MODES` 里 ⇒ `--permission-mode dontAsk`
|
|
70
|
-
* 是合法 CLI 取值、`-p` 车道真可达。wire 五词没有对应词;**不归一的后果是方向错的**——落
|
|
71
|
-
* permissionModeField 表外支 ⇒ 不 stamp ⇒ server `deriveSettingsPolicy` 因 `!perms` 返回 `{}`
|
|
72
|
-
* ⇒ **客户端表态派生的门一个都不铸**(部署基线 approvalRequire 与 runtime governance 仍在,
|
|
73
|
-
* 不是「什么都不拦」;但按模式该有的那道门没了),观测上与最松的 `bypassPermissions` 同形
|
|
74
|
-
* —— 用户要最严、拿到的是最松那一档的形。归一到 `default`(fs 写 ask 门)。
|
|
75
|
-
* 🔴 **这是近似投影,不是等价映射;别把它读成「已经修好了」**,三条残余按坐标记账:
|
|
76
|
-
* ① `default` 不是 wire 词表里最严的词(`plan` 才是 handsReadOnly 只读手)。选它是因为 `plan`
|
|
77
|
-
* 会连带改变工作流形态(present_plan + 只读手),把「别问我、直接拒」翻成「进规划模式」是
|
|
78
|
-
* 另一种谎报。`default` 是**不改工作流形态的前提下最接近**的落点。
|
|
79
|
-
* ② `dontAsk` 要的是即刻 deny,`default` 是 ask/park —— 有活体审批面时那条 ask **可以被批准**,
|
|
80
|
-
* 而 dontAsk 语义禁止这条路径。所以「只紧不松」这句话的比较基准**只能是不 stamp 那个落点**
|
|
81
|
-
* (归一前:该模式的门一个不铸),不是 dontAsk 本义 —— 相对 dontAsk 本义它是松的。要精确
|
|
82
|
-
* 投影必须 server 词表补一个 deny 语义的 wire 词(另票)。
|
|
83
|
-
* ③ 非 host lane(e2b/k8s/ssh)上 server 的 `fsWriteGate` wiring 恒为 undefined
|
|
84
|
-
* (resolve-spec `hostSemanticsLane ? … : undefined`),`deriveSettingsPolicy` 的 default 臂
|
|
85
|
-
* 只剩 workflow ask 政策 ⇒ **Write/Edit 在沙箱 lane 上仍不挂门**。
|
|
86
|
-
* ⚠️ 别写成「壳侧关不掉」——那是过度声称。壳侧**有**一条路:`settings.permissions.ask:
|
|
87
|
-
* ['Write','Edit','NotebookEdit']` 走 `createAskListPolicy`,那条政策是**名字键控、与 lane
|
|
88
|
-
* 无关**的(task-settings.ts:494-495,不吃 fsWriteGate wiring)。**这条路真的能关掉这个洞**,
|
|
89
|
-
* 本批刻意不走,理由如下(前两条曾被写错、双复审驳回,这里是订正后的版本):
|
|
90
|
-
* (a) 代价 = **host lane 上 fs 门自己的放行腿被盖掉**。名字键控 ask 与其它政策 deny/ask
|
|
91
|
-
* 恒赢地折叠,所以 ask-list 一挂,host lane 上现在被 scratchpad 豁免/acceptDirs 放行的
|
|
92
|
-
* 写也变成 ask —— 丢的是精度。
|
|
93
|
-
* (⚠️ 这条只说到这里就够了。两次复审都栽在替这个「没走的选项」推演更细的后果上:
|
|
94
|
-
* 先写成「两 lane 更不一致」被驳,再写成「两 lane 都凡写必问」又被驳——敏感路径 deny 腿
|
|
95
|
-
* 在 host 上仍然 deny,两 lane 并不同形。真要选这条路,后果得当场重新取证,别信这段。)
|
|
96
|
-
* (b) 代价 = 在 headless 上「凡写必问」而**没有应答者**(#165 = -p 车道无客户端审批面)⇒
|
|
97
|
-
* 沙箱 lane 的每一次 Write 都停在门上 —— 停成 park 还是直接 deny 由部署定(park 要
|
|
98
|
-
* `durableApproval` 与 checkpoint 存储**两个都在**,缺一就不是 park;精确条件在 server
|
|
99
|
-
* approval.ts 的 durable 政策 doc 里,本注释不复述以免漂)。两种都是行为面大改,要过
|
|
100
|
-
* 宪法三问,不是复审顺手能落的。
|
|
101
|
-
* (⚠️ 也不要写成「server 修了这层补偿自然作废」—— 已核实为假:server #153/7.1.0 只把
|
|
102
|
-
* `MANUAL_MODE_SHELL_GATE` 升到 governance 层,**非 host lane 的 fsWriteGate 仍不建**,
|
|
103
|
-
* [2713] 那条 @server 分单到今天没兑现,所以这层补偿不会因为 #153 而自动过时。)
|
|
104
|
-
* (c) 越过「壳带意图、service 解释」的分层——壳替 server 决定了拦哪几个工具名。
|
|
105
|
-
* ⇒ 记账在此,决定权在仓主(要不要用 ask-list 换掉精度、并同时推 #165);本表只负责
|
|
106
|
-
* 「让 server 有表态可读」。
|
|
107
|
-
* ⚠️ 判据方向(比较基准写死,别读成别的):本表允许的落点 = **相对「不 stamp」严格更紧或等紧**。
|
|
108
|
-
* 加词前先问「这个词 stamp 出去之后,server 铸出来的门比不 stamp 时更紧吗」——更松就不许进表
|
|
109
|
-
* (宁可不 stamp 回落部署基线,也不许客户端表态制造放行)。
|
|
110
|
-
* 注意这**不是**「落点 ≥ 壳内语义」:`dontAsk → default` 就不满足后者(见上方残余②),它满足的是
|
|
111
|
-
* 前者。写判据时用错基准会把这张表读成「已经等价了」。
|
|
112
|
-
* **刻意用 Map 而不是对象字面量**(与 adapt/arms.ts ARMS 表同一条纪律):键来自原始 argv,是开集;
|
|
113
|
-
* 对象表上 `tbl['__proto__']`/`tbl['constructor']` 会顺着原型链取回一个**非字符串**值,把它当
|
|
114
|
-
* `PermissionMode` 往下传是类型谎报(tsc 因 `Record<string,…>` 的索引签名全盲)。Map 无原型链取值。
|
|
115
|
-
*/
|
|
116
9
|
const SHELL_INTERNAL_MODE_TO_WIRE = new Map([
|
|
117
10
|
['manual', 'default'],
|
|
118
11
|
['dontAsk', 'default'],
|
|
119
12
|
]);
|
|
120
|
-
/**
|
|
121
|
-
* 归一表的**唯一取值口**(#164 [2760]② wire 面三面同拍,2026-08-06):壳内部模式词 → wire 词;
|
|
122
|
-
* 表外词与 undefined 恒等透传(未表态不制造表态)。两个消费方共用同一张表(单表纪律,禁抄写):
|
|
123
|
-
* · headless flag 支(本模块 resolveHeadlessPermissionMode);
|
|
124
|
-
* · 壳交互车道(seamQuery 在 permissionModeField stamp 前归一——修前交互车道 `dontAsk` 落
|
|
125
|
-
* permissionModeField 表外支不 stamp ⇒ 引擎侧 absent-mode 一个门不铸,与底栏「don't ask on」
|
|
126
|
-
* 指示相反;归一后 stamp `default` ⇒ 引擎铸 ask 门,ask 到壳后由壳侧 dontAsk 决策臂
|
|
127
|
-
* (ask⇒deny)落地,与 CC 单进程语义对位)。
|
|
128
|
-
* 方向纪律与三条残余记账见上方表 doc,本函数不另立口径。
|
|
129
|
-
*/
|
|
130
13
|
export function normalizeShellPermissionModeForWire(mode) {
|
|
131
14
|
if (mode === undefined)
|
|
132
15
|
return undefined;
|
|
133
16
|
return SHELL_INTERNAL_MODE_TO_WIRE.get(mode) ?? mode;
|
|
134
17
|
}
|
|
135
|
-
/**
|
|
136
|
-
* argv 里的 `--permission-mode <v>` / `--permission-mode=<v>`(后者/后出现者赢,commander 同语义)与
|
|
137
|
-
* `--dangerously-skip-permissions`(= bypassPermissions;`--permission-mode` 在场时让位)。
|
|
138
|
-
* 返回 undefined = flag 车道未显式表态。
|
|
139
|
-
*
|
|
140
|
-
* REF-CC-143(dup-07)收编:`--permission-mode` 的取值改吃共用 lastFlagValue(argvFlagValue.ts,
|
|
141
|
-
* `onMissingValue:'latch-previous'`)——旧手写循环对「某一次 occurrence 缺值」的处置是跳过这一次、
|
|
142
|
-
* 锁存(latch)住之前已经取到的合法值,不是把整个旗塌缩成「从没写过」(`--permission-mode plan
|
|
143
|
-
* --permission-mode` 的旧行为是 `mode==='plan'`,不是 `undefined`)。共用叶的缺省策略
|
|
144
|
-
* (`'invalidate'`,sandboxWire/scenarioWire 用)会把这个情形塌缩成「有旗无值」,与本函数原有语义
|
|
145
|
-
* 不符,所以本调用点显式传 `'latch-previous'` 保住旧行为——这才是任务书说的「各调用方保持自己现有
|
|
146
|
-
* 对缺值的处置」(wave1 回炉修复,blocker:此前误用了共用叶的 invalidate 缺省,详见 commit 记账)。
|
|
147
|
-
* `--dangerously-skip-permissions` 的存在性判别不属于「取某旗最后值」这个不变量,单独一个小循环即
|
|
148
|
-
* 可,零重复。
|
|
149
|
-
*/
|
|
150
18
|
export function permissionModeFromArgv(argv) {
|
|
151
19
|
const flag = lastFlagValue(argv, '--permission-mode', 'latch-previous');
|
|
152
20
|
if (flag.present && flag.raw !== undefined)
|
|
@@ -154,50 +22,29 @@ export function permissionModeFromArgv(argv) {
|
|
|
154
22
|
for (let i = 0; i < argv.length; i++) {
|
|
155
23
|
const a = argv[i];
|
|
156
24
|
if (a === '--')
|
|
157
|
-
break;
|
|
25
|
+
break;
|
|
158
26
|
if (a === '--dangerously-skip-permissions')
|
|
159
27
|
return 'bypassPermissions';
|
|
160
28
|
}
|
|
161
29
|
return undefined;
|
|
162
30
|
}
|
|
163
|
-
// 一次性告警 latch(-p 是 one-shot 进程;测试钩子可重置)
|
|
164
31
|
let warnedInvalidEnv = false;
|
|
165
|
-
/**
|
|
166
|
-
* 解析 headless `-p` 的 permissionMode stamp。纯函数除告警 latch(同值只警一次)。
|
|
167
|
-
* 调用方(seamQueryEngine.ask)live-gated:mock/pty 车道永不经过这里。
|
|
168
|
-
*/
|
|
169
32
|
export function resolveHeadlessPermissionMode(argv, env = hostEnv()) {
|
|
170
|
-
// 1) CLI flag 恒赢:flag 在场(含 wire 词表外的壳内部模式)⇒ env 完全不看。
|
|
171
33
|
const flagMode = permissionModeFromArgv(argv);
|
|
172
34
|
if (flagMode !== undefined) {
|
|
173
|
-
// [2713] 最小刀:flag 显式表态 ⇒ 显式 stamp(含 default——旧形 flag=default 不 stamp 让 server
|
|
174
|
-
// deriveSettingsPolicy 因 settings.permissions 缺席返回 {},按模式派生的门不铸)。壳内部词经 SHELL_INTERNAL_MODE_TO_WIRE
|
|
175
|
-
// 归一到 wire 词(manual/dontAsk → default;归一表的方向纪律见该常量 doc),勿改 server 词表;
|
|
176
|
-
// 表外词(未来新增的壳内部模式)经 permissionModeField 双支仍不 stamp = 回落部署基线。
|
|
177
35
|
const normalized = normalizeShellPermissionModeForWire(flagMode);
|
|
178
36
|
return { fields: permissionModeField(normalized, { stampDefault: true }), source: 'flag' };
|
|
179
37
|
}
|
|
180
|
-
// 2) env 垫层。
|
|
181
38
|
const raw = env[HEADLESS_PERMISSION_MODE_ENV]?.trim();
|
|
182
39
|
if (raw === undefined || raw === '') {
|
|
183
|
-
// 3) 缺省垫(2026-08-11 裁定,headless 权限缺省收窄):flag/env 双缺席不再走 absent-mode
|
|
184
|
-
// (server 7.12.0 起模式翻译表对缺席=键不写=无门,headless 缺省会**无门直落**——与
|
|
185
|
-
// 对标实现「headless 门照挂照报」相反)。缺省显式 stamp "default" ⇒ 翻译表挂 classify 档,
|
|
186
|
-
// 写形过分类器、读形白名单放行。旧 server(≤7.11.0)对显式 default 走 manual ask 门解释,
|
|
187
|
-
// 同向收紧,version-safe。要旧「无门」行为的部署用显式
|
|
188
|
-
// `SEMA_HEADLESS_PERMISSION_MODE=bypassPermissions` 表态(缺省绝不宽)。
|
|
189
|
-
// source='default' 与 'absent' 分词:absent 只剩「wire 词表外值回落」一支已不存在——保留
|
|
190
|
-
// 枚举员是为了消费端(日志/围栏)对旧值的开集容纳,本函数不再产它。
|
|
191
40
|
return { fields: permissionModeField('default', { stampDefault: true }), source: 'default' };
|
|
192
41
|
}
|
|
193
42
|
if (HEADLESS_PERMISSION_WIRE_MODES.includes(raw)) {
|
|
194
|
-
// env 是显式垫层:五词全 stamp(含 default——stampDefault 显式垫,不依赖 absent-mode 缺省解释)。
|
|
195
43
|
return {
|
|
196
44
|
fields: permissionModeField(raw, { stampDefault: true }),
|
|
197
45
|
source: 'env',
|
|
198
46
|
};
|
|
199
47
|
}
|
|
200
|
-
// 4) 非法 env 值:一次性 warn + 回落缺省垫(绝不 fail,也绝不因坏值放宽成无门)。
|
|
201
48
|
const resolution = {
|
|
202
49
|
fields: permissionModeField('default', { stampDefault: true }),
|
|
203
50
|
source: 'default',
|
|
@@ -208,7 +55,6 @@ export function resolveHeadlessPermissionMode(argv, env = hostEnv()) {
|
|
|
208
55
|
}
|
|
209
56
|
return resolution;
|
|
210
57
|
}
|
|
211
|
-
/** 测试钩子:重置一次性告警 latch。 */
|
|
212
58
|
export function _resetHeadlessPermissionModeWireForTest() {
|
|
213
59
|
warnedInvalidEnv = false;
|
|
214
60
|
}
|
|
@@ -1,70 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* src/sema/headlessReconnectWire.ts — 重连腿 M2 · R1 换车道续收(design/HEADLESS-RECONNECT-DESIGN.md
|
|
3
|
-
* §3 R1 + §6 M2,2026-07-16)。M1(detachWire 头 + 信号 cancel 兜底,2545900)已发运;本模块把
|
|
4
|
-
* engine-alive-idle 判死升级为「先重连、耗尽才判死」——但只在 headless `-p` detach 车道。
|
|
5
|
-
*
|
|
6
|
-
* 触发点(design §3,四条同时成立才进重连分支):
|
|
7
|
-
* ① tasks/stream 以 SseIdleError 收场(流静默超 grace)——其它失败形态(engine-down/restarted/
|
|
8
|
-
* 4xx/断连 reset)原样穿透,现行路径一字不动;
|
|
9
|
-
* ② headless `-p` ∧ detach 头已随首次 POST 发出——本 wrapper 只在 liveClient.tasks.stream 的
|
|
10
|
-
* opts.headers 携带 x-detach-on-disconnect: 'true' 时套上(唯一 set 头的调用方 =
|
|
11
|
-
* seamQueryEngine.ask;交互 REPL(seamQuery)与 headless-bg worker 都不传 headers ⇒ 源码级
|
|
12
|
-
* 证明这两条车道一根毛不动,断连=取消语义保持,铁律 5);
|
|
13
|
-
* ③ durableTaskId 已捕获(X-Task-Id 早捕获,liveClient onResponse)——没有 id 无从换道,原样抛;
|
|
14
|
-
* ④ 每次重连前置 probeEngineAlive(批 D /health 探针复用)——引擎死了绝不空等,原样抛走
|
|
15
|
-
* 现行 engine-down 判死。
|
|
16
|
-
*
|
|
17
|
-
* 铁律对表:
|
|
18
|
-
* · signal.aborted 恒先行(铁律 3,seamQuery.ts:1073 契约):重试环每一轮入口先查 aborted,
|
|
19
|
-
* 用户中止绝不进重连分支(连探活都不做);续收中途 aborted → 干净 return(镜像 SDK parseSse
|
|
20
|
-
* 的 abort 语义),上游 print.ts 的 SIGINT 处置(M1 cancel 兜底)全权接管。
|
|
21
|
-
* · 有界(铁律 5/任务 §4):每 run 最多 HEADLESS_RECONNECT_MAX=2 次壳级重连;耗尽 → 重抛
|
|
22
|
-
* 【原始】SseIdleError(对象恒原件,后续 diagnoseSseIdleTear 打 engine-alive-idle 标 →
|
|
23
|
-
* seamQueryEngine 现行诚实判死文案,字节不变)。
|
|
24
|
-
* · 15min STREAM_MAX_DURATION 硬顶(任务 §3):runs.events 车道被 cap 断开时,SDK sse.js
|
|
25
|
-
* parseSse 自带 Last-Event-ID 立即重连(frame.id 锁存 → 重开带 lastEventId;无进展 5 连败
|
|
26
|
-
* 才放弃)——cap 重连发生在【同一次】openEvents 调用内部,计入同一次重连预算(不额外扣),
|
|
27
|
-
* 铁律 4「不动 SDK」同时满足:runs.events 消费面已有,本模块零 SDK 改动。
|
|
28
|
-
* · 与 headless-bg 有界重发腿(bgTearResends)互斥:重发腿在 seamQuery.query(REPL 形 worker),
|
|
29
|
-
* 其触发词表本就只含 restarted/engine-down(seamQuery.ts:1143),engine-alive-idle 从不重发;
|
|
30
|
-
* 本重连腿只在 -p detach 车道。两腿车道 + 词表双重不相交,结构性互斥。
|
|
31
|
-
*
|
|
32
|
-
* ── R1 去重锚选型(任务书要求写明选型与理由)────────────────────────────────────────────────
|
|
33
|
-
* runs.events 车道:server streamRunEvents 把账本 seq 写成 SSE `id:` 行(formatEvent id: ev.seq),
|
|
34
|
-
* SDK sse.js 把 frame.id 回贴到 ev.id ⇒ 每个续收帧带单调递增数字 seq。锚 = lastSeenSeq:
|
|
35
|
-
* a) 跨壳级 attempt 续传:第二次 openEvents 传 Last-Event-ID=lastSeenSeq(server 从其后回放);
|
|
36
|
-
* b) 防双投:丢弃 seq ≤ lastSeenSeq 的重放帧(server 从头回放/416 回卷都兜住)。
|
|
37
|
-
* 首次换道(tasks/stream → runs.events):tasks/stream 帧无 id(SDK tasks.js 不回贴 frame.id,
|
|
38
|
-
* server sync 腿也不写 id: 行)⇒ 无从定位,只能从起点(不带 Last-Event-ID)拉。防双投依据 =
|
|
39
|
-
* server 实证(1.205/1.209 dist 逐行核对):sync /v1/tasks/stream 腿【不】逐事件落账(runs.js 的
|
|
40
|
-
* appendEvent 只在 async runs 腿与 resume 腿;sync 腿只 createRun + setTerminal(finalResult))⇒
|
|
41
|
-
* sync 腿 run 的账本在终局前恒空,从起点拉不存在「重放已消费帧」面;将来 server 若开始 sync 腿
|
|
42
|
-
* 落账,守卫 = ①终帧唯一(本 wrapper 首终帧即 return + adapter runStream 首终帧 return + 批 B
|
|
43
|
-
* 双帧守卫「恰一条 result」)②seq 锚(首帧起锁存,attempt 间绝不回放)③gap-check 记账:换道前
|
|
44
|
-
* 已消费的 delta 与账本聚合 text 事件无逐字节对齐关系,真正的精确锚需要 server 给 tasks/stream
|
|
45
|
-
* 帧发 id(引擎侧诉求,走协作板,非壳侧可解)。
|
|
46
|
-
*
|
|
47
|
-
* ── 账本空(现役 server sync 腿)时的续收降级(R1b)────────────────────────────────────────
|
|
48
|
-
* 同一实证的另一面:detach 后 run 后台跑完,账本无事件行,runs.events 只会心跳保活直到 run row
|
|
49
|
-
* 落终局,然后无终帧地收流(SDK 无进展 5 连败抛错)。此时 run 的终局【已在】run row 里
|
|
50
|
-
* (GET /v1/runs/:id → RunRecord.result = TaskResult,含完整最终文本)——续收环的 catch 里查
|
|
51
|
-
* run row:已终局 → 合成终帧(done{result} / failed)喂回同一消费管线,turn 以 rc=0 正常收尾,
|
|
52
|
-
* 最终答案全量保真(-p 的 result 面 = done.result.result 字符串,非增量拼接);未终局(还在跑/
|
|
53
|
-
* suspended)→ 计预算继续重试,耗尽才判死。中途 delta 的全帧保真(R1a 环)在账本有事件行时
|
|
54
|
-
* (resume 腿 run / 将来 sync 腿落账的 server)自动生效——两形态由同一环处理,帧结构差异
|
|
55
|
-
* (text/reasoning 聚合事件 vs *_delta)由 adapter eventToSdkMessage 既有 case 'text'/'reasoning'
|
|
56
|
-
* 消费面兜住。
|
|
57
|
-
*/
|
|
58
1
|
import type { AgentEvent } from '@sema-agent/sdk';
|
|
59
|
-
/** 每 run 壳级重连预算(design 铁律 5)。cap/416 的 SDK 内部续传不计入(同一次 openEvents)。
|
|
60
|
-
* 选值:design/HEADLESS-RECONNECT-DESIGN.md §2 铁律 5 只钉了「有界」与这个数,未留更细的推导
|
|
61
|
-
* —— 诚实记账,不倒推一个当时没写下来的公式。可核实的取值依据是本环自身的形状(REF-CC-148
|
|
62
|
-
* 普查记账):每次尝试是两次真网络往返(重试环里的 `probe(deps.baseUrl)` + `deps.openEvents(…)`)
|
|
63
|
-
* 且两次尝试之间**零退避**,预算越大,在一个真死引擎上耗尽这个环、落到诚实判死文案之前的墙钟代价就越高
|
|
64
|
-
* ——2 是「给瞬时抖动一次重试余地」与「死引擎上不过度拖延判死」之间的保守取值,不是精算结果;
|
|
65
|
-
* 若上游把撕裂形态改成更常见的可重连态,这个数可能需要上调(域词表-19 已留此账)。 */
|
|
66
2
|
export declare const HEADLESS_RECONNECT_MAX = 2;
|
|
67
|
-
/** GET /v1/runs/:id 的 run row 终局子集(SDK RunRecord;字段防御性读)。 */
|
|
68
3
|
export interface RunRowLike {
|
|
69
4
|
status?: string;
|
|
70
5
|
result?: unknown;
|
|
@@ -72,31 +7,12 @@ export interface RunRowLike {
|
|
|
72
7
|
error?: string;
|
|
73
8
|
}
|
|
74
9
|
export interface HeadlessReconnectDeps {
|
|
75
|
-
/** 引擎 baseUrl(探活用;凭证不经本模块——openEvents/getRun 闭包自带)。 */
|
|
76
10
|
baseUrl: string;
|
|
77
|
-
/** X-Task-Id 早捕获读数(liveClient onResponse 闭包);null = 未捕获 ⇒ 不换道。 */
|
|
78
11
|
getTaskId: () => string | null;
|
|
79
|
-
/** runs.events 换道开流(liveClient 闭包 → client.runs.events;lastEventId = 去重锚续传)。 */
|
|
80
12
|
openEvents: (taskId: string, lastEventId?: string) => AsyncGenerator<AgentEvent>;
|
|
81
|
-
/** run row 终局读数(R1b 降级捞终局;失败返回 null,永不抛)。 */
|
|
82
13
|
getRun: (taskId: string) => Promise<RunRowLike | null>;
|
|
83
14
|
signal?: AbortSignal;
|
|
84
|
-
/** 测试注入位;缺省 = 批 D probeEngineAlive(/health,2s 预算)。 */
|
|
85
15
|
probeAlive?: (baseUrl: string) => Promise<boolean>;
|
|
86
16
|
}
|
|
87
|
-
/** run row → 合成终帧(R1b)。带 result 对象的引擎终态(全词表)合成 done{result}——与
|
|
88
|
-
* tasks/stream 终帧字节同构,adapter terminalToSdkResult 全枚举分流([909]B1)原样生效
|
|
89
|
-
* (timeout→error_max_turns、blocked→error_during_execution、park→[884]A1 臂);裸 failed
|
|
90
|
-
* (无 result)合成 failed 事件。running / 无 result 的 park(可能还会被 approvals 解锁)null
|
|
91
|
-
* —— 计预算继续重试,耗尽才判死。 */
|
|
92
17
|
export declare function terminalEventFromRunRow(row: RunRowLike | null): AgentEvent | null;
|
|
93
|
-
/**
|
|
94
|
-
* withHeadlessR1Reconnect(live, deps) — the M2 R1 lane-switch wrapper.
|
|
95
|
-
*
|
|
96
|
-
* 位置:liveClient.tasks.stream 管线【最内层】(demux/HITL 桥/captureSessionId/normalizeToolNames/
|
|
97
|
-
* diagnoseSseIdleTear 之内)——续收帧与合成终帧流经与 live 帧完全相同的下游包装(工具名规整、
|
|
98
|
-
* sessionId 捕获、HITL 桥、批 B 守卫),零特殊路径。重连成功 → 生成器以终帧正常 return ⇒
|
|
99
|
-
* diagnoseSseIdleTear/tearVerdict 永不介入,turn 正常收尾;耗尽/不可换道 → 重抛原始 SseIdleError,
|
|
100
|
-
* 外层打标 + 现行判死文案,字节不变。
|
|
101
|
-
*/
|
|
102
18
|
export declare function withHeadlessR1Reconnect(live: AsyncGenerator<AgentEvent>, deps: HeadlessReconnectDeps): AsyncGenerator<AgentEvent>;
|
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
import { isSseIdleError, probeEngineAlive } from './sseIdleTriage.js';
|
|
2
2
|
import { hostEnv } from './hostEnv.js';
|
|
3
|
-
/** 每 run 壳级重连预算(design 铁律 5)。cap/416 的 SDK 内部续传不计入(同一次 openEvents)。
|
|
4
|
-
* 选值:design/HEADLESS-RECONNECT-DESIGN.md §2 铁律 5 只钉了「有界」与这个数,未留更细的推导
|
|
5
|
-
* —— 诚实记账,不倒推一个当时没写下来的公式。可核实的取值依据是本环自身的形状(REF-CC-148
|
|
6
|
-
* 普查记账):每次尝试是两次真网络往返(重试环里的 `probe(deps.baseUrl)` + `deps.openEvents(…)`)
|
|
7
|
-
* 且两次尝试之间**零退避**,预算越大,在一个真死引擎上耗尽这个环、落到诚实判死文案之前的墙钟代价就越高
|
|
8
|
-
* ——2 是「给瞬时抖动一次重试余地」与「死引擎上不过度拖延判死」之间的保守取值,不是精算结果;
|
|
9
|
-
* 若上游把撕裂形态改成更常见的可重连态,这个数可能需要上调(域词表-19 已留此账)。 */
|
|
10
3
|
export const HEADLESS_RECONNECT_MAX = 2;
|
|
11
|
-
/** SEMA_DEBUG 探针(headless `-p` 车道 Ink 未挂载,stderr 可用;绝不带凭证/帧内容)。 */
|
|
12
4
|
function debugLog(msg) {
|
|
13
5
|
if (hostEnv().SEMA_DEBUG) {
|
|
14
|
-
// eslint-disable-next-line no-console
|
|
15
6
|
console.error(`[sema] headless reconnect: ${msg}`);
|
|
16
7
|
}
|
|
17
8
|
}
|
|
18
|
-
/** 引擎终态词表全集(core 1.298 TaskStatus;server runs.js setTerminal(taskId, safe.status, …)
|
|
19
|
-
* 把引擎 status【原样】写进 run row ⇒ row.status 可以是全部 6 词,不只 completed/failed)。
|
|
20
|
-
* 🔴 **run 行自己的 `status` 列 engine 7.64.0 没动**(BREAKING 帖逐字:变的是引擎结果 blob,
|
|
21
|
-
* 行的列照旧说五词,只是数据源改成从因由投影一次)⇒ 本表原样有效,不随 `TaskResult` 形变。
|
|
22
|
-
* [909]B3 复核发现的真缺口:此前只认 completed/failed,timeout/blocked 终局的 run row 永不
|
|
23
|
-
* 合成终帧 → 续收环重试到预算耗尽 → 假判死(终局明明就在 row 里)。 */
|
|
24
9
|
const RUN_ROW_TERMINAL_STATUSES = new Set([
|
|
25
10
|
'completed',
|
|
26
11
|
'failed',
|
|
@@ -29,23 +14,11 @@ const RUN_ROW_TERMINAL_STATUSES = new Set([
|
|
|
29
14
|
'suspended',
|
|
30
15
|
'needs_review',
|
|
31
16
|
]);
|
|
32
|
-
/** run row → 合成终帧(R1b)。带 result 对象的引擎终态(全词表)合成 done{result}——与
|
|
33
|
-
* tasks/stream 终帧字节同构,adapter terminalToSdkResult 全枚举分流([909]B1)原样生效
|
|
34
|
-
* (timeout→error_max_turns、blocked→error_during_execution、park→[884]A1 臂);裸 failed
|
|
35
|
-
* (无 result)合成 failed 事件。running / 无 result 的 park(可能还会被 approvals 解锁)null
|
|
36
|
-
* —— 计预算继续重试,耗尽才判死。 */
|
|
37
17
|
export function terminalEventFromRunRow(row) {
|
|
38
18
|
if (!row || typeof row.status !== 'string')
|
|
39
19
|
return null;
|
|
40
20
|
if (RUN_ROW_TERMINAL_STATUSES.has(row.status)) {
|
|
41
21
|
if (row.result && typeof row.result === 'object') {
|
|
42
|
-
// sync 腿 setTerminal 存的就是终帧的 TaskResult —— 与 tasks/stream 终帧 done{result} 字节同构,
|
|
43
|
-
// terminalToSdkResult 文案线原样生效。
|
|
44
|
-
// 🔴 **这是一条读盘面**(0.60.0 起要点名):`GET /v1/runs/:id` 的 `result` 是存储 blob 的**逐字
|
|
45
|
-
// 透传**,server **不补** `terminal` ⇒ 一台跨 engine 7.64.0 升级过的部署上,升级**之前**落盘
|
|
46
|
-
// 的那些行读出来仍是**扁平**形(退役的八个平面键)。两代字节由 `runTerminal.readRunTerminal`
|
|
47
|
-
// 的判别位 `"terminal" in result` 各归各位,所以本函数**照旧原样透传、一个键都不补**:补一个
|
|
48
|
-
// `terminal` 出来就是替停产的写者重新裁定一次形状(server 自己也刻意不做)。
|
|
49
22
|
return { type: 'done', result: row.result };
|
|
50
23
|
}
|
|
51
24
|
if (row.status === 'failed') {
|
|
@@ -58,15 +31,6 @@ export function terminalEventFromRunRow(row) {
|
|
|
58
31
|
}
|
|
59
32
|
return null;
|
|
60
33
|
}
|
|
61
|
-
/**
|
|
62
|
-
* withHeadlessR1Reconnect(live, deps) — the M2 R1 lane-switch wrapper.
|
|
63
|
-
*
|
|
64
|
-
* 位置:liveClient.tasks.stream 管线【最内层】(demux/HITL 桥/captureSessionId/normalizeToolNames/
|
|
65
|
-
* diagnoseSseIdleTear 之内)——续收帧与合成终帧流经与 live 帧完全相同的下游包装(工具名规整、
|
|
66
|
-
* sessionId 捕获、HITL 桥、批 B 守卫),零特殊路径。重连成功 → 生成器以终帧正常 return ⇒
|
|
67
|
-
* diagnoseSseIdleTear/tearVerdict 永不介入,turn 正常收尾;耗尽/不可换道 → 重抛原始 SseIdleError,
|
|
68
|
-
* 外层打标 + 现行判死文案,字节不变。
|
|
69
|
-
*/
|
|
70
34
|
export async function* withHeadlessR1Reconnect(live, deps) {
|
|
71
35
|
let originalTearErr;
|
|
72
36
|
try {
|
|
@@ -74,85 +38,68 @@ export async function* withHeadlessR1Reconnect(live, deps) {
|
|
|
74
38
|
yield ev;
|
|
75
39
|
const t = ev?.type;
|
|
76
40
|
if (t === 'done' || t === 'failed')
|
|
77
|
-
return;
|
|
41
|
+
return;
|
|
78
42
|
}
|
|
79
|
-
return;
|
|
43
|
+
return;
|
|
80
44
|
}
|
|
81
45
|
catch (e) {
|
|
82
46
|
originalTearErr = e;
|
|
83
47
|
}
|
|
84
|
-
// ── 重试环:每轮入口按铁律顺序分诊,非命中一律重抛【原始】错误(现行失败路径字节不变)──
|
|
85
48
|
let attempts = 0;
|
|
86
|
-
let lastSeenSeq;
|
|
49
|
+
let lastSeenSeq;
|
|
87
50
|
const probe = deps.probeAlive ?? probeEngineAlive;
|
|
88
|
-
// REF-CC-148(域词表-19):originalTearErr 在环内从不被重写(它是进入本重试环前唯一捕获的
|
|
89
|
-
// 错误对象),所以这个判型是**环不变式**——算一次即可,不必逐轮重算。
|
|
90
|
-
// wave1 回炉复审(复审 blocker):求值时机必须排在铁律 3(用户中止恒先行)**之后**才对 main
|
|
91
|
-
// 逐字——main 是「每轮入口先查 aborted,再判型」,若把判型提到循环顶(环外、抢在第一轮的
|
|
92
|
-
// aborted 检查之前),当 originalTearErr 是一个 `.name` getter 会抛的畸形错误对象、且入环时
|
|
93
|
-
// signal 已经 aborted 时,新顺序会先让 isSseIdleError 抛出**那个畸形对象的二次异常**,盖过
|
|
94
|
-
// 本该抛出的 originalTearErr,违反铁律 3。改法:惰性 memo——用 `undefined` 起始态占位「尚未算
|
|
95
|
-
// 过」(合法返回值只有 true/false),真正求值仍只发生一次,但**排在每轮的 aborted 检查之后**,
|
|
96
|
-
// 与 main 的求值顺序逐字一致,「只判一次」的不变量原样保留。
|
|
97
51
|
let isRecoverableTear;
|
|
98
52
|
for (;;) {
|
|
99
53
|
if (deps.signal?.aborted)
|
|
100
|
-
throw originalTearErr;
|
|
54
|
+
throw originalTearErr;
|
|
101
55
|
if (isRecoverableTear === undefined)
|
|
102
56
|
isRecoverableTear = isSseIdleError(originalTearErr);
|
|
103
57
|
if (!isRecoverableTear)
|
|
104
|
-
throw originalTearErr;
|
|
58
|
+
throw originalTearErr;
|
|
105
59
|
const taskId = deps.getTaskId();
|
|
106
60
|
if (!taskId)
|
|
107
|
-
throw originalTearErr;
|
|
61
|
+
throw originalTearErr;
|
|
108
62
|
if (attempts >= HEADLESS_RECONNECT_MAX) {
|
|
109
63
|
debugLog(`budget exhausted (${attempts}/${HEADLESS_RECONNECT_MAX}) — falling to the honest death path`);
|
|
110
|
-
throw originalTearErr;
|
|
64
|
+
throw originalTearErr;
|
|
111
65
|
}
|
|
112
66
|
attempts++;
|
|
113
67
|
if (!(await probe(deps.baseUrl)))
|
|
114
|
-
throw originalTearErr;
|
|
68
|
+
throw originalTearErr;
|
|
115
69
|
debugLog(`attempt ${attempts}/${HEADLESS_RECONNECT_MAX} — switching to runs.events(${taskId}${lastSeenSeq !== undefined ? `, Last-Event-ID ${lastSeenSeq}` : ''})`);
|
|
116
70
|
try {
|
|
117
71
|
const cont = deps.openEvents(taskId, lastSeenSeq !== undefined ? String(lastSeenSeq) : undefined);
|
|
118
72
|
for await (const ev of cont) {
|
|
119
73
|
if (deps.signal?.aborted)
|
|
120
|
-
return;
|
|
74
|
+
return;
|
|
121
75
|
const rec = ev;
|
|
122
76
|
const t = rec?.type;
|
|
123
77
|
if (t === undefined)
|
|
124
|
-
continue;
|
|
78
|
+
continue;
|
|
125
79
|
if (t === 'error') {
|
|
126
|
-
// STREAM_MAX_DURATION cap 帧(server streamSseLog):SDK parseSse 已锁存 Last-Event-ID
|
|
127
|
-
// 并自动重开(同一次 openEvents 内部,计入同一次预算)——本帧是车道协议杂音,不下发。
|
|
128
80
|
debugLog(`runs.events lane frame type=error code=${String(rec?.errorCode ?? rec?.code ?? '')} — SDK resumes with Last-Event-ID internally`);
|
|
129
81
|
continue;
|
|
130
82
|
}
|
|
131
83
|
const seq = typeof rec?.id === 'string' && /^\d+$/.test(rec.id) ? Number(rec.id) : undefined;
|
|
132
84
|
if (seq !== undefined) {
|
|
133
85
|
if (lastSeenSeq !== undefined && seq <= lastSeenSeq)
|
|
134
|
-
continue;
|
|
86
|
+
continue;
|
|
135
87
|
lastSeenSeq = seq;
|
|
136
88
|
}
|
|
137
|
-
// 终帧日志必须在 yield 之前:下游(adapter runStream)拿到首终帧即 return 弃养本生成器,
|
|
138
|
-
// yield 之后的语句不再执行(受控腿 leg 1 实测)。return 语义不受影响(弃养即收官)。
|
|
139
89
|
if (t === 'done' || t === 'failed')
|
|
140
|
-
debugLog(`resumed to terminal (${String(t)}) after ${attempts} reconnect(s)`);
|
|
90
|
+
debugLog(`resumed to terminal (${String(t)}) after ${attempts} reconnect(s)`);
|
|
141
91
|
yield ev;
|
|
142
92
|
if (t === 'done' || t === 'failed')
|
|
143
93
|
return;
|
|
144
94
|
}
|
|
145
|
-
// 无终帧收流(SDK 只在 signal.aborted 时干净 return;防御分支)——按撕裂再走一轮预算
|
|
146
95
|
if (deps.signal?.aborted)
|
|
147
96
|
return;
|
|
148
97
|
debugLog('runs.events continuation ended without a terminal frame');
|
|
149
98
|
}
|
|
150
99
|
catch (contErr) {
|
|
151
|
-
// 续收环失败。现役 server sync 腿账本为空 ⇒ run 落终局后 SDK 以「无进展 5 连败」收场
|
|
152
|
-
// ——这不是死刑:终局已在 run row(R1b),查得到就合成终帧收官。
|
|
153
100
|
debugLog(`runs.events continuation failed: ${contErr instanceof Error ? contErr.message : String(contErr)}`);
|
|
154
101
|
if (deps.signal?.aborted)
|
|
155
|
-
throw originalTearErr;
|
|
102
|
+
throw originalTearErr;
|
|
156
103
|
const row = await deps.getRun(taskId).catch(() => null);
|
|
157
104
|
const terminal = terminalEventFromRunRow(row);
|
|
158
105
|
if (terminal) {
|
|
@@ -160,7 +107,6 @@ export async function* withHeadlessR1Reconnect(live, deps) {
|
|
|
160
107
|
yield terminal;
|
|
161
108
|
return;
|
|
162
109
|
}
|
|
163
|
-
// run 还在跑 / suspended / row 读不到 —— 计预算继续重试(环顶做 aborted/预算/探活分诊)
|
|
164
110
|
}
|
|
165
111
|
}
|
|
166
112
|
}
|