@sema-agent/client-core 0.97.1 → 0.99.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 +607 -0
- package/README.md +96 -46
- package/dist/adapt/arms.d.ts +1 -0
- package/dist/adapt/arms.js +188 -53
- package/dist/adapt/ids.d.ts +12 -1
- package/dist/adapt/ids.js +59 -8
- package/dist/adapt/instanceLedger.d.ts +50 -0
- package/dist/adapt/instanceLedger.js +147 -0
- package/dist/adapt/panelTasks.d.ts +1 -1
- package/dist/adapt/panelTasks.js +2 -2
- package/dist/adapt/textStream.d.ts +1 -0
- package/dist/adapt/textStream.js +24 -7
- package/dist/adapt/toolCards.d.ts +27 -5
- package/dist/adapt/toolCards.js +39 -6
- package/dist/adapt/wireShapes.js +6 -2
- package/dist/adapt.d.ts +2 -0
- package/dist/adapt.js +8 -3
- package/dist/adapter/activeRunSelfHeal.d.ts +9 -3
- package/dist/adapter/activeRunSelfHeal.js +205 -313
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
- package/dist/adapter/downstream/eventToSdkMessage.js +77 -36
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
- package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
- package/dist/adapter/runStream.js +79 -48
- package/dist/adapter/types.d.ts +4 -4
- package/dist/adapter/types.js +2 -1
- package/dist/agentSession/backgroundView.js +2 -1
- package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
- package/dist/agentSession/engineAgentRegistryRead.js +12 -13
- package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
- package/dist/agentsWireCaps.d.ts +8 -11
- package/dist/agentsWireCaps.js +196 -194
- package/dist/approvalDecidedByCapability.d.ts +0 -4
- package/dist/approvalDecidedByCapability.js +0 -6
- package/dist/approvalsStreamLiveCapability.d.ts +0 -4
- package/dist/approvalsStreamLiveCapability.js +0 -6
- package/dist/assistantInbox.d.ts +34 -0
- package/dist/assistantInbox.js +118 -0
- package/dist/centerWiringCapability.js +9 -1
- package/dist/clientSlice.d.ts +0 -9
- package/dist/clientSlice.js +0 -3
- package/dist/cloudConfigWireCaps.d.ts +5 -3
- package/dist/cloudConfigWireCaps.js +106 -64
- package/dist/compensations.js +1 -1
- package/dist/connectorStatus.d.ts +21 -0
- package/dist/connectorStatus.js +112 -0
- package/dist/controlRouter.d.ts +18 -3
- package/dist/controlRouter.js +106 -67
- package/dist/coreValuePorts.d.ts +29 -4
- package/dist/coreValuePorts.js +10 -0
- package/dist/corruptSessionCopy.d.ts +2 -1
- package/dist/corruptSessionCopy.js +3 -3
- package/dist/decideReceipt.d.ts +2 -2
- package/dist/decideReceipt.js +5 -2
- package/dist/declared/supportFloorDeclared.js +3 -3
- package/dist/detachWire.js +3 -2
- package/dist/deviceExecutorManagementCapability.d.ts +0 -4
- package/dist/deviceExecutorManagementCapability.js +0 -6
- package/dist/deviceRebind.d.ts +49 -1
- package/dist/deviceRebind.js +221 -3
- package/dist/devicesFace.d.ts +34 -0
- package/dist/devicesFace.js +90 -0
- package/dist/displayUntrusted.d.ts +2 -0
- package/dist/displayUntrusted.js +253 -76
- package/dist/engineAgentAbsence.d.ts +1 -1
- package/dist/engineAgentPanelStore.d.ts +12 -4
- package/dist/engineAgentPanelStore.js +16 -11
- package/dist/engineCapReader.d.ts +2 -5
- package/dist/engineCapReader.js +8 -10
- package/dist/engineCapsCache.d.ts +12 -0
- package/dist/engineCapsCache.js +76 -18
- package/dist/engineCapsChange.d.ts +2 -0
- package/dist/engineCapsChange.js +9 -0
- package/dist/engineClosedSets.d.ts +1 -0
- package/dist/engineClosedSets.js +4 -1
- package/dist/engineErrorCodes.d.ts +11 -3
- package/dist/engineErrorCodes.js +11 -8
- package/dist/engineIdentity.d.ts +1 -0
- package/dist/engineIdentity.js +8 -0
- package/dist/engineRowRef.d.ts +28 -0
- package/dist/engineRowRef.js +114 -0
- package/dist/engineSessionMessages.d.ts +68 -0
- package/dist/engineSessionMessages.js +370 -0
- package/dist/engineTargetSeat.d.ts +27 -0
- package/dist/engineTargetSeat.js +199 -0
- package/dist/engineToolDirectory.d.ts +0 -9
- package/dist/engineToolDirectory.js +1 -94
- package/dist/engineUrl.d.ts +18 -0
- package/dist/engineUrl.js +52 -0
- package/dist/engineWireFor.js +3 -8
- package/dist/env/uiLanguage.d.ts +11 -1
- package/dist/env/uiLanguage.js +38 -2
- package/dist/eventLeg.d.ts +100 -0
- package/dist/eventLeg.js +305 -0
- package/dist/executionLaneCapability.d.ts +0 -4
- package/dist/executionLaneCapability.js +3 -16
- package/dist/fileHistoryCaptureCapability.d.ts +2 -5
- package/dist/fileHistoryCaptureCapability.js +13 -21
- package/dist/fileHistoryLegNotice.d.ts +2 -1
- package/dist/fileHistoryLegNotice.js +3 -3
- package/dist/fleet/fleetLedger.d.ts +0 -3
- package/dist/fleet/fleetLedger.js +21 -36
- package/dist/fleet/fleetProjection.d.ts +2 -2
- package/dist/fleet/fleetProjection.js +10 -8
- package/dist/frameBinding.d.ts +8 -0
- package/dist/frameBinding.js +35 -0
- package/dist/gateFailureCodes.d.ts +2 -0
- package/dist/gateFailureCodes.js +15 -0
- package/dist/gateOutcome.d.ts +3 -1
- package/dist/gateOutcome.js +41 -8
- package/dist/gateVocabulary.d.ts +10 -4
- package/dist/gateVocabulary.js +107 -47
- package/dist/generated/engineAskFaceTables.js +2 -2
- package/dist/generated/engineFactTables.d.ts +22 -3
- package/dist/generated/engineFactTables.js +51 -4
- package/dist/generated/engineNoticeTables.js +18 -3
- package/dist/generated/settingsSchemaFns.d.ts +6 -0
- package/dist/generated/settingsSchemaFns.js +57 -0
- package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
- package/dist/generated/settingsSchemaTables.d.ts +1 -0
- package/dist/generated/settingsSchemaTables.js +4 -0
- package/dist/generated/settingsSchemaTypes.d.ts +105 -0
- package/dist/generated/settingsSchemaTypes.js +1 -0
- package/dist/generated/toolNameTables.d.ts +1 -0
- package/dist/generated/toolNameTables.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +8 -2
- package/dist/hitl/allowRuleShadow.js +36 -29
- package/dist/hitl/approvalCardReading.d.ts +15 -0
- package/dist/hitl/approvalCardReading.js +154 -0
- package/dist/hitl/approvalCardReasons.d.ts +14 -0
- package/dist/hitl/approvalCardReasons.js +119 -0
- package/dist/hitl/approvalHolds.d.ts +50 -15
- package/dist/hitl/approvalHolds.js +177 -27
- package/dist/hitl/approvalResolution.d.ts +51 -26
- package/dist/hitl/approvalResolution.js +86 -122
- package/dist/hitl/approvalsFeed.js +6 -18
- package/dist/hitl/askClassPair.d.ts +2 -0
- package/dist/hitl/askClassPair.js +17 -0
- package/dist/hitl/askGateWire.d.ts +20 -2
- package/dist/hitl/askGateWire.js +50 -1
- package/dist/hitl/askParkRowRouting.d.ts +5 -0
- package/dist/hitl/askParkRowRouting.js +32 -1
- package/dist/hitl/askSettlementLine.d.ts +28 -0
- package/dist/hitl/askSettlementLine.js +99 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +3 -2
- package/dist/hitl/automaticAnswerVerdict.js +29 -13
- package/dist/hitl/crashConverged.d.ts +11 -20
- package/dist/hitl/crashConverged.js +56 -0
- package/dist/hitl/crashConvergedNotice.d.ts +6 -3
- package/dist/hitl/crashConvergedNotice.js +48 -24
- package/dist/hitl/decisionConflict.js +3 -10
- package/dist/hitl/decisionRefusal.d.ts +40 -1
- package/dist/hitl/decisionRefusal.js +199 -42
- package/dist/hitl/frameRouter.d.ts +5 -2
- package/dist/hitl/frameRouter.js +27 -24
- package/dist/hitl/gateLedger.d.ts +2 -0
- package/dist/hitl/gateLedger.js +50 -13
- package/dist/hitl/hitlBridge.d.ts +2 -2
- package/dist/hitl/hitlBridge.js +13 -10
- package/dist/hitl/livePendingAsk.d.ts +3 -3
- package/dist/hitl/livePendingAsk.js +7 -18
- package/dist/hitl/parkResolver.d.ts +2 -24
- package/dist/hitl/parkResolver.js +61 -97
- package/dist/hitl/persistedRulesWire.d.ts +25 -0
- package/dist/hitl/persistedRulesWire.js +104 -2
- package/dist/hitl/planReviewWire.d.ts +31 -13
- package/dist/hitl/planReviewWire.js +120 -78
- package/dist/hitl/refusedToolNameProse.d.ts +0 -1
- package/dist/hitl/refusedToolNameProse.js +0 -3
- package/dist/hitl/replayedApproval.d.ts +4 -3
- package/dist/hitl/replayedApproval.js +7 -4
- package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
- package/dist/hitl/sessionPolicyDeliverable.js +48 -7
- package/dist/hitl/sessionPolicyWire.d.ts +34 -21
- package/dist/hitl/sessionPolicyWire.js +179 -70
- package/dist/hitl/standingRows.d.ts +20 -2
- package/dist/hitl/standingRows.js +69 -8
- package/dist/hitl/suspendedReopen.d.ts +2 -1
- package/dist/hitl/suspendedReopen.js +7 -10
- package/dist/hitl/toolApprovalWire.d.ts +103 -156
- package/dist/hitl/toolApprovalWire.js +661 -411
- package/dist/hookMatcherVerdict.d.ts +6 -1
- package/dist/hookMatcherVerdict.js +14 -7
- package/dist/hooksWireCaps.d.ts +2 -2
- package/dist/hooksWireCaps.js +174 -81
- package/dist/host.d.ts +21 -0
- package/dist/hostTurnSettings.d.ts +71 -0
- package/dist/hostTurnSettings.js +291 -0
- package/dist/humanTurn.d.ts +14 -1
- package/dist/humanTurn.js +100 -12
- package/dist/humanTurnRead.d.ts +2 -0
- package/dist/humanTurnRead.js +22 -1
- package/dist/i18n/messages.en.d.ts +703 -0
- package/dist/i18n/messages.en.js +701 -0
- package/dist/i18n/messages.zh.d.ts +3 -0
- package/dist/i18n/messages.zh.js +837 -0
- package/dist/i18n/translate.d.ts +25 -0
- package/dist/i18n/translate.js +127 -0
- package/dist/index.d.ts +78 -29
- package/dist/index.js +54 -18
- package/dist/inheritEnvCapability.d.ts +32 -0
- package/dist/inheritEnvCapability.js +104 -0
- package/dist/inheritEnvWire.d.ts +3 -2
- package/dist/inheritEnvWire.js +12 -14
- package/dist/interactiveHalt.js +17 -6
- package/dist/liveModelCatalog.d.ts +3 -3
- package/dist/liveModelCatalog.js +15 -13
- package/dist/liveQuestionStore.d.ts +2 -21
- package/dist/mcpLiveness.d.ts +2 -1
- package/dist/mcpPanel.d.ts +10 -1
- package/dist/mcpPanel.js +40 -13
- package/dist/mcpProbeCapability.d.ts +2 -1
- package/dist/mcpProbeCapability.js +7 -11
- package/dist/mcpProbeWire.d.ts +9 -2
- package/dist/mcpProbeWire.js +6 -1
- package/dist/mcpWireCaps.d.ts +47 -2
- package/dist/mcpWireCaps.js +164 -16
- package/dist/memoryEntriesWire.d.ts +4 -9
- package/dist/memoryEntriesWire.js +5 -10
- package/dist/model/modelSupplyRules.d.ts +0 -2
- package/dist/model/modelSupplyRules.js +3 -12
- package/dist/model/modelsPolicy.d.ts +0 -5
- package/dist/model/modelsPolicy.js +6 -36
- package/dist/model/onboardJudgement.d.ts +93 -0
- package/dist/model/onboardJudgement.js +415 -0
- package/dist/model/subagentModelWord.d.ts +31 -0
- package/dist/model/subagentModelWord.js +261 -0
- package/dist/model/tierVocabulary.d.ts +2 -0
- package/dist/model/tierVocabulary.js +17 -5
- package/dist/modelCapabilityProbe.d.ts +64 -0
- package/dist/modelCapabilityProbe.js +600 -0
- package/dist/modelIdentityResolvability.d.ts +3 -0
- package/dist/modelIdentityResolvability.js +26 -17
- package/dist/notifications.d.ts +6 -0
- package/dist/notifications.js +71 -23
- package/dist/outputStyleSeatCapability.d.ts +0 -3
- package/dist/outputStyleSeatCapability.js +0 -3
- package/dist/ownKey.d.ts +22 -0
- package/dist/ownKey.js +94 -3
- package/dist/panelReduce.d.ts +21 -10
- package/dist/panelReduce.js +728 -550
- package/dist/panelStateHolder.d.ts +3 -7
- package/dist/panelStateHolder.js +14 -130
- package/dist/peerLaneCapability.d.ts +0 -4
- package/dist/peerLaneCapability.js +0 -6
- package/dist/permissionRuleIssue.js +2 -0
- package/dist/permissionRulesWriteCapability.d.ts +2 -5
- package/dist/permissionRulesWriteCapability.js +8 -12
- package/dist/permissionWireCaps.d.ts +2 -2
- package/dist/permissionWireCaps.js +2 -0
- package/dist/permissionsAllowGrantCapability.d.ts +0 -4
- package/dist/permissionsAllowGrantCapability.js +0 -6
- package/dist/permissionsDeclaration.d.ts +0 -11
- package/dist/permissionsDeclaration.js +60 -53
- package/dist/pluginHooksWire.d.ts +46 -3
- package/dist/pluginHooksWire.js +219 -16
- package/dist/preemptWire.d.ts +44 -0
- package/dist/preemptWire.js +83 -0
- package/dist/printModelStatus.d.ts +63 -0
- package/dist/printModelStatus.js +155 -0
- package/dist/printToolResultFrame.js +15 -4
- package/dist/replayBody.d.ts +3 -0
- package/dist/replayBody.js +14 -0
- package/dist/request/taskRequest.d.ts +11 -6
- package/dist/request/taskRequest.js +112 -19
- package/dist/resumeRefusalCopy.d.ts +13 -9
- package/dist/resumeRefusalCopy.js +81 -118
- package/dist/retryStatus.d.ts +45 -0
- package/dist/retryStatus.js +185 -1
- package/dist/rewindArchiveCapability.d.ts +0 -4
- package/dist/rewindArchiveCapability.js +2 -10
- package/dist/rewindArchiveReading.d.ts +0 -1
- package/dist/rewindArchiveReading.js +0 -3
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +4 -2
- package/dist/runReattachPolicy.d.ts +31 -0
- package/dist/runReattachPolicy.js +46 -0
- package/dist/runTerminal.d.ts +3 -6
- package/dist/runTerminal.js +8 -9
- package/dist/sandboxWire.d.ts +3 -1
- package/dist/sandboxWire.js +76 -27
- package/dist/scenarioRefusal.d.ts +9 -0
- package/dist/scenarioRefusal.js +111 -0
- package/dist/scenarioWire.js +1 -1
- package/dist/seam.d.ts +48 -2
- package/dist/seam.js +25 -4
- package/dist/seatContract.d.ts +311 -18
- package/dist/seatContract.js +824 -100
- package/dist/selfOrchestrationDenial.js +7 -19
- package/dist/sessionIdSegment.d.ts +6 -0
- package/dist/sessionIdSegment.js +24 -0
- package/dist/sessionMemoryStatus.js +6 -11
- package/dist/sessionPolicyCapability.d.ts +2 -5
- package/dist/sessionPolicyCapability.js +8 -12
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
- package/dist/sessionSyncFileHistoryCapability.js +0 -3
- package/dist/settingsHooksSalvage.d.ts +44 -0
- package/dist/settingsHooksSalvage.js +211 -0
- package/dist/skillToolListsCapability.d.ts +2 -4
- package/dist/skillToolListsCapability.js +8 -9
- package/dist/sqlEngineCapability.d.ts +0 -4
- package/dist/sqlEngineCapability.js +0 -6
- package/dist/sseIdleTriage.js +3 -2
- package/dist/steerPriorityCapability.d.ts +0 -3
- package/dist/steerPriorityCapability.js +0 -3
- package/dist/streamDrainingLegs.d.ts +4 -0
- package/dist/streamDrainingLegs.js +6 -1
- package/dist/subagent/engineCompactWire.d.ts +0 -1
- package/dist/subagent/engineCompactWire.js +7 -5
- package/dist/subagent/engineSubagentResume.js +15 -9
- package/dist/subagent/engineTaskHandleWire.js +4 -7
- package/dist/subagentContentStore.d.ts +3 -0
- package/dist/subagentContentStore.js +22 -10
- package/dist/submitReopen.d.ts +24 -0
- package/dist/submitReopen.js +75 -0
- package/dist/terminalStatuses.d.ts +3 -0
- package/dist/terminalStatuses.js +10 -2
- package/dist/toolHistoryMismatch.js +3 -2
- package/dist/toolResult.d.ts +10 -1
- package/dist/toolResult.js +34 -6
- package/dist/toolRoster.d.ts +3 -4
- package/dist/toolRoster.js +21 -22
- package/dist/turnFailurePresentation.d.ts +39 -0
- package/dist/turnFailurePresentation.js +402 -0
- package/dist/usageAnalytics.js +6 -11
- package/dist/userAttachmentEnvelope.d.ts +1 -0
- package/dist/userAttachmentEnvelope.js +37 -7
- package/dist/userAttachmentSeat.d.ts +21 -0
- package/dist/userAttachmentSeat.js +75 -0
- package/dist/userInvokedSkillsCapability.d.ts +11 -4
- package/dist/userInvokedSkillsCapability.js +31 -10
- package/dist/webSearchBackendCapability.d.ts +0 -4
- package/dist/webSearchBackendCapability.js +0 -6
- package/dist/wireErrorTriage.d.ts +7 -0
- package/dist/wireErrorTriage.js +26 -23
- package/dist/wireFailureShape.d.ts +62 -5
- package/dist/wireFailureShape.js +106 -5
- package/dist/wireRefusalCopy.d.ts +25 -3
- package/dist/wireRefusalCopy.js +74 -80
- package/dist/workflowsJournalCapability.d.ts +2 -5
- package/dist/workflowsJournalCapability.js +8 -12
- package/dist/writeProtectionCapability.d.ts +0 -4
- package/dist/writeProtectionCapability.js +0 -6
- package/docs/INTEGRATION-CLIENTS.md +1775 -56
- package/package.json +6 -5
- package/dist/attachmentSeatCapability.d.ts +0 -12
- package/dist/attachmentSeatCapability.js +0 -23
- package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
- package/dist/hitl/approvalOutcomeNote.js +0 -29
- package/dist/sessionReadRedactionCapability.d.ts +0 -13
- package/dist/sessionReadRedactionCapability.js +0 -35
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { abortableSleep } from '../abortableSleep.js';
|
|
2
|
+
import { EN_MESSAGES } from '../i18n/messages.en.js';
|
|
3
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
2
4
|
import { corruptStoredRowContent, corruptStoredRowWhere, effectiveWireErrorCode } from '../wireErrorTriage.js';
|
|
5
|
+
import { readThrownStatusSlot } from '../wireFailureShape.js';
|
|
3
6
|
import { steerBodyOf, UNOBSERVED_STEER_PRIORITY } from '../controlRouter.js';
|
|
4
7
|
import { atMostOnceFailureClass } from '../atMostOnce.js';
|
|
5
8
|
import { readSteerReceipt } from '../steerReceipt.js';
|
|
6
9
|
import { resumeAttachReplayDisclosure, runningAttachOffered } from '../hitl/resumeRunningCard.js';
|
|
7
|
-
import { isSdkRunTerminal,
|
|
10
|
+
import { isSdkRunParked, isSdkRunTerminal, SDK_RUN_LIVE_STATUSES } from '../terminalStatuses.js';
|
|
8
11
|
import { SDK_APPROVAL_DECIDE_GATE_KINDS, SDK_PLAN_REVIEW_GATE_KINDS } from '../generated/sdkFactTables.js';
|
|
9
12
|
export const PLAN_REVIEW_GATE_KIND = 'plan_review';
|
|
10
13
|
const APPROVAL_LEG_GATE_KINDS = SDK_APPROVAL_DECIDE_GATE_KINDS;
|
|
@@ -40,7 +43,7 @@ export function askParkForeignGateKind(row) {
|
|
|
40
43
|
export const PLAN_REVIEW_STATES = Object.freeze(['needs_review']);
|
|
41
44
|
export const ASK_PARK_STATES = Object.freeze(['suspended']);
|
|
42
45
|
export const RUNNING_STATES = Object.freeze(['running']);
|
|
43
|
-
export const CLAIM_HELD_STATES =
|
|
46
|
+
export const CLAIM_HELD_STATES = SDK_RUN_LIVE_STATUSES;
|
|
44
47
|
export function selfHealSubmissionDisposition(outcome) {
|
|
45
48
|
switch (outcome.kind) {
|
|
46
49
|
case 'decision-pending':
|
|
@@ -76,16 +79,6 @@ function sessionOpts(deps) {
|
|
|
76
79
|
const sessionId = deps?.sessionId;
|
|
77
80
|
return typeof sessionId === 'string' && sessionId.length > 0 ? { session: sessionId } : {};
|
|
78
81
|
}
|
|
79
|
-
function errorSlot(e, key) {
|
|
80
|
-
if (e === null || e === undefined)
|
|
81
|
-
return undefined;
|
|
82
|
-
try {
|
|
83
|
-
return e[key];
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
82
|
function describeFailure(e) {
|
|
90
83
|
const where = corruptStoredRowWhere(e);
|
|
91
84
|
const rowNote = where === undefined ? '' : ` — ${corruptStoredRowContent(where)}`;
|
|
@@ -452,6 +445,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
|
|
|
452
445
|
if (gateLeg === 'approval')
|
|
453
446
|
return askParkArm(taskId, signal, runs, deps);
|
|
454
447
|
let status = signal.activeTaskStatus;
|
|
448
|
+
const statusFresh = status === null;
|
|
455
449
|
if (status === null) {
|
|
456
450
|
if (typeof runs?.get !== 'function') {
|
|
457
451
|
return { kind: 'state-unknown', taskId, detail: 'this client exposes no durable run verbs' };
|
|
@@ -468,8 +462,11 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
|
|
|
468
462
|
if (status === null) {
|
|
469
463
|
return { kind: 'state-unknown', taskId, detail: 'the engine reported no status for that run' };
|
|
470
464
|
}
|
|
465
|
+
if (isSdkRunTerminal(status))
|
|
466
|
+
return { kind: 'running-settled', taskId, status };
|
|
467
|
+
const triageGate = signal.pendingGate && !statusFresh ? { pendingGateKind: signal.pendingGate.kind ?? null } : {};
|
|
471
468
|
if (gateKind !== null)
|
|
472
|
-
return { kind: 'not-parked', taskId, status };
|
|
469
|
+
return { kind: 'not-parked', taskId, status, ...triageGate };
|
|
473
470
|
if (PLAN_REVIEW_STATES.includes(status))
|
|
474
471
|
return planReviewArm(taskId, signal, deps);
|
|
475
472
|
if (ASK_PARK_STATES.includes(status))
|
|
@@ -477,7 +474,7 @@ export async function attemptActiveRunSelfHeal(signal, runs, deps) {
|
|
|
477
474
|
if (RUNNING_STATES.includes(status)) {
|
|
478
475
|
return runningChoiceArm(taskId, status, signal, signal.activeTaskStatus !== null, runs, deps);
|
|
479
476
|
}
|
|
480
|
-
return { kind: 'not-parked', taskId, status };
|
|
477
|
+
return { kind: 'not-parked', taskId, status, ...triageGate };
|
|
481
478
|
}
|
|
482
479
|
async function planVerdict(taskId, deps) {
|
|
483
480
|
try {
|
|
@@ -576,7 +573,7 @@ async function probeRunStatusOnce(taskId, durable, durableGet, deps) {
|
|
|
576
573
|
answered = true;
|
|
577
574
|
}
|
|
578
575
|
catch (e) {
|
|
579
|
-
if (
|
|
576
|
+
if (typeof e === 'object' && e !== null && readThrownStatusSlot(e) === 404)
|
|
580
577
|
ghost = true;
|
|
581
578
|
else
|
|
582
579
|
errorCode = failureWireCode(e);
|
|
@@ -619,6 +616,8 @@ async function staleParkArm(taskId, busy, runs, deps) {
|
|
|
619
616
|
return runningChoiceArm(taskId, fresh, busy, false, runs, deps);
|
|
620
617
|
if (PLAN_REVIEW_STATES.includes(fresh))
|
|
621
618
|
return planReviewArm(taskId, busy, deps);
|
|
619
|
+
if (isSdkRunTerminal(fresh))
|
|
620
|
+
return { kind: 'ask-run-settled', taskId, status: fresh };
|
|
622
621
|
if (!ASK_PARK_STATES.includes(fresh))
|
|
623
622
|
return reopenFailed;
|
|
624
623
|
const offer = deps?.offerStaleParkChoice;
|
|
@@ -656,6 +655,10 @@ async function staleParkArm(taskId, busy, runs, deps) {
|
|
|
656
655
|
if (afterCard.status === null)
|
|
657
656
|
return withFailureCode(reopenFailedAfterCard, afterCard.errorCode);
|
|
658
657
|
if (!ASK_PARK_STATES.includes(afterCard.status)) {
|
|
658
|
+
if (isSdkRunTerminal(afterCard.status))
|
|
659
|
+
return { kind: 'ask-run-settled', taskId, status: afterCard.status };
|
|
660
|
+
if (RUNNING_STATES.includes(afterCard.status))
|
|
661
|
+
return { kind: 'not-parked', taskId, status: afterCard.status };
|
|
659
662
|
return !CLAIM_HELD_STATES.includes(afterCard.status) ? reopenFailed : reopenFailedAfterCard;
|
|
660
663
|
}
|
|
661
664
|
const recheck = await readOwnedPendingCount(recheckOwnedPending, deps);
|
|
@@ -737,14 +740,10 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
|
|
|
737
740
|
return { kind: 'running-not-found', taskId };
|
|
738
741
|
if (probeCallerAborted())
|
|
739
742
|
return notParked;
|
|
740
|
-
if (fresh !== null
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return askParkArm(taskId, busy, runs, deps);
|
|
745
|
-
if (isSdkRunTerminal(fresh))
|
|
746
|
-
return { kind: 'running-settled', taskId, status: fresh };
|
|
747
|
-
return { kind: 'not-parked', taskId, status: fresh };
|
|
743
|
+
if (fresh !== null) {
|
|
744
|
+
const routed = await routeFreshNonRunning(fresh, taskId, busy, runs, deps);
|
|
745
|
+
if (routed !== undefined)
|
|
746
|
+
return routed;
|
|
748
747
|
}
|
|
749
748
|
}
|
|
750
749
|
const declineKey = runningChoiceDeclineKey(deps?.sessionId, taskId);
|
|
@@ -795,6 +794,16 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
|
|
|
795
794
|
}
|
|
796
795
|
}
|
|
797
796
|
if (choice === 'cancel' && canCancel && runs?.cancel !== undefined && runs.get !== undefined) {
|
|
797
|
+
if (probeCallerAborted())
|
|
798
|
+
return notParked;
|
|
799
|
+
const preFire = await probeRunStatusOnce(taskId, runs, runs.get, deps);
|
|
800
|
+
if (preFire.ghost)
|
|
801
|
+
return { kind: 'running-not-found', taskId };
|
|
802
|
+
if (probeCallerAborted() || preFire.status === null)
|
|
803
|
+
return notParked;
|
|
804
|
+
const rerouted = await routeFreshNonRunning(preFire.status, taskId, busy, runs, deps);
|
|
805
|
+
if (rerouted !== undefined)
|
|
806
|
+
return rerouted;
|
|
798
807
|
const verdict = await cancelAndConfirmRelease(taskId, runs, runs.get, deps);
|
|
799
808
|
if (verdict.outcome === 'released') {
|
|
800
809
|
return { kind: 'running-cancelled', taskId, ...(verdict.engineStatedRelease ? { releaseConfirmedByEngine: true } : {}) };
|
|
@@ -814,38 +823,45 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
|
|
|
814
823
|
return { kind: 'running-attach', taskId };
|
|
815
824
|
return notParked;
|
|
816
825
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
826
|
+
async function routeFreshNonRunning(fresh, taskId, busy, runs, deps) {
|
|
827
|
+
if (RUNNING_STATES.includes(fresh))
|
|
828
|
+
return undefined;
|
|
829
|
+
if (PLAN_REVIEW_STATES.includes(fresh))
|
|
830
|
+
return planReviewArm(taskId, busy, deps);
|
|
831
|
+
if (ASK_PARK_STATES.includes(fresh))
|
|
832
|
+
return askParkArm(taskId, busy, runs, deps);
|
|
833
|
+
if (isSdkRunTerminal(fresh))
|
|
834
|
+
return { kind: 'running-settled', taskId, status: fresh };
|
|
835
|
+
return { kind: 'not-parked', taskId, status: fresh };
|
|
836
|
+
}
|
|
837
|
+
export const INTERACTIVE_WAY_OUT = EN_MESSAGES['session.selfHeal.wayOut.interactive'];
|
|
838
|
+
const say = (lang, key, params) => renderMessage(msg(key, params), lang);
|
|
839
|
+
function gateKindPhrase(kind, lang) {
|
|
840
|
+
return kind ? say(lang, 'session.selfHeal.gate.kind', { kind }) : say(lang, 'session.selfHeal.gate.generic');
|
|
822
841
|
}
|
|
823
|
-
function decidePathClause(signal) {
|
|
842
|
+
function decidePathClause(signal, lang) {
|
|
824
843
|
const decidePath = signal?.pendingGate?.decidePath;
|
|
825
844
|
if (!decidePath)
|
|
826
845
|
return '';
|
|
827
|
-
return (
|
|
828
|
-
` decided at POST ${decidePath} — deciding it releases the session.`);
|
|
846
|
+
return say(lang, 'session.selfHeal.decidePathClause', { gate: gateKindPhrase(signal?.pendingGate?.kind, lang), decidePath });
|
|
829
847
|
}
|
|
830
|
-
function governanceOriginClause(signal) {
|
|
831
|
-
return signal?.pendingGate?.governanceForced === true
|
|
832
|
-
? ' That gate is enforced by this deployment\'s governance policy, not by a permission rule you set.'
|
|
833
|
-
: '';
|
|
848
|
+
function governanceOriginClause(signal, lang) {
|
|
849
|
+
return signal?.pendingGate?.governanceForced === true ? say(lang, 'session.selfHeal.governanceOrigin') : '';
|
|
834
850
|
}
|
|
835
|
-
function lastActivityClause(signal) {
|
|
851
|
+
function lastActivityClause(signal, lang) {
|
|
836
852
|
const ms = signal?.msSinceLastActivity;
|
|
837
853
|
if (typeof ms !== 'number' || !Number.isFinite(ms) || ms < 0)
|
|
838
854
|
return '';
|
|
839
855
|
const human = ms < 120_000 ? `${String(Math.max(1, Math.round(ms / 1000)))}s` : `${String(Math.round(ms / 60_000))}m`;
|
|
840
|
-
return
|
|
856
|
+
return say(lang, 'session.selfHeal.lastActivity', { ago: human });
|
|
841
857
|
}
|
|
842
|
-
export function activeRunSelfHealRow(outcome, signal, copy, origin, follow) {
|
|
858
|
+
export function activeRunSelfHealRow(outcome, signal, copy, origin, follow, lang) {
|
|
843
859
|
const override = copy?.rowFor?.(outcome, signal);
|
|
844
860
|
if (typeof override === 'string')
|
|
845
861
|
return override;
|
|
846
862
|
const following = follow?.following === true && steerFollowIntent(outcome)?.kind === 'tail';
|
|
847
863
|
if (origin === 'injected')
|
|
848
|
-
return injectedSubmissionRow(outcome, following);
|
|
864
|
+
return injectedSubmissionRow(outcome, following, lang);
|
|
849
865
|
const engineDecide = copy?.engineDecidePath !== false;
|
|
850
866
|
const keep = (outcome.kind === 'plan-review-reopen-failed' || outcome.kind === 'ask-reopen-failed') &&
|
|
851
867
|
outcome.decisionInFlight !== true &&
|
|
@@ -853,101 +869,77 @@ export function activeRunSelfHealRow(outcome, signal, copy, origin, follow) {
|
|
|
853
869
|
(outcome.kind !== 'plan-review-reopen-failed' || outcome.dismissedByUser !== true)
|
|
854
870
|
? keepSessionWayOutOf(copy)
|
|
855
871
|
: null;
|
|
856
|
-
const base = activeRunSelfHealBaseRow(outcome,
|
|
857
|
-
const viaEngine = engineDecide ? decidePathClause(signal) : '';
|
|
872
|
+
const base = activeRunSelfHealBaseRow(outcome, copy?.wayOut ?? say(lang, 'session.selfHeal.wayOut.interactive'), following, keep, engineDecide, lang);
|
|
873
|
+
const viaEngine = engineDecide ? decidePathClause(signal, lang) : '';
|
|
858
874
|
switch (outcome.kind) {
|
|
859
875
|
case 'not-parked':
|
|
860
|
-
return base + lastActivityClause(signal) + viaEngine + governanceOriginClause(signal);
|
|
876
|
+
return base + lastActivityClause(signal, lang) + (outcome.pendingGateKind !== undefined ? viaEngine + governanceOriginClause(signal, lang) : '');
|
|
861
877
|
case 'state-unknown':
|
|
862
|
-
return base + viaEngine + governanceOriginClause(signal);
|
|
878
|
+
return base + viaEngine + governanceOriginClause(signal, lang);
|
|
863
879
|
default:
|
|
864
|
-
return base + governanceOriginClause(signal);
|
|
880
|
+
return base + governanceOriginClause(signal, lang);
|
|
865
881
|
}
|
|
866
882
|
}
|
|
867
|
-
|
|
868
|
-
const
|
|
869
|
-
const
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
const id = 'taskId' in outcome && outcome.taskId ? ` (id ${outcome.taskId})` : '';
|
|
873
|
-
if (outcome.kind === 'running-attach') {
|
|
874
|
-
return `${lead} was not delivered: you chose to watch the reply already in progress${id} instead, and sema is replaying that reply here, so the part already shown above will appear again below. sema did not retry, so the model has not seen it.`;
|
|
875
|
-
}
|
|
883
|
+
function injectedSubmissionRow(outcome, following = false, lang) {
|
|
884
|
+
const lead = msg('session.selfHeal.injected.lead');
|
|
885
|
+
const id = 'taskId' in outcome && outcome.taskId ? msg('session.selfHeal.injected.id', { id: outcome.taskId }) : '';
|
|
886
|
+
if (outcome.kind === 'running-attach')
|
|
887
|
+
return say(lang, 'session.selfHeal.injected.attach', { lead, id });
|
|
876
888
|
if (outcome.kind === 'running-steer-failed') {
|
|
877
889
|
return outcome.delivery === 'unknown'
|
|
878
|
-
?
|
|
879
|
-
|
|
880
|
-
`is not safe; watch that reply for what it does next.`
|
|
881
|
-
: `${lead} was not delivered: passing it to the reply already in progress${id} was refused (${outcome.detail}). ` +
|
|
882
|
-
`sema did not retry, so the model has not seen it.`;
|
|
890
|
+
? say(lang, 'session.selfHeal.injected.steerUnknown', { lead, id, detail: outcome.detail })
|
|
891
|
+
: say(lang, 'session.selfHeal.injected.steerRejected', { lead, id, detail: outcome.detail });
|
|
883
892
|
}
|
|
884
893
|
if ((outcome.kind === 'ask-reopen-failed' || outcome.kind === 'plan-review-reopen-failed') && outcome.decisionInFlight === true) {
|
|
885
|
-
return (
|
|
886
|
-
`it is waiting on is still on its way. sema did not retry, so the model has not seen it.`);
|
|
894
|
+
return say(lang, 'session.selfHeal.injected.decisionInFlight', { lead, id });
|
|
887
895
|
}
|
|
888
896
|
if (outcome.kind === 'plan-review-reopen-failed' && outcome.dismissedByUser === true) {
|
|
889
|
-
return (
|
|
890
|
-
`you closed that approval card — ${USER_CLOSED_CARD_NOT_PUT_BACK}. Send a message when you want the card back; ` +
|
|
891
|
-
`sema did not retry, so the model has not seen it.`);
|
|
897
|
+
return say(lang, 'session.selfHeal.injected.dismissedPlan', { lead, id, closed: msg('session.selfHeal.userClosedCardNotPutBack') });
|
|
892
898
|
}
|
|
893
899
|
if (outcome.kind === 'running-steered' && outcome.delivery === 'queued') {
|
|
894
|
-
const queuedOn =
|
|
900
|
+
const queuedOn = msg('session.selfHeal.injected.queuedOn', { lead, id });
|
|
895
901
|
const reopened = reopenedOfOutcome(outcome);
|
|
896
|
-
if (reopened !== null && reopenDelivered(reopened))
|
|
897
|
-
return
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
`back, and the message is picked up once that decision is made.`);
|
|
905
|
-
}
|
|
906
|
-
const noView = reopenRefusedForNoPresentationSurface(reopened) ? ` (${NO_CARD_VIEW_ATTACHED})` : '';
|
|
907
|
-
return `${queuedOn} sema could not show here${noView}; the message is picked up only once that decision is made.`;
|
|
902
|
+
if (reopened !== null && reopenDelivered(reopened))
|
|
903
|
+
return say(lang, 'session.selfHeal.injected.queuedShown', { queuedOn });
|
|
904
|
+
if (reopenRefusedForDecisionInFlight(reopened))
|
|
905
|
+
return say(lang, 'session.selfHeal.injected.queuedInFlight', { queuedOn });
|
|
906
|
+
if (reopenRefusedForUserDismissal(reopened))
|
|
907
|
+
return say(lang, 'session.selfHeal.injected.queuedDismissed', { queuedOn });
|
|
908
|
+
const noView = reopenRefusedForNoPresentationSurface(reopened) ? msg('session.selfHeal.noCardView.inParens') : '';
|
|
909
|
+
return say(lang, 'session.selfHeal.injected.queuedCannotShow', { queuedOn, noView });
|
|
908
910
|
}
|
|
909
911
|
if (outcome.kind === 'running-steered' && outcome.delivery === 'parked_for_wake') {
|
|
910
|
-
return (
|
|
911
|
-
`instead of starting a new reply, and sema did not retry it.`);
|
|
912
|
+
return say(lang, 'session.selfHeal.injected.parkedForWake', { lead, id });
|
|
912
913
|
}
|
|
913
914
|
if (outcome.kind === 'running-steered' && outcome.delivery !== 'applied') {
|
|
914
|
-
const unknown =
|
|
915
|
-
`so sema cannot tell whether that reply will pick it up`;
|
|
915
|
+
const unknown = msg('session.selfHeal.injected.unknownDelivery', { lead, id });
|
|
916
916
|
return following
|
|
917
|
-
?
|
|
918
|
-
|
|
919
|
-
: `${unknown} — watch that reply before deciding whether anything needs to be sent again.`;
|
|
917
|
+
? say(lang, 'session.selfHeal.injected.unknownDeliveryFollowing', { unknown })
|
|
918
|
+
: say(lang, 'session.selfHeal.injected.unknownDeliveryWatch', { unknown });
|
|
920
919
|
}
|
|
921
920
|
switch (selfHealSubmissionDisposition(outcome)) {
|
|
922
921
|
case 'held-for-decision':
|
|
923
|
-
return (
|
|
924
|
-
`sema kept the message queued and will send it after you answer the open card.`);
|
|
922
|
+
return say(lang, 'session.selfHeal.injected.heldForDecision', { lead, id });
|
|
925
923
|
case 'resending':
|
|
926
924
|
return 'releaseConfirmedByEngine' in outcome && outcome.releaseConfirmedByEngine === true
|
|
927
|
-
?
|
|
928
|
-
|
|
929
|
-
: `${lead} was held back because this session was busy with an earlier reply${id}; that reply is now reported ` +
|
|
930
|
-
`as finished, so sema is sending the message now — nothing for you to do (if the session has not quite ` +
|
|
931
|
-
`freed up yet, it may be held back once more).`;
|
|
925
|
+
? say(lang, 'session.selfHeal.injected.resendingConfirmed', { lead, id })
|
|
926
|
+
: say(lang, 'session.selfHeal.injected.resendingInferred', { lead, id });
|
|
932
927
|
case 'handed-off':
|
|
933
928
|
return following
|
|
934
|
-
?
|
|
935
|
-
|
|
936
|
-
: `${lead} was passed to the reply already in progress${id} instead of starting a new one — ` +
|
|
937
|
-
`watch that reply for what it does with it.`;
|
|
929
|
+
? say(lang, 'session.selfHeal.injected.handedOffFollowing', { lead, id })
|
|
930
|
+
: say(lang, 'session.selfHeal.injected.handedOffWatch', { lead, id });
|
|
938
931
|
case 'not-delivered': {
|
|
939
932
|
const noView = (outcome.kind === 'ask-reopen-failed' || outcome.kind === 'plan-review-reopen-failed') && outcome.noPresentationSurface === true
|
|
940
|
-
?
|
|
933
|
+
? msg('session.selfHeal.noCardView.inParens')
|
|
941
934
|
: '';
|
|
942
|
-
return (
|
|
943
|
-
`you could answer to free it${noView}. sema did not retry, so the model has not seen it.`);
|
|
935
|
+
return say(lang, 'session.selfHeal.injected.notDelivered', { lead, id, noView });
|
|
944
936
|
}
|
|
945
937
|
}
|
|
946
938
|
}
|
|
947
|
-
function decisionInFlightRow(parkedOn) {
|
|
948
|
-
return (
|
|
949
|
-
|
|
950
|
-
|
|
939
|
+
function decisionInFlightRow(parkedOn, taskId, lang) {
|
|
940
|
+
return say(lang, 'session.selfHeal.decisionInFlight', {
|
|
941
|
+
parkedOn: msg(parkedOn === 'ask' ? 'session.selfHeal.parkedOn.ask' : 'session.selfHeal.parkedOn.plan', { taskId }),
|
|
942
|
+
});
|
|
951
943
|
}
|
|
952
944
|
function keepSessionWayOutOf(copy) {
|
|
953
945
|
if (typeof copy?.keepSessionWayOut !== 'function')
|
|
@@ -961,282 +953,182 @@ function keepSessionWayOutOf(copy) {
|
|
|
961
953
|
return null;
|
|
962
954
|
}
|
|
963
955
|
}
|
|
964
|
-
function activeRunSelfHealBaseRow(outcome,
|
|
956
|
+
function activeRunSelfHealBaseRow(outcome, wayOut, following = false, keepSessionWayOut = null, engineDecide = true, lang) {
|
|
965
957
|
switch (outcome.kind) {
|
|
966
958
|
case 'decision-pending':
|
|
967
|
-
return (
|
|
968
|
-
`is waiting on a decision you have not made yet, and there is a decision card open for it. ` +
|
|
969
|
-
`sema did NOT cancel it — answering that card is what releases the session, and cancelling ` +
|
|
970
|
-
`would decide it for you. Your message was NOT sent; answer the open card and send it again.`);
|
|
959
|
+
return say(lang, 'session.selfHeal.row.decisionPending', { handle: outcome.taskId ? msg('session.selfHeal.handle.run', { taskId: outcome.taskId }) : '' });
|
|
971
960
|
case 'ask-reopened':
|
|
972
|
-
if (outcome.firstSight)
|
|
973
|
-
return (
|
|
974
|
-
|
|
975
|
-
`message again. (sema did NOT cancel the run: cancelling would have decided it for you.)`);
|
|
976
|
-
}
|
|
977
|
-
return (`The previous turn is parked waiting for your decision (run ${outcome.taskId}), which is why ` +
|
|
978
|
-
`nothing new could start — that card was closed without being answered, so sema reopened it. ` +
|
|
979
|
-
`Answer it and send your message again. (sema did NOT cancel the run: cancelling would have ` +
|
|
980
|
-
`decided it for you.)`);
|
|
961
|
+
if (outcome.firstSight)
|
|
962
|
+
return say(lang, 'session.selfHeal.row.askReopened.firstSight', { taskId: outcome.taskId });
|
|
963
|
+
return say(lang, 'session.selfHeal.row.askReopened.reseen', { taskId: outcome.taskId });
|
|
981
964
|
case 'plan-review-reopened':
|
|
982
|
-
if (outcome.firstSight)
|
|
983
|
-
return (
|
|
984
|
-
|
|
985
|
-
`your message again. (sema did NOT cancel the run: cancelling would have thrown the plan away ` +
|
|
986
|
-
`on your behalf.)`);
|
|
987
|
-
}
|
|
988
|
-
return (`The previous turn is parked waiting for you to review its plan (run ${outcome.taskId}), which is ` +
|
|
989
|
-
`why nothing new could start — that approval card was closed without being answered, so sema ` +
|
|
990
|
-
`reopened it. Answer it and send your message again. (sema did NOT cancel the run: cancelling ` +
|
|
991
|
-
`would have thrown the plan away on your behalf.)`);
|
|
965
|
+
if (outcome.firstSight)
|
|
966
|
+
return say(lang, 'session.selfHeal.row.planReviewReopened.firstSight', { taskId: outcome.taskId });
|
|
967
|
+
return say(lang, 'session.selfHeal.row.planReviewReopened.reseen', { taskId: outcome.taskId });
|
|
992
968
|
case 'ask-decided-without-card':
|
|
993
|
-
if (outcome.releaseConfirmedByEngine === true)
|
|
994
|
-
return (
|
|
995
|
-
|
|
996
|
-
`sema is re-sending your message.`);
|
|
997
|
-
}
|
|
998
|
-
return (`The previous turn was parked on an approval that your permission rules decided on their own (no card was ` +
|
|
999
|
-
`needed); run ${outcome.taskId} resumed and has since finished — sema is re-sending your message; if that ` +
|
|
1000
|
-
`run has not fully let go of the session yet, you may have to send it once more.`);
|
|
969
|
+
if (outcome.releaseConfirmedByEngine === true)
|
|
970
|
+
return say(lang, 'session.selfHeal.row.askDecided.confirmed', { taskId: outcome.taskId });
|
|
971
|
+
return say(lang, 'session.selfHeal.row.askDecided.inferred', { taskId: outcome.taskId });
|
|
1001
972
|
case 'ask-decided-release-unknown':
|
|
1002
|
-
return (
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
973
|
+
return say(lang, 'session.selfHeal.row.askDecided.releaseUnknown', {
|
|
974
|
+
taskId: outcome.taskId,
|
|
975
|
+
status: outcome.lastStatus ? msg('session.selfHeal.lastEngineStatus', { status: outcome.lastStatus }) : '',
|
|
976
|
+
});
|
|
1006
977
|
case 'ask-reopen-failed': {
|
|
1007
978
|
if (outcome.decisionInFlight === true)
|
|
1008
|
-
return decisionInFlightRow(
|
|
1009
|
-
const viaEngine = engineDecide && outcome.decidePath
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
`not reopen that card here${noView}. It did NOT cancel the run — that would have decided it for you. ` +
|
|
1015
|
-
(keepSessionWayOut !== null
|
|
1016
|
-
? `Your message was NOT sent. To keep this conversation, ${keepSessionWayOut}: the card comes back when the session resumes, if it is still waiting. Or ${wayOut} if you no longer want it.${viaEngine}`
|
|
1017
|
-
: `Your message was NOT sent; ${wayOut} if you no longer want it.${viaEngine}`));
|
|
979
|
+
return decisionInFlightRow('ask', outcome.taskId, lang);
|
|
980
|
+
const viaEngine = engineDecide && outcome.decidePath ? msg('session.selfHeal.viaEngine', { decidePath: outcome.decidePath }) : '';
|
|
981
|
+
const noView = outcome.noPresentationSurface === true ? msg('session.selfHeal.noCardView.afterColon') : '';
|
|
982
|
+
return keepSessionWayOut !== null
|
|
983
|
+
? say(lang, 'session.selfHeal.row.askReopenFailed.withKeep', { taskId: outcome.taskId, noView, keep: keepSessionWayOut, wayOut, viaEngine })
|
|
984
|
+
: say(lang, 'session.selfHeal.row.askReopenFailed.noKeep', { taskId: outcome.taskId, noView, wayOut, viaEngine });
|
|
1018
985
|
}
|
|
1019
986
|
case 'plan-review-reopen-failed': {
|
|
1020
987
|
if (outcome.decisionInFlight === true)
|
|
1021
|
-
return decisionInFlightRow(
|
|
988
|
+
return decisionInFlightRow('plan', outcome.taskId, lang);
|
|
1022
989
|
if (outcome.dismissedByUser === true) {
|
|
1023
|
-
return (
|
|
1024
|
-
`${USER_CLOSED_CARD_NOT_PUT_BACK}. It did NOT cancel the run — that would have discarded the plan for you. ` +
|
|
1025
|
-
`Your message was NOT sent; send it again to bring the card back.`);
|
|
990
|
+
return say(lang, 'session.selfHeal.row.planReopenFailed.dismissed', { taskId: outcome.taskId, closed: msg('session.selfHeal.userClosedCardNotPutBack') });
|
|
1026
991
|
}
|
|
1027
|
-
const viaEngine = engineDecide && outcome.decidePath
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
`reopen that approval card${noView}. It did NOT cancel the run — that would have discarded the plan for ` +
|
|
1033
|
-
(keepSessionWayOut !== null
|
|
1034
|
-
? `you. Your message was NOT sent. To keep this conversation, ${keepSessionWayOut}: the card comes back when the session resumes, if it is still waiting. Or ${wayOut} if you no longer want that plan.${viaEngine}`
|
|
1035
|
-
: `you. Your message was NOT sent; ${wayOut} if you no longer want that plan.${viaEngine}`));
|
|
992
|
+
const viaEngine = engineDecide && outcome.decidePath ? msg('session.selfHeal.viaEngine', { decidePath: outcome.decidePath }) : '';
|
|
993
|
+
const noView = outcome.noPresentationSurface === true ? msg('session.selfHeal.noCardView.afterColon') : '';
|
|
994
|
+
return keepSessionWayOut !== null
|
|
995
|
+
? say(lang, 'session.selfHeal.row.planReopenFailed.withKeep', { taskId: outcome.taskId, noView, keep: keepSessionWayOut, wayOut, viaEngine })
|
|
996
|
+
: say(lang, 'session.selfHeal.row.planReopenFailed.noKeep', { taskId: outcome.taskId, noView, wayOut, viaEngine });
|
|
1036
997
|
}
|
|
1037
998
|
case 'running-steered': {
|
|
1038
|
-
const
|
|
1039
|
-
const textOnly =
|
|
999
|
+
const taskId = outcome.taskId;
|
|
1000
|
+
const textOnly = msg('session.selfHeal.row.steered.textOnly');
|
|
1040
1001
|
if (outcome.delivery === 'applied') {
|
|
1041
|
-
return (
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
(following
|
|
1045
|
-
|
|
1046
|
-
: `watch that run for what it does with it.`));
|
|
1002
|
+
return say(lang, 'session.selfHeal.row.steered.applied', {
|
|
1003
|
+
taskId,
|
|
1004
|
+
textOnly,
|
|
1005
|
+
tail: msg(following ? 'session.selfHeal.row.steered.tail.following' : 'session.selfHeal.row.steered.tail.watch'),
|
|
1006
|
+
});
|
|
1047
1007
|
}
|
|
1048
1008
|
if (outcome.delivery === 'queued') {
|
|
1049
|
-
const parked = outcome.status ?
|
|
1009
|
+
const parked = outcome.status ? msg('session.selfHeal.row.steered.parked.withStatus', { status: outcome.status }) : msg('session.selfHeal.row.steered.parked.plain');
|
|
1050
1010
|
const reopened = reopenedOfOutcome(outcome);
|
|
1051
1011
|
const next = reopened !== null && reopenDelivered(reopened)
|
|
1052
|
-
?
|
|
1012
|
+
? msg('session.selfHeal.row.steered.next.shown')
|
|
1053
1013
|
: reopenRefusedForDecisionInFlight(reopened)
|
|
1054
|
-
?
|
|
1055
|
-
`that run moves on once the engine applies it.`
|
|
1014
|
+
? msg('session.selfHeal.row.steered.next.inFlight')
|
|
1056
1015
|
: reopenRefusedForUserDismissal(reopened)
|
|
1057
|
-
?
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
return (`${handle} is not actually working right now: the engine reports it ${parked} on a decision it needs ` +
|
|
1064
|
-
`from you, so it queued your message on that park instead of running it. ${next} ${textOnly} ` +
|
|
1065
|
-
`Nothing was cancelled, and your message did NOT start a new turn.`);
|
|
1016
|
+
? msg('session.selfHeal.row.steered.next.dismissed')
|
|
1017
|
+
: msg('session.selfHeal.row.steered.next.cannotShow', {
|
|
1018
|
+
noView: reopenRefusedForNoPresentationSurface(reopened) ? msg('session.selfHeal.noCardView.inParens') : '',
|
|
1019
|
+
wayOut,
|
|
1020
|
+
});
|
|
1021
|
+
return say(lang, 'session.selfHeal.row.steered.queued', { taskId, parked, next, textOnly });
|
|
1066
1022
|
}
|
|
1067
1023
|
if (outcome.delivery === 'parked_for_wake') {
|
|
1068
|
-
return (
|
|
1069
|
-
`running it — a parked message is delivered only if this session is woken on the engine ` +
|
|
1070
|
-
`(POST /v1/sessions/:id/wake), which sema does not do here. That run is no longer holding this ` +
|
|
1071
|
-
`session: send your message again to run it as a new turn — but note that the parked copy is NOT ` +
|
|
1072
|
-
`discarded, so if anything ever wakes this session on the engine that instruction would run a ` +
|
|
1073
|
-
`second time. ${textOnly} Nothing was cancelled.`);
|
|
1024
|
+
return say(lang, 'session.selfHeal.row.steered.parkedForWake', { taskId, textOnly });
|
|
1074
1025
|
}
|
|
1075
|
-
return (
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1026
|
+
return say(lang, 'session.selfHeal.row.steered.unknown', {
|
|
1027
|
+
taskId,
|
|
1028
|
+
reported: outcome.status ? msg('session.selfHeal.row.steered.reported', { status: outcome.status }) : '',
|
|
1029
|
+
textOnly,
|
|
1030
|
+
tail: msg(following ? 'session.selfHeal.row.steered.unknownTail.following' : 'session.selfHeal.row.steered.unknownTail.watch'),
|
|
1031
|
+
});
|
|
1081
1032
|
}
|
|
1082
1033
|
case 'running-steer-failed':
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
`Your message was NOT sent; send it again if you still want it.`);
|
|
1087
|
-
}
|
|
1088
|
-
return (`sema sent your message to the running run (run ${outcome.taskId}) but could not confirm what happened ` +
|
|
1089
|
-
`to it (${outcome.detail}). A steer is not safe to send twice, so sema did NOT retry it, and it did NOT ` +
|
|
1090
|
-
`cancel that run. That run may or may not have received your message — watch what it does next ` +
|
|
1091
|
-
`before sending it again.`);
|
|
1034
|
+
return outcome.delivery === 'rejected'
|
|
1035
|
+
? say(lang, 'session.selfHeal.row.steerFailed.rejected', { taskId: outcome.taskId, detail: outcome.detail })
|
|
1036
|
+
: say(lang, 'session.selfHeal.row.steerFailed.unknown', { taskId: outcome.taskId, detail: outcome.detail });
|
|
1092
1037
|
case 'running-attach':
|
|
1093
|
-
return (
|
|
1038
|
+
return say(lang, 'session.selfHeal.row.attach', { disclosure: resumeAttachReplayDisclosure(outcome.taskId) });
|
|
1094
1039
|
case 'running-cancelled':
|
|
1095
1040
|
return outcome.releaseConfirmedByEngine === true
|
|
1096
|
-
?
|
|
1097
|
-
|
|
1098
|
-
: `You chose to cancel run ${outcome.taskId}. The engine now reports that run as finished, so sema is ` +
|
|
1099
|
-
`sending your message now; if that run has not fully let go of the session yet, you may have to send ` +
|
|
1100
|
-
`it once more.`;
|
|
1041
|
+
? say(lang, 'session.selfHeal.row.cancelled.confirmed', { taskId: outcome.taskId })
|
|
1042
|
+
: say(lang, 'session.selfHeal.row.cancelled.reported', { taskId: outcome.taskId });
|
|
1101
1043
|
case 'running-cancel-timeout': {
|
|
1102
1044
|
const waited = `${String(Math.max(1, Math.round(outcome.waitedMs / 1000)))}s`;
|
|
1103
|
-
if (outcome.aborted)
|
|
1104
|
-
return (
|
|
1105
|
-
`confirming (${waited} in). Cancelling is asynchronous, so that run may still be winding down and ` +
|
|
1106
|
-
`may still hold this session. Your message was NOT sent; send it again in a moment, or ${wayOut}.`);
|
|
1107
|
-
}
|
|
1045
|
+
if (outcome.aborted)
|
|
1046
|
+
return say(lang, 'session.selfHeal.row.cancelTimeout.aborted', { taskId: outcome.taskId, waited, wayOut });
|
|
1108
1047
|
if (!outcome.confirmedHeld) {
|
|
1109
|
-
return (
|
|
1110
|
-
`within ${waited}, so it cannot confirm whether the session was released. Your message was NOT sent; ` +
|
|
1111
|
-
`send it again in a moment (if that run really is gone it will just run), or ${wayOut}.`);
|
|
1048
|
+
return say(lang, 'session.selfHeal.row.cancelTimeout.unread', { taskId: outcome.taskId, waited, wayOut });
|
|
1112
1049
|
}
|
|
1113
|
-
return (
|
|
1114
|
-
`${waited} later — cancelling is asynchronous and it may still be winding down. Your message was NOT ` +
|
|
1115
|
-
`sent; send it again in a moment, or ${wayOut}.`);
|
|
1050
|
+
return say(lang, 'session.selfHeal.row.cancelTimeout.held', { taskId: outcome.taskId, waited, wayOut });
|
|
1116
1051
|
}
|
|
1117
1052
|
case 'running-cancel-failed':
|
|
1118
1053
|
if (outcome.delivery === 'unknown') {
|
|
1119
|
-
return (
|
|
1120
|
-
`(${outcome.detail}), and it could not read that run back as released either. That run may or may ` +
|
|
1121
|
-
`not still be holding this session. Your message was NOT sent; send it again in a moment, or ${wayOut}.`);
|
|
1054
|
+
return say(lang, 'session.selfHeal.row.cancelFailed.unknown', { taskId: outcome.taskId, detail: outcome.detail, wayOut });
|
|
1122
1055
|
}
|
|
1123
|
-
return (
|
|
1124
|
-
`nothing was cancelled and sema cannot tell whether that run is still holding this session. Your message ` +
|
|
1125
|
-
`was NOT sent; send it again to find out, or ${wayOut}.`);
|
|
1056
|
+
return say(lang, 'session.selfHeal.row.cancelFailed.rejected', { taskId: outcome.taskId, detail: outcome.detail, wayOut });
|
|
1126
1057
|
case 'ask-run-not-found':
|
|
1127
|
-
return (
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
`not allowed to read. Either way sema has nothing it can act on here, so it did NOT cancel anything. ` +
|
|
1131
|
-
`Your message was NOT sent; send it again (if the session really is free it will just run), or ${wayOut}.`);
|
|
1058
|
+
return say(lang, 'session.selfHeal.row.askRunNotFound', { taskId: outcome.taskId, wayOut });
|
|
1059
|
+
case 'ask-run-settled':
|
|
1060
|
+
return say(lang, 'session.selfHeal.row.askRunSettled', { taskId: outcome.taskId, status: outcome.status, wayOut });
|
|
1132
1061
|
case 'stale-park-cancelled':
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
`holding this session, so sema is sending your message again now.`);
|
|
1137
|
-
}
|
|
1138
|
-
return (`Run ${outcome.taskId} was parked on an approval that no longer exists on the engine, so there was ` +
|
|
1139
|
-
`nothing left for you to answer. You chose to cancel that run: the engine now reports it as finished, ` +
|
|
1140
|
-
`so it will not resume — whatever that turn had left to do is not coming back. sema is sending your ` +
|
|
1141
|
-
`message again now; if that run has not fully let go of the session yet, you may have to send it once ` +
|
|
1142
|
-
`more.`);
|
|
1062
|
+
return outcome.releaseConfirmedByEngine === true
|
|
1063
|
+
? say(lang, 'session.selfHeal.row.stale.cancelled.confirmed', { taskId: outcome.taskId })
|
|
1064
|
+
: say(lang, 'session.selfHeal.row.stale.cancelled.reported', { taskId: outcome.taskId });
|
|
1143
1065
|
case 'stale-park-cancel-timeout': {
|
|
1144
1066
|
const waited = `${String(Math.max(1, Math.round(outcome.waitedMs / 1000)))}s`;
|
|
1145
|
-
if (outcome.aborted)
|
|
1146
|
-
return (
|
|
1147
|
-
`exists there) and you interrupted while it was still confirming (${waited} in). Cancelling is ` +
|
|
1148
|
-
`asynchronous, so that run may still be winding down and may still hold this session. Your message ` +
|
|
1149
|
-
`was NOT sent; send it again in a moment, or ${wayOut}.`);
|
|
1150
|
-
}
|
|
1067
|
+
if (outcome.aborted)
|
|
1068
|
+
return say(lang, 'session.selfHeal.row.stale.cancelTimeout.aborted', { taskId: outcome.taskId, waited, wayOut });
|
|
1151
1069
|
if (!outcome.confirmedHeld) {
|
|
1152
|
-
return (
|
|
1153
|
-
`there) but could not read that run's state back within ${waited}, so it cannot confirm whether the ` +
|
|
1154
|
-
`session was released. Your message was NOT sent; send it again in a moment (if that run really is ` +
|
|
1155
|
-
`gone it will just run), or ${wayOut}.`);
|
|
1070
|
+
return say(lang, 'session.selfHeal.row.stale.cancelTimeout.unread', { taskId: outcome.taskId, waited, wayOut });
|
|
1156
1071
|
}
|
|
1157
|
-
return (
|
|
1158
|
-
`there), but that run still held this session ${waited} later — cancelling is asynchronous and it may ` +
|
|
1159
|
-
`still be winding down. Your message was NOT sent; send it again in a moment, or ${wayOut}.`);
|
|
1072
|
+
return say(lang, 'session.selfHeal.row.stale.cancelTimeout.held', { taskId: outcome.taskId, waited, wayOut });
|
|
1160
1073
|
}
|
|
1161
1074
|
case 'stale-park-cancel-failed':
|
|
1162
1075
|
if (outcome.delivery === 'unknown') {
|
|
1163
|
-
return (
|
|
1164
|
-
`engine) but could not confirm what happened to it (${outcome.detail}), and it could not read that ` +
|
|
1165
|
-
`run back as released either. That run may or may not still be holding this session. Your message ` +
|
|
1166
|
-
`was NOT sent; send it again in a moment, or ${wayOut}.`);
|
|
1076
|
+
return say(lang, 'session.selfHeal.row.stale.cancelFailed.unknown', { taskId: outcome.taskId, detail: outcome.detail, wayOut });
|
|
1167
1077
|
}
|
|
1168
|
-
return (
|
|
1169
|
-
`so nothing was cancelled and sema cannot tell whether that run is still holding this session. Your ` +
|
|
1170
|
-
`message was NOT sent; send it again to find out, or ${wayOut}.`);
|
|
1078
|
+
return say(lang, 'session.selfHeal.row.cancelFailed.rejected', { taskId: outcome.taskId, detail: outcome.detail, wayOut });
|
|
1171
1079
|
case 'stale-park-wait':
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
`is not asking again. Your message was NOT sent; cancel that run on the engine ` +
|
|
1176
|
-
`(POST /v1/runs/${outcome.taskId}/cancel — that ends it for good), or ${wayOut}.`);
|
|
1177
|
-
}
|
|
1178
|
-
return (`Run ${outcome.taskId} is still parked (status ${outcome.status}) on an approval that no longer exists ` +
|
|
1179
|
-
`on the engine, so there is no card left to answer and that run will not settle on its own. sema did ` +
|
|
1180
|
-
`NOT cancel it — you chose to leave it alone. Your message was NOT sent; cancel that run on the engine ` +
|
|
1181
|
-
`(POST /v1/runs/${outcome.taskId}/cancel — that ends it for good), or ${wayOut}.`);
|
|
1080
|
+
return outcome.alreadyOffered === true
|
|
1081
|
+
? say(lang, 'session.selfHeal.row.stale.wait.offered', { taskId: outcome.taskId, status: outcome.status, wayOut })
|
|
1082
|
+
: say(lang, 'session.selfHeal.row.stale.wait.first', { taskId: outcome.taskId, status: outcome.status, wayOut });
|
|
1182
1083
|
case 'running-not-found':
|
|
1183
|
-
return (
|
|
1184
|
-
`longer recognizes that run when asked directly — that claim looks stale (the run most likely no ` +
|
|
1185
|
-
`longer exists). sema did not offer to steer or cancel it: there is nothing left to act on. ` +
|
|
1186
|
-
`Your message was NOT sent; send it again (if the session really is free it will just run), or ${wayOut}.`);
|
|
1084
|
+
return say(lang, 'session.selfHeal.row.runNotFound', { taskId: outcome.taskId, wayOut });
|
|
1187
1085
|
case 'running-settled':
|
|
1188
|
-
return (
|
|
1189
|
-
`reported it as holding this session — that claim looks stale or mid-release. sema did not offer ` +
|
|
1190
|
-
`to steer or cancel it: the run is over. Your message was NOT sent; send it again (once the claim ` +
|
|
1191
|
-
`clears it will just run), or ${wayOut}.`);
|
|
1086
|
+
return say(lang, 'session.selfHeal.row.runSettled', { taskId: outcome.taskId, status: outcome.status, wayOut });
|
|
1192
1087
|
case 'not-parked':
|
|
1193
1088
|
if (outcome.alreadyOffered === true) {
|
|
1194
|
-
return (
|
|
1195
|
-
`asked what to do with it and you chose to leave it alone, so it is not asking again. ` +
|
|
1196
|
-
`Your message was NOT sent; wait for that run, cancel it on the engine ` +
|
|
1197
|
-
`(POST /v1/runs/${outcome.taskId}/cancel), or ${wayOut}.`);
|
|
1089
|
+
return say(lang, 'session.selfHeal.row.notParked.offered', { taskId: outcome.taskId, status: outcome.status, wayOut });
|
|
1198
1090
|
}
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1091
|
+
const parkedOn = outcome.pendingGateKind !== undefined
|
|
1092
|
+
? gateKindPhrase(outcome.pendingGateKind, lang)
|
|
1093
|
+
: isSdkRunParked(outcome.status)
|
|
1094
|
+
? gateKindPhrase(null, lang)
|
|
1095
|
+
: undefined;
|
|
1096
|
+
if (parkedOn !== undefined) {
|
|
1097
|
+
return say(lang, 'session.selfHeal.row.notParked.parkedOn', { taskId: outcome.taskId, status: outcome.status, parkedOn, wayOut });
|
|
1204
1098
|
}
|
|
1205
|
-
return (
|
|
1206
|
-
`most likely a turn you sent to the background. sema did NOT cancel it, because that would ` +
|
|
1207
|
-
`throw away work you asked for. Wait for it to finish, or ${wayOut}.`);
|
|
1099
|
+
return say(lang, 'session.selfHeal.row.notParked.inFlight', { taskId: outcome.taskId, status: outcome.status, wayOut });
|
|
1208
1100
|
case 'state-unknown':
|
|
1209
|
-
return (
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1101
|
+
return say(lang, 'session.selfHeal.row.stateUnknown', {
|
|
1102
|
+
handle: outcome.taskId ? msg('session.selfHeal.handle.run', { taskId: outcome.taskId }) : '',
|
|
1103
|
+
detail: outcome.detail,
|
|
1104
|
+
wayOut,
|
|
1105
|
+
});
|
|
1213
1106
|
}
|
|
1214
1107
|
}
|
|
1215
|
-
export function activeRunBusyHeadlessRow(signal, copy) {
|
|
1108
|
+
export function activeRunBusyHeadlessRow(signal, copy, lang) {
|
|
1216
1109
|
const override = copy?.headlessRowFor?.(signal);
|
|
1217
1110
|
if (typeof override === 'string')
|
|
1218
1111
|
return override;
|
|
1219
1112
|
const activeTaskId = signal.activeTaskId;
|
|
1220
|
-
const handle = activeTaskId ?
|
|
1113
|
+
const handle = activeTaskId ? msg('session.selfHeal.handle.run', { taskId: activeTaskId }) : '';
|
|
1221
1114
|
const cancelPath = `POST /v1/runs/${activeTaskId ?? '<id>'}/cancel`;
|
|
1222
1115
|
const status = signal.activeTaskStatus;
|
|
1223
1116
|
const decidePath = signal.pendingGate?.decidePath ?? null;
|
|
1224
|
-
const
|
|
1117
|
+
const hostFresh = copy?.freshSession ?? undefined;
|
|
1118
|
+
const freshSession = hostFresh ?? say(lang, 'session.selfHeal.freshSession.default');
|
|
1225
1119
|
if (decidePath) {
|
|
1226
|
-
return (
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
const startOver = `${
|
|
1239
|
-
return (
|
|
1240
|
-
`NOT sent. Nothing here clears on its own. ${startOver}, or ` +
|
|
1241
|
-
`release the run on the engine: ${cancelPath}`);
|
|
1120
|
+
return say(lang, 'session.selfHeal.headless.decide', {
|
|
1121
|
+
handle,
|
|
1122
|
+
status: status ? msg('session.selfHeal.headless.status', { status }) : '',
|
|
1123
|
+
gate: gateKindPhrase(signal.pendingGate?.kind, lang),
|
|
1124
|
+
decidePath,
|
|
1125
|
+
cancelPath,
|
|
1126
|
+
freshSession,
|
|
1127
|
+
governance: governanceOriginClause(signal, lang),
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
if (status)
|
|
1131
|
+
return say(lang, 'session.selfHeal.headless.statusOnly', { handle, status, cancelPath, freshSession });
|
|
1132
|
+
const startOver = hostFresh !== undefined ? `${hostFresh.charAt(0).toUpperCase()}${hostFresh.slice(1)}` : say(lang, 'session.selfHeal.freshSession.defaultCapitalized');
|
|
1133
|
+
return say(lang, 'session.selfHeal.headless.neverReleased', { handle, startOver, cancelPath });
|
|
1242
1134
|
}
|