@sema-agent/client-core 0.100.0 → 0.101.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 +395 -0
- package/README.md +164 -117
- package/dist/adapt/arms.js +51 -16
- package/dist/adapt/textStream.js +7 -4
- package/dist/adapt/toolCards.js +9 -8
- package/dist/adapt.js +7 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
- package/dist/adapter/activeRunSelfHeal.js +108 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +33 -12
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
- package/dist/adapter/runStream.d.ts +4 -4
- package/dist/adapter/runStream.js +158 -43
- package/dist/agentsWireCaps.d.ts +2 -7
- package/dist/agentsWireCaps.js +1 -2
- package/dist/approvalDecidedByCapability.js +2 -2
- package/dist/approvalFrameFamilies.d.ts +33 -0
- package/dist/approvalFrameFamilies.js +120 -0
- package/dist/approvalsStreamLiveCapability.js +2 -2
- package/dist/attachmentsWireCaps.js +41 -13
- package/dist/callerCwdCapability.js +2 -2
- package/dist/centerWiringCapability.js +2 -2
- package/dist/clockReading.d.ts +2 -0
- package/dist/clockReading.js +4 -0
- package/dist/cloudConfigWireCaps.d.ts +19 -5
- package/dist/cloudConfigWireCaps.js +193 -56
- package/dist/coreValuePorts.d.ts +12 -2
- package/dist/coreValuePorts.js +9 -0
- package/dist/decideFailureNote.js +5 -3
- package/dist/decideReceipt.js +2 -2
- package/dist/deviceExecutorManagementCapability.js +2 -2
- package/dist/deviceFlowPolling.js +1 -1
- package/dist/disableSkillsWire.d.ts +1 -1
- package/dist/disableSkillsWire.js +4 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +65 -8
- package/dist/engineCapReader.js +1 -1
- package/dist/engineConfigDrift.js +1 -1
- package/dist/engineErrorCodes.d.ts +14 -5
- package/dist/engineErrorCodes.js +27 -6
- package/dist/engineGenerationConvergence.d.ts +39 -0
- package/dist/engineGenerationConvergence.js +95 -0
- package/dist/engineGenerationPort.d.ts +61 -0
- package/dist/engineGenerationPort.js +144 -0
- package/dist/engineHealthFacts.d.ts +23 -0
- package/dist/engineHealthFacts.js +92 -0
- package/dist/engineIdentity.d.ts +4 -0
- package/dist/engineIdentity.js +11 -0
- package/dist/engineNoticeCodes.d.ts +2 -5
- package/dist/engineRowRef.js +3 -0
- package/dist/engineSessionMessages.js +2 -2
- package/dist/engineToolDirectory.js +2 -2
- package/dist/engineWireFor.d.ts +99 -0
- package/dist/engineWireFor.js +248 -6
- package/dist/engineWireTarget.d.ts +1 -0
- package/dist/engineWireTarget.js +8 -0
- package/dist/env/uiLanguage.js +1 -1
- package/dist/errorSupplementRoles.d.ts +3 -0
- package/dist/errorSupplementRoles.js +37 -0
- package/dist/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.js +3 -3
- package/dist/finalVerifyWire.d.ts +6 -3
- package/dist/finalVerifyWire.js +6 -23
- package/dist/flagInput.d.ts +4 -0
- package/dist/flagInput.js +24 -0
- package/dist/fleet/fleetLedger.js +5 -2
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +15 -2
- package/dist/gateVocabulary.js +3 -0
- package/dist/generated/engineFactTables.d.ts +7 -3
- package/dist/generated/engineFactTables.js +52 -0
- package/dist/generated/engineNoticeTables.js +12 -0
- package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
- package/dist/generated/settingsSchemaActiveTiers.js +14 -0
- package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
- package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
- package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
- package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
- package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
- package/dist/generated/settingsSchemaDefaultModel.js +25 -0
- package/dist/generated/settingsSchemaFns.d.ts +54 -0
- package/dist/generated/settingsSchemaFns.js +26 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
- package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
- package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
- package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
- package/dist/generated/settingsSchemaSettingsSources.js +58 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +13 -0
- package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlPattern.js +183 -0
- package/dist/headlessPermissionModeWire.d.ts +18 -2
- package/dist/headlessPermissionModeWire.js +30 -19
- package/dist/hitl/allowRuleShadow.js +7 -5
- package/dist/hitl/approvalCardReading.d.ts +3 -0
- package/dist/hitl/approvalCardReading.js +17 -0
- package/dist/hitl/approvalCompleteParked.js +1 -1
- package/dist/hitl/approvalDelivery.d.ts +87 -0
- package/dist/hitl/approvalDelivery.js +193 -0
- package/dist/hitl/approvalResolution.d.ts +11 -0
- package/dist/hitl/approvalResolution.js +50 -11
- package/dist/hitl/askClassPair.d.ts +6 -0
- package/dist/hitl/askClassPair.js +30 -3
- package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
- package/dist/hitl/askParkAutoReopenBlock.js +117 -0
- package/dist/hitl/askParkRowRouting.js +4 -1
- package/dist/hitl/attributionLadder.d.ts +42 -3
- package/dist/hitl/attributionLadder.js +79 -8
- package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
- package/dist/hitl/automaticAnswerVerdict.js +46 -11
- package/dist/hitl/crashConverged.js +2 -2
- package/dist/hitl/decisionConflict.d.ts +6 -2
- package/dist/hitl/decisionConflict.js +24 -9
- package/dist/hitl/decisionRefusal.d.ts +20 -10
- package/dist/hitl/decisionRefusal.js +99 -54
- package/dist/hitl/decisionSend.d.ts +3 -0
- package/dist/hitl/decisionSend.js +87 -103
- package/dist/hitl/frameRouter.d.ts +1 -0
- package/dist/hitl/frameRouter.js +9 -2
- package/dist/hitl/hitlBridge.d.ts +18 -6
- package/dist/hitl/hitlBridge.js +41 -37
- package/dist/hitl/livePendingAsk.js +4 -3
- package/dist/hitl/noAllowCause.js +1 -1
- package/dist/hitl/parkResolver.js +3 -2
- package/dist/hitl/persistedRulesWire.js +1 -0
- package/dist/hitl/planReviewWire.d.ts +4 -0
- package/dist/hitl/planReviewWire.js +59 -30
- package/dist/hitl/resumeRunningCard.d.ts +3 -2
- package/dist/hitl/resumeRunningCard.js +17 -11
- package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
- package/dist/hitl/sessionPolicyDeliverable.js +62 -29
- package/dist/hitl/sessionPolicyWire.d.ts +13 -3
- package/dist/hitl/sessionPolicyWire.js +81 -16
- package/dist/hitl/standingRows.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +9 -10
- package/dist/hitl/toolApprovalWire.js +72 -54
- package/dist/hookMatcherVerdict.d.ts +2 -0
- package/dist/hookMatcherVerdict.js +12 -0
- package/dist/hooksCompactTransition.d.ts +19 -0
- package/dist/hooksCompactTransition.js +41 -0
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +202 -203
- package/dist/host.d.ts +1 -14
- package/dist/host.js +0 -8
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +1 -1
- package/dist/hostSettingsSource.d.ts +172 -0
- package/dist/hostSettingsSource.js +675 -0
- package/dist/hostTurnSettings.d.ts +73 -17
- package/dist/hostTurnSettings.js +594 -97
- package/dist/httpHookPolicy.d.ts +37 -0
- package/dist/httpHookPolicy.js +176 -0
- package/dist/humanTurn.d.ts +2 -1
- package/dist/humanTurn.js +37 -7
- package/dist/humanTurnRead.js +4 -3
- package/dist/humanTurnSentences.d.ts +10 -0
- package/dist/humanTurnSentences.js +74 -0
- package/dist/i18n/messages.en.d.ts +184 -2
- package/dist/i18n/messages.en.js +187 -5
- package/dist/i18n/messages.zh.js +197 -5
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +69 -15
- package/dist/index.js +45 -13
- package/dist/inheritEnvCapability.d.ts +3 -1
- package/dist/inheritEnvCapability.js +31 -17
- package/dist/inheritEnvWire.d.ts +2 -1
- package/dist/inheritEnvWire.js +11 -5
- package/dist/interactiveToolsWire.d.ts +4 -2
- package/dist/interactiveToolsWire.js +5 -5
- package/dist/jsonFaithful.d.ts +20 -0
- package/dist/jsonFaithful.js +152 -0
- package/dist/limitsWire.d.ts +7 -2
- package/dist/limitsWire.js +19 -13
- package/dist/liveInitToolFace.d.ts +6 -1
- package/dist/liveInitToolFace.js +5 -3
- package/dist/liveModelCatalog.d.ts +22 -0
- package/dist/liveModelCatalog.js +132 -18
- package/dist/mcpPanel.js +1 -1
- package/dist/mcpProbeCapability.js +2 -2
- package/dist/mcpStatusSupersetKeys.d.ts +24 -0
- package/dist/mcpStatusSupersetKeys.js +45 -0
- package/dist/mcpToolToggles.js +2 -1
- package/dist/mcpWireCaps.d.ts +39 -1
- package/dist/mcpWireCaps.js +254 -50
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/model/catalogDefault.d.ts +24 -0
- package/dist/model/catalogDefault.js +4 -0
- package/dist/model/liveCatalogShape.js +5 -4
- package/dist/model/modelsPolicy.js +4 -3
- package/dist/model/onboardJudgement.d.ts +1 -0
- package/dist/model/onboardJudgement.js +1 -1
- package/dist/model/subagentModelWord.js +2 -2
- package/dist/modelCapabilityProbe.js +6 -6
- package/dist/modelIdentityResolvability.d.ts +10 -1
- package/dist/modelIdentityResolvability.js +62 -39
- package/dist/modsKernelIdentity.d.ts +10 -0
- package/dist/modsKernelIdentity.js +103 -0
- package/dist/modsKernelTransit.d.ts +8 -0
- package/dist/modsKernelTransit.js +6 -0
- package/dist/notifications.d.ts +30 -12
- package/dist/notifications.js +241 -53
- package/dist/outputStyleSeatCapability.js +2 -2
- package/dist/ownKey.d.ts +11 -0
- package/dist/ownKey.js +164 -3
- package/dist/panelReduce.js +1 -1
- package/dist/peerFrames.d.ts +1 -1
- package/dist/peerFrames.js +6 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.js +4 -4
- package/dist/permissionRuleIssue.js +2 -0
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionsAllowGrantCapability.js +2 -2
- package/dist/permissionsDeclaration.d.ts +43 -4
- package/dist/permissionsDeclaration.js +102 -35
- package/dist/pluginHooksWire.d.ts +20 -4
- package/dist/pluginHooksWire.js +92 -53
- package/dist/prepareRefusal.d.ts +3 -2
- package/dist/prepareRefusal.js +27 -9
- package/dist/printInitToolFace.js +2 -2
- package/dist/printModelStatus.js +1 -1
- package/dist/projectMemory.d.ts +32 -0
- package/dist/projectMemory.js +70 -0
- package/dist/promptBlockedCopy.d.ts +2 -1
- package/dist/promptBlockedCopy.js +2 -1
- package/dist/promptDelivery.d.ts +23 -3
- package/dist/promptDelivery.js +169 -30
- package/dist/providerRejection.d.ts +19 -1
- package/dist/providerRejection.js +75 -4
- package/dist/queuedDelivery.d.ts +48 -0
- package/dist/queuedDelivery.js +233 -0
- package/dist/reattachWindow.d.ts +94 -0
- package/dist/reattachWindow.js +127 -0
- package/dist/request/printNotification.d.ts +1 -1
- package/dist/request/printNotification.js +5 -1
- package/dist/request/submissionIdentity.d.ts +37 -0
- package/dist/request/submissionIdentity.js +65 -0
- package/dist/request/taskRequest.d.ts +12 -4
- package/dist/request/taskRequest.js +221 -152
- package/dist/resultFrameKeys.d.ts +1 -0
- package/dist/resultFrameKeys.js +4 -1
- package/dist/retryStatus.d.ts +8 -0
- package/dist/retryStatus.js +57 -9
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/rewindEngineAction.d.ts +2 -0
- package/dist/rewindEngineAction.js +23 -1
- package/dist/rowKind.d.ts +36 -0
- package/dist/rowKind.js +97 -0
- package/dist/ruleCompileVerdict.d.ts +18 -0
- package/dist/ruleCompileVerdict.js +67 -2
- package/dist/ruleReadings.d.ts +58 -0
- package/dist/ruleReadings.js +132 -0
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +9 -3
- package/dist/runCancelContext.d.ts +0 -1
- package/dist/runCancelContext.js +1 -2
- package/dist/runTerminal.d.ts +5 -0
- package/dist/runTerminal.js +52 -17
- package/dist/sandboxWire.d.ts +1 -1
- package/dist/sandboxWire.js +4 -6
- package/dist/scenarioRefusal.js +1 -1
- package/dist/scenarioSkills.d.ts +20 -0
- package/dist/scenarioSkills.js +72 -0
- package/dist/scenarioWire.d.ts +5 -2
- package/dist/scenarioWire.js +9 -9
- package/dist/sealedKeyCapability.js +2 -2
- package/dist/seam.d.ts +2 -0
- package/dist/seam.js +2 -2
- package/dist/seatContract.d.ts +46 -1
- package/dist/seatContract.js +49 -19
- package/dist/selfOrchestrationDenial.js +1 -1
- package/dist/sessionPolicyCapability.js +2 -2
- package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
- package/dist/sessionRulesChildrenReadLive.js +5 -0
- package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
- package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
- package/dist/sessionSyncFileHistoryCapability.js +2 -2
- package/dist/settingsCredentialKeyPaths.js +60 -5
- package/dist/settingsHooksSalvage.d.ts +1 -0
- package/dist/settingsHooksSalvage.js +7 -1
- package/dist/settingsLayerAdmission.d.ts +4 -0
- package/dist/settingsLayerAdmission.js +16 -0
- package/dist/skillToolListsCapability.js +6 -5
- package/dist/skillsWireCaps.d.ts +14 -0
- package/dist/skillsWireCaps.js +47 -16
- package/dist/slashCommandGate.d.ts +24 -0
- package/dist/slashCommandGate.js +74 -0
- package/dist/slashCommandTable.d.ts +14 -0
- package/dist/slashCommandTable.js +99 -0
- package/dist/sqlEngineCapability.js +2 -2
- package/dist/steerPriorityCapability.js +2 -2
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/agentStateDetail.js +1 -1
- package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
- package/dist/subagent/engineDelegatedPrompt.js +38 -7
- package/dist/subagent/engineRowStopGate.js +2 -2
- package/dist/subagent/engineSubagentResume.js +3 -3
- package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
- package/dist/subagent/engineTaskHandleWire.js +10 -0
- package/dist/submitFailure.d.ts +8 -0
- package/dist/submitFailure.js +17 -0
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +7 -0
- package/dist/terminationIntent.d.ts +55 -0
- package/dist/terminationIntent.js +352 -0
- package/dist/toolHistoryMismatch.d.ts +8 -0
- package/dist/toolHistoryMismatch.js +37 -6
- package/dist/toolResult.d.ts +13 -3
- package/dist/toolResult.js +158 -9
- package/dist/toolResultContent.d.ts +13 -0
- package/dist/toolResultContent.js +82 -7
- package/dist/toolRoster.d.ts +18 -0
- package/dist/toolRoster.js +64 -0
- package/dist/turnFailurePresentation.js +27 -90
- package/dist/usageLimitAutoResume.d.ts +74 -0
- package/dist/usageLimitAutoResume.js +227 -0
- package/dist/userAttachmentEnvelope.js +1 -1
- package/dist/userAttachmentSeat.js +5 -5
- package/dist/userInvokedSkillsCapability.js +2 -2
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/wireErrorTriage.js +99 -50
- package/dist/wireFailureShape.d.ts +25 -1
- package/dist/wireFailureShape.js +92 -5
- package/dist/wireRefusalCopy.d.ts +24 -1
- package/dist/wireRefusalCopy.js +253 -32
- package/dist/wiringFleetDoctor.d.ts +3 -0
- package/dist/wiringFleetDoctor.js +21 -0
- package/dist/workflow.d.ts +2 -1
- package/dist/workflow.js +38 -1
- package/dist/workflowClient.d.ts +2 -7
- package/dist/workflowsJournalCapability.js +2 -2
- package/dist/writeProtectionCapability.js +2 -2
- package/docs/INTEGRATION-CLIENTS.md +607 -181
- package/package.json +14 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentClient } from '@sema-agent/sdk';
|
|
2
|
+
import type { UiLanguage } from '../env/uiLanguage.js';
|
|
2
3
|
import type { EngineWireInjection } from '../engineWireSdk.js';
|
|
3
4
|
export type DelegatedPromptWireClient = {
|
|
4
5
|
sessions: Pick<AgentClient['sessions'], 'get'>;
|
|
@@ -11,9 +12,17 @@ export declare function delegatedPromptText(content: unknown): string | undefine
|
|
|
11
12
|
export declare function pickDelegatedPrompt(messages: readonly unknown[]): string | undefined;
|
|
12
13
|
type TranscriptWindowReader = (transcriptId: string) => Promise<readonly unknown[] | null>;
|
|
13
14
|
export declare function __setTranscriptWindowReaderForTests(r: TranscriptWindowReader | null): void;
|
|
15
|
+
export declare const DELEGATED_PROMPT_ABSENCE_CAUSES: readonly ["not_owned_after_restart", "not_in_store", "forbidden", "prompt_absent", "unknown"];
|
|
16
|
+
export type DelegatedPromptAbsenceCause = (typeof DELEGATED_PROMPT_ABSENCE_CAUSES)[number];
|
|
17
|
+
export interface DelegatedPromptAbsence {
|
|
18
|
+
readonly cause: DelegatedPromptAbsenceCause;
|
|
19
|
+
readonly text: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function delegatedPromptAbsenceSentence(cause: DelegatedPromptAbsenceCause | string, lang?: UiLanguage): string;
|
|
14
22
|
export interface DelegatedPromptFetch {
|
|
15
23
|
prompt?: string;
|
|
16
24
|
outcome: 'hit' | 'skipped' | 'unreadable' | 'absent';
|
|
25
|
+
absence?: DelegatedPromptAbsence;
|
|
17
26
|
}
|
|
18
27
|
export declare function fetchDelegatedPrompt(taskId: string, opts?: {
|
|
19
28
|
wire?: DelegatedPromptWire;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { stripSystemReminderBlocks } from '../systemReminderTag.js';
|
|
2
2
|
import { hostLog } from '../host.js';
|
|
3
3
|
import { isSessionIdPathSegment } from '../sessionIdSegment.js';
|
|
4
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
5
|
+
import { readThrownSlot } from '../wireFailureShape.js';
|
|
4
6
|
import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, settleInjected } from '../engineWireFor.js';
|
|
5
7
|
import { resolveOwnerContext } from './engineSubagentResume.js';
|
|
6
8
|
import { panelAnchorOf } from '../panelReduce.js';
|
|
@@ -22,7 +24,7 @@ export function __resetEngineDelegatedPromptForTests() {
|
|
|
22
24
|
clearEnginePanelAnchors();
|
|
23
25
|
promptHydrateInFlight.clear();
|
|
24
26
|
}
|
|
25
|
-
const promptHydrateInFlight = new
|
|
27
|
+
const promptHydrateInFlight = new Map();
|
|
26
28
|
function roleOf(entry) {
|
|
27
29
|
if (typeof entry !== 'object' || entry === null)
|
|
28
30
|
return undefined;
|
|
@@ -113,13 +115,38 @@ async function readTranscriptWindow(transcriptId, sessionKey, injectedWire) {
|
|
|
113
115
|
const msgs = rec.messages;
|
|
114
116
|
return Array.isArray(msgs) ? msgs : null;
|
|
115
117
|
}
|
|
118
|
+
export const DELEGATED_PROMPT_ABSENCE_CAUSES = Object.freeze(['not_owned_after_restart', 'not_in_store', 'forbidden', 'prompt_absent', 'unknown']);
|
|
119
|
+
const ABSENCE_KEY = {
|
|
120
|
+
not_owned_after_restart: 'session.subagent.delegatedPrompt.absence.notOwnedAfterRestart',
|
|
121
|
+
not_in_store: 'session.subagent.delegatedPrompt.absence.notInStore',
|
|
122
|
+
forbidden: 'session.subagent.delegatedPrompt.absence.forbidden',
|
|
123
|
+
prompt_absent: 'session.subagent.delegatedPrompt.absence.promptAbsent',
|
|
124
|
+
unknown: 'session.subagent.delegatedPrompt.absence.unknown',
|
|
125
|
+
};
|
|
126
|
+
export function delegatedPromptAbsenceSentence(cause, lang) {
|
|
127
|
+
const known = typeof cause === 'string' && Object.hasOwn(ABSENCE_KEY, cause);
|
|
128
|
+
return renderMessage(msg(known ? ABSENCE_KEY[cause] : ABSENCE_KEY.unknown), lang);
|
|
129
|
+
}
|
|
130
|
+
function absenceOf(cause) {
|
|
131
|
+
return Object.freeze({ cause, text: delegatedPromptAbsenceSentence(cause) });
|
|
132
|
+
}
|
|
133
|
+
function absenceOfThrown(e) {
|
|
134
|
+
const status = readThrownSlot(e, 'status');
|
|
135
|
+
if (status === 404)
|
|
136
|
+
return absenceOf('not_in_store');
|
|
137
|
+
if (status === 401 || status === 403)
|
|
138
|
+
return absenceOf('forbidden');
|
|
139
|
+
return absenceOf('unknown');
|
|
140
|
+
}
|
|
116
141
|
export async function fetchDelegatedPrompt(taskId, opts) {
|
|
117
|
-
if (promptHydrateInFlight.has(taskId))
|
|
118
|
-
|
|
142
|
+
if (promptHydrateInFlight.has(taskId)) {
|
|
143
|
+
const settled = promptHydrateInFlight.get(taskId);
|
|
144
|
+
return settled ? { outcome: 'skipped', absence: settled } : { outcome: 'skipped' };
|
|
145
|
+
}
|
|
119
146
|
const transcriptId = getEngineTranscriptId(taskId);
|
|
120
147
|
if (!isSessionIdPathSegment(transcriptId))
|
|
121
|
-
return { outcome: 'skipped' };
|
|
122
|
-
promptHydrateInFlight.
|
|
148
|
+
return { outcome: 'skipped', absence: absenceOf(transcriptId === undefined ? 'not_owned_after_restart' : 'unknown') };
|
|
149
|
+
promptHydrateInFlight.set(taskId, null);
|
|
123
150
|
let msgs = null;
|
|
124
151
|
try {
|
|
125
152
|
msgs = await readTranscriptWindow(transcriptId, resolveOwnerContext(taskId).key, opts?.wire);
|
|
@@ -127,14 +154,18 @@ export async function fetchDelegatedPrompt(taskId, opts) {
|
|
|
127
154
|
catch (e) {
|
|
128
155
|
promptHydrateInFlight.delete(taskId);
|
|
129
156
|
hostLog('debug', `[delegated-prompt] ${taskId} transcript ${transcriptId} read failed: ${String(e).slice(0, 160)}`);
|
|
130
|
-
return { outcome: 'unreadable' };
|
|
157
|
+
return { outcome: 'unreadable', absence: absenceOfThrown(e) };
|
|
131
158
|
}
|
|
132
159
|
const prompt = msgs ? pickDelegatedPrompt(msgs) : undefined;
|
|
133
160
|
if (!prompt) {
|
|
134
161
|
if (msgs === null)
|
|
135
162
|
promptHydrateInFlight.delete(taskId);
|
|
136
163
|
hostLog('debug', `[delegated-prompt] ${taskId} transcript ${transcriptId}: ${msgs === null ? 'transcript unreadable (retryable)' : 'no delegated user message (final)'}`);
|
|
137
|
-
|
|
164
|
+
if (msgs === null)
|
|
165
|
+
return { outcome: 'unreadable', absence: absenceOf('unknown') };
|
|
166
|
+
const settled = absenceOf('prompt_absent');
|
|
167
|
+
promptHydrateInFlight.set(taskId, settled);
|
|
168
|
+
return { outcome: 'absent', absence: settled };
|
|
138
169
|
}
|
|
139
170
|
hostLog('debug', `[delegated-prompt] ${taskId} <- transcript ${transcriptId} (${prompt.length} chars) head=${JSON.stringify(prompt.slice(0, 60))}`);
|
|
140
171
|
return { prompt, outcome: 'hit' };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { engineCapTrue } from '../engineCapsCache.js';
|
|
2
|
-
import {
|
|
2
|
+
import { engineWireTargetBaseUrl } from '../engineWireTarget.js';
|
|
3
3
|
import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
4
4
|
export const engineOwnedRowIds = new Set();
|
|
5
5
|
export const fleetViewStubRowIds = new Set();
|
|
@@ -7,7 +7,7 @@ export function isEngineViewRow(taskId) {
|
|
|
7
7
|
return engineOwnedRowIds.has(taskId) || fleetViewStubRowIds.has(taskId);
|
|
8
8
|
}
|
|
9
9
|
export function engineTaskHandlesCapable(sessionKey = DEFAULT_SESSION_KEY, capsBaseUrl) {
|
|
10
|
-
return engineCapTrue(capsBaseUrl ??
|
|
10
|
+
return engineCapTrue(capsBaseUrl ?? engineWireTargetBaseUrl(sessionKey), 'taskHandles');
|
|
11
11
|
}
|
|
12
12
|
export function engineRowNeedsStopConfirm(taskId, sessionKey, capsBaseUrl) {
|
|
13
13
|
return isEngineViewRow(taskId) && engineTaskHandlesCapable(sessionKey ?? DEFAULT_SESSION_KEY, capsBaseUrl);
|
|
@@ -5,13 +5,13 @@ import { RESUME_SESSION_NOT_FOUND } from '../engineErrorCodes.js';
|
|
|
5
5
|
import { displayUntrusted } from '../displayUntrusted.js';
|
|
6
6
|
import { engineCapTrue } from '../engineCapsCache.js';
|
|
7
7
|
import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, noAnswerDetailFrom, sendOnce, settleInjected } from '../engineWireFor.js';
|
|
8
|
-
import {
|
|
8
|
+
import { engineWireTargetBaseUrl } from '../engineWireTarget.js';
|
|
9
9
|
import { activeEngineRunId, engineSessionParamFor } from '../engineSessionParam.js';
|
|
10
10
|
import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
11
11
|
import { getBgParentRunOwner, parentToolCallIdOf, } from '../subagentContentStore.js';
|
|
12
12
|
export const SUBAGENT_RESUME_CAP = 'subagentResume';
|
|
13
13
|
export function subagentResumeAvailable(baseUrl, sessionKey = DEFAULT_SESSION_KEY) {
|
|
14
|
-
return engineCapTrue(baseUrl ??
|
|
14
|
+
return engineCapTrue(baseUrl ?? engineWireTargetBaseUrl(sessionKey), SUBAGENT_RESUME_CAP);
|
|
15
15
|
}
|
|
16
16
|
export function resolveSubagentContinueTarget(rowId, displayName) {
|
|
17
17
|
const precise = parentToolCallIdOf(rowId);
|
|
@@ -149,7 +149,7 @@ export async function resumeSettledSubagent(facade, runId, target, content, opts
|
|
|
149
149
|
}
|
|
150
150
|
const warnedRetainWithoutWake = new Set();
|
|
151
151
|
export function auditRetainWithoutWake(input) {
|
|
152
|
-
const baseUrl = input.baseUrl ??
|
|
152
|
+
const baseUrl = input.baseUrl ?? engineWireTargetBaseUrl(input.sessionKey ?? DEFAULT_SESSION_KEY);
|
|
153
153
|
if (!engineCapTrue(baseUrl, SUBAGENT_RESUME_CAP))
|
|
154
154
|
return undefined;
|
|
155
155
|
if (input.retainRequested === false)
|
|
@@ -13,6 +13,7 @@ export interface EngineTaskOutputResult {
|
|
|
13
13
|
status?: string;
|
|
14
14
|
stoppedBy?: string;
|
|
15
15
|
partialResult?: boolean;
|
|
16
|
+
exitCode?: number;
|
|
16
17
|
}
|
|
17
18
|
export declare function __resetTaskHandleWireForTests(): void;
|
|
18
19
|
export declare function fetchEngineTaskOutput(handle: string, opts?: {
|
|
@@ -6,6 +6,7 @@ import { engineSessionParamFor } from '../engineSessionParam.js';
|
|
|
6
6
|
import { resolveOwnerContext } from './engineSubagentResume.js';
|
|
7
7
|
import { engineTaskHandlesCapable } from './engineRowStopGate.js';
|
|
8
8
|
import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
|
|
9
|
+
import { guardedRead, readOwnDataValue } from '../ownKey.js';
|
|
9
10
|
function usableTaskOutputClient(client) {
|
|
10
11
|
return clientHasVerbs(client, [['runs', 'taskOutput']]);
|
|
11
12
|
}
|
|
@@ -27,6 +28,13 @@ function sessionOf(ctx) {
|
|
|
27
28
|
const s = ctx.record?.sessionId ?? engineSessionParamFor(ctx.key);
|
|
28
29
|
return s !== undefined ? { session: s } : {};
|
|
29
30
|
}
|
|
31
|
+
function exitCodeOfTaskOutput(output) {
|
|
32
|
+
const details = guardedRead(() => readOwnDataValue(output, 'details'));
|
|
33
|
+
if (typeof details !== 'object' || details === null)
|
|
34
|
+
return undefined;
|
|
35
|
+
const code = guardedRead(() => readOwnDataValue(details, 'exitCode'));
|
|
36
|
+
return typeof code === 'number' && Number.isInteger(code) ? code : undefined;
|
|
37
|
+
}
|
|
30
38
|
const accumulated = new Map();
|
|
31
39
|
export function __resetTaskHandleWireForTests() {
|
|
32
40
|
accumulated.clear();
|
|
@@ -67,11 +75,13 @@ export async function fetchEngineTaskOutput(handle, opts) {
|
|
|
67
75
|
if (engineWireDebugEnabled()) {
|
|
68
76
|
hostLog('debug', `[task-handle] output ${handle} via run ${runId}: ok fresh=${fresh.length}b merged=${merged.length}b status=${typeof out.status === 'string' ? out.status : '-'}`);
|
|
69
77
|
}
|
|
78
|
+
const exitCode = exitCodeOfTaskOutput(out);
|
|
70
79
|
return {
|
|
71
80
|
content: merged,
|
|
72
81
|
...(typeof out.status === 'string' ? { status: out.status } : {}),
|
|
73
82
|
...(typeof out.stoppedBy === 'string' ? { stoppedBy: out.stoppedBy } : {}),
|
|
74
83
|
...(out.partial_result === true ? { partialResult: true } : {}),
|
|
84
|
+
...(exitCode !== undefined ? { exitCode } : {}),
|
|
75
85
|
};
|
|
76
86
|
}
|
|
77
87
|
catch (e) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SDKAssistantMessageError } from '@sema-agent/agent-types';
|
|
2
|
+
import type { SemaRowKind } from './rowKind.js';
|
|
3
|
+
export interface SubmitFailureClass {
|
|
4
|
+
readonly kind: Extract<SemaRowKind, 'api_error' | 'model_output_error'>;
|
|
5
|
+
readonly errorCode?: string;
|
|
6
|
+
readonly ccError?: SDKAssistantMessageError;
|
|
7
|
+
}
|
|
8
|
+
export declare function classifySubmitFailure(err: {} | null | undefined): SubmitFailureClass;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isModelOutputErrorText } from './adapter/runStream.js';
|
|
2
|
+
import { ccErrorOfProviderStatus } from './providerRejection.js';
|
|
3
|
+
import { classifyTurnWireError } from './wireErrorTriage.js';
|
|
4
|
+
export function classifySubmitFailure(err) {
|
|
5
|
+
const verdict = classifyTurnWireError(err);
|
|
6
|
+
const status = verdict.kind === 'http' ? verdict.status : undefined;
|
|
7
|
+
const errorCode = verdict.kind === 'http' && verdict.errorCode !== undefined && verdict.errorCode.length > 0 ? verdict.errorCode : undefined;
|
|
8
|
+
const text = verdict.kind === 'http' ? verdict.message : verdict.kind === 'transport' || verdict.kind === 'internal' ? verdict.detail : '';
|
|
9
|
+
const kind = isModelOutputErrorText(text) ? 'model_output_error' : 'api_error';
|
|
10
|
+
const mapped = status === undefined ? undefined : ccErrorOfProviderStatus(status);
|
|
11
|
+
const ccError = mapped === 'model_not_found' && errorCode !== undefined ? undefined : mapped;
|
|
12
|
+
return {
|
|
13
|
+
kind,
|
|
14
|
+
...(errorCode !== undefined ? { errorCode } : {}),
|
|
15
|
+
...(ccError !== undefined ? { ccError } : {}),
|
|
16
|
+
};
|
|
17
|
+
}
|
package/dist/supportFloor.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export type EngineVersionTier = 'engine' | 'legacy' | 'unknown';
|
|
|
10
10
|
export declare function engineVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
|
11
11
|
export declare function engineSupportFloorEffective(floor?: string): string;
|
|
12
12
|
export declare function coreVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
|
13
|
+
export declare function compareReleaseVersions(a: string, b: string): -1 | 0 | 1 | undefined;
|
package/dist/supportFloor.js
CHANGED
|
@@ -51,3 +51,10 @@ export function engineSupportFloorEffective(floor) {
|
|
|
51
51
|
export function coreVersionTier(version, floor) {
|
|
52
52
|
return judgeAgainst(version, SUPPORT_FLOOR.core, floor, 'coreVersionTier').tier;
|
|
53
53
|
}
|
|
54
|
+
export function compareReleaseVersions(a, b) {
|
|
55
|
+
const ta = releaseTriple(a);
|
|
56
|
+
const tb = releaseTriple(b);
|
|
57
|
+
if (ta === undefined || tb === undefined)
|
|
58
|
+
return undefined;
|
|
59
|
+
return compareTriple(ta, tb);
|
|
60
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
2
|
+
export declare const TERMINATION_INTENT_TTL_MS = 60000;
|
|
3
|
+
export declare const TERMINATION_INTENT_WEAK_SOURCE = "esc-abort";
|
|
4
|
+
export declare const INTERRUPTED_SETTLE_BUDGET_MS = 10000;
|
|
5
|
+
export declare const INTERRUPTED_SETTLE_POLL_MS = 1000;
|
|
6
|
+
export type TerminationIntentSource = string;
|
|
7
|
+
export interface TerminationIntentSnapshot {
|
|
8
|
+
readonly source: TerminationIntentSource;
|
|
9
|
+
readonly at: number;
|
|
10
|
+
readonly abortAt: number | null;
|
|
11
|
+
}
|
|
12
|
+
export interface TerminationIntentLedgerOptions {
|
|
13
|
+
readonly now: () => number;
|
|
14
|
+
readonly ttlMs?: number;
|
|
15
|
+
readonly exemptAbortReasons?: readonly string[];
|
|
16
|
+
}
|
|
17
|
+
export interface TerminationIntentLedger {
|
|
18
|
+
record(taskId: string | null | undefined, source: TerminationIntentSource): number;
|
|
19
|
+
snapshot(taskId: string | null | undefined): TerminationIntentSnapshot | null;
|
|
20
|
+
restoreIf(taskId: string | null | undefined, version: number, snapshot: TerminationIntentSnapshot | null): boolean;
|
|
21
|
+
rollbackIf(taskId: string | null | undefined, version: number, prior: TerminationIntentSource | null): boolean;
|
|
22
|
+
rollback(taskId: string | null | undefined, prior: TerminationIntentSource | null): void;
|
|
23
|
+
wasRecentlyTerminatedByUs(taskId: string | null | undefined): boolean;
|
|
24
|
+
sourceOf(taskId: string | null | undefined): TerminationIntentSource | null;
|
|
25
|
+
armOnAbort(signal: AbortSignal | undefined, taskId: string): void;
|
|
26
|
+
forget(taskId: string | null | undefined): void;
|
|
27
|
+
size(): number;
|
|
28
|
+
}
|
|
29
|
+
export declare function createTerminationIntentLedger(options: TerminationIntentLedgerOptions): TerminationIntentLedger;
|
|
30
|
+
export type InterruptedRunSettleVerdict = {
|
|
31
|
+
readonly kind: 'settled';
|
|
32
|
+
readonly status: string;
|
|
33
|
+
} | {
|
|
34
|
+
readonly kind: 'still-running';
|
|
35
|
+
readonly waitedMs: number;
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: 'parked';
|
|
38
|
+
readonly status: string;
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: 'unknown';
|
|
41
|
+
};
|
|
42
|
+
export interface InterruptedRunRow {
|
|
43
|
+
readonly status?: string | null;
|
|
44
|
+
}
|
|
45
|
+
export interface InterruptedRunSettleDeps {
|
|
46
|
+
readonly getRun?: (taskId: string, opts?: {
|
|
47
|
+
signal?: AbortSignal;
|
|
48
|
+
}) => Promise<InterruptedRunRow | null>;
|
|
49
|
+
readonly signal?: AbortSignal;
|
|
50
|
+
readonly budgetMs?: number;
|
|
51
|
+
readonly intervalMs?: number;
|
|
52
|
+
readonly now?: () => number;
|
|
53
|
+
}
|
|
54
|
+
export declare function awaitInterruptedRunSettle(taskId: string, deps: InterruptedRunSettleDeps): Promise<InterruptedRunSettleVerdict>;
|
|
55
|
+
export declare function interruptedRunSettleRow(taskId: string, verdict: InterruptedRunSettleVerdict, lang?: UiLanguage): string | null;
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { usableClockMs } from './clockReading.js';
|
|
2
|
+
import { displayUntrusted } from './displayUntrusted.js';
|
|
3
|
+
import { linkedAbortSignal, readSignalAborted, readSignalReason, tryListenAbortOnce, tryUnlistenAbort } from './engineWireFor.js';
|
|
4
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
5
|
+
import { abortableSleep } from './abortableSleep.js';
|
|
6
|
+
import { isSdkRunParked, isSdkRunTerminal } from './terminalStatuses.js';
|
|
7
|
+
export const TERMINATION_INTENT_TTL_MS = 60_000;
|
|
8
|
+
export const TERMINATION_INTENT_WEAK_SOURCE = 'esc-abort';
|
|
9
|
+
export const INTERRUPTED_SETTLE_BUDGET_MS = 10_000;
|
|
10
|
+
export const INTERRUPTED_SETTLE_POLL_MS = 1_000;
|
|
11
|
+
const MAX_ROWS = 256;
|
|
12
|
+
const MAX_TRACKED_WRITES = 1024;
|
|
13
|
+
const validId = (taskId) => typeof taskId === 'string' && taskId.length > 0;
|
|
14
|
+
const validSource = (s) => typeof s === 'string' && s.length > 0;
|
|
15
|
+
function readSnapshot(s) {
|
|
16
|
+
try {
|
|
17
|
+
if (typeof s !== 'object' || s === null)
|
|
18
|
+
return null;
|
|
19
|
+
const raw = s;
|
|
20
|
+
const source = raw.source;
|
|
21
|
+
const at = raw.at;
|
|
22
|
+
const abortAt = raw.abortAt;
|
|
23
|
+
if (!validSource(source) || usableClockMs(at) === null)
|
|
24
|
+
return null;
|
|
25
|
+
return { source, at: at, abortAt: typeof abortAt === 'number' && usableClockMs(abortAt) !== null ? abortAt : null };
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export function createTerminationIntentLedger(options) {
|
|
32
|
+
if (typeof options !== 'object' || options === null || typeof options.now !== 'function') {
|
|
33
|
+
throw new TypeError('createTerminationIntentLedger: options.now must be a function returning milliseconds');
|
|
34
|
+
}
|
|
35
|
+
const readClock = options.now;
|
|
36
|
+
const ttl = typeof options.ttlMs === 'number' && Number.isFinite(options.ttlMs) && options.ttlMs > 0 ? options.ttlMs : TERMINATION_INTENT_TTL_MS;
|
|
37
|
+
const exempt = Object.freeze([...(options.exemptAbortReasons ?? ['background'])]);
|
|
38
|
+
const rows = new Map();
|
|
39
|
+
let nextVersion = 1;
|
|
40
|
+
const priors = new Map();
|
|
41
|
+
const refused = new Set();
|
|
42
|
+
const trackBounded = (m, k, v) => {
|
|
43
|
+
m.set(k, v);
|
|
44
|
+
while (m.size > MAX_TRACKED_WRITES) {
|
|
45
|
+
const oldest = m.keys().next();
|
|
46
|
+
if (oldest.done === true)
|
|
47
|
+
break;
|
|
48
|
+
m.delete(oldest.value);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const markRefused = (version) => {
|
|
52
|
+
if (typeof version !== 'number')
|
|
53
|
+
return;
|
|
54
|
+
refused.add(version);
|
|
55
|
+
while (refused.size > MAX_TRACKED_WRITES) {
|
|
56
|
+
const oldest = refused.values().next();
|
|
57
|
+
if (oldest.done === true)
|
|
58
|
+
break;
|
|
59
|
+
refused.delete(oldest.value);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const effectivePrior = (version) => {
|
|
63
|
+
if (!priors.has(version))
|
|
64
|
+
return { known: false, row: null };
|
|
65
|
+
let row = priors.get(version) ?? null;
|
|
66
|
+
for (let hops = 0; row !== null && refused.has(row.version) && priors.has(row.version) && hops < MAX_TRACKED_WRITES; hops += 1)
|
|
67
|
+
row = priors.get(row.version) ?? null;
|
|
68
|
+
return { known: true, row };
|
|
69
|
+
};
|
|
70
|
+
const clock = () => {
|
|
71
|
+
try {
|
|
72
|
+
return usableClockMs(readClock());
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const isFresh = (now, at) => {
|
|
79
|
+
const age = now - at;
|
|
80
|
+
return age >= 0 && age < ttl;
|
|
81
|
+
};
|
|
82
|
+
const purge = (now) => {
|
|
83
|
+
for (const [taskId, row] of rows) {
|
|
84
|
+
if (isFresh(now, row.at))
|
|
85
|
+
continue;
|
|
86
|
+
if (row.abortAt !== null && isFresh(now, row.abortAt)) {
|
|
87
|
+
rows.set(taskId, { at: row.abortAt, source: TERMINATION_INTENT_WEAK_SOURCE, abortAt: row.abortAt, version: nextVersion++ });
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
rows.delete(taskId);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const put = (taskId, row) => {
|
|
95
|
+
rows.delete(taskId);
|
|
96
|
+
while (rows.size >= MAX_ROWS) {
|
|
97
|
+
const oldest = rows.keys().next();
|
|
98
|
+
if (oldest.done === true)
|
|
99
|
+
break;
|
|
100
|
+
rows.delete(oldest.value);
|
|
101
|
+
}
|
|
102
|
+
rows.set(taskId, row);
|
|
103
|
+
};
|
|
104
|
+
const record = (taskId, source) => {
|
|
105
|
+
if (!validId(taskId) || !validSource(source))
|
|
106
|
+
return 0;
|
|
107
|
+
const now = clock();
|
|
108
|
+
if (now === null)
|
|
109
|
+
return 0;
|
|
110
|
+
purge(now);
|
|
111
|
+
const prev = rows.get(taskId);
|
|
112
|
+
const abortAt = prev?.abortAt ?? (source === TERMINATION_INTENT_WEAK_SOURCE ? now : null);
|
|
113
|
+
const version = nextVersion++;
|
|
114
|
+
trackBounded(priors, version, prev ?? null);
|
|
115
|
+
put(taskId, { at: now, source, abortAt, version });
|
|
116
|
+
return version;
|
|
117
|
+
};
|
|
118
|
+
const rollback = (taskId, prior) => {
|
|
119
|
+
if (!validId(taskId))
|
|
120
|
+
return;
|
|
121
|
+
const now = clock();
|
|
122
|
+
if (now === null)
|
|
123
|
+
return;
|
|
124
|
+
purge(now);
|
|
125
|
+
if (prior !== null && validSource(prior) && prior !== TERMINATION_INTENT_WEAK_SOURCE) {
|
|
126
|
+
record(taskId, prior);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const row = rows.get(taskId);
|
|
130
|
+
const abortAt = row?.abortAt ?? null;
|
|
131
|
+
if (abortAt !== null && isFresh(now, abortAt)) {
|
|
132
|
+
put(taskId, { at: abortAt, source: TERMINATION_INTENT_WEAK_SOURCE, abortAt, version: nextVersion++ });
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
rows.delete(taskId);
|
|
136
|
+
};
|
|
137
|
+
const restoreTo = (taskId, row, target, now) => {
|
|
138
|
+
if (target === null) {
|
|
139
|
+
rollback(taskId, null);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const abortAt = target.abortAt === null ? row.abortAt : row.abortAt === null ? target.abortAt : Math.max(target.abortAt, row.abortAt);
|
|
143
|
+
put(taskId, { at: target.at, source: target.source, abortAt, version: target.version ?? nextVersion++ });
|
|
144
|
+
purge(now);
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
record,
|
|
148
|
+
snapshot(taskId) {
|
|
149
|
+
if (!validId(taskId))
|
|
150
|
+
return null;
|
|
151
|
+
const now = clock();
|
|
152
|
+
if (now === null)
|
|
153
|
+
return null;
|
|
154
|
+
purge(now);
|
|
155
|
+
const row = rows.get(taskId);
|
|
156
|
+
return row === undefined ? null : Object.freeze({ source: row.source, at: row.at, abortAt: row.abortAt });
|
|
157
|
+
},
|
|
158
|
+
restoreIf(taskId, version, snapshot) {
|
|
159
|
+
if (!validId(taskId))
|
|
160
|
+
return false;
|
|
161
|
+
const now = clock();
|
|
162
|
+
if (now === null)
|
|
163
|
+
return false;
|
|
164
|
+
purge(now);
|
|
165
|
+
markRefused(version);
|
|
166
|
+
const row = rows.get(taskId);
|
|
167
|
+
if (row === undefined || row.version !== version)
|
|
168
|
+
return false;
|
|
169
|
+
const eff = effectivePrior(version);
|
|
170
|
+
restoreTo(taskId, row, eff.known ? eff.row : readSnapshot(snapshot), now);
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
rollbackIf(taskId, version, prior) {
|
|
174
|
+
if (!validId(taskId))
|
|
175
|
+
return false;
|
|
176
|
+
const now = clock();
|
|
177
|
+
if (now === null)
|
|
178
|
+
return false;
|
|
179
|
+
purge(now);
|
|
180
|
+
markRefused(version);
|
|
181
|
+
const row = rows.get(taskId);
|
|
182
|
+
if (row === undefined || row.version !== version)
|
|
183
|
+
return false;
|
|
184
|
+
const eff = effectivePrior(version);
|
|
185
|
+
if (eff.known)
|
|
186
|
+
restoreTo(taskId, row, eff.row, now);
|
|
187
|
+
else
|
|
188
|
+
rollback(taskId, prior);
|
|
189
|
+
return true;
|
|
190
|
+
},
|
|
191
|
+
rollback,
|
|
192
|
+
wasRecentlyTerminatedByUs(taskId) {
|
|
193
|
+
if (!validId(taskId))
|
|
194
|
+
return false;
|
|
195
|
+
const now = clock();
|
|
196
|
+
if (now === null)
|
|
197
|
+
return false;
|
|
198
|
+
purge(now);
|
|
199
|
+
return rows.has(taskId);
|
|
200
|
+
},
|
|
201
|
+
sourceOf(taskId) {
|
|
202
|
+
if (!validId(taskId))
|
|
203
|
+
return null;
|
|
204
|
+
const now = clock();
|
|
205
|
+
if (now === null)
|
|
206
|
+
return null;
|
|
207
|
+
purge(now);
|
|
208
|
+
return rows.get(taskId)?.source ?? null;
|
|
209
|
+
},
|
|
210
|
+
armOnAbort(signal, taskId) {
|
|
211
|
+
if (signal === undefined || signal === null || !validId(taskId))
|
|
212
|
+
return;
|
|
213
|
+
const onAbort = () => {
|
|
214
|
+
const read = readSignalReason(signal);
|
|
215
|
+
if (read === null)
|
|
216
|
+
return;
|
|
217
|
+
if (typeof read.reason === 'string' && exempt.includes(read.reason))
|
|
218
|
+
return;
|
|
219
|
+
const now = clock();
|
|
220
|
+
if (now === null)
|
|
221
|
+
return;
|
|
222
|
+
purge(now);
|
|
223
|
+
const existing = rows.get(taskId);
|
|
224
|
+
if (existing !== undefined && existing.source !== TERMINATION_INTENT_WEAK_SOURCE) {
|
|
225
|
+
put(taskId, { ...existing, abortAt: now });
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
put(taskId, { at: now, source: TERMINATION_INTENT_WEAK_SOURCE, abortAt: now, version: nextVersion++ });
|
|
229
|
+
};
|
|
230
|
+
const aborted = readSignalAborted(signal);
|
|
231
|
+
if (aborted === null)
|
|
232
|
+
return;
|
|
233
|
+
if (aborted) {
|
|
234
|
+
onAbort();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
tryListenAbortOnce(signal, onAbort);
|
|
238
|
+
},
|
|
239
|
+
forget(taskId) {
|
|
240
|
+
if (!validId(taskId))
|
|
241
|
+
return;
|
|
242
|
+
rows.delete(taskId);
|
|
243
|
+
},
|
|
244
|
+
size() {
|
|
245
|
+
const now = clock();
|
|
246
|
+
if (now !== null)
|
|
247
|
+
purge(now);
|
|
248
|
+
return rows.size;
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function readStatus(row) {
|
|
253
|
+
try {
|
|
254
|
+
const s = row?.status;
|
|
255
|
+
return typeof s === 'string' && s.length > 0 ? s : null;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const PROBE_STOPPED = Symbol('sema.interruptedSettleProbeStopped');
|
|
262
|
+
const PROBE_FAILED = Symbol('sema.interruptedSettleProbeFailed');
|
|
263
|
+
const positive = (v, fallback) => (typeof v === 'number' && Number.isFinite(v) && v > 0 ? v : fallback);
|
|
264
|
+
export async function awaitInterruptedRunSettle(taskId, deps) {
|
|
265
|
+
const getRun = deps?.getRun;
|
|
266
|
+
if (typeof getRun !== 'function')
|
|
267
|
+
return { kind: 'unknown' };
|
|
268
|
+
if (!validId(taskId))
|
|
269
|
+
return { kind: 'unknown' };
|
|
270
|
+
const budgetMs = positive(deps.budgetMs, INTERRUPTED_SETTLE_BUDGET_MS);
|
|
271
|
+
const intervalMs = positive(deps.intervalMs, INTERRUPTED_SETTLE_POLL_MS);
|
|
272
|
+
const clockNow = typeof deps.now === 'function' ? deps.now : () => performance.now();
|
|
273
|
+
const readNow = () => {
|
|
274
|
+
try {
|
|
275
|
+
const t = clockNow();
|
|
276
|
+
return Number.isFinite(t) ? t : 0;
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return 0;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
const started = readNow();
|
|
283
|
+
let sawRunning = false;
|
|
284
|
+
const isAborted = () => deps.signal?.aborted === true;
|
|
285
|
+
const budgetAc = new AbortController();
|
|
286
|
+
let budgetSpent = false;
|
|
287
|
+
let markStopped = () => { };
|
|
288
|
+
const stopped = new Promise((resolve) => {
|
|
289
|
+
markStopped = () => resolve(PROBE_STOPPED);
|
|
290
|
+
});
|
|
291
|
+
const onCallerAbort = () => markStopped();
|
|
292
|
+
const budgetTimer = setTimeout(() => {
|
|
293
|
+
budgetSpent = true;
|
|
294
|
+
budgetAc.abort();
|
|
295
|
+
markStopped();
|
|
296
|
+
}, budgetMs);
|
|
297
|
+
if (deps.signal !== undefined)
|
|
298
|
+
tryListenAbortOnce(deps.signal, onCallerAbort);
|
|
299
|
+
if (isAborted())
|
|
300
|
+
markStopped();
|
|
301
|
+
const linked = linkedAbortSignal(deps.signal, budgetAc.signal);
|
|
302
|
+
const probeSignal = linked.signal;
|
|
303
|
+
try {
|
|
304
|
+
for (;;) {
|
|
305
|
+
if (isAborted())
|
|
306
|
+
return { kind: 'unknown' };
|
|
307
|
+
if (budgetSpent)
|
|
308
|
+
break;
|
|
309
|
+
let probe;
|
|
310
|
+
try {
|
|
311
|
+
probe = Promise.resolve(getRun(taskId, { signal: probeSignal })).then((row) => row, () => PROBE_FAILED);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
probe = Promise.resolve(PROBE_FAILED);
|
|
315
|
+
}
|
|
316
|
+
const outcome = await Promise.race([probe, stopped]);
|
|
317
|
+
if (isAborted())
|
|
318
|
+
return { kind: 'unknown' };
|
|
319
|
+
const status = outcome === PROBE_STOPPED || outcome === PROBE_FAILED ? null : readStatus(outcome);
|
|
320
|
+
if (status !== null) {
|
|
321
|
+
if (isSdkRunTerminal(status))
|
|
322
|
+
return { kind: 'settled', status };
|
|
323
|
+
if (isSdkRunParked(status))
|
|
324
|
+
return { kind: 'parked', status };
|
|
325
|
+
if (status === 'running')
|
|
326
|
+
sawRunning = true;
|
|
327
|
+
}
|
|
328
|
+
if (budgetSpent)
|
|
329
|
+
break;
|
|
330
|
+
const left = started + budgetMs - readNow();
|
|
331
|
+
if (left <= 0)
|
|
332
|
+
break;
|
|
333
|
+
await abortableSleep(Math.min(intervalMs, left), probeSignal);
|
|
334
|
+
if (isAborted())
|
|
335
|
+
return { kind: 'unknown' };
|
|
336
|
+
}
|
|
337
|
+
if (isAborted())
|
|
338
|
+
return { kind: 'unknown' };
|
|
339
|
+
return sawRunning ? { kind: 'still-running', waitedMs: Math.max(0, readNow() - started) } : { kind: 'unknown' };
|
|
340
|
+
}
|
|
341
|
+
finally {
|
|
342
|
+
clearTimeout(budgetTimer);
|
|
343
|
+
linked.dispose();
|
|
344
|
+
if (deps.signal !== undefined)
|
|
345
|
+
tryUnlistenAbort(deps.signal, onCallerAbort);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
export function interruptedRunSettleRow(taskId, verdict, lang) {
|
|
349
|
+
if (typeof verdict !== 'object' || verdict === null || verdict.kind !== 'settled')
|
|
350
|
+
return null;
|
|
351
|
+
return renderMessage(msg('session.selfHeal.row.interrupted.settled', { taskId: displayUntrusted(String(taskId), { max: 120 }) }), lang);
|
|
352
|
+
}
|
|
@@ -29,6 +29,8 @@ export interface ToolHistoryMismatchRowKey {
|
|
|
29
29
|
}
|
|
30
30
|
export declare function toolHistoryMismatchRowKey(m: ToolHistoryMismatch, consecutive: number | undefined, rewindOffered: boolean): ToolHistoryMismatchRowKey;
|
|
31
31
|
export declare function readToolHistoryMismatchKey(v: object | null | undefined): ToolHistoryMismatchRowKey | undefined;
|
|
32
|
+
export declare const SEMA_TOOL_HISTORY_ACCEPTED_KEY = "_sema_tool_history_accepted";
|
|
33
|
+
export declare function readToolHistoryAcceptedKey(frame: object | null | undefined): true | undefined;
|
|
32
34
|
export declare const TOOL_HISTORY_LEDGER_CAP = 64;
|
|
33
35
|
export declare function openToolHistoryGeneration(): number;
|
|
34
36
|
export interface ToolHistoryTerminalNote {
|
|
@@ -38,8 +40,14 @@ export interface ToolHistoryTerminalNote {
|
|
|
38
40
|
runId: string | undefined;
|
|
39
41
|
replay: boolean;
|
|
40
42
|
mismatch: ToolHistoryMismatch | null;
|
|
43
|
+
accepted?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface ToolHistoryTerminalFacts {
|
|
46
|
+
readonly consecutive: number | undefined;
|
|
47
|
+
readonly acceptedSinceMismatch: true | undefined;
|
|
41
48
|
}
|
|
42
49
|
export declare function noteToolHistoryTerminal(note: ToolHistoryTerminalNote): number | undefined;
|
|
50
|
+
export declare function noteToolHistoryTerminalFacts(note: ToolHistoryTerminalNote): ToolHistoryTerminalFacts;
|
|
43
51
|
export declare function _resetToolHistoryLedgerForTest(): void;
|
|
44
52
|
export interface ToolHistoryRow {
|
|
45
53
|
readonly toolUseIds?: readonly string[];
|