@sema-agent/client-core 0.98.0 → 0.100.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 +376 -0
- package/README.md +61 -35
- package/dist/adapt/arms.js +120 -55
- package/dist/adapt/panelTasks.d.ts +3 -2
- package/dist/adapt/panelTasks.js +34 -11
- package/dist/adapt/textStream.d.ts +1 -1
- package/dist/adapt/textStream.js +51 -28
- package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
- package/dist/adapter/activeRunSelfHeal.js +210 -294
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
- package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
- package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
- package/dist/adapter/downstream/wiringManifestView.js +1 -0
- package/dist/adapter/runStream.js +82 -40
- package/dist/adapter/types.d.ts +2 -0
- package/dist/adapter/types.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
- package/dist/agentsWireCaps.d.ts +7 -3
- package/dist/agentsWireCaps.js +133 -39
- package/dist/cloudConfigWireCaps.d.ts +10 -1
- package/dist/cloudConfigWireCaps.js +181 -65
- package/dist/compactionStatus.d.ts +34 -0
- package/dist/compactionStatus.js +196 -0
- package/dist/controlRouter.d.ts +4 -2
- package/dist/controlRouter.js +39 -51
- package/dist/coreValuePorts.d.ts +26 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/corruptSessionCopy.d.ts +2 -1
- package/dist/corruptSessionCopy.js +3 -3
- package/dist/decideFailureNote.js +3 -3
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/detachWire.js +3 -2
- package/dist/devicesFace.d.ts +34 -0
- package/dist/devicesFace.js +90 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +153 -5
- package/dist/engineAgentPanelStore.d.ts +14 -4
- package/dist/engineAgentPanelStore.js +14 -0
- package/dist/engineCapReader.d.ts +2 -1
- package/dist/engineCapReader.js +7 -5
- package/dist/engineCapsCache.d.ts +8 -0
- package/dist/engineCapsCache.js +59 -6
- package/dist/engineCapsChange.d.ts +2 -0
- package/dist/engineCapsChange.js +9 -0
- package/dist/engineErrorCodes.d.ts +11 -2
- package/dist/engineErrorCodes.js +11 -12
- package/dist/engineRowRef.js +4 -0
- package/dist/engineSessionMessages.d.ts +1 -0
- package/dist/engineSessionMessages.js +7 -1
- package/dist/engineTargetSeat.d.ts +27 -0
- package/dist/engineTargetSeat.js +199 -0
- package/dist/engineToolDirectory.d.ts +3 -0
- package/dist/engineToolDirectory.js +4 -2
- package/dist/engineWireFor.js +3 -8
- package/dist/env/uiLanguage.d.ts +2 -1
- package/dist/env/uiLanguage.js +3 -2
- package/dist/eventLeg.d.ts +7 -5
- package/dist/eventLeg.js +68 -49
- package/dist/fileHistoryCaptureCapability.d.ts +2 -4
- package/dist/fileHistoryCaptureCapability.js +12 -22
- package/dist/fileHistoryLegNotice.d.ts +2 -1
- package/dist/fileHistoryLegNotice.js +3 -3
- package/dist/frameBinding.d.ts +3 -0
- package/dist/frameBinding.js +12 -0
- package/dist/gateOutcome.js +16 -2
- package/dist/gateVocabulary.d.ts +8 -7
- package/dist/gateVocabulary.js +71 -73
- package/dist/generated/engineFactTables.d.ts +18 -1
- package/dist/generated/engineFactTables.js +56 -0
- package/dist/generated/engineNoticeTables.js +12 -3
- package/dist/generated/settingsSchemaFns.d.ts +18 -0
- package/dist/generated/settingsSchemaFns.js +70 -0
- package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +9 -0
- package/dist/generated/settingsSchemaTypes.d.ts +133 -0
- package/dist/generated/settingsSchemaTypes.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +2 -1
- package/dist/hitl/allowRuleShadow.js +18 -15
- package/dist/hitl/approvalCardReasons.d.ts +3 -2
- package/dist/hitl/approvalCardReasons.js +29 -30
- package/dist/hitl/approvalHolds.d.ts +17 -0
- package/dist/hitl/approvalHolds.js +114 -29
- package/dist/hitl/askClassPair.d.ts +2 -2
- package/dist/hitl/askClassPair.js +16 -0
- package/dist/hitl/askGateWire.js +2 -1
- package/dist/hitl/askSettlementLine.d.ts +14 -4
- package/dist/hitl/askSettlementLine.js +67 -47
- package/dist/hitl/attributionLadder.d.ts +23 -0
- package/dist/hitl/attributionLadder.js +67 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
- package/dist/hitl/automaticAnswerVerdict.js +8 -8
- package/dist/hitl/crashConvergedNotice.d.ts +5 -4
- package/dist/hitl/crashConvergedNotice.js +28 -41
- package/dist/hitl/decisionLedger.d.ts +55 -0
- package/dist/hitl/decisionLedger.js +156 -0
- package/dist/hitl/decisionRefusal.d.ts +1 -0
- package/dist/hitl/decisionRefusal.js +1 -1
- package/dist/hitl/decisionSend.d.ts +113 -0
- package/dist/hitl/decisionSend.js +579 -0
- package/dist/hitl/frameRouter.js +7 -8
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +21 -9
- package/dist/hitl/persistedRulesWire.d.ts +6 -5
- package/dist/hitl/persistedRulesWire.js +55 -73
- package/dist/hitl/planReviewWire.d.ts +5 -0
- package/dist/hitl/planReviewWire.js +53 -76
- package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
- package/dist/hitl/sessionPolicyDeliverable.js +49 -9
- package/dist/hitl/sessionPolicyWire.d.ts +2 -1
- package/dist/hitl/sessionPolicyWire.js +23 -24
- package/dist/hitl/suspendedReopen.d.ts +2 -1
- package/dist/hitl/suspendedReopen.js +7 -10
- package/dist/hitl/toolApprovalWire.d.ts +17 -5
- package/dist/hitl/toolApprovalWire.js +120 -147
- package/dist/hooksWireCaps.js +145 -56
- package/dist/host.d.ts +21 -0
- package/dist/hostTurnSettings.d.ts +110 -0
- package/dist/hostTurnSettings.js +692 -0
- package/dist/humanTurn.d.ts +15 -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 +713 -0
- package/dist/i18n/messages.en.js +713 -0
- package/dist/i18n/messages.zh.js +854 -1
- package/dist/index.d.ts +45 -13
- package/dist/index.js +27 -9
- package/dist/inheritEnvCapability.d.ts +4 -2
- package/dist/inheritEnvCapability.js +12 -5
- package/dist/inheritEnvWire.d.ts +3 -2
- package/dist/inheritEnvWire.js +14 -16
- package/dist/injectionLaneNotice.d.ts +5 -0
- package/dist/injectionLaneNotice.js +46 -0
- package/dist/interactiveHalt.js +17 -6
- package/dist/liveModelCatalog.d.ts +2 -1
- package/dist/liveModelCatalog.js +14 -8
- package/dist/mcpPanel.d.ts +10 -1
- package/dist/mcpPanel.js +42 -13
- package/dist/mcpProbeCapability.d.ts +2 -1
- package/dist/mcpProbeCapability.js +7 -11
- package/dist/mcpProbeWire.d.ts +3 -1
- package/dist/mcpProbeWire.js +5 -0
- package/dist/mcpReconnect.js +2 -2
- package/dist/mcpToolToggles.d.ts +6 -0
- package/dist/mcpToolToggles.js +46 -0
- package/dist/mcpWireCaps.d.ts +43 -3
- package/dist/mcpWireCaps.js +194 -59
- package/dist/mcpWireTransport.d.ts +4 -0
- package/dist/mcpWireTransport.js +18 -0
- package/dist/memoryEntriesWire.js +5 -10
- package/dist/model/onboardJudgement.d.ts +93 -0
- package/dist/model/onboardJudgement.js +415 -0
- package/dist/model/tierVocabulary.d.ts +2 -0
- package/dist/model/tierVocabulary.js +17 -5
- package/dist/modelCapabilityProbe.d.ts +65 -0
- package/dist/modelCapabilityProbe.js +601 -0
- package/dist/modelIdentityResolvability.d.ts +5 -0
- package/dist/modelIdentityResolvability.js +49 -22
- package/dist/ownKey.d.ts +33 -0
- package/dist/ownKey.js +109 -0
- package/dist/panelReduce.d.ts +11 -1
- package/dist/panelReduce.js +95 -16
- package/dist/panelStateHolder.d.ts +1 -0
- package/dist/panelStateHolder.js +10 -1
- package/dist/permissionRuleIssue.d.ts +2 -1
- package/dist/permissionRuleIssue.js +23 -20
- package/dist/permissionRulesWriteCapability.d.ts +2 -1
- package/dist/permissionRulesWriteCapability.js +8 -6
- package/dist/pluginHooksWire.d.ts +46 -3
- package/dist/pluginHooksWire.js +220 -12
- package/dist/prepareRefusal.d.ts +8 -0
- package/dist/prepareRefusal.js +72 -0
- package/dist/printModelStatus.d.ts +63 -0
- package/dist/printModelStatus.js +155 -0
- package/dist/request/taskRequest.d.ts +16 -10
- package/dist/request/taskRequest.js +195 -58
- package/dist/resumeRefusalCopy.d.ts +14 -9
- package/dist/resumeRefusalCopy.js +89 -144
- package/dist/retryStatus.d.ts +55 -0
- package/dist/retryStatus.js +155 -19
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +58 -0
- package/dist/sandboxWire.d.ts +2 -1
- package/dist/sandboxWire.js +55 -21
- package/dist/scenarioRefusal.d.ts +10 -0
- package/dist/scenarioRefusal.js +111 -0
- package/dist/seam.d.ts +48 -9
- package/dist/seam.js +54 -5
- package/dist/seatContract.d.ts +272 -14
- package/dist/seatContract.js +711 -23
- 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 -1
- package/dist/sessionPolicyCapability.js +8 -6
- package/dist/settingsCredentialKeyPaths.d.ts +8 -0
- package/dist/settingsCredentialKeyPaths.js +219 -0
- package/dist/settingsHooksSalvage.d.ts +44 -0
- package/dist/settingsHooksSalvage.js +211 -0
- package/dist/skillToolListsCapability.d.ts +2 -1
- package/dist/skillToolListsCapability.js +8 -6
- package/dist/skillsWireCaps.d.ts +0 -3
- package/dist/skillsWireCaps.js +1 -2
- package/dist/sseIdleTriage.js +3 -2
- package/dist/subagent/engineSubagentResume.js +15 -9
- package/dist/subagentContentStore.d.ts +4 -0
- package/dist/subagentContentStore.js +157 -27
- package/dist/toolHistoryMismatch.js +3 -2
- package/dist/toolRoster.d.ts +3 -2
- package/dist/toolRoster.js +21 -20
- package/dist/toolsFlagNames.d.ts +8 -0
- package/dist/toolsFlagNames.js +110 -0
- package/dist/turnFailurePresentation.d.ts +12 -1
- package/dist/turnFailurePresentation.js +220 -15
- 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 -1
- package/dist/userInvokedSkillsCapability.js +31 -7
- package/dist/wireErrorTriage.d.ts +7 -0
- package/dist/wireErrorTriage.js +23 -1
- package/dist/wireFailureShape.js +2 -1
- package/dist/wireRefusalCopy.d.ts +62 -16
- package/dist/wireRefusalCopy.js +307 -148
- package/dist/workflowsJournalCapability.d.ts +2 -1
- package/dist/workflowsJournalCapability.js +8 -6
- package/docs/INTEGRATION-CLIENTS.md +951 -42
- package/package.json +5 -5
|
@@ -11,15 +11,17 @@ import { readAllowRuleShadowFromWire, retiredAllowRuleShadowKeyPresent, RETIRED_
|
|
|
11
11
|
import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
12
12
|
import { readEngineActiveBgTasks } from '../fleet/fleetLedger.js';
|
|
13
13
|
import { CORE_SKILL_TOOL_NAME } from '../generated/toolNameTables.js';
|
|
14
|
+
import { CORE_ALLOW_ENTRY_INERT_REASONS } from '../generated/engineFactTables.js';
|
|
15
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
14
16
|
import { INTERRUPT_DENY_REASON, observeCancelByDeny, surfaceApprovalParking, surfaceRememberNotApplied, surfaceEditNotForwarded, surfaceEditRefusedOnBlindAsk, surfaceRuleArmNotSent, surfaceRuleArmRejected } from './hitlHostSurface.js';
|
|
15
17
|
import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
|
|
16
18
|
import { displayUntrusted } from '../displayUntrusted.js';
|
|
17
19
|
import { frameBindingOf } from '../frameBinding.js';
|
|
18
|
-
import {
|
|
20
|
+
import { carriesAttributionKey, deliverWithAttributionLadder } from './attributionLadder.js';
|
|
21
|
+
import { approvalDecisionHolds, approvalHoldFor, awaitApprovalHolder, claimApprovalCardFor, enterLiveRespondPhase, holdLiveCard, joinLiveCard, liveCardHoldOf, clearSettledApprovals, noteHolderSettledApproval, settledApprovalOf, settledForDurableLane, settledLiveCardOutcome } from './approvalHolds.js';
|
|
19
22
|
import { joinedResolution, resolutionOfDecisionFailure } from './approvalResolution.js';
|
|
20
23
|
import { parkRowDeadlineState } from './parkExpiryJudgements.js';
|
|
21
24
|
import { isApprovalMandateWord } from '../gateVocabulary.js';
|
|
22
|
-
import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
|
|
23
25
|
import { approvalDecidedByAdmitted } from '../approvalDecidedByCapability.js';
|
|
24
26
|
import { decideFailureNote } from '../decideFailureNote.js';
|
|
25
27
|
import { wireFailureTextsOf } from '../wireFailureShape.js';
|
|
@@ -460,49 +462,30 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
|
|
|
460
462
|
try {
|
|
461
463
|
const denyPayload = { decision: 'deny', reason: answerPayloadFor({ kind: 'deny', ...(denyReasonSnapshot !== undefined ? { reason: denyReasonSnapshot } : {}) }, 'decide').reason };
|
|
462
464
|
const denyBody = { ...denyPayload, ...attributionKeys };
|
|
463
|
-
|
|
464
|
-
let attributionRenamed = false;
|
|
465
|
+
const ladder = { lastCarried: carriesAttributionKey(attributionKeys), dropped: false, renamed: false };
|
|
465
466
|
let raw;
|
|
466
|
-
lastSendCarriedAttribution =
|
|
467
|
+
lastSendCarriedAttribution = ladder.lastCarried;
|
|
467
468
|
emitAnswerCommitted(callKey, 'decide', card, denyPayload);
|
|
468
469
|
try {
|
|
469
|
-
raw = await bridge.decideTool(
|
|
470
|
+
raw = await deliverWithAttributionLadder(denyBody, (b) => bridge.decideTool(b, gatedCallId, decideOpts, pending), signal, ladder, (step) => {
|
|
471
|
+
hostLog('debug', step === 'renamed'
|
|
472
|
+
? `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note was sent under a name ` +
|
|
473
|
+
'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
|
|
474
|
+
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
|
|
475
|
+
: step === 'dropped'
|
|
476
|
+
? `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note is not part of ` +
|
|
477
|
+
'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
|
|
478
|
+
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
|
|
479
|
+
: `liveToolApprovalWire: decide(deny) for task ${taskId} was refused again because the settlement note is not part of ` +
|
|
480
|
+
'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
|
|
481
|
+
'(still before the approval was judged)');
|
|
482
|
+
});
|
|
470
483
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
const withoutAttribution = withoutAttributionKey(denyBody);
|
|
474
|
-
lastSendCarriedAttribution = false;
|
|
475
|
-
hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note is not part of ` +
|
|
476
|
-
'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
|
|
477
|
-
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
|
|
478
|
-
raw = await bridge.decideTool(withoutAttribution, gatedCallId, decideOpts, pending);
|
|
479
|
-
attributionDropped = true;
|
|
480
|
-
}
|
|
481
|
-
else if (shouldResendUnderSuccessorKey(first, Object.hasOwn(denyBody, 'settledBy'), signal)) {
|
|
482
|
-
const renamed = withAttributionKeyRenamed(denyBody);
|
|
483
|
-
hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note was sent under a name ` +
|
|
484
|
-
'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
|
|
485
|
-
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
|
|
486
|
-
try {
|
|
487
|
-
raw = await bridge.decideTool(renamed, gatedCallId, decideOpts, pending);
|
|
488
|
-
attributionRenamed = true;
|
|
489
|
-
}
|
|
490
|
-
catch (second) {
|
|
491
|
-
if (!shouldResendWithoutAttribution(second, true, signal))
|
|
492
|
-
throw second;
|
|
493
|
-
const renamedWithoutAttribution = withoutAttributionKey(renamed);
|
|
494
|
-
lastSendCarriedAttribution = false;
|
|
495
|
-
hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused again because the settlement note is not part of ` +
|
|
496
|
-
'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
|
|
497
|
-
'(still before the approval was judged)');
|
|
498
|
-
raw = await bridge.decideTool(renamedWithoutAttribution, gatedCallId, decideOpts, pending);
|
|
499
|
-
attributionDropped = true;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
throw first;
|
|
504
|
-
}
|
|
484
|
+
finally {
|
|
485
|
+
lastSendCarriedAttribution = ladder.lastCarried;
|
|
505
486
|
}
|
|
487
|
+
const attributionDropped = ladder.dropped;
|
|
488
|
+
const attributionRenamed = ladder.renamed;
|
|
506
489
|
const receipt = readDecideReceipt(raw);
|
|
507
490
|
const deny = denyFactsOf(denySettledByForWire, denyReasonSnapshot, attributionDropped, attributionRenamed);
|
|
508
491
|
return {
|
|
@@ -870,39 +853,11 @@ function readPersistedRuleAnchors(v) {
|
|
|
870
853
|
function isNonNegativeSafeInt(v) {
|
|
871
854
|
return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
|
|
872
855
|
}
|
|
873
|
-
function shouldResendWithoutAttribution(e, sentAttributionKey, signal) {
|
|
874
|
-
if (!sentAttributionKey)
|
|
875
|
-
return false;
|
|
876
|
-
if (signal?.aborted === true)
|
|
877
|
-
return false;
|
|
878
|
-
return denyAttributionRefusalFromError(e, true)?.kind === 'not_in_proof';
|
|
879
|
-
}
|
|
880
|
-
function shouldResendUnderSuccessorKey(e, lastSendCarriedRetiredKey, signal) {
|
|
881
|
-
if (!lastSendCarriedRetiredKey)
|
|
882
|
-
return false;
|
|
883
|
-
if (signal?.aborted === true)
|
|
884
|
-
return false;
|
|
885
|
-
return denyAttributionRefusalFromError(e, true)?.kind === 'retired_key';
|
|
886
|
-
}
|
|
887
856
|
export function decisionAttributionKeyOf(reading, denySettledBy) {
|
|
888
857
|
if (denySettledBy !== 'policy')
|
|
889
858
|
return {};
|
|
890
859
|
return approvalDecidedByAdmitted(reading) ? { decidedBy: 'policy' } : { settledBy: 'policy' };
|
|
891
860
|
}
|
|
892
|
-
function carriesAttributionKey(body) {
|
|
893
|
-
return Object.hasOwn(body, 'settledBy') || Object.hasOwn(body, 'decidedBy');
|
|
894
|
-
}
|
|
895
|
-
function withoutAttributionKey(body) {
|
|
896
|
-
const { settledBy: _droppedSettledBy, decidedBy: _droppedDecidedBy, ...rest } = body;
|
|
897
|
-
void _droppedSettledBy;
|
|
898
|
-
void _droppedDecidedBy;
|
|
899
|
-
return rest;
|
|
900
|
-
}
|
|
901
|
-
function withAttributionKeyRenamed(body) {
|
|
902
|
-
const { settledBy, decidedBy: _replaced, ...rest } = body;
|
|
903
|
-
void _replaced;
|
|
904
|
-
return settledBy === undefined ? rest : { ...rest, decidedBy: settledBy };
|
|
905
|
-
}
|
|
906
861
|
function readDecidedByReadingOf(holder) {
|
|
907
862
|
try {
|
|
908
863
|
return readOwnDataValue(holder, 'approvalDecidedBy');
|
|
@@ -967,23 +922,24 @@ function usableProbeReason(raw) {
|
|
|
967
922
|
return typeof raw === 'string' && raw.trim() !== '' ? raw : undefined;
|
|
968
923
|
}
|
|
969
924
|
const PROBE_CAUSE_CODE_WORD = /^[a-z][a-z0-9_]{0,31}(?:\.[a-z][a-z0-9_]{0,31}){1,3}$/;
|
|
970
|
-
export function askProbeReasonDetail(card) {
|
|
925
|
+
export function askProbeReasonDetail(card, lang) {
|
|
971
926
|
const prose = usableProbeReason(ownDataValue(card, 'probeReason'));
|
|
972
927
|
const shown = prose === undefined ? '' : displayUntrusted(prose);
|
|
973
|
-
const sentence = probeCauseSentence(ownDataValue(card, 'probeCause'), shown !== '');
|
|
928
|
+
const sentence = probeCauseSentence(ownDataValue(card, 'probeCause'), shown !== '', lang);
|
|
974
929
|
if (sentence === undefined)
|
|
975
930
|
return shown === '' ? undefined : shown;
|
|
976
|
-
return shown === '' ? sentence :
|
|
931
|
+
return shown === '' ? sentence : renderMessage(msg('approval.probe.proseJoin', { sentence, prose: shown }), lang);
|
|
977
932
|
}
|
|
978
|
-
function probeCauseSentence(cause, withProse) {
|
|
933
|
+
function probeCauseSentence(cause, withProse, lang) {
|
|
979
934
|
try {
|
|
980
935
|
if (!isWireRecordCarrier(cause))
|
|
981
936
|
return undefined;
|
|
982
937
|
const code = ownDataValue(cause, 'code');
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
938
|
+
const withCode = typeof code === 'string' && PROBE_CAUSE_CODE_WORD.test(code);
|
|
939
|
+
const key = withProse
|
|
940
|
+
? withCode ? 'approval.probe.withProseCode' : 'approval.probe.withProse'
|
|
941
|
+
: withCode ? 'approval.probe.noProseCode' : 'approval.probe.noProse';
|
|
942
|
+
return renderMessage(withCode ? msg(key, { code: displayUntrusted(code) }) : msg(key), lang);
|
|
987
943
|
}
|
|
988
944
|
catch {
|
|
989
945
|
return undefined;
|
|
@@ -1041,6 +997,21 @@ export function readApprovalBoundGrants(v) {
|
|
|
1041
997
|
return undefined;
|
|
1042
998
|
return Object.freeze({ skill, allowedTools, disallowedTools });
|
|
1043
999
|
}
|
|
1000
|
+
const READS_AS_NOTHING_HEAD = '<reads as nothing (';
|
|
1001
|
+
export function readBoundGrantEntry(entry) {
|
|
1002
|
+
if (typeof entry !== 'string' || entry === '')
|
|
1003
|
+
return undefined;
|
|
1004
|
+
if (!entry.startsWith('<'))
|
|
1005
|
+
return Object.freeze({ kind: 'rule' });
|
|
1006
|
+
if (entry.startsWith(READS_AS_NOTHING_HEAD)) {
|
|
1007
|
+
const close = entry.indexOf('): ', READS_AS_NOTHING_HEAD.length);
|
|
1008
|
+
const word = close > 0 ? entry.slice(READS_AS_NOTHING_HEAD.length, close) : undefined;
|
|
1009
|
+
if (word !== undefined && CORE_ALLOW_ENTRY_INERT_REASONS.includes(word)) {
|
|
1010
|
+
return Object.freeze({ kind: 'reads_as_nothing', reason: word });
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
return Object.freeze({ kind: 'reads_as_nothing' });
|
|
1014
|
+
}
|
|
1044
1015
|
const BOUND_GRANT_NOT_BINDABLE = 'not_bindable';
|
|
1045
1016
|
const SERVER_CLASS_READ_CAP = 64;
|
|
1046
1017
|
function readApprovalGrantBinding(carrier) {
|
|
@@ -1161,34 +1132,45 @@ export function readApprovalClassifierNoRuling(v) {
|
|
|
1161
1132
|
return typeof w === 'string' && CAUSE_WORD.test(w) ? w : undefined;
|
|
1162
1133
|
}
|
|
1163
1134
|
const CLASSIFIER_NO_RULING_REASONS = Object.freeze({
|
|
1164
|
-
error: '
|
|
1165
|
-
timeout: '
|
|
1166
|
-
parse_error: '
|
|
1135
|
+
error: 'approval.classifier.noRulingError',
|
|
1136
|
+
timeout: 'approval.classifier.noRulingTimeout',
|
|
1137
|
+
parse_error: 'approval.classifier.noRulingParseError',
|
|
1167
1138
|
});
|
|
1168
1139
|
const _noRulingPin = [true, true];
|
|
1169
1140
|
void _noRulingPin;
|
|
1170
|
-
export function classifierNoRulingDetail(word) {
|
|
1141
|
+
export function classifierNoRulingDetail(word, lang) {
|
|
1171
1142
|
if (typeof word === 'string' && Object.hasOwn(CLASSIFIER_NO_RULING_REASONS, word)) {
|
|
1172
|
-
return
|
|
1143
|
+
return renderMessage(msg(CLASSIFIER_NO_RULING_REASONS[word]), lang);
|
|
1173
1144
|
}
|
|
1174
1145
|
if (typeof word === 'string' && CAUSE_WORD.test(word))
|
|
1175
|
-
return
|
|
1176
|
-
return '
|
|
1146
|
+
return renderMessage(msg('approval.classifier.noRulingOther', { reason: displayUntrusted(word) }), lang);
|
|
1147
|
+
return renderMessage(msg('approval.classifier.noRulingBare'), lang);
|
|
1177
1148
|
}
|
|
1178
|
-
|
|
1179
|
-
export function approvalBoundGrantsDetail(grants) {
|
|
1149
|
+
export function approvalBoundGrantsDetail(grants, lang) {
|
|
1180
1150
|
const g = readApprovalBoundGrants({ boundGrants: grants });
|
|
1181
1151
|
if (g === undefined)
|
|
1182
1152
|
return undefined;
|
|
1183
1153
|
if (g.skill === null)
|
|
1184
|
-
return '
|
|
1185
|
-
const
|
|
1186
|
-
const
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
|
|
1154
|
+
return renderMessage(msg('approval.boundGrants.noSkill'), lang);
|
|
1155
|
+
const isRule = (e) => readBoundGrantEntry(e)?.kind === 'rule';
|
|
1156
|
+
const a = g.allowedTools.filter(isRule).length;
|
|
1157
|
+
const d = g.disallowedTools.filter(isRule).length;
|
|
1158
|
+
const allowNothing = g.allowedTools.length - a;
|
|
1159
|
+
const denyNothing = g.disallowedTools.length - d;
|
|
1160
|
+
if (denyNothing > 0) {
|
|
1161
|
+
return renderMessage(denyNothing === 1 ? msg('approval.boundGrants.notActivated.one') : msg('approval.boundGrants.notActivated.other', { count: String(denyNothing) }), lang);
|
|
1162
|
+
}
|
|
1163
|
+
if (a === 0 && d === 0) {
|
|
1164
|
+
if (allowNothing > 0)
|
|
1165
|
+
return renderMessage(allowNothing === 1 ? msg('approval.boundGrants.listsNoToolsWithNothing.one') : msg('approval.boundGrants.listsNoToolsWithNothing.other', { count: String(allowNothing) }), lang);
|
|
1166
|
+
return renderMessage(msg('approval.boundGrants.listsNoTools'), lang);
|
|
1167
|
+
}
|
|
1168
|
+
const allow = a === 1 ? msg('approval.boundGrants.allowPart.one') : msg('approval.boundGrants.allowPart.other', { count: a });
|
|
1169
|
+
const deny = d === 1 ? msg('approval.boundGrants.denyPart.one') : msg('approval.boundGrants.denyPart.other', { count: d });
|
|
1170
|
+
if (allowNothing > 0) {
|
|
1171
|
+
return renderMessage(allowNothing === 1 ? msg('approval.boundGrants.activatesWithNothing.one', { allow, deny }) : msg('approval.boundGrants.activatesWithNothing.other', { allow, deny, count: String(allowNothing) }), lang);
|
|
1172
|
+
}
|
|
1173
|
+
return renderMessage(msg('approval.boundGrants.activates', { allow, deny }), lang);
|
|
1192
1174
|
}
|
|
1193
1175
|
const CALL_LEDGER_MAX_CALLS = 256;
|
|
1194
1176
|
const CALL_LEDGER_MAX_ASKS_PER_CALL = 8;
|
|
@@ -1289,7 +1271,7 @@ function noteCallOutcome(slot, r) {
|
|
|
1289
1271
|
const fateRank = { not_sent: 0, not_accepted: 1, unconfirmed: 2 };
|
|
1290
1272
|
entry.answerFate = entry.answerFate !== undefined && fateRank[entry.answerFate] > fateRank[next] ? entry.answerFate : next;
|
|
1291
1273
|
}
|
|
1292
|
-
export function approvalPriorCardsDetail(card) {
|
|
1274
|
+
export function approvalPriorCardsDetail(card, lang) {
|
|
1293
1275
|
const prior = ownDataValue(card, 'priorCardsForCall');
|
|
1294
1276
|
let isList = false;
|
|
1295
1277
|
try {
|
|
@@ -1307,13 +1289,12 @@ export function approvalPriorCardsDetail(card) {
|
|
|
1307
1289
|
for (let i = 0; i < length; i++)
|
|
1308
1290
|
items.push(ownDataValue(prior, String(i)));
|
|
1309
1291
|
const outcome = ownDataValue(items[length - 1], 'outcome');
|
|
1310
|
-
const earlier = outcome === 'allowed' ? '
|
|
1292
|
+
const earlier = msg(outcome === 'allowed' ? 'approval.priorCard.earlier.allowed' : outcome === 'denied' ? 'approval.priorCard.earlier.denied' : 'approval.priorCard.earlier.shown');
|
|
1311
1293
|
const fromRule = items.some((p) => ownDataValue(p, 'origin') === 'ask_rule');
|
|
1312
1294
|
const thisFromRule = ownDataValue(card, 'origin') === 'ask_rule';
|
|
1313
|
-
if (fromRule && !thisFromRule)
|
|
1314
|
-
return
|
|
1315
|
-
}
|
|
1316
|
-
return `This is a second approval for the same call: ${earlier}. This one is a separate check and needs its own answer.`;
|
|
1295
|
+
if (fromRule && !thisFromRule)
|
|
1296
|
+
return renderMessage(msg('approval.priorCard.fromRule', { earlier }), lang);
|
|
1297
|
+
return renderMessage(msg('approval.priorCard.plain', { earlier }), lang);
|
|
1317
1298
|
}
|
|
1318
1299
|
const PRIOR_ANSWER_PHRASE = Object.freeze({
|
|
1319
1300
|
allow: 'Yes',
|
|
@@ -1710,10 +1691,9 @@ export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamA
|
|
|
1710
1691
|
const receivedAtMs = Date.now();
|
|
1711
1692
|
const approvalId = frame.approvalId;
|
|
1712
1693
|
const entry = { frame, approvalId, identity: liveCardIdentityOf(approvalId, frame, run), respond, streamArgs, signal, lane, receivedAtMs };
|
|
1713
|
-
return enterLiveCard(entry
|
|
1694
|
+
return enterLiveCard(entry);
|
|
1714
1695
|
}
|
|
1715
|
-
|
|
1716
|
-
function enterLiveCard(e, round) {
|
|
1696
|
+
function enterLiveCard(e) {
|
|
1717
1697
|
const { approvalId, signal } = e;
|
|
1718
1698
|
const held = liveCardHoldOf(liveFrameCallKey(approvalId));
|
|
1719
1699
|
if (held !== undefined)
|
|
@@ -1721,9 +1701,9 @@ function enterLiveCard(e, round) {
|
|
|
1721
1701
|
const settled = settledLiveCardOutcome(approvalId);
|
|
1722
1702
|
if (settled !== undefined)
|
|
1723
1703
|
return Promise.resolve(settled);
|
|
1724
|
-
const other =
|
|
1704
|
+
const other = approvalHoldFor(e.identity, (h) => h.lane === 'live');
|
|
1725
1705
|
if (other !== undefined)
|
|
1726
|
-
return joinOtherLaneHolder(e, other
|
|
1706
|
+
return joinOtherLaneHolder(e, other);
|
|
1727
1707
|
return holdLiveCard(e.identity, signal, async (hold) => {
|
|
1728
1708
|
const slot = {};
|
|
1729
1709
|
const out = await presentToolApprovalFrameAndRespond(e.frame, approvalId, e.respond, e.streamArgs, signal, e.lane, hold, slot, e.receivedAtMs);
|
|
@@ -1731,7 +1711,7 @@ function enterLiveCard(e, round) {
|
|
|
1731
1711
|
return out;
|
|
1732
1712
|
});
|
|
1733
1713
|
}
|
|
1734
|
-
async function joinOtherLaneHolder(e, other
|
|
1714
|
+
async function joinOtherLaneHolder(e, other) {
|
|
1735
1715
|
const wait = await awaitApprovalHolder(other, e.signal, 'respond');
|
|
1736
1716
|
if (wait.kind === 'settled') {
|
|
1737
1717
|
noteHolderSettledApproval(e.approvalId, wait.how, wait.outcome);
|
|
@@ -1739,7 +1719,7 @@ async function joinOtherLaneHolder(e, other, round) {
|
|
|
1739
1719
|
}
|
|
1740
1720
|
if (wait.kind === 'left')
|
|
1741
1721
|
return { kind: 'not_sent', lane: 'respond', cause: 'retracted', joinedInFlight: true };
|
|
1742
|
-
return enterLiveCard(e
|
|
1722
|
+
return enterLiveCard(e);
|
|
1743
1723
|
}
|
|
1744
1724
|
function liveCardIdentityOf(approvalId, frame, run) {
|
|
1745
1725
|
const toolCallId = typeof frame.toolCallId === 'string' && frame.toolCallId !== '' ? frame.toolCallId : undefined;
|
|
@@ -1789,8 +1769,20 @@ export async function joinApprovalHolder(identity, signal) {
|
|
|
1789
1769
|
return { kind: 'joined', outcome: { kind: 'not_sent', lane: 'decide', cause: 'retracted', joinedInFlight: true } };
|
|
1790
1770
|
return { kind: 'free' };
|
|
1791
1771
|
}
|
|
1792
|
-
|
|
1793
|
-
|
|
1772
|
+
function readApprovalCardClaimSignal(v) {
|
|
1773
|
+
if (typeof v !== 'object' || v === null)
|
|
1774
|
+
return undefined;
|
|
1775
|
+
try {
|
|
1776
|
+
const d = Object.getOwnPropertyDescriptor(v, 'signal');
|
|
1777
|
+
const x = d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
|
|
1778
|
+
return typeof x === 'object' && x !== null ? x : undefined;
|
|
1779
|
+
}
|
|
1780
|
+
catch {
|
|
1781
|
+
return undefined;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
export function claimApprovalCard(identity, options) {
|
|
1785
|
+
return claimApprovalCardFor(readApprovalHolderIdentity(identity), readApprovalCardClaimSignal(options));
|
|
1794
1786
|
}
|
|
1795
1787
|
async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, streamArgs, signal, lane, hold, ledgerSlot, receivedAtMs) {
|
|
1796
1788
|
const frameToolCallId = typeof frame.toolCallId === 'string' && frame.toolCallId !== '' ? frame.toolCallId : undefined;
|
|
@@ -1824,7 +1816,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1824
1816
|
return { kind: 'not_sent', lane: 'respond', cause: 'retracted' };
|
|
1825
1817
|
}
|
|
1826
1818
|
if (card.kind === 'aborted') {
|
|
1827
|
-
hold
|
|
1819
|
+
enterLiveRespondPhase(hold);
|
|
1828
1820
|
const interruptOpts = lane?.approvalDecisionNoteCapable === true ? { note: INTERRUPT_DENY_REASON } : {};
|
|
1829
1821
|
let interruptDeny;
|
|
1830
1822
|
try {
|
|
@@ -1838,7 +1830,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1838
1830
|
hostLog('debug', `liveToolApprovalWire: ${approvalId} card aborted — one tool-level deny issued to settle the pending ask`);
|
|
1839
1831
|
return { kind: 'unsettled', lane: 'respond', cause: 'interrupted' };
|
|
1840
1832
|
}
|
|
1841
|
-
hold
|
|
1833
|
+
enterLiveRespondPhase(hold);
|
|
1842
1834
|
const noteCapable = lane?.approvalDecisionNoteCapable === true;
|
|
1843
1835
|
const denyReasonRead = card.kind === 'deny' ? ((r) => (typeof r === 'string' ? r : undefined))(card.reason) : undefined;
|
|
1844
1836
|
const answerSnapshot = card.kind === 'deny'
|
|
@@ -1943,49 +1935,30 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
|
|
|
1943
1935
|
...(note !== undefined ? { note } : {}),
|
|
1944
1936
|
...attributionKeys,
|
|
1945
1937
|
};
|
|
1946
|
-
|
|
1947
|
-
let attributionRenamed = false;
|
|
1938
|
+
const ladder = { lastCarried: lastSendCarriedAttribution, dropped: false, renamed: false };
|
|
1948
1939
|
let raw;
|
|
1949
1940
|
if (basePayload !== undefined)
|
|
1950
1941
|
emitAnswerCommitted(liveFrameCallKey(approvalId), 'respond', answerSnapshot, basePayload);
|
|
1951
1942
|
try {
|
|
1952
|
-
raw = await respond(approvalId, decision,
|
|
1943
|
+
raw = await deliverWithAttributionLadder(respondOpts, (o) => respond(approvalId, decision, o), signal, ladder, (step) => {
|
|
1944
|
+
hostLog('debug', step === 'renamed'
|
|
1945
|
+
? `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note was sent under a name ` +
|
|
1946
|
+
'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
|
|
1947
|
+
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
|
|
1948
|
+
: step === 'dropped'
|
|
1949
|
+
? `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note is not part of ` +
|
|
1950
|
+
'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
|
|
1951
|
+
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
|
|
1952
|
+
: `liveToolApprovalWire: respond(deny) for ${approvalId} was refused again because the settlement note is not part of ` +
|
|
1953
|
+
'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
|
|
1954
|
+
'(still before the approval was judged)');
|
|
1955
|
+
});
|
|
1953
1956
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
const withoutAttribution = withoutAttributionKey(respondOpts);
|
|
1957
|
-
lastSendCarriedAttribution = false;
|
|
1958
|
-
hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note is not part of ` +
|
|
1959
|
-
'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
|
|
1960
|
-
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
|
|
1961
|
-
raw = await respond(approvalId, decision, withoutAttribution);
|
|
1962
|
-
attributionDropped = true;
|
|
1963
|
-
}
|
|
1964
|
-
else if (shouldResendUnderSuccessorKey(first, Object.hasOwn(respondOpts, 'settledBy'), signal)) {
|
|
1965
|
-
const renamed = withAttributionKeyRenamed(respondOpts);
|
|
1966
|
-
hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note was sent under a name ` +
|
|
1967
|
-
'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
|
|
1968
|
-
'(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
|
|
1969
|
-
try {
|
|
1970
|
-
raw = await respond(approvalId, decision, renamed);
|
|
1971
|
-
attributionRenamed = true;
|
|
1972
|
-
}
|
|
1973
|
-
catch (second) {
|
|
1974
|
-
if (!shouldResendWithoutAttribution(second, true, signal))
|
|
1975
|
-
throw second;
|
|
1976
|
-
const renamedWithoutAttribution = withoutAttributionKey(renamed);
|
|
1977
|
-
lastSendCarriedAttribution = false;
|
|
1978
|
-
hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused again because the settlement note is not part of ` +
|
|
1979
|
-
'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
|
|
1980
|
-
'(still before the approval was judged)');
|
|
1981
|
-
raw = await respond(approvalId, decision, renamedWithoutAttribution);
|
|
1982
|
-
attributionDropped = true;
|
|
1983
|
-
}
|
|
1984
|
-
}
|
|
1985
|
-
else {
|
|
1986
|
-
throw first;
|
|
1987
|
-
}
|
|
1957
|
+
finally {
|
|
1958
|
+
lastSendCarriedAttribution = ladder.lastCarried;
|
|
1988
1959
|
}
|
|
1960
|
+
const attributionDropped = ladder.dropped;
|
|
1961
|
+
const attributionRenamed = ladder.renamed;
|
|
1989
1962
|
const parkingBody = readToolApprovalRespondParking(raw);
|
|
1990
1963
|
if (parkingBody !== undefined) {
|
|
1991
1964
|
const parking = parkingBody.kind === 'parking' && parkingBody.view.approvalId === approvalId ? parkingBody.view : undefined;
|