@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UiLanguage } from '../env/uiLanguage.js';
|
|
1
2
|
import { type DenialLimitFallback } from './toolApprovalWire.js';
|
|
2
3
|
export declare const APPROVAL_CARD_REASON_SOURCES: readonly ["payload_unreadable", "prior_cards", "message", "mandated", "mandate", "origin", "denial_limit", "probe", "allow_rule_shadow", "classifier_no_ruling", "bound_grants", "more"];
|
|
3
4
|
export type ApprovalCardReasonSource = (typeof APPROVAL_CARD_REASON_SOURCES)[number];
|
|
@@ -9,5 +10,5 @@ export interface ApprovalCardReasonsOptions {
|
|
|
9
10
|
readonly maxLines?: number;
|
|
10
11
|
}
|
|
11
12
|
export declare const APPROVAL_CARD_REASONS_DEFAULT_MAX_LINES = 4;
|
|
12
|
-
export declare function denialLimitFallbackDetail(v: DenialLimitFallback | null | undefined): string | undefined;
|
|
13
|
-
export declare function approvalCardReasons(card: object | null | undefined, opts?: ApprovalCardReasonsOptions | null): readonly ApprovalCardReasonLine[];
|
|
13
|
+
export declare function denialLimitFallbackDetail(v: DenialLimitFallback | null | undefined, lang?: UiLanguage): string | undefined;
|
|
14
|
+
export declare function approvalCardReasons(card: object | null | undefined, opts?: ApprovalCardReasonsOptions | null, lang?: UiLanguage): readonly ApprovalCardReasonLine[];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { displayUntrusted } from '../displayUntrusted.js';
|
|
2
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
2
3
|
import { approvalMandateDetail, askOriginNoteOf } from '../gateVocabulary.js';
|
|
3
4
|
import { readAskOrigin, readOwnDataValue, guardedRead } from '../ownKey.js';
|
|
4
5
|
import { allowRuleShadowSentence } from './allowRuleShadow.js';
|
|
@@ -20,22 +21,20 @@ export const APPROVAL_CARD_REASON_SOURCES = Object.freeze([
|
|
|
20
21
|
]);
|
|
21
22
|
export const APPROVAL_CARD_REASONS_DEFAULT_MAX_LINES = 4;
|
|
22
23
|
const MESSAGE_DISPLAY_MAX = 300;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return n === 1 ? '1 more reason for this card is not shown.' : `${String(n)} more reasons for this card are not shown.`;
|
|
24
|
+
function payloadUnreadableDetail(lang) {
|
|
25
|
+
return renderMessage(msg('approval.card.payloadUnreadable'), lang);
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
function moreDetail(n, lang) {
|
|
28
|
+
return renderMessage(n === 1 ? msg('approval.card.more.one') : msg('approval.card.more.other', { count: n }), lang);
|
|
29
|
+
}
|
|
30
|
+
export function denialLimitFallbackDetail(v, lang) {
|
|
28
31
|
const d = readDenialLimitFallback(v);
|
|
29
32
|
if (d === undefined)
|
|
30
33
|
return undefined;
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
];
|
|
36
|
-
if (d.autoDenyAfterMs > 0)
|
|
37
|
-
parts.push(`the engine auto-denies it in ${String(Math.round(d.autoDenyAfterMs / 1000))}s if nobody answers`);
|
|
38
|
-
return parts.join('; ');
|
|
34
|
+
const limit = displayUntrusted(d.limit, { max: 24 });
|
|
35
|
+
return renderMessage(d.autoDenyAfterMs > 0
|
|
36
|
+
? msg('approval.card.denialLimit.withAutoDeny', { consecutive: d.consecutive, total: d.total, limit, seconds: Math.round(d.autoDenyAfterMs / 1000) })
|
|
37
|
+
: msg('approval.card.denialLimit.plain', { consecutive: d.consecutive, total: d.total, limit }), lang);
|
|
39
38
|
}
|
|
40
39
|
function ownData(card, key) {
|
|
41
40
|
return guardedRead(() => readOwnDataValue(card, key));
|
|
@@ -44,7 +43,7 @@ function readMaxLines(opts) {
|
|
|
44
43
|
const raw = typeof opts === 'object' && opts !== null ? guardedRead(() => readOwnDataValue(opts, 'maxLines')) : undefined;
|
|
45
44
|
return typeof raw === 'number' && Number.isSafeInteger(raw) && raw >= 1 ? raw : APPROVAL_CARD_REASONS_DEFAULT_MAX_LINES;
|
|
46
45
|
}
|
|
47
|
-
export function approvalCardReasons(card, opts) {
|
|
46
|
+
export function approvalCardReasons(card, opts, lang) {
|
|
48
47
|
if (typeof card !== 'object' || card === null)
|
|
49
48
|
return Object.freeze([]);
|
|
50
49
|
const raw = [];
|
|
@@ -65,21 +64,21 @@ export function approvalCardReasons(card, opts) {
|
|
|
65
64
|
catch {
|
|
66
65
|
denialLimitReadable = false;
|
|
67
66
|
}
|
|
68
|
-
add('payload_unreadable', () => (ownData(card, 'cardPayloadUnreadable') === true ?
|
|
69
|
-
add('prior_cards', () => approvalPriorCardsDetail(card));
|
|
67
|
+
add('payload_unreadable', () => (ownData(card, 'cardPayloadUnreadable') === true ? payloadUnreadableDetail(lang) : undefined));
|
|
68
|
+
add('prior_cards', () => approvalPriorCardsDetail(card, lang));
|
|
70
69
|
add('message', () => {
|
|
71
|
-
const
|
|
72
|
-
if (typeof
|
|
70
|
+
const engineMessage = ownData(card, 'message');
|
|
71
|
+
if (typeof engineMessage !== 'string' || engineMessage.trim() === '')
|
|
73
72
|
return undefined;
|
|
74
73
|
const tool = ownData(card, 'toolName');
|
|
75
|
-
if (typeof tool === 'string' &&
|
|
74
|
+
if (typeof tool === 'string' && engineMessage.trim() === `approval required for "${tool}"`)
|
|
76
75
|
return undefined;
|
|
77
|
-
return displayUntrusted(
|
|
76
|
+
return displayUntrusted(engineMessage, { max: MESSAGE_DISPLAY_MAX });
|
|
78
77
|
});
|
|
79
|
-
add('mandated', () => (approvalIsMandated(card) ? mandatedApprovalDetailOf(card) : undefined));
|
|
78
|
+
add('mandated', () => (approvalIsMandated(card) ? mandatedApprovalDetailOf(card, lang) : undefined));
|
|
80
79
|
add('mandate', () => {
|
|
81
80
|
const word = readApprovalMandate(card);
|
|
82
|
-
return word !== undefined ? approvalMandateDetail(word) : undefined;
|
|
81
|
+
return word !== undefined ? approvalMandateDetail(word, lang) : undefined;
|
|
83
82
|
});
|
|
84
83
|
add('origin', () => {
|
|
85
84
|
const origin = readAskOrigin(card);
|
|
@@ -87,26 +86,26 @@ export function approvalCardReasons(card, opts) {
|
|
|
87
86
|
return undefined;
|
|
88
87
|
if (origin === 'denial_limit_fallback' && denialLimitReadable)
|
|
89
88
|
return undefined;
|
|
90
|
-
return askOriginNoteOf(origin);
|
|
89
|
+
return askOriginNoteOf(origin, lang);
|
|
91
90
|
});
|
|
92
|
-
add('denial_limit', () => denialLimitFallbackDetail(ownData(card, 'denialLimitFallback')));
|
|
93
|
-
add('probe', () => askProbeReasonDetail(card));
|
|
94
|
-
add('allow_rule_shadow', () => allowRuleShadowSentence(card));
|
|
91
|
+
add('denial_limit', () => denialLimitFallbackDetail(ownData(card, 'denialLimitFallback'), lang));
|
|
92
|
+
add('probe', () => askProbeReasonDetail(card, lang));
|
|
93
|
+
add('allow_rule_shadow', () => allowRuleShadowSentence(card, lang));
|
|
95
94
|
add('classifier_no_ruling', () => {
|
|
96
95
|
const word = readApprovalClassifierNoRuling(card);
|
|
97
|
-
return word !== undefined ? classifierNoRulingDetail(word) : undefined;
|
|
96
|
+
return word !== undefined ? classifierNoRulingDetail(word, lang) : undefined;
|
|
98
97
|
});
|
|
99
98
|
add('bound_grants', () => {
|
|
100
99
|
const grants = readApprovalBoundGrants(card);
|
|
101
|
-
return grants !== undefined ? approvalBoundGrantsDetail(grants) : undefined;
|
|
100
|
+
return grants !== undefined ? approvalBoundGrantsDetail(grants, lang) : undefined;
|
|
102
101
|
});
|
|
103
102
|
const seen = new Set();
|
|
104
103
|
const lines = [];
|
|
105
104
|
for (const r of raw) {
|
|
106
105
|
if (r.text === undefined)
|
|
107
106
|
continue;
|
|
108
|
-
const text =
|
|
109
|
-
if (text === '' || seen.has(text))
|
|
107
|
+
const text = r.text;
|
|
108
|
+
if (text.trim() === '' || seen.has(text))
|
|
110
109
|
continue;
|
|
111
110
|
seen.add(text);
|
|
112
111
|
lines.push(Object.freeze({ source: r.source, text }));
|
|
@@ -115,6 +114,6 @@ export function approvalCardReasons(card, opts) {
|
|
|
115
114
|
if (lines.length <= max)
|
|
116
115
|
return Object.freeze(lines);
|
|
117
116
|
const kept = lines.slice(0, max - 1);
|
|
118
|
-
kept.push(Object.freeze({ source: 'more', text: moreDetail(lines.length - kept.length) }));
|
|
117
|
+
kept.push(Object.freeze({ source: 'more', text: moreDetail(lines.length - kept.length, lang) }));
|
|
119
118
|
return Object.freeze(kept);
|
|
120
119
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApprovalHolderIdentity } from './toolApprovalWire.js';
|
|
2
2
|
import type { ApprovalResolution, ApprovalResolutionLane } from './approvalResolution.js';
|
|
3
|
+
import { type DecisionLedgerOp } from './decisionLedger.js';
|
|
3
4
|
export declare const APPROVAL_SETTLED_HOWS: readonly ["answered", "interrupted", "closed_by_engine"];
|
|
4
5
|
export type ApprovalSettledHow = (typeof APPROVAL_SETTLED_HOWS)[number];
|
|
5
6
|
export declare const SETTLED_APPROVALS_MAX_ENTRIES = 4096;
|
|
@@ -29,6 +30,7 @@ export interface LiveCardHold {
|
|
|
29
30
|
readonly cardSignal: AbortSignal;
|
|
30
31
|
readonly interrupt: () => void;
|
|
31
32
|
trailing?: Promise<boolean>;
|
|
33
|
+
ledgerOp?: DecisionLedgerOp;
|
|
32
34
|
}
|
|
33
35
|
export interface HostCardHold {
|
|
34
36
|
readonly lane: 'host';
|
|
@@ -61,12 +63,25 @@ export interface HostApprovalCardHold {
|
|
|
61
63
|
sending(): void;
|
|
62
64
|
release(settled?: 'answered' | 'interrupted'): void;
|
|
63
65
|
}
|
|
66
|
+
export declare function hostHoldIsActive(handle: HostApprovalCardHold): boolean;
|
|
67
|
+
export declare function takeHostHoldLedgerOp(handle: HostApprovalCardHold): DecisionLedgerOp | undefined;
|
|
68
|
+
export type ApprovalHoldAttempt = {
|
|
69
|
+
readonly kind: 'settled';
|
|
70
|
+
} | {
|
|
71
|
+
readonly kind: 'busy';
|
|
72
|
+
} | {
|
|
73
|
+
readonly kind: 'held';
|
|
74
|
+
readonly hold: HostApprovalCardHold;
|
|
75
|
+
};
|
|
76
|
+
export declare function tryHoldApprovalNow(who: HoldIdentity, signal: AbortSignal | undefined): ApprovalHoldAttempt;
|
|
64
77
|
export type ApprovalCardClaim = {
|
|
65
78
|
readonly kind: 'held';
|
|
66
79
|
readonly hold: HostApprovalCardHold;
|
|
67
80
|
} | {
|
|
68
81
|
readonly kind: 'joined';
|
|
69
82
|
readonly outcome: ApprovalResolution;
|
|
83
|
+
} | {
|
|
84
|
+
readonly kind: 'aborted';
|
|
70
85
|
};
|
|
71
86
|
export declare function claimApprovalCardFor(who: HoldIdentity, signal: AbortSignal | undefined): Promise<ApprovalCardClaim>;
|
|
72
87
|
export interface ApprovalDecisionHoldTable {
|
|
@@ -85,9 +100,11 @@ export declare function settledApprovalOf(approvalId: string | undefined): Settl
|
|
|
85
100
|
export declare function clearSettledApprovals(): void;
|
|
86
101
|
export declare function anyApprovalSettled(): boolean;
|
|
87
102
|
export declare function noteEngineClosedApproval(approvalId: string, parked: boolean): void;
|
|
103
|
+
export declare function settleEngineClosedApproval(frame: object, parked: boolean): boolean;
|
|
88
104
|
export declare function noteHolderSettledApproval(approvalId: string, how: 'answered' | 'interrupted', outcome: ApprovalResolution): void;
|
|
89
105
|
export declare function settledLiveCardOutcome(approvalId: string): ApprovalResolution | undefined;
|
|
90
106
|
export declare function liveCardHoldOf(key: string): LiveCardHold | undefined;
|
|
91
107
|
export declare function holdLiveCard(identity: LiveCardIdentity, callerSignal: AbortSignal | undefined, present: (hold: LiveCardHold) => Promise<ApprovalResolution>): Promise<ApprovalResolution>;
|
|
92
108
|
export declare function joinLiveCard(hold: LiveCardHold, signal: AbortSignal | undefined): Promise<ApprovalResolution>;
|
|
109
|
+
export declare function enterLiveRespondPhase(hold: LiveCardHold): void;
|
|
93
110
|
export declare function supersedeLiveCard(key: string, parked: boolean): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hostLog } from '../host.js';
|
|
2
2
|
import { liveFrameCallKey } from './gateIdentity.js';
|
|
3
|
-
import { decideReceiptReopen } from '../decideReceipt.js';
|
|
3
|
+
import { decideReceiptReopen, readDecideReceipt } from '../decideReceipt.js';
|
|
4
|
+
import { closeDecisionOp, decisionLedgerKeysOf, openDecisionOp, settleDecisionOp } from './decisionLedger.js';
|
|
4
5
|
export const APPROVAL_SETTLED_HOWS = Object.freeze(['answered', 'interrupted', 'closed_by_engine']);
|
|
5
6
|
export const SETTLED_APPROVALS_MAX_ENTRIES = 4096;
|
|
6
7
|
const nonEmpty = (v) => typeof v === 'string' && v !== '';
|
|
@@ -73,7 +74,7 @@ export async function awaitApprovalHolder(hold, signal, asker) {
|
|
|
73
74
|
}
|
|
74
75
|
if (r.kind !== 'unsettled' || r.cause !== 'interrupted' || hold.trailing === undefined)
|
|
75
76
|
return HOLDER_FREE;
|
|
76
|
-
const landed = await hold.trailing.then(() =>
|
|
77
|
+
const landed = await hold.trailing.then((raw) => decideReceiptReopen(readDecideReceipt(raw)) === null, () => false);
|
|
77
78
|
return landed ? Object.freeze({ kind: 'settled', how: 'interrupted', outcome: r }) : HOLDER_FREE;
|
|
78
79
|
}
|
|
79
80
|
finally {
|
|
@@ -98,7 +99,7 @@ async function awaitHostHolder(hold, signal, asker) {
|
|
|
98
99
|
unsubscribe();
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
|
-
function holdHostCard(identity) {
|
|
102
|
+
function holdHostCard(identity, signal) {
|
|
102
103
|
const h = approvalDecisionHolds;
|
|
103
104
|
const key = `hitl-host:${++h.clock}`;
|
|
104
105
|
let resolveReleased = () => { };
|
|
@@ -109,41 +110,101 @@ function holdHostCard(identity) {
|
|
|
109
110
|
const hold = { lane: 'host', identity: frozen, phase: 'card', released };
|
|
110
111
|
h.inFlight.set(key, hold);
|
|
111
112
|
let done = false;
|
|
112
|
-
|
|
113
|
+
let stopFollowing = () => { };
|
|
114
|
+
let ledgerOp;
|
|
115
|
+
const release = (settled) => {
|
|
116
|
+
if (done)
|
|
117
|
+
return;
|
|
118
|
+
done = true;
|
|
119
|
+
stopFollowing();
|
|
120
|
+
if (ledgerOp !== undefined) {
|
|
121
|
+
settleDecisionOp(ledgerOp, 'host');
|
|
122
|
+
ledgerOp.ownCallOpen = false;
|
|
123
|
+
}
|
|
124
|
+
const how = settled === 'answered' || settled === 'interrupted' ? settled : undefined;
|
|
125
|
+
if (how !== undefined && nonEmpty(frozen.approvalId))
|
|
126
|
+
noteSettled(frozen.approvalId, how, false, how === 'interrupted' ? interruptedThere('decide') : nothingSentHere('decide'), true);
|
|
127
|
+
if (h.inFlight.get(key) === hold)
|
|
128
|
+
h.inFlight.delete(key);
|
|
129
|
+
resolveReleased(how);
|
|
130
|
+
};
|
|
131
|
+
const handle = Object.freeze({
|
|
113
132
|
identity: frozen,
|
|
114
133
|
sending: () => {
|
|
115
|
-
if (!done)
|
|
116
|
-
hold.phase = 'respond';
|
|
117
|
-
},
|
|
118
|
-
release: (settled) => {
|
|
119
134
|
if (done)
|
|
120
135
|
return;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
if (hold.phase !== 'respond')
|
|
137
|
+
ledgerOp = openDecisionOp('tool_approval', ledgerKeysOfHold(frozen), 'handed', true);
|
|
138
|
+
hold.phase = 'respond';
|
|
139
|
+
stopFollowing();
|
|
140
|
+
},
|
|
141
|
+
release,
|
|
142
|
+
});
|
|
143
|
+
stopFollowing = followCallerSignal(signal, () => {
|
|
144
|
+
if (!done && hold.phase === 'card')
|
|
145
|
+
release();
|
|
146
|
+
});
|
|
147
|
+
hostHoldControls.set(handle, {
|
|
148
|
+
active: () => !done && h.inFlight.get(key) === hold,
|
|
149
|
+
takeLedgerOp: () => {
|
|
150
|
+
const op = ledgerOp;
|
|
151
|
+
ledgerOp = undefined;
|
|
152
|
+
return op;
|
|
128
153
|
},
|
|
129
154
|
});
|
|
155
|
+
return handle;
|
|
156
|
+
}
|
|
157
|
+
const hostHoldControls = new WeakMap();
|
|
158
|
+
export function hostHoldIsActive(handle) {
|
|
159
|
+
return hostHoldControls.get(handle)?.active() === true;
|
|
160
|
+
}
|
|
161
|
+
export function takeHostHoldLedgerOp(handle) {
|
|
162
|
+
return hostHoldControls.get(handle)?.takeLedgerOp();
|
|
163
|
+
}
|
|
164
|
+
export function tryHoldApprovalNow(who, signal) {
|
|
165
|
+
const entry = settledApprovalOf(who.approvalId);
|
|
166
|
+
if (entry !== undefined && settledForDurableLane(entry))
|
|
167
|
+
return Object.freeze({ kind: 'settled' });
|
|
168
|
+
if (approvalHoldFor(who) !== undefined)
|
|
169
|
+
return Object.freeze({ kind: 'busy' });
|
|
170
|
+
return Object.freeze({ kind: 'held', hold: holdHostCard(who, signal) });
|
|
171
|
+
}
|
|
172
|
+
function callerSignalAborted(signal) {
|
|
173
|
+
if (signal === undefined || signal === null)
|
|
174
|
+
return false;
|
|
175
|
+
try {
|
|
176
|
+
return signal.aborted === true;
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
130
181
|
}
|
|
131
|
-
const CLAIM_MAX_ROUNDS = 8;
|
|
132
182
|
export async function claimApprovalCardFor(who, signal) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
183
|
+
let leave = () => { };
|
|
184
|
+
const left = new Promise((resolve) => {
|
|
185
|
+
leave = () => resolve('aborted');
|
|
186
|
+
});
|
|
187
|
+
const unsubscribe = followCallerSignal(signal, leave);
|
|
188
|
+
try {
|
|
189
|
+
for (;;) {
|
|
190
|
+
if (callerSignalAborted(signal))
|
|
191
|
+
return Object.freeze({ kind: 'aborted' });
|
|
192
|
+
const entry = settledApprovalOf(who.approvalId);
|
|
193
|
+
if (settledForDurableLane(entry) && entry !== undefined)
|
|
194
|
+
return Object.freeze({ kind: 'joined', outcome: { ...entry.outcome, joinedInFlight: true } });
|
|
195
|
+
const holder = approvalHoldFor(who);
|
|
196
|
+
if (holder === undefined)
|
|
197
|
+
return Object.freeze({ kind: 'held', hold: holdHostCard(who, signal) });
|
|
198
|
+
const wait = await Promise.race([awaitApprovalHolder(holder, undefined, 'decide'), left]);
|
|
199
|
+
if (wait === 'aborted')
|
|
200
|
+
return Object.freeze({ kind: 'aborted' });
|
|
201
|
+
if (wait.kind === 'settled')
|
|
202
|
+
return Object.freeze({ kind: 'joined', outcome: { ...wait.outcome, joinedInFlight: true } });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
unsubscribe();
|
|
145
207
|
}
|
|
146
|
-
return Object.freeze({ kind: 'held', hold: holdHostCard(who) });
|
|
147
208
|
}
|
|
148
209
|
export const approvalDecisionHolds = { inFlight: new Map(), settled: new Map(), openReads: new Set(), outcomes: new Map(), clock: 0 };
|
|
149
210
|
export function settledApprovalOf(approvalId) {
|
|
@@ -180,6 +241,20 @@ function engineClosedOutcome() {
|
|
|
180
241
|
export function noteEngineClosedApproval(approvalId, parked) {
|
|
181
242
|
noteSettled(approvalId, 'closed_by_engine', parked, engineClosedOutcome());
|
|
182
243
|
}
|
|
244
|
+
export function settleEngineClosedApproval(frame, parked) {
|
|
245
|
+
let id;
|
|
246
|
+
try {
|
|
247
|
+
const d = typeof frame === 'object' && frame !== null ? Object.getOwnPropertyDescriptor(frame, 'approvalId') : undefined;
|
|
248
|
+
id = d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
if (!nonEmpty(id))
|
|
254
|
+
return false;
|
|
255
|
+
noteEngineClosedApproval(id, parked);
|
|
256
|
+
return supersedeLiveCard(liveFrameCallKey(id), parked);
|
|
257
|
+
}
|
|
183
258
|
export function noteHolderSettledApproval(approvalId, how, outcome) {
|
|
184
259
|
noteSettled(approvalId, how, false, outcome, true);
|
|
185
260
|
}
|
|
@@ -210,6 +285,8 @@ export function holdLiveCard(identity, callerSignal, present) {
|
|
|
210
285
|
const hold = { lane: 'live', identity: Object.freeze({ ...identity }), outcome, phase: 'card', cardSignal: cut.signal, interrupt };
|
|
211
286
|
h.inFlight.set(key, hold);
|
|
212
287
|
const release = () => {
|
|
288
|
+
if (hold.ledgerOp !== undefined)
|
|
289
|
+
closeDecisionOp(hold.ledgerOp, 'package');
|
|
213
290
|
if (h.inFlight.get(key) === hold)
|
|
214
291
|
h.inFlight.delete(key);
|
|
215
292
|
};
|
|
@@ -276,6 +353,14 @@ function followCallerSignal(signal, onAbort) {
|
|
|
276
353
|
}
|
|
277
354
|
};
|
|
278
355
|
}
|
|
356
|
+
function ledgerKeysOfHold(identity) {
|
|
357
|
+
return decisionLedgerKeysOf({ taskId: identity.taskId, approvalId: identity.approvalId, callId: identity.toolCallId });
|
|
358
|
+
}
|
|
359
|
+
export function enterLiveRespondPhase(hold) {
|
|
360
|
+
if (hold.ledgerOp === undefined)
|
|
361
|
+
hold.ledgerOp = openDecisionOp('tool_approval', ledgerKeysOfHold(hold.identity), 'posting', true);
|
|
362
|
+
hold.phase = 'respond';
|
|
363
|
+
}
|
|
279
364
|
export function supersedeLiveCard(key, parked) {
|
|
280
365
|
const hold = liveCardHoldOf(key);
|
|
281
366
|
if (hold === undefined || hold.phase !== 'card' || hold.superseded !== undefined)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare const DEPLOYMENT_LIST_ASK_CLASSES: readonly (
|
|
1
|
+
import { CORE_ASK_CLASSES } from '../generated/engineFactTables.js';
|
|
2
|
+
export declare const DEPLOYMENT_LIST_ASK_CLASSES: readonly (typeof CORE_ASK_CLASSES)[number][];
|
|
3
3
|
export type AskClassPairReading = {
|
|
4
4
|
readonly state: 'pair';
|
|
5
5
|
readonly askClass: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CORE_ASK_CLASSES } from '../generated/engineFactTables.js';
|
|
1
2
|
export const DEPLOYMENT_LIST_ASK_CLASSES = Object.freeze(['ask_rule']);
|
|
2
3
|
const ABSENT = Object.freeze({ state: 'absent' });
|
|
3
4
|
const MALFORMED = Object.freeze({ state: 'malformed' });
|
|
@@ -35,8 +36,23 @@ export function readAskClassPairState(v) {
|
|
|
35
36
|
return MALFORMED;
|
|
36
37
|
if (classes[0] !== askClass)
|
|
37
38
|
return MALFORMED;
|
|
39
|
+
if (!inCanonicalOrder(classes))
|
|
40
|
+
return MALFORMED;
|
|
38
41
|
return Object.freeze({ state: 'pair', askClass, classes: Object.freeze(classes) });
|
|
39
42
|
}
|
|
43
|
+
function inCanonicalOrder(classes) {
|
|
44
|
+
const order = CORE_ASK_CLASSES;
|
|
45
|
+
let last = -1;
|
|
46
|
+
for (const c of classes) {
|
|
47
|
+
const rank = order.indexOf(c);
|
|
48
|
+
if (rank < 0)
|
|
49
|
+
continue;
|
|
50
|
+
if (rank <= last)
|
|
51
|
+
return false;
|
|
52
|
+
last = rank;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
40
56
|
export function readAskClassPair(v) {
|
|
41
57
|
const r = readAskClassPairState(v);
|
|
42
58
|
return r.state === 'pair' ? { askClass: r.askClass, classes: r.classes } : undefined;
|
package/dist/hitl/askGateWire.js
CHANGED
|
@@ -6,6 +6,7 @@ import { abortableSleep } from '../abortableSleep.js';
|
|
|
6
6
|
import { hostLog } from '../host.js';
|
|
7
7
|
import { decideAcceptedNotResolved, readDecideReceipt } from '../decideReceipt.js';
|
|
8
8
|
import { APPROVAL_EXPIRED } from '../engineErrorCodes.js';
|
|
9
|
+
import { isNotFoundFailure } from '../wireErrorTriage.js';
|
|
9
10
|
import { readDecisionRefusalAsk } from './decisionRefusal.js';
|
|
10
11
|
import { resumeReopenFromError } from './suspendedReopen.js';
|
|
11
12
|
import { refusedParkFromError, resumeRefusalFromError } from '../resumeRefusalCopy.js';
|
|
@@ -192,7 +193,7 @@ export function lateDecideOutcomeOf(reply, opts) {
|
|
|
192
193
|
const r = readDecisionRefusalAsk(e);
|
|
193
194
|
if (r.reading !== 'settled' && !(r.reading === 'not_settled' && r.gateMoved))
|
|
194
195
|
return LATE_UNKNOWN;
|
|
195
|
-
const probeWorthy = status === 404 || status === 410 || (
|
|
196
|
+
const probeWorthy = status === 404 || status === 410 || isNotFoundFailure(e) !== false;
|
|
196
197
|
return Object.freeze(probeWorthy ? { kind: 'settled-elsewhere', probeWorthy: true } : { kind: 'settled-elsewhere' });
|
|
197
198
|
}
|
|
198
199
|
catch {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import type { UiLanguage } from '../env/uiLanguage.js';
|
|
2
|
+
export declare function askEndingCauseClause(cause: string | undefined, lang?: UiLanguage): string | undefined;
|
|
2
3
|
export interface AskSettlementInput {
|
|
3
4
|
readonly cause?: string | undefined;
|
|
4
5
|
readonly toolName?: string | undefined;
|
|
5
6
|
readonly parked?: boolean | undefined;
|
|
6
7
|
}
|
|
7
|
-
export declare function askSettlementLine(settled: AskSettlementInput): string | undefined;
|
|
8
|
+
export declare function askSettlementLine(settled: AskSettlementInput, lang?: UiLanguage): string | undefined;
|
|
8
9
|
export type AskAcceptedFollow = 'following' | 'already-following' | 'not-following';
|
|
9
10
|
export interface AskAcceptedInput {
|
|
10
11
|
readonly decision?: string | undefined;
|
|
@@ -13,6 +14,15 @@ export interface AskAcceptedInput {
|
|
|
13
14
|
readonly follow?: AskAcceptedFollow | undefined;
|
|
14
15
|
readonly executed?: string | undefined;
|
|
15
16
|
}
|
|
16
|
-
export declare function askAcceptedLine(accepted: AskAcceptedInput): string;
|
|
17
|
+
export declare function askAcceptedLine(accepted: AskAcceptedInput, lang?: UiLanguage): string;
|
|
17
18
|
export type AskParkedCardForm = 'approval' | 'question' | 'queue_no_deadline';
|
|
18
|
-
export declare function askParkedCardNote(form?: string | undefined, toolName?: string | undefined): string;
|
|
19
|
+
export declare function askParkedCardNote(form?: string | undefined, toolName?: string | undefined, lang?: UiLanguage): string;
|
|
20
|
+
export interface AskHumanSettledInput {
|
|
21
|
+
readonly kind?: string | undefined;
|
|
22
|
+
readonly decision?: string | undefined;
|
|
23
|
+
readonly taskId?: string | undefined;
|
|
24
|
+
readonly late?: boolean | undefined;
|
|
25
|
+
readonly follow?: AskAcceptedFollow | undefined;
|
|
26
|
+
readonly executed?: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
export declare function askHumanSettlementLine(settled: AskHumanSettledInput, lang?: UiLanguage): string | undefined;
|
|
@@ -1,79 +1,99 @@
|
|
|
1
1
|
import { displayUntrusted, quoteUntrustedForSentence } from '../displayUntrusted.js';
|
|
2
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
2
3
|
import { guardedRead, readOwnDataValue } from '../ownKey.js';
|
|
3
|
-
const
|
|
4
|
-
routing_failure_fail_closed: '
|
|
5
|
-
run_cancelled: '
|
|
6
|
-
run_exited: '
|
|
7
|
-
batch_aborted: '
|
|
8
|
-
batch_sibling_withdrawn: '
|
|
9
|
-
batch_bound_elsewhere: '
|
|
10
|
-
adhoc_leg_no_durable_domain: '
|
|
11
|
-
orphan_ttl_exceeded:
|
|
12
|
-
crashed_before_park: '
|
|
13
|
-
shutdown_before_park: '
|
|
14
|
-
ttl_expired: '
|
|
15
|
-
broadcast_lost: '
|
|
16
|
-
stream_disconnected: '
|
|
17
|
-
undeliverable: '
|
|
4
|
+
const ENDING_CAUSE_KEYS = Object.freeze({
|
|
5
|
+
routing_failure_fail_closed: 'approval.settle.cause.routingFailureFailClosed',
|
|
6
|
+
run_cancelled: 'approval.settle.cause.runCancelled',
|
|
7
|
+
run_exited: 'approval.settle.cause.runExited',
|
|
8
|
+
batch_aborted: 'approval.settle.cause.batchAborted',
|
|
9
|
+
batch_sibling_withdrawn: 'approval.settle.cause.batchSiblingWithdrawn',
|
|
10
|
+
batch_bound_elsewhere: 'approval.settle.cause.batchBoundElsewhere',
|
|
11
|
+
adhoc_leg_no_durable_domain: 'approval.settle.cause.adhocLegNoDurableDomain',
|
|
12
|
+
orphan_ttl_exceeded: 'approval.settle.cause.orphanTtlExceeded',
|
|
13
|
+
crashed_before_park: 'approval.settle.cause.crashedBeforePark',
|
|
14
|
+
shutdown_before_park: 'approval.settle.cause.shutdownBeforePark',
|
|
15
|
+
ttl_expired: 'approval.settle.cause.ttlExpired',
|
|
16
|
+
broadcast_lost: 'approval.settle.cause.broadcastLost',
|
|
17
|
+
stream_disconnected: 'approval.settle.cause.streamDisconnected',
|
|
18
|
+
undeliverable: 'approval.settle.cause.undeliverable',
|
|
18
19
|
});
|
|
19
|
-
|
|
20
|
-
return typeof cause === 'string' && Object.hasOwn(
|
|
20
|
+
function endingCauseKeyOf(cause) {
|
|
21
|
+
return typeof cause === 'string' && Object.hasOwn(ENDING_CAUSE_KEYS, cause) ? ENDING_CAUSE_KEYS[cause] : undefined;
|
|
22
|
+
}
|
|
23
|
+
export function askEndingCauseClause(cause, lang) {
|
|
24
|
+
const key = endingCauseKeyOf(cause);
|
|
25
|
+
return key !== undefined ? renderMessage(msg(key), lang) : undefined;
|
|
21
26
|
}
|
|
22
27
|
function ownSlot(o, key) {
|
|
23
28
|
if (typeof o !== 'object' || o === null)
|
|
24
29
|
return undefined;
|
|
25
30
|
return guardedRead(() => readOwnDataValue(o, key));
|
|
26
31
|
}
|
|
27
|
-
function subjectOf(toolName, named,
|
|
32
|
+
function subjectOf(toolName, named, generic) {
|
|
28
33
|
const quoted = typeof toolName === 'string' ? guardedRead(() => quoteUntrustedForSentence(toolName, 80)) : undefined;
|
|
29
|
-
return quoted === undefined ?
|
|
34
|
+
return quoted === undefined ? msg(generic) : msg(named, { tool: quoted });
|
|
30
35
|
}
|
|
31
|
-
|
|
32
|
-
export function askSettlementLine(settled) {
|
|
36
|
+
export function askSettlementLine(settled, lang) {
|
|
33
37
|
if (ownSlot(settled, 'parked') === true)
|
|
34
38
|
return undefined;
|
|
35
39
|
const cause = ownSlot(settled, 'cause');
|
|
36
40
|
if (typeof cause !== 'string' || cause === '')
|
|
37
41
|
return undefined;
|
|
38
|
-
const subject = subjectOf(ownSlot(settled, 'toolName'),
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
return `${subject} ended on the engine without an answer${why}.${SETTLEMENT_TAIL}`;
|
|
42
|
+
const subject = subjectOf(ownSlot(settled, 'toolName'), 'approval.settle.subject.named', 'approval.settle.subject.generic');
|
|
43
|
+
const clauseKey = endingCauseKeyOf(cause);
|
|
44
|
+
return renderMessage(clauseKey !== undefined ? msg('approval.settle.endedKnown', { subject, clause: msg(clauseKey) }) : msg('approval.settle.endedUnknown', { subject }), lang);
|
|
42
45
|
}
|
|
43
46
|
const TASK_ID_MAX = 64;
|
|
44
|
-
const
|
|
45
|
-
allowed: '
|
|
46
|
-
denied: '
|
|
47
|
+
const EXECUTED_TAIL_KEYS = Object.freeze({
|
|
48
|
+
allowed: 'approval.settle.executed.allowed',
|
|
49
|
+
denied: 'approval.settle.executed.denied',
|
|
47
50
|
});
|
|
48
|
-
const
|
|
49
|
-
following: '
|
|
50
|
-
'already-following': '
|
|
51
|
+
const FOLLOW_CLAUSE_KEYS = Object.freeze({
|
|
52
|
+
following: 'approval.settle.follow.following',
|
|
53
|
+
'already-following': 'approval.settle.follow.alreadyFollowing',
|
|
51
54
|
});
|
|
52
|
-
export function askAcceptedLine(accepted) {
|
|
55
|
+
export function askAcceptedLine(accepted, lang) {
|
|
53
56
|
const decision = ownSlot(accepted, 'decision');
|
|
54
|
-
const what = decision === 'approve' ? 'approved' : decision === 'deny' ? 'denied' : 'answered';
|
|
55
|
-
const late = ownSlot(accepted, 'late') === false ? '' : '
|
|
57
|
+
const what = msg(decision === 'approve' ? 'approval.settle.what.approved' : decision === 'deny' ? 'approval.settle.what.denied' : 'approval.settle.what.answered');
|
|
58
|
+
const late = ownSlot(accepted, 'late') === false ? '' : msg('approval.settle.late');
|
|
56
59
|
const rawTask = ownSlot(accepted, 'taskId');
|
|
57
60
|
const shownTask = typeof rawTask === 'string' ? guardedRead(() => displayUntrusted(rawTask, { max: TASK_ID_MAX, blanks: true })) : undefined;
|
|
58
|
-
const where = shownTask === undefined || shownTask === '' ? '' :
|
|
61
|
+
const where = shownTask === undefined || shownTask === '' ? '' : msg('approval.settle.where', { task: shownTask });
|
|
59
62
|
const follow = ownSlot(accepted, 'follow');
|
|
60
63
|
const executed = ownSlot(accepted, 'executed');
|
|
61
|
-
const tail = executed === 'allowed' || executed === 'denied' ?
|
|
64
|
+
const tail = executed === 'allowed' || executed === 'denied' ? msg(EXECUTED_TAIL_KEYS[executed]) : '';
|
|
62
65
|
if (follow === 'following' || follow === 'already-following') {
|
|
63
|
-
return
|
|
66
|
+
return renderMessage(msg('approval.settle.acceptedFollowing', { what, late, where, follow: msg(FOLLOW_CLAUSE_KEYS[follow]), tail }), lang);
|
|
64
67
|
}
|
|
65
|
-
return (
|
|
66
|
-
`this screen is not following that run, so what it does next will not show up here by itself.${tail}`);
|
|
68
|
+
return renderMessage(msg('approval.settle.acceptedNotFollowing', { what, late, where, tail }), lang);
|
|
67
69
|
}
|
|
68
|
-
const
|
|
69
|
-
approval:
|
|
70
|
-
question:
|
|
71
|
-
queue_no_deadline:
|
|
70
|
+
const PARKED_CARD_NOTE_KEYS = Object.freeze({
|
|
71
|
+
approval: 'approval.settle.parkedNote.approval',
|
|
72
|
+
question: 'approval.settle.parkedNote.question',
|
|
73
|
+
queue_no_deadline: 'approval.settle.parkedNote.queueNoDeadline',
|
|
72
74
|
});
|
|
73
|
-
export function askParkedCardNote(form, toolName) {
|
|
75
|
+
export function askParkedCardNote(form, toolName, lang) {
|
|
74
76
|
const key = form === 'question' || form === 'queue_no_deadline' ? form : 'approval';
|
|
75
|
-
const template = PARKED_CARD_NOTES[key];
|
|
76
77
|
if (key !== 'queue_no_deadline')
|
|
77
|
-
return
|
|
78
|
-
return
|
|
78
|
+
return renderMessage(msg(PARKED_CARD_NOTE_KEYS[key]), lang);
|
|
79
|
+
return renderMessage(msg(PARKED_CARD_NOTE_KEYS[key], { subject: subjectOf(toolName, 'approval.settle.parkedSubject.named', 'approval.settle.parkedSubject.generic') }), lang);
|
|
80
|
+
}
|
|
81
|
+
export function askHumanSettlementLine(settled, lang) {
|
|
82
|
+
const kind = ownSlot(settled, 'kind');
|
|
83
|
+
if (kind === 'accepted-not-resolved')
|
|
84
|
+
return askAcceptedLine(settled, lang);
|
|
85
|
+
if (kind === 'expired-reaped')
|
|
86
|
+
return renderMessage(msg('approval.settleHuman.expiredReaped'), lang);
|
|
87
|
+
if (kind === 'settled-elsewhere')
|
|
88
|
+
return renderMessage(msg('approval.settleHuman.settledElsewhere'), lang);
|
|
89
|
+
if (kind !== 'resumed')
|
|
90
|
+
return undefined;
|
|
91
|
+
const decision = ownSlot(settled, 'decision');
|
|
92
|
+
const what = msg(decision === 'approve' ? 'approval.settle.what.approved' : decision === 'deny' ? 'approval.settle.what.denied' : 'approval.settle.what.answered');
|
|
93
|
+
const rawTask = ownSlot(settled, 'taskId');
|
|
94
|
+
const shownTask = typeof rawTask === 'string' ? guardedRead(() => displayUntrusted(rawTask, { max: TASK_ID_MAX, blanks: true })) : undefined;
|
|
95
|
+
const where = shownTask === undefined || shownTask === '' ? '' : msg('approval.settle.where', { task: shownTask });
|
|
96
|
+
const executed = ownSlot(settled, 'executed');
|
|
97
|
+
const tail = executed === 'allowed' || executed === 'denied' ? msg(EXECUTED_TAIL_KEYS[executed]) : '';
|
|
98
|
+
return renderMessage(msg(ownSlot(settled, 'late') === false ? 'approval.settleHuman.resumed' : 'approval.settleHuman.resumedLate', { what, where, tail }), lang);
|
|
79
99
|
}
|