@sema-agent/client-core 0.109.0 → 0.111.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 +342 -0
- package/README.md +88 -32
- package/dist/abortableSleep.d.ts +7 -0
- package/dist/abortableSleep.js +37 -0
- package/dist/adapt/arms.js +45 -11
- package/dist/adapt/toolCards.d.ts +3 -1
- package/dist/adapt/toolCards.js +4 -2
- package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
- package/dist/adapter/activeRunSelfHeal.js +171 -3
- package/dist/adapter/downstream/eventToSdkMessage.js +20 -15
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
- package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
- package/dist/adapter/runStream.d.ts +5 -0
- package/dist/adapter/runStream.js +15 -3
- package/dist/attachmentRoute.d.ts +20 -0
- package/dist/attachmentRoute.js +39 -0
- package/dist/attachmentsWireCaps.js +1 -1
- package/dist/builtinOutputStyles.d.ts +12 -0
- package/dist/builtinOutputStyles.js +147 -0
- package/dist/compactionStatus.d.ts +9 -0
- package/dist/compactionStatus.js +29 -5
- package/dist/controlRouter.js +2 -1
- package/dist/coreValuePorts.d.ts +39 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +138 -14
- package/dist/engineErrorCodes.d.ts +3 -0
- package/dist/engineErrorCodes.js +3 -0
- package/dist/engineHealthFacts.d.ts +20 -0
- package/dist/engineHealthFacts.js +42 -1
- package/dist/engineHealthProbeVerdict.d.ts +23 -0
- package/dist/engineHealthProbeVerdict.js +115 -0
- package/dist/engineInlineTaskStats.d.ts +4 -3
- package/dist/engineInlineTaskStats.js +18 -2
- package/dist/engineNoticeCodes.d.ts +10 -0
- package/dist/engineNoticeCodes.js +36 -6
- package/dist/engineRepoint.d.ts +147 -0
- package/dist/engineRepoint.js +310 -0
- package/dist/engineRowRef.d.ts +3 -0
- package/dist/engineRowRef.js +13 -1
- package/dist/engineSessionMessages.d.ts +2 -1
- package/dist/engineSessionMessages.js +5 -0
- package/dist/engineSwapCrossing.d.ts +57 -0
- package/dist/engineSwapCrossing.js +297 -0
- package/dist/engineUnavailable.d.ts +44 -0
- package/dist/engineUnavailable.js +492 -0
- package/dist/errorSupplementRoles.js +2 -1
- package/dist/eventLeg.js +3 -3
- package/dist/fleet/fleetProjection.js +3 -2
- package/dist/generated/engineFactTables.d.ts +2 -0
- package/dist/generated/engineFactTables.js +12 -0
- package/dist/generated/sdkFactTables.d.ts +2 -1
- package/dist/generated/sdkFactTables.js +5 -0
- package/dist/generated/settingsSchemaTables.d.ts +4 -0
- package/dist/generated/settingsSchemaTables.js +1 -0
- package/dist/hitl/approvalAskers.d.ts +6 -0
- package/dist/hitl/approvalAskers.js +30 -0
- package/dist/hitl/approvalCardReasons.js +6 -3
- package/dist/hitl/approvalDelivery.d.ts +1 -0
- package/dist/hitl/approvalDelivery.js +1 -1
- package/dist/hitl/approvalRequestFrameReading.d.ts +7 -0
- package/dist/hitl/approvalRequestFrameReading.js +11 -0
- package/dist/hitl/approvalResolution.d.ts +9 -2
- package/dist/hitl/approvalResolution.js +6 -1
- package/dist/hitl/askGateWire.js +5 -8
- package/dist/hitl/automaticAnswerVerdict.js +2 -2
- package/dist/hitl/decisionConflict.js +6 -3
- package/dist/hitl/decisionRefusal.d.ts +2 -0
- package/dist/hitl/decisionRefusal.js +8 -8
- package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
- package/dist/hitl/decisionRefusalCarrier.js +348 -0
- package/dist/hitl/decisionSend.d.ts +10 -0
- package/dist/hitl/decisionSend.js +57 -17
- package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
- package/dist/hitl/editedApprovalAcceptance.js +26 -0
- package/dist/hitl/elicitationRefusal.d.ts +4 -0
- package/dist/hitl/elicitationRefusal.js +23 -0
- package/dist/hitl/frameRouter.d.ts +2 -2
- package/dist/hitl/frameRouter.js +12 -33
- package/dist/hitl/gateIdentity.d.ts +5 -0
- package/dist/hitl/gateIdentity.js +23 -0
- package/dist/hitl/gateLedger.d.ts +0 -4
- package/dist/hitl/gateLedger.js +0 -19
- package/dist/hitl/hitlBridge.d.ts +7 -0
- package/dist/hitl/hitlBridge.js +14 -8
- package/dist/hitl/hitlHostSurface.d.ts +3 -1
- package/dist/hitl/hitlHostSurface.js +14 -4
- package/dist/hitl/hostWithdrawal.d.ts +15 -0
- package/dist/hitl/hostWithdrawal.js +38 -0
- package/dist/hitl/localAllowRedemption.d.ts +67 -0
- package/dist/hitl/localAllowRedemption.js +256 -0
- package/dist/hitl/parkResolver.js +32 -13
- package/dist/hitl/persistedRulesWire.d.ts +16 -0
- package/dist/hitl/persistedRulesWire.js +72 -2
- package/dist/hitl/planReviewWire.d.ts +3 -0
- package/dist/hitl/planReviewWire.js +37 -10
- package/dist/hitl/policyDenyCause.d.ts +1 -1
- package/dist/hitl/policyDenyCause.js +1 -1
- package/dist/hitl/resumeRunningCard.d.ts +1 -0
- package/dist/hitl/resumeRunningCard.js +1 -0
- package/dist/hitl/screenCardCarriers.d.ts +15 -0
- package/dist/hitl/screenCardCarriers.js +41 -0
- package/dist/hitl/screenDecisionCards.d.ts +98 -0
- package/dist/hitl/screenDecisionCards.js +362 -0
- package/dist/hitl/sessionPolicyWire.js +6 -4
- package/dist/hitl/standingRows.d.ts +4 -1
- package/dist/hitl/standingRows.js +33 -1
- package/dist/hitl/toolApprovalWire.d.ts +64 -15
- package/dist/hitl/toolApprovalWire.js +470 -125
- package/dist/hooksWireCaps.js +31 -1
- package/dist/hostSettingNoticeArm.d.ts +3 -0
- package/dist/hostSettingNoticeArm.js +12 -0
- package/dist/hostTurnSettings.d.ts +13 -4
- package/dist/hostTurnSettings.js +150 -10
- package/dist/humanTurnRead.js +11 -1
- package/dist/i18n/messages.en.d.ts +212 -0
- package/dist/i18n/messages.en.js +217 -5
- package/dist/i18n/messages.zh.js +235 -5
- package/dist/i18n/translate.d.ts +3 -0
- package/dist/i18n/translate.js +78 -10
- package/dist/i18n/zh.d.ts +1 -0
- package/dist/i18n/zh.js +1 -0
- package/dist/index.d.ts +56 -16
- package/dist/index.js +40 -12
- package/dist/inheritEnvCapability.js +2 -0
- package/dist/inputAuthor.d.ts +16 -0
- package/dist/inputAuthor.js +44 -0
- package/dist/interactiveHalt.js +2 -1
- package/dist/interactiveInterrupt.js +20 -2
- package/dist/interruptRefusalNote.d.ts +2 -0
- package/dist/interruptRefusalNote.js +17 -0
- package/dist/liveModelCatalog.d.ts +2 -0
- package/dist/liveModelCatalog.js +23 -9
- package/dist/liveQuestionStore.d.ts +4 -1
- package/dist/liveQuestionStore.js +12 -3
- package/dist/localEngineSeatReading.d.ts +2 -2
- package/dist/localEngineSeatReading.js +5 -3
- package/dist/localEngineSpawn.d.ts +0 -7
- package/dist/localEngineSpawn.js +0 -92
- package/dist/localEngineStep.d.ts +2 -2
- package/dist/localEngineStep.js +2 -0
- package/dist/mcpEngineLeg.d.ts +3 -0
- package/dist/mcpEngineLeg.js +38 -1
- package/dist/mcpPanel.js +2 -0
- package/dist/mcpReconnect.d.ts +9 -1
- package/dist/mcpReconnect.js +124 -19
- package/dist/mcpWireCaps.js +1 -1
- package/dist/model/engineModelWords.d.ts +3 -0
- package/dist/model/engineModelWords.js +13 -0
- package/dist/model/subagentModelWord.d.ts +21 -2
- package/dist/model/subagentModelWord.js +100 -29
- package/dist/modelCapabilityProbe.js +7 -43
- package/dist/modsFace.d.ts +8 -1
- package/dist/modsFace.js +27 -0
- package/dist/notifications.d.ts +36 -6
- package/dist/notifications.js +170 -20
- package/dist/ownKey.d.ts +6 -5
- package/dist/ownKey.js +31 -7
- package/dist/peerFrames.d.ts +40 -2
- package/dist/peerFrames.js +158 -3
- package/dist/pendingUserRow.d.ts +4 -0
- package/dist/pendingUserRow.js +16 -0
- package/dist/permissionsDeclaration.d.ts +1 -0
- package/dist/permissionsDeclaration.js +11 -1
- package/dist/planReviewCardFacts.d.ts +3 -0
- package/dist/planReviewCardFacts.js +52 -2
- package/dist/pluginHooksWire.d.ts +10 -1
- package/dist/pluginHooksWire.js +96 -7
- package/dist/printToolResultFrame.js +4 -2
- package/dist/promptBlockedCopy.js +11 -6
- package/dist/promptSuggestionBatch.d.ts +7 -0
- package/dist/promptSuggestionBatch.js +9 -0
- package/dist/promptSuggestionsTail.d.ts +39 -0
- package/dist/promptSuggestionsTail.js +116 -0
- package/dist/replayBody.js +10 -2
- package/dist/request/taskRequest.d.ts +5 -0
- package/dist/request/taskRequest.js +142 -21
- package/dist/requestCoordinate.d.ts +1 -0
- package/dist/requestCoordinate.js +13 -0
- package/dist/resumeRefusalCopy.d.ts +1 -3
- package/dist/resumeRefusalCopy.js +2 -1
- package/dist/retryStatus.d.ts +2 -2
- package/dist/retryStatus.js +2 -0
- package/dist/rewindArchiveReading.js +4 -4
- package/dist/runCancelContext.d.ts +2 -1
- package/dist/runCancelContext.js +1 -0
- package/dist/runPermissionModeSwitch.js +2 -2
- package/dist/scenarioRefusal.js +11 -13
- package/dist/scenarioSkills.js +11 -6
- package/dist/seam.d.ts +27 -2
- package/dist/seam.js +17 -1
- package/dist/seatContract.d.ts +189 -12
- package/dist/seatContract.js +401 -9
- package/dist/sessionBackground.js +2 -1
- package/dist/sessionBackgroundHandoff.js +2 -1
- package/dist/sessionCostReading.d.ts +70 -0
- package/dist/sessionCostReading.js +150 -0
- package/dist/sessionEngine.d.ts +2 -0
- package/dist/sessionEngine.js +111 -0
- package/dist/sessionHooksRoster.d.ts +4 -0
- package/dist/sessionHooksRoster.js +158 -0
- package/dist/sessionMemoryStatus.d.ts +2 -1
- package/dist/sessionMemoryStatus.js +2 -2
- package/dist/sessionReadRedaction.d.ts +7 -0
- package/dist/sessionReadRedaction.js +26 -0
- package/dist/sessionSyncFileHistory.d.ts +4 -0
- package/dist/sessionSyncFileHistory.js +27 -0
- package/dist/settingsHooksSalvage.js +2 -1
- package/dist/sseIdleTriage.d.ts +13 -1
- package/dist/sseIdleTriage.js +25 -6
- package/dist/storeDurabilityWord.d.ts +15 -0
- package/dist/storeDurabilityWord.js +18 -0
- package/dist/storePostureCapability.d.ts +7 -3
- package/dist/storePostureCapability.js +69 -39
- package/dist/subagent/engineSubagentResume.js +2 -2
- package/dist/subagent/engineSubagentTail.js +8 -1
- package/dist/subagentContentStore.d.ts +11 -0
- package/dist/subagentContentStore.js +28 -2
- package/dist/terminalStatuses.d.ts +1 -0
- package/dist/terminalStatuses.js +4 -1
- package/dist/toolResult.d.ts +1 -0
- package/dist/toolResult.js +2 -0
- package/dist/turnFailurePresentation.js +9 -2
- package/dist/typePins.d.ts +11 -0
- package/dist/usageAnalytics.d.ts +17 -0
- package/dist/usageAnalytics.js +44 -2
- package/dist/userAttachmentEnvelope.d.ts +2 -1
- package/dist/userAttachmentEnvelope.js +10 -0
- package/dist/wireErrorTriage.js +2 -1
- package/dist/wireFailureShape.d.ts +6 -5
- package/dist/wireFailureShape.js +150 -38
- package/dist/wireRefusalCopy.d.ts +16 -5
- package/dist/wireRefusalCopy.js +119 -86
- package/docs/INTEGRATION-CLIENTS.md +4228 -21
- package/package.json +7 -3
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { SCREEN_CARD_ORIGINS } from './gateIdentity.js';
|
|
2
|
+
import { convergeEndedEngineGeneration, } from '../engineGenerationConvergence.js';
|
|
3
|
+
import { checkpointRowVerdictOf } from '../checkpointRowVerdict.js';
|
|
4
|
+
import { planReviewCardFactsFrom } from '../planReviewCardFacts.js';
|
|
5
|
+
import { slotReadOf } from '../wireFailureShape.js';
|
|
6
|
+
import { PARK_GATE_KEY } from './screenCardCarriers.js';
|
|
7
|
+
import { pendingRowAnswersCall } from './hitlBridge.js';
|
|
8
|
+
import { cardIsOnParkRow } from './toolApprovalWire.js';
|
|
9
|
+
export const SCREEN_CARD_KEEP_REASONS = Object.freeze(['not-ready', 'generation-moved', 'not-withdrawable', 'no-gate', 'not-early', 'no-row', 'not-owned', 'verdict-ok', 'verdict-absent']);
|
|
10
|
+
const nonEmpty = (v) => typeof v === 'string' && v.length > 0;
|
|
11
|
+
const finite = (v) => typeof v === 'number' && Number.isFinite(v);
|
|
12
|
+
const ORIGIN_SET = new Set(SCREEN_CARD_ORIGINS);
|
|
13
|
+
const PACKAGE_WITHDRAWABLE = new Set(['park-approval', 'park-question', 'plan-review', 'host-reopen-question']);
|
|
14
|
+
const NOT_ENGINE_DECISION = new Set(['host-choice', 'local-permission']);
|
|
15
|
+
function own(o, key) {
|
|
16
|
+
const r = slotReadOf(o, key);
|
|
17
|
+
return r.presence === 'present' ? r.value : undefined;
|
|
18
|
+
}
|
|
19
|
+
function originOf(v) {
|
|
20
|
+
return typeof v === 'string' && ORIGIN_SET.has(v) ? v : undefined;
|
|
21
|
+
}
|
|
22
|
+
function toolGateOf(v) {
|
|
23
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
24
|
+
return undefined;
|
|
25
|
+
const taskId = own(v, 'taskId');
|
|
26
|
+
const gatedCallId = own(v, 'gatedCallId');
|
|
27
|
+
return nonEmpty(taskId) && nonEmpty(gatedCallId) ? Object.freeze({ kind: 'tool', taskId, gatedCallId }) : undefined;
|
|
28
|
+
}
|
|
29
|
+
export function questionFrameGateOf(frame) {
|
|
30
|
+
try {
|
|
31
|
+
if (typeof frame !== 'object' || frame === null)
|
|
32
|
+
return undefined;
|
|
33
|
+
const park = slotReadOf(frame, PARK_GATE_KEY);
|
|
34
|
+
const plan = slotReadOf(frame, '_sema_planReview');
|
|
35
|
+
if (park.presence === 'unreadable' || plan.presence === 'unreadable')
|
|
36
|
+
return undefined;
|
|
37
|
+
const hasPark = park.presence === 'present' && park.value !== undefined;
|
|
38
|
+
const hasPlan = plan.presence === 'present' && plan.value !== undefined;
|
|
39
|
+
if (hasPark && hasPlan)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (hasPark)
|
|
42
|
+
return toolGateOf(park.value);
|
|
43
|
+
if (!hasPlan)
|
|
44
|
+
return undefined;
|
|
45
|
+
const facts = planReviewCardFactsFrom(plan.value);
|
|
46
|
+
if (facts === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
return Object.freeze({ kind: 'plan', taskId: facts.taskId, ...(facts.checkpointId !== undefined ? { checkpointId: facts.checkpointId } : {}) });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function approvalCardGateOf(card) {
|
|
55
|
+
try {
|
|
56
|
+
if (typeof card !== 'object' || card === null || !cardIsOnParkRow(card))
|
|
57
|
+
return undefined;
|
|
58
|
+
const taskId = own(card, 'taskId');
|
|
59
|
+
const park = own(card, 'parkRow');
|
|
60
|
+
if (!nonEmpty(taskId) || typeof park !== 'object' || park === null)
|
|
61
|
+
return undefined;
|
|
62
|
+
const gatedCallId = own(park, 'gatedCallId');
|
|
63
|
+
return nonEmpty(gatedCallId) ? Object.freeze({ kind: 'tool', taskId, gatedCallId }) : undefined;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function approvalCardOriginOf(card) {
|
|
70
|
+
try {
|
|
71
|
+
return cardIsOnParkRow(card) ? 'park-approval' : 'live-approval';
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return 'live-approval';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function screenCardsHoldEngineDecision(cards) {
|
|
78
|
+
return engineDecisionReadingOf(cards) !== 'none';
|
|
79
|
+
}
|
|
80
|
+
function engineDecisionReadingOf(cards) {
|
|
81
|
+
try {
|
|
82
|
+
if (!Array.isArray(cards))
|
|
83
|
+
return 'none';
|
|
84
|
+
const len = own(cards, 'length');
|
|
85
|
+
if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0)
|
|
86
|
+
return 'unreadable';
|
|
87
|
+
for (let i = 0; i < len; i++) {
|
|
88
|
+
const card = own(cards, String(i));
|
|
89
|
+
const origin = typeof card === 'object' && card !== null ? originOf(own(card, 'origin')) : undefined;
|
|
90
|
+
if (origin === undefined || !NOT_ENGINE_DECISION.has(origin))
|
|
91
|
+
return 'holds';
|
|
92
|
+
}
|
|
93
|
+
return 'none';
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return 'unreadable';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function cardReadingOf(card) {
|
|
100
|
+
try {
|
|
101
|
+
if (typeof card !== 'object' || card === null)
|
|
102
|
+
return undefined;
|
|
103
|
+
const instance = own(card, 'instance');
|
|
104
|
+
if (!nonEmpty(instance))
|
|
105
|
+
return undefined;
|
|
106
|
+
return {
|
|
107
|
+
instance,
|
|
108
|
+
origin: originOf(own(card, 'origin')),
|
|
109
|
+
gate: own(card, 'gate'),
|
|
110
|
+
sourceGeneration: own(card, 'sourceGeneration'),
|
|
111
|
+
toolCallId: own(card, 'toolCallId'),
|
|
112
|
+
window: own(card, 'window'),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function distinctCards(cards) {
|
|
120
|
+
if (!Array.isArray(cards))
|
|
121
|
+
return [];
|
|
122
|
+
const out = [];
|
|
123
|
+
const seen = new Set();
|
|
124
|
+
for (const card of cards) {
|
|
125
|
+
const r = cardReadingOf(card);
|
|
126
|
+
if (r === undefined || seen.has(r.instance))
|
|
127
|
+
continue;
|
|
128
|
+
seen.add(r.instance);
|
|
129
|
+
out.push(r);
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
function usableGateOf(v) {
|
|
134
|
+
if (typeof v !== 'object' || v === null)
|
|
135
|
+
return undefined;
|
|
136
|
+
const kind = own(v, 'kind');
|
|
137
|
+
const taskId = own(v, 'taskId');
|
|
138
|
+
if (!nonEmpty(taskId))
|
|
139
|
+
return undefined;
|
|
140
|
+
if (kind === 'tool') {
|
|
141
|
+
const gatedCallId = own(v, 'gatedCallId');
|
|
142
|
+
return nonEmpty(gatedCallId) ? { kind: 'tool', taskId, gatedCallId } : undefined;
|
|
143
|
+
}
|
|
144
|
+
if (kind === 'plan') {
|
|
145
|
+
const checkpointId = own(v, 'checkpointId');
|
|
146
|
+
return nonEmpty(checkpointId) ? { kind: 'plan', taskId, checkpointId } : undefined;
|
|
147
|
+
}
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
function withdrawableSetOf(v) {
|
|
151
|
+
const out = new Set();
|
|
152
|
+
if (!Array.isArray(v))
|
|
153
|
+
return out;
|
|
154
|
+
for (const o of v) {
|
|
155
|
+
const origin = originOf(o);
|
|
156
|
+
if (origin !== undefined && PACKAGE_WITHDRAWABLE.has(origin))
|
|
157
|
+
out.add(origin);
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
function candidacyOf(card, generation, cap) {
|
|
162
|
+
if (card.origin === undefined || !cap.has(card.origin))
|
|
163
|
+
return { ok: false, why: 'not-withdrawable' };
|
|
164
|
+
const gate = usableGateOf(card.gate);
|
|
165
|
+
if (gate === undefined)
|
|
166
|
+
return { ok: false, why: 'no-gate' };
|
|
167
|
+
if (finite(card.sourceGeneration) && card.sourceGeneration >= generation)
|
|
168
|
+
return { ok: false, why: 'not-early' };
|
|
169
|
+
return { ok: true, origin: card.origin, gate };
|
|
170
|
+
}
|
|
171
|
+
function rowAnswersGate(row, gate) {
|
|
172
|
+
const r = row;
|
|
173
|
+
if (gate.kind === 'tool')
|
|
174
|
+
return pendingRowAnswersCall(r, gate.taskId, gate.gatedCallId);
|
|
175
|
+
return r.taskId === gate.taskId && r.checkpointId === gate.checkpointId;
|
|
176
|
+
}
|
|
177
|
+
function ownedSafely(isOwned, row) {
|
|
178
|
+
try {
|
|
179
|
+
return isOwned(row) === true;
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const EMPTY_ENDED = Object.freeze({ phase: 'ended', retract: Object.freeze([]), phases: Object.freeze([]) });
|
|
186
|
+
const EMPTY_READY = Object.freeze({ phase: 'ready', withdraw: Object.freeze([]), keep: Object.freeze([]) });
|
|
187
|
+
function endedPlanOf(facts) {
|
|
188
|
+
const cards = distinctCards(own(facts, 'cards')).map((c) => {
|
|
189
|
+
const w = c.window;
|
|
190
|
+
const leftMs = typeof w === 'object' && w !== null ? own(w, 'leftMs') : undefined;
|
|
191
|
+
const closedByEngine = typeof w === 'object' && w !== null ? own(w, 'closedByEngine') : undefined;
|
|
192
|
+
return {
|
|
193
|
+
callKey: c.instance,
|
|
194
|
+
parkRow: c.origin !== 'live-approval',
|
|
195
|
+
...(nonEmpty(c.toolCallId) ? { toolCallId: c.toolCallId } : {}),
|
|
196
|
+
...(finite(leftMs) ? { windowLeftMs: leftMs } : {}),
|
|
197
|
+
...(closedByEngine === true ? { closedByEngine: true } : {}),
|
|
198
|
+
};
|
|
199
|
+
});
|
|
200
|
+
const opened = own(facts, 'opened');
|
|
201
|
+
const phases = own(facts, 'phases');
|
|
202
|
+
const endedGeneration = own(facts, 'endedGeneration');
|
|
203
|
+
const plan = convergeEndedEngineGeneration({
|
|
204
|
+
cards,
|
|
205
|
+
opened: Array.isArray(opened) ? opened : [],
|
|
206
|
+
...(Array.isArray(phases) ? { phases: phases } : {}),
|
|
207
|
+
endedGeneration: finite(endedGeneration) ? endedGeneration : Number.NaN,
|
|
208
|
+
});
|
|
209
|
+
return Object.freeze({ phase: 'ended', retract: plan.retract, phases: plan.phases });
|
|
210
|
+
}
|
|
211
|
+
function readyPlanOf(facts) {
|
|
212
|
+
const cards = distinctCards(own(facts, 'cards'));
|
|
213
|
+
const generation = own(facts, 'generation');
|
|
214
|
+
const keep = [];
|
|
215
|
+
const withdraw = [];
|
|
216
|
+
const keepAll = (why) => Object.freeze({ phase: 'ready', withdraw: Object.freeze([]), keep: Object.freeze(cards.map((c) => Object.freeze({ instance: c.instance, why }))) });
|
|
217
|
+
if (own(facts, 'ready') !== true || !finite(generation))
|
|
218
|
+
return keepAll('not-ready');
|
|
219
|
+
if (own(facts, 'readGeneration') !== generation)
|
|
220
|
+
return keepAll('generation-moved');
|
|
221
|
+
const cap = withdrawableSetOf(own(facts, 'withdrawable'));
|
|
222
|
+
const rowsRaw = own(facts, 'rows');
|
|
223
|
+
const rows = Array.isArray(rowsRaw) ? rowsRaw.filter((r) => typeof r === 'object' && r !== null) : [];
|
|
224
|
+
const isOwnedRaw = own(facts, 'isOwned');
|
|
225
|
+
const isOwned = typeof isOwnedRaw === 'function' ? isOwnedRaw : () => false;
|
|
226
|
+
for (const card of cards) {
|
|
227
|
+
const c = candidacyOf(card, generation, cap);
|
|
228
|
+
if (!c.ok) {
|
|
229
|
+
keep.push(Object.freeze({ instance: card.instance, why: c.why }));
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const matched = rows.filter((r) => rowAnswersGate(r, c.gate));
|
|
233
|
+
if (matched.length === 0) {
|
|
234
|
+
keep.push(Object.freeze({ instance: card.instance, why: 'no-row' }));
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const row = matched.find((r) => ownedSafely(isOwned, r));
|
|
238
|
+
if (row === undefined) {
|
|
239
|
+
keep.push(Object.freeze({ instance: card.instance, why: 'not-owned' }));
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const verdict = checkpointRowVerdictOf(row);
|
|
243
|
+
if (verdict === undefined) {
|
|
244
|
+
keep.push(Object.freeze({ instance: card.instance, why: 'verdict-absent' }));
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (verdict.kind === 'ok') {
|
|
248
|
+
keep.push(Object.freeze({ instance: card.instance, why: 'verdict-ok' }));
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const rowVerdict = verdict;
|
|
252
|
+
withdraw.push(Object.freeze({ instance: card.instance, origin: c.origin, row, withdrawal: Object.freeze({ toldBy: 'host', rowVerdict }) }));
|
|
253
|
+
}
|
|
254
|
+
return Object.freeze({ phase: 'ready', withdraw: Object.freeze(withdraw), keep: Object.freeze(keep) });
|
|
255
|
+
}
|
|
256
|
+
export function engineGenerationCardPlan(facts) {
|
|
257
|
+
let phase;
|
|
258
|
+
try {
|
|
259
|
+
if (typeof facts !== 'object' || facts === null)
|
|
260
|
+
return EMPTY_READY;
|
|
261
|
+
phase = own(facts, 'phase');
|
|
262
|
+
if (phase === 'ended')
|
|
263
|
+
return endedPlanOf(facts);
|
|
264
|
+
if (phase === 'ready')
|
|
265
|
+
return readyPlanOf(facts);
|
|
266
|
+
return EMPTY_READY;
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
return (phase === 'ended' ? EMPTY_ENDED : EMPTY_READY);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
export function engineGenerationCardRecheckDue(facts) {
|
|
273
|
+
try {
|
|
274
|
+
if (typeof facts !== 'object' || facts === null)
|
|
275
|
+
return false;
|
|
276
|
+
const generation = own(facts, 'generation');
|
|
277
|
+
if (own(facts, 'ready') !== true || !finite(generation))
|
|
278
|
+
return false;
|
|
279
|
+
const cap = withdrawableSetOf(own(facts, 'withdrawable'));
|
|
280
|
+
return distinctCards(own(facts, 'cards')).some((c) => candidacyOf(c, generation, cap).ok);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function deepFreeze(v) {
|
|
287
|
+
if (typeof v === 'object' && v !== null && !Object.isFrozen(v)) {
|
|
288
|
+
Object.freeze(v);
|
|
289
|
+
for (const k of Object.keys(v))
|
|
290
|
+
deepFreeze(v[k]);
|
|
291
|
+
}
|
|
292
|
+
return v;
|
|
293
|
+
}
|
|
294
|
+
const GOLD_LACKING = { kind: 'lacking', code: 'checkpoint.unsupported_version', reason: 'version_newer', sentence: 'Newer engine.' };
|
|
295
|
+
const GOLD_DAMAGED = { kind: 'damaged', code: 'checkpoint.invalid_outcome', reason: 'requirements_damaged', sentence: 'Row damaged.' };
|
|
296
|
+
function goldenCases() {
|
|
297
|
+
const ALL = ['park-approval', 'park-question', 'plan-review', 'host-reopen-question'];
|
|
298
|
+
const ready = (name, cards, rows, pick, over = {}) => {
|
|
299
|
+
const facts = { phase: 'ready', generation: 2, ready: true, readGeneration: 2, cards, rows, withdrawable: ALL, ...over };
|
|
300
|
+
return { name, facts, plan: { phase: 'ready', ...pick(facts.rows) } };
|
|
301
|
+
};
|
|
302
|
+
const tool = (taskId, gatedCallId) => ({ kind: 'tool', taskId, gatedCallId });
|
|
303
|
+
const W = (instance, origin, row, rowVerdict) => ({ instance, origin, row, withdrawal: { toldBy: 'host', rowVerdict } });
|
|
304
|
+
const K = (instance, why) => ({ instance, why });
|
|
305
|
+
const lacking = GOLD_LACKING;
|
|
306
|
+
const damaged = GOLD_DAMAGED;
|
|
307
|
+
const cases = [
|
|
308
|
+
{
|
|
309
|
+
name: 'ended-live-window-open-only',
|
|
310
|
+
facts: {
|
|
311
|
+
phase: 'ended',
|
|
312
|
+
endedGeneration: 1,
|
|
313
|
+
cards: [
|
|
314
|
+
{ instance: 'live-open', origin: 'live-approval', toolCallId: 'call-1', window: { leftMs: 60_000 } },
|
|
315
|
+
{ instance: 'live-margin', origin: 'live-approval', toolCallId: 'call-2', window: { leftMs: 5_000 } },
|
|
316
|
+
{ instance: 'live-closed', origin: 'live-approval', toolCallId: 'call-3', window: { leftMs: 60_000, closedByEngine: true } },
|
|
317
|
+
{ instance: 'live-no-window', origin: 'live-approval', toolCallId: 'call-4' },
|
|
318
|
+
{ instance: 'parked', origin: 'park-approval', toolCallId: 'call-5', window: { leftMs: 60_000 } },
|
|
319
|
+
{ instance: 'no-origin', toolCallId: 'call-6', window: { leftMs: 60_000 } },
|
|
320
|
+
],
|
|
321
|
+
opened: [{ toolCallId: 'call-7', generation: 1 }, { toolCallId: 'call-8', generation: 0 }],
|
|
322
|
+
},
|
|
323
|
+
plan: { phase: 'ended', retract: ['live-open'], phases: [{ toolCallId: 'call-1', phase: 'engine-stopped-awaiting-approval', viaCallKey: 'live-open' }, { toolCallId: 'call-7', phase: 'engine-stopped-before-result' }] },
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: 'ended-live-without-call-id',
|
|
327
|
+
facts: { phase: 'ended', endedGeneration: 3, cards: [{ instance: 'live', origin: 'live-approval', window: { leftMs: 9_000 } }], opened: [] },
|
|
328
|
+
plan: { phase: 'ended', retract: ['live'], phases: [] },
|
|
329
|
+
},
|
|
330
|
+
ready('ready-park-question-withdrawn', [{ instance: 'q', origin: 'park-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 }], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }], (rows) => ({ withdraw: [W('q', 'park-question', rows[0], lacking)], keep: [] })),
|
|
331
|
+
ready('ready-bound-call-id-matches', [{ instance: 'a', origin: 'park-approval', gate: tool('run-2', 'call-2'), sourceGeneration: 1 }], [{ taskId: 'run-2', toolCallId: 'call-x', boundCallId: 'call-2', rowVerdict: GOLD_DAMAGED, owned: true }], (rows) => ({ withdraw: [W('a', 'park-approval', rows[0], damaged)], keep: [] })),
|
|
332
|
+
ready('ready-plan-by-checkpoint', [
|
|
333
|
+
{ instance: 'plan-same', origin: 'plan-review', gate: { kind: 'plan', taskId: 'run-3', checkpointId: 'cp-1' } },
|
|
334
|
+
{ instance: 'plan-moved', origin: 'plan-review', gate: { kind: 'plan', taskId: 'run-4', checkpointId: 'cp-old' }, sourceGeneration: 1 },
|
|
335
|
+
{ instance: 'plan-no-checkpoint', origin: 'plan-review', gate: { kind: 'plan', taskId: 'run-5' }, sourceGeneration: 1 },
|
|
336
|
+
], [{ taskId: 'run-3', checkpointId: 'cp-1', rowVerdict: GOLD_LACKING, owned: true }, { taskId: 'run-4', checkpointId: 'cp-new', rowVerdict: GOLD_LACKING, owned: true }, { taskId: 'run-5', checkpointId: 'cp-5', rowVerdict: GOLD_LACKING, owned: true }], (rows) => ({ withdraw: [W('plan-same', 'plan-review', rows[0], lacking)], keep: [K('plan-moved', 'no-row'), K('plan-no-checkpoint', 'no-gate')] })),
|
|
337
|
+
ready('ready-kinds-never-withdrawn', [
|
|
338
|
+
{ instance: 'live', origin: 'live-approval', gate: tool('run-1', 'call-1'), sourceGeneration: 1 },
|
|
339
|
+
{ instance: 'choice', origin: 'host-choice', gate: tool('run-1', 'call-1'), sourceGeneration: 1 },
|
|
340
|
+
{ instance: 'unnamed', gate: tool('run-1', 'call-1'), sourceGeneration: 1 },
|
|
341
|
+
{ instance: 'reopened', origin: 'host-reopen-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 },
|
|
342
|
+
], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }], (rows) => ({ withdraw: [W('reopened', 'host-reopen-question', rows[0], lacking)], keep: [K('live', 'not-withdrawable'), K('choice', 'not-withdrawable'), K('unnamed', 'not-withdrawable')] })),
|
|
343
|
+
ready('ready-host-withdrawable-only', [{ instance: 'q', origin: 'park-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 }, { instance: 'r', origin: 'host-reopen-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 }], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }], (rows) => ({ withdraw: [W('r', 'host-reopen-question', rows[0], lacking)], keep: [K('q', 'not-withdrawable')] }), { withdrawable: ['host-reopen-question'] }),
|
|
344
|
+
ready('ready-current-generation-kept', [{ instance: 'q', origin: 'park-question', gate: tool('run-1', 'call-1'), sourceGeneration: 2 }], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }], () => ({ withdraw: [], keep: [K('q', 'not-early')] })),
|
|
345
|
+
ready('ready-keep-reasons', [
|
|
346
|
+
{ instance: 'no-gate', origin: 'park-question', sourceGeneration: 1 },
|
|
347
|
+
{ instance: 'no-row', origin: 'park-question', gate: tool('run-9', 'call-9'), sourceGeneration: 1 },
|
|
348
|
+
{ instance: 'foreign', origin: 'park-question', gate: tool('run-7', 'call-7'), sourceGeneration: 1 },
|
|
349
|
+
{ instance: 'fine', origin: 'park-question', gate: tool('run-8', 'call-8'), sourceGeneration: 1 },
|
|
350
|
+
{ instance: 'no-verdict', origin: 'park-question', gate: tool('run-6', 'call-6'), sourceGeneration: 1 },
|
|
351
|
+
], [
|
|
352
|
+
{ taskId: 'run-7', toolCallId: 'call-7', rowVerdict: GOLD_LACKING, owned: false },
|
|
353
|
+
{ taskId: 'run-8', toolCallId: 'call-8', rowVerdict: { kind: 'ok' }, owned: true },
|
|
354
|
+
{ taskId: 'run-6', toolCallId: 'call-6', owned: true },
|
|
355
|
+
], () => ({ withdraw: [], keep: [K('no-gate', 'no-gate'), K('no-row', 'no-row'), K('foreign', 'not-owned'), K('fine', 'verdict-ok'), K('no-verdict', 'verdict-absent')] })),
|
|
356
|
+
ready('ready-not-ready', [{ instance: 'q', origin: 'park-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 }], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }], () => ({ withdraw: [], keep: [K('q', 'not-ready')] }), { ready: false }),
|
|
357
|
+
ready('ready-generation-moved', [{ instance: 'q', origin: 'park-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 }], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }], () => ({ withdraw: [], keep: [K('q', 'generation-moved')] }), { readGeneration: 1 }),
|
|
358
|
+
ready('ready-instance-judged-once', [{ instance: 'q', origin: 'park-question', gate: tool('run-8', 'call-8'), sourceGeneration: 1 }, { instance: 'q', origin: 'park-question', gate: tool('run-1', 'call-1'), sourceGeneration: 1 }], [{ taskId: 'run-1', toolCallId: 'call-1', rowVerdict: GOLD_LACKING, owned: true }, { taskId: 'run-8', toolCallId: 'call-8', rowVerdict: { kind: 'ok' }, owned: true }], () => ({ withdraw: [], keep: [K('q', 'verdict-ok')] })),
|
|
359
|
+
];
|
|
360
|
+
return deepFreeze(cases);
|
|
361
|
+
}
|
|
362
|
+
export const ENGINE_GENERATION_CARD_PLAN_GOLDEN = goldenCases();
|
|
@@ -701,10 +701,12 @@ export function sessionPolicyRemovalNotice(outcome, deployment) {
|
|
|
701
701
|
return 'This session’s rule record holds no entry naming a tool the engine refuses that the supplied roster does not mount, so nothing was changed. If runs still fail at startup over a refused tool name, that entry is set somewhere this record does not cover — the settings sent with the run, a parent session’s rule record, or the deployment’s own tool rules — or it is a name the engine refuses that this version does not yet recognise, or the failing run does not mount a tool the supplied roster has under that name.';
|
|
702
702
|
case 'judge_failed':
|
|
703
703
|
return 'Nothing was changed: this client could not check which entries in this session’s rule record name a tool the engine refuses (its copy of the engine’s tool-name check is unavailable or gave no clear answer), so it removed none rather than guess. Removing them needs that check available in this client.';
|
|
704
|
-
case 'loosen_forbidden':
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
704
|
+
case 'loosen_forbidden': {
|
|
705
|
+
const stem = msg('rules.sessionPolicy.remove.loosenForbiddenStem');
|
|
706
|
+
return deploymentHasNoOperator(deployment)
|
|
707
|
+
? renderMessage(msg('rules.sessionPolicy.deployment.noOperator.removeLoosenForbidden', { stem }))
|
|
708
|
+
: renderMessage(msg('rules.sessionPolicy.remove.loosenForbidden', { stem }));
|
|
709
|
+
}
|
|
708
710
|
case 'conflict':
|
|
709
711
|
return 'This session’s rule record was changed by someone else while the refused entries were being removed, twice in a row — nothing was changed. Try again once the other change has finished.';
|
|
710
712
|
case 'read_failed':
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PermissionsKeptReason } from '../permissionsDeclaration.js';
|
|
2
2
|
import type { PermissionsAllowGrantReading } from '../permissionsAllowGrantCapability.js';
|
|
3
|
-
|
|
3
|
+
import { type LocalAllowOfferedFacts } from './localAllowRedemption.js';
|
|
4
|
+
export type StandingRowWhy = 'given' | 'card_unreadable' | 'remember_refused' | 'remember_unreadable' | 'route_cannot_carry' | 'classes_unreadable' | 'not_deployment_list_question' | 'evidence_unreadable' | 'offers_unreadable' | 'engine_lane_closed' | 'args_unavailable' | 'grant_binding' | 'tool_name_unreadable' | 'rule_cannot_clear' | 'host_fact_missing' | 'card_face_absent' | 'face_not_generic' | 'rule_not_sent' | 'redemption_closed' | 'redemption_unknown';
|
|
4
5
|
export type StandingPersistentRow = 'engine_offer' | 'local_whole_tool' | 'none';
|
|
5
6
|
export interface StandingRowsWhy {
|
|
6
7
|
readonly session: StandingRowWhy;
|
|
@@ -15,9 +16,11 @@ export interface StandingRows {
|
|
|
15
16
|
}
|
|
16
17
|
export interface StandingRowsHostFacts {
|
|
17
18
|
readonly wholeToolRuleSent?: boolean;
|
|
19
|
+
readonly readOnlyRedemption?: LocalAllowOfferedFacts;
|
|
18
20
|
}
|
|
19
21
|
export declare function standingRowsOf(card: object | null | undefined, host?: StandingRowsHostFacts | null): StandingRows;
|
|
20
22
|
export declare function seatSessionRowOf(card: object | null | undefined, requestId: string | undefined): boolean;
|
|
23
|
+
export declare function seatAllowNoteCarriedOf(card: object | null | undefined, requestId: string | undefined): boolean;
|
|
21
24
|
export type RememberOffer = 'offerable' | 'refused' | 'unknown';
|
|
22
25
|
export interface RememberOfferable {
|
|
23
26
|
readonly session: RememberOffer;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { DEPLOYMENT_LIST_ASK_CLASSES, readAskClassPairState } from './askClassPair.js';
|
|
2
2
|
import { askLevelVerdict } from './automaticAnswerVerdict.js';
|
|
3
|
-
import { readApprovalCardWord, readRuleOffers } from './toolApprovalWire.js';
|
|
3
|
+
import { answerCarriage, readApprovalCardWord, readRuleOffers } from './toolApprovalWire.js';
|
|
4
4
|
import { CORE_SKILL_TOOL_NAME } from '../generated/toolNameTables.js';
|
|
5
5
|
import { inSlotReadOf, inValueOf } from '../wireFailureShape.js';
|
|
6
6
|
import { toolPermissionRequestIdDomain } from '../seatContract.js';
|
|
7
7
|
import { permissionsDeclarationReport } from '../permissionsDeclaration.js';
|
|
8
8
|
import { readCardUnreadableEvidence, sessionAllowCardReadable, sessionAllowEligible } from './sessionAllowRoute.js';
|
|
9
|
+
import { localAllowRedeemability } from './localAllowRedemption.js';
|
|
9
10
|
const UNREADABLE = Symbol('unreadable');
|
|
10
11
|
function ownData(v, key) {
|
|
11
12
|
try {
|
|
@@ -54,6 +55,21 @@ function persistentRowOf(card, host, evidenceUnreadable) {
|
|
|
54
55
|
const offers = readRuleOffers(p.state === 'present' ? p.value : undefined);
|
|
55
56
|
if (offers === undefined || offers.length === 0)
|
|
56
57
|
return { row: 'none', why: 'offers_unreadable' };
|
|
58
|
+
if (key === 'ruleOffersReadOnly') {
|
|
59
|
+
const facts = typeof host === 'object' && host !== null ? ownData(host, 'readOnlyRedemption') : undefined;
|
|
60
|
+
if (typeof facts !== 'object' || facts === null)
|
|
61
|
+
return { row: 'none', why: 'redemption_unknown' };
|
|
62
|
+
const judged = localAllowRedeemability({
|
|
63
|
+
subject: 'offered',
|
|
64
|
+
managedRulesOnly: ownData(facts, 'managedRulesOnly'),
|
|
65
|
+
scopeRoot: ownData(facts, 'scopeRoot'),
|
|
66
|
+
road: ownData(facts, 'road'),
|
|
67
|
+
});
|
|
68
|
+
if (judged.kind === 'not_redeemable')
|
|
69
|
+
return { row: 'none', why: 'redemption_closed' };
|
|
70
|
+
if (judged.kind === 'unknown')
|
|
71
|
+
return { row: 'none', why: 'redemption_unknown' };
|
|
72
|
+
}
|
|
57
73
|
return { row: 'engine_offer', why: 'given' };
|
|
58
74
|
}
|
|
59
75
|
const absence = present(card, 'ruleOffersAbsence');
|
|
@@ -153,6 +169,20 @@ export function seatSessionRowOf(card, requestId) {
|
|
|
153
169
|
return false;
|
|
154
170
|
}
|
|
155
171
|
}
|
|
172
|
+
export function seatAllowNoteCarriedOf(card, requestId) {
|
|
173
|
+
if (typeof card !== 'object' || card === null)
|
|
174
|
+
return false;
|
|
175
|
+
try {
|
|
176
|
+
if (Object.hasOwn(card, 'requestId'))
|
|
177
|
+
return false;
|
|
178
|
+
if (toolPermissionRequestIdDomain(requestId) !== 'durable:')
|
|
179
|
+
return false;
|
|
180
|
+
return answerCarriage(card).allowNote === 'model';
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
156
186
|
const SESSION_OFFER = Object.freeze({
|
|
157
187
|
given: 'offerable',
|
|
158
188
|
card_unreadable: 'unknown',
|
|
@@ -172,6 +202,8 @@ const SESSION_OFFER = Object.freeze({
|
|
|
172
202
|
card_face_absent: 'unknown',
|
|
173
203
|
face_not_generic: 'refused',
|
|
174
204
|
rule_not_sent: 'refused',
|
|
205
|
+
redemption_closed: 'refused',
|
|
206
|
+
redemption_unknown: 'unknown',
|
|
175
207
|
});
|
|
176
208
|
const PERSISTENT_OFFER = Object.freeze({ ...SESSION_OFFER, remember_refused: 'unknown' });
|
|
177
209
|
export function rememberOfferable(card, host) {
|