@sema-agent/client-core 0.99.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 +177 -0
- package/README.md +32 -19
- package/dist/adapt/arms.js +60 -36
- package/dist/adapt/panelTasks.d.ts +2 -1
- package/dist/adapt/panelTasks.js +32 -9
- package/dist/adapt/textStream.d.ts +1 -1
- package/dist/adapt/textStream.js +51 -28
- package/dist/adapter/activeRunSelfHeal.d.ts +7 -0
- package/dist/adapter/activeRunSelfHeal.js +58 -11
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +125 -9
- 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 +32 -5
- package/dist/adapter/types.d.ts +2 -0
- package/dist/agentsWireCaps.d.ts +7 -0
- package/dist/agentsWireCaps.js +100 -15
- package/dist/cloudConfigWireCaps.d.ts +10 -1
- package/dist/cloudConfigWireCaps.js +156 -62
- package/dist/compactionStatus.d.ts +34 -0
- package/dist/compactionStatus.js +196 -0
- package/dist/decideFailureNote.js +3 -3
- package/dist/displayUntrusted.js +150 -5
- package/dist/engineAgentPanelStore.d.ts +7 -4
- package/dist/engineErrorCodes.d.ts +9 -1
- package/dist/engineErrorCodes.js +9 -5
- package/dist/engineRowRef.js +1 -0
- package/dist/engineToolDirectory.d.ts +3 -0
- package/dist/engineToolDirectory.js +4 -2
- package/dist/eventLeg.d.ts +1 -7
- package/dist/eventLeg.js +7 -8
- package/dist/fileHistoryCaptureCapability.d.ts +0 -3
- package/dist/fileHistoryCaptureCapability.js +0 -4
- package/dist/generated/engineFactTables.d.ts +1 -0
- package/dist/generated/engineFactTables.js +27 -0
- package/dist/generated/engineNoticeTables.js +3 -0
- package/dist/generated/settingsSchemaFns.d.ts +12 -0
- package/dist/generated/settingsSchemaFns.js +13 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
- package/dist/generated/settingsSchemaTables.d.ts +1 -0
- package/dist/generated/settingsSchemaTables.js +5 -0
- package/dist/generated/settingsSchemaTypes.d.ts +28 -0
- package/dist/hitl/allowRuleShadow.js +2 -2
- package/dist/hitl/approvalCardReasons.js +2 -2
- package/dist/hitl/approvalHolds.d.ts +14 -0
- package/dist/hitl/approvalHolds.js +41 -0
- package/dist/hitl/askClassPair.d.ts +2 -2
- package/dist/hitl/askClassPair.js +2 -2
- package/dist/hitl/attributionLadder.d.ts +23 -0
- package/dist/hitl/attributionLadder.js +67 -0
- 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/hitlBridge.js +18 -6
- package/dist/hitl/planReviewWire.js +45 -76
- package/dist/hitl/sessionPolicyDeliverable.js +3 -6
- package/dist/hitl/toolApprovalWire.js +43 -109
- package/dist/hostTurnSettings.d.ts +46 -7
- package/dist/hostTurnSettings.js +408 -7
- package/dist/humanTurn.d.ts +2 -1
- package/dist/humanTurn.js +3 -3
- package/dist/i18n/messages.en.d.ts +131 -0
- package/dist/i18n/messages.en.js +143 -12
- package/dist/i18n/messages.zh.js +148 -12
- package/dist/index.d.ts +18 -2
- package/dist/index.js +10 -1
- package/dist/inheritEnvCapability.d.ts +1 -0
- package/dist/inheritEnvCapability.js +9 -2
- package/dist/inheritEnvWire.js +2 -2
- package/dist/injectionLaneNotice.d.ts +5 -0
- package/dist/injectionLaneNotice.js +46 -0
- package/dist/mcpPanel.js +2 -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 +10 -4
- package/dist/mcpWireCaps.js +106 -71
- package/dist/mcpWireTransport.d.ts +4 -0
- package/dist/mcpWireTransport.js +18 -0
- package/dist/modelCapabilityProbe.d.ts +2 -1
- package/dist/modelCapabilityProbe.js +10 -9
- package/dist/modelIdentityResolvability.d.ts +2 -0
- package/dist/modelIdentityResolvability.js +23 -5
- package/dist/ownKey.d.ts +26 -0
- package/dist/ownKey.js +75 -0
- package/dist/panelReduce.d.ts +5 -0
- package/dist/panelReduce.js +45 -13
- package/dist/panelStateHolder.d.ts +1 -0
- package/dist/panelStateHolder.js +10 -1
- package/dist/permissionRuleIssue.d.ts +2 -1
- package/dist/permissionRuleIssue.js +22 -21
- package/dist/pluginHooksWire.js +12 -10
- package/dist/prepareRefusal.d.ts +8 -0
- package/dist/prepareRefusal.js +72 -0
- package/dist/request/taskRequest.d.ts +10 -10
- package/dist/request/taskRequest.js +106 -65
- package/dist/resumeRefusalCopy.d.ts +3 -1
- package/dist/resumeRefusalCopy.js +22 -4
- package/dist/retryStatus.d.ts +18 -0
- package/dist/retryStatus.js +76 -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 +2 -1
- package/dist/scenarioRefusal.js +5 -5
- package/dist/seam.d.ts +24 -9
- package/dist/seam.js +44 -4
- package/dist/seatContract.d.ts +16 -8
- package/dist/seatContract.js +21 -6
- package/dist/settingsCredentialKeyPaths.d.ts +8 -0
- package/dist/settingsCredentialKeyPaths.js +219 -0
- package/dist/skillsWireCaps.d.ts +0 -3
- package/dist/skillsWireCaps.js +1 -2
- package/dist/subagentContentStore.d.ts +1 -0
- package/dist/subagentContentStore.js +135 -27
- package/dist/toolsFlagNames.d.ts +8 -0
- package/dist/toolsFlagNames.js +110 -0
- package/dist/turnFailurePresentation.js +15 -7
- package/dist/wireRefusalCopy.d.ts +51 -17
- package/dist/wireRefusalCopy.js +298 -135
- package/docs/INTEGRATION-CLIENTS.md +423 -26
- package/package.json +4 -4
package/dist/wireRefusalCopy.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { PROTOCOL_ERROR_NAME, THROWN_SLOT_UNREADABLE, protocolErrorNameOf, readErrorNumber, readErrorRecord, readErrorStrictStringList, readErrorString, readErrorStringList, readRefusalField, readThrownSlot, readThrownStatusSlot } from './wireFailureShape.js';
|
|
2
2
|
import { readOwnDataValue, readOwnNonEmptyString } from './ownKey.js';
|
|
3
|
-
import { ACTIVE_RUN_BUSY_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, REQUEST_AUTONOMY_LANE_REFUSED, REQUEST_FIELD_CONFLICT, RESUME_OUTCOME_INVALID, RESUME_POLICY_FOLD_CODE,
|
|
3
|
+
import { ACTIVE_RUN_BUSY_ERROR_CODE, FLEET_LEASE_UNAVAILABLE, REQUEST_AUTONOMY_LANE_REFUSED, REQUEST_FIELD_CONFLICT, RESUME_OUTCOME_INVALID, RESUME_POLICY_FOLD_CODE, USAGE_WINDOW_EXHAUSTED, USER_ATTACHMENT_INVALID_ERROR_CODE, USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE } from './engineErrorCodes.js';
|
|
4
4
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
5
5
|
import { effectiveWireErrorCode } from './wireErrorTriage.js';
|
|
6
6
|
import { CORE_TOOL_DECLARATION_CODES } from './generated/engineFactTables.js';
|
|
7
|
-
import {
|
|
7
|
+
import { prepareRefusalNoteOf } from './prepareRefusal.js';
|
|
8
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
8
9
|
export const CONFLICT_APPROVAL_SETTLED = 'conflict.approval_settled';
|
|
9
10
|
export const CONFLICT_RUN_NOT_RUNNING = 'conflict.run_not_running';
|
|
10
11
|
function ownNonEmptyStringSlot(o, key) {
|
|
@@ -26,17 +27,14 @@ export function cancelConflictFromError(err) {
|
|
|
26
27
|
return { kind: 'run_not_running', code };
|
|
27
28
|
return { kind: 'unrecognized', ...(code !== undefined ? { code } : {}) };
|
|
28
29
|
}
|
|
29
|
-
export function cancelConflictContent(detail) {
|
|
30
|
+
export function cancelConflictContent(detail, lang) {
|
|
30
31
|
switch (detail.kind) {
|
|
31
32
|
case 'approval_settled':
|
|
32
|
-
return ('
|
|
33
|
-
'Check what that decision did to the task before doing anything else');
|
|
33
|
+
return renderMessage(msg('notice.wireRefusal.cancel.approvalSettled'), lang);
|
|
34
34
|
case 'run_not_running':
|
|
35
|
-
return ('
|
|
36
|
-
'Nothing was changed — send the cancel again');
|
|
35
|
+
return renderMessage(msg('notice.wireRefusal.cancel.runNotRunning'), lang);
|
|
37
36
|
case 'unrecognized':
|
|
38
|
-
return ('
|
|
39
|
-
'The task may have just been decided elsewhere, or may have changed state mid-cancel — check its current state, then cancel again if it is still active');
|
|
37
|
+
return renderMessage(msg('notice.wireRefusal.cancel.unrecognized'), lang);
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
function nonNegativeFinite(v) {
|
|
@@ -80,11 +78,11 @@ function humanWait(sec) {
|
|
|
80
78
|
const mm = m % 60;
|
|
81
79
|
return mm === 0 ? `${h} h` : `${h} h ${mm} min`;
|
|
82
80
|
}
|
|
83
|
-
export function usageWindowExhaustedContent(detail) {
|
|
84
|
-
const head =
|
|
81
|
+
export function usageWindowExhaustedContent(detail, lang) {
|
|
82
|
+
const head = renderMessage(msg('notice.wireRefusal.usageWindow.head'), lang);
|
|
85
83
|
return detail.retryAfterSec !== undefined
|
|
86
|
-
? `${head} ·
|
|
87
|
-
: `${head} ·
|
|
84
|
+
? `${head} · ${renderMessage(msg('notice.wireRefusal.sendAgainAbout', { wait: humanWait(detail.retryAfterSec) }), lang)}`
|
|
85
|
+
: `${head} · ${renderMessage(msg('notice.wireRefusal.usageWindow.unknownWait'), lang)}`;
|
|
88
86
|
}
|
|
89
87
|
const positiveFinite = (v) => typeof v === 'number' && Number.isFinite(v) && v > 0;
|
|
90
88
|
export function fleetLeaseUnavailableFromError(err) {
|
|
@@ -112,7 +110,7 @@ export function fleetLeaseUnavailableFromError(err) {
|
|
|
112
110
|
...(sec !== undefined ? { retryAfterSec: sec } : {}),
|
|
113
111
|
};
|
|
114
112
|
}
|
|
115
|
-
export function fleetLeaseUnavailableContent(detail) {
|
|
113
|
+
export function fleetLeaseUnavailableContent(detail, lang) {
|
|
116
114
|
let reason;
|
|
117
115
|
let sec;
|
|
118
116
|
try {
|
|
@@ -127,27 +125,17 @@ export function fleetLeaseUnavailableContent(detail) {
|
|
|
127
125
|
catch {
|
|
128
126
|
sec = undefined;
|
|
129
127
|
}
|
|
130
|
-
const head =
|
|
128
|
+
const head = renderMessage(msg('notice.wireRefusal.fleetLease.head'), lang);
|
|
131
129
|
const cause = reason === 'auth-rejected'
|
|
132
|
-
?
|
|
130
|
+
? ` · ${renderMessage(msg('notice.wireRefusal.fleetLease.authRejected'), lang)}`
|
|
133
131
|
: reason === 'unreachable'
|
|
134
|
-
?
|
|
132
|
+
? ` · ${renderMessage(msg('notice.wireRefusal.fleetLease.unreachable'), lang)}`
|
|
135
133
|
: '';
|
|
136
134
|
const wait = positiveFinite(sec)
|
|
137
|
-
? ` ·
|
|
138
|
-
:
|
|
135
|
+
? ` · ${renderMessage(msg('notice.wireRefusal.sendAgainAbout', { wait: humanWait(Math.ceil(sec)) }), lang)}`
|
|
136
|
+
: ` · ${renderMessage(msg('notice.wireRefusal.fleetLease.unknownWait'), lang)}`;
|
|
139
137
|
return `${head}${cause}${wait}`;
|
|
140
138
|
}
|
|
141
|
-
export function scenarioAssignmentUnknownFromError(err) {
|
|
142
|
-
const r = scenarioRefusalFromError(err);
|
|
143
|
-
if (r === null)
|
|
144
|
-
return null;
|
|
145
|
-
return {
|
|
146
|
-
code: SCENARIO_ASSIGNMENT_UNKNOWN_ERROR_CODE,
|
|
147
|
-
...(r.scenario !== undefined ? { scenario: r.scenario } : {}),
|
|
148
|
-
...(r.source !== undefined ? { source: r.source } : {}),
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
139
|
const SETTLED_BY_NOT_IN_PROOF = 'settled_by_not_in_proof';
|
|
152
140
|
const DECIDED_BY_NOT_IN_PROOF = 'decided_by_not_in_proof';
|
|
153
141
|
const RETIRED_DECISION_KEY = 'settledBy';
|
|
@@ -184,26 +172,19 @@ export function denyAttributionRefusalFromError(err, sentAttributionKey) {
|
|
|
184
172
|
return null;
|
|
185
173
|
}
|
|
186
174
|
}
|
|
187
|
-
export function denyAttributionRefusalContent(detail) {
|
|
175
|
+
export function denyAttributionRefusalContent(detail, lang) {
|
|
188
176
|
switch (detail.kind) {
|
|
189
177
|
case 'not_in_proof':
|
|
190
|
-
return ('
|
|
191
|
-
'who settled this one is not part of what gets signed · Nothing was decided and the approval is still waiting — ' +
|
|
192
|
-
'send the same decision again without that note');
|
|
178
|
+
return renderMessage(msg('notice.wireRefusal.denyAttribution.notInProof'), lang);
|
|
193
179
|
case 'decision_conflict':
|
|
194
|
-
return ('
|
|
195
|
-
'and only a person can allow one · Nothing was decided and the approval is still waiting — ' +
|
|
196
|
-
'send it again with the decision and the note in agreement');
|
|
180
|
+
return renderMessage(msg('notice.wireRefusal.denyAttribution.decisionConflict'), lang);
|
|
197
181
|
case 'retired_key':
|
|
198
|
-
return ('
|
|
199
|
-
'Nothing was decided and the approval is still waiting — send the decision again with who made it given under the name the engine now takes in its place');
|
|
182
|
+
return renderMessage(msg('notice.wireRefusal.denyAttribution.retiredKey'), lang);
|
|
200
183
|
case 'attribution_rejected': {
|
|
201
184
|
const named = typeof detail.field === 'string' && APPROVAL_NON_BINDING_FIELDS.has(detail.field)
|
|
202
|
-
?
|
|
185
|
+
? renderMessage(msg('notice.wireRefusal.denyAttribution.named', { field: detail.field }), lang)
|
|
203
186
|
: '';
|
|
204
|
-
return ('
|
|
205
|
-
`${named} · Nothing was decided and the approval is still waiting at the same coordinates — ` +
|
|
206
|
-
'check what that part carried (the only piece this client sets is the note saying who settled the refusal) and decide once more');
|
|
187
|
+
return renderMessage(msg('notice.wireRefusal.denyAttribution.attributionRejected', { named }), lang);
|
|
207
188
|
}
|
|
208
189
|
}
|
|
209
190
|
}
|
|
@@ -234,36 +215,36 @@ export function sessionDeleteConflictFromError(err) {
|
|
|
234
215
|
}
|
|
235
216
|
const DELETE_CONFLICT_IDS_SHOWN = 3;
|
|
236
217
|
const DELETE_CONFLICT_ID_MAX = 64;
|
|
237
|
-
function sessionDeleteConflictUnrecognizedContent() {
|
|
238
|
-
return ('
|
|
239
|
-
'Check whether the session is still listed and whether anything of it is still running, then try the delete again');
|
|
218
|
+
function sessionDeleteConflictUnrecognizedContent(lang) {
|
|
219
|
+
return renderMessage(msg('notice.wireRefusal.sessionDelete.unrecognized'), lang);
|
|
240
220
|
}
|
|
241
|
-
export function sessionDeleteConflictContent(detail) {
|
|
221
|
+
export function sessionDeleteConflictContent(detail, lang) {
|
|
242
222
|
try {
|
|
243
223
|
if (detail === null || typeof detail !== 'object')
|
|
244
|
-
return sessionDeleteConflictUnrecognizedContent();
|
|
224
|
+
return sessionDeleteConflictUnrecognizedContent(lang);
|
|
245
225
|
switch (detail.kind) {
|
|
246
226
|
case 'children_alive': {
|
|
247
227
|
const raw = detail.remaining;
|
|
248
228
|
const ids = Array.isArray(raw) ? raw.filter((id) => typeof id === 'string' && id.length > 0) : [];
|
|
249
229
|
const shown = ids.slice(0, DELETE_CONFLICT_IDS_SHOWN).map((id) => capForDisplay(id, DELETE_CONFLICT_ID_MAX));
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
230
|
+
const which = shown.length === 0
|
|
231
|
+
? ''
|
|
232
|
+
: ids.length > shown.length
|
|
233
|
+
? renderMessage(msg('notice.wireRefusal.sessionDelete.whichMore', { ids: shown.join(', '), count: ids.length - shown.length }), lang)
|
|
234
|
+
: renderMessage(msg('notice.wireRefusal.sessionDelete.which', { ids: shown.join(', ') }), lang);
|
|
235
|
+
return renderMessage(msg('notice.wireRefusal.sessionDelete.childrenAlive', { which }), lang);
|
|
254
236
|
}
|
|
255
237
|
case 'active_run': {
|
|
256
238
|
const active = detail.activeTaskId;
|
|
257
|
-
const run = typeof active === 'string' && active.length > 0 ?
|
|
258
|
-
return (
|
|
259
|
-
'Nothing was deleted — cancel that run or let it finish, then delete the session again');
|
|
239
|
+
const run = typeof active === 'string' && active.length > 0 ? renderMessage(msg('notice.wireRefusal.sessionDelete.runId', { id: capForDisplay(active, DELETE_CONFLICT_ID_MAX) }), lang) : '';
|
|
240
|
+
return renderMessage(msg('notice.wireRefusal.sessionDelete.activeRun', { run }), lang);
|
|
260
241
|
}
|
|
261
242
|
default:
|
|
262
|
-
return sessionDeleteConflictUnrecognizedContent();
|
|
243
|
+
return sessionDeleteConflictUnrecognizedContent(lang);
|
|
263
244
|
}
|
|
264
245
|
}
|
|
265
246
|
catch {
|
|
266
|
-
return sessionDeleteConflictUnrecognizedContent();
|
|
247
|
+
return sessionDeleteConflictUnrecognizedContent(lang);
|
|
267
248
|
}
|
|
268
249
|
}
|
|
269
250
|
const FIELD_INVALID = 'request.field_invalid';
|
|
@@ -275,6 +256,24 @@ const BUCKET_OF_FIELD = Object.freeze({
|
|
|
275
256
|
const nonNegInt = (v) => (typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 ? v : undefined);
|
|
276
257
|
const posInt = (v) => (typeof v === 'number' && Number.isSafeInteger(v) && v >= 1 ? v : undefined);
|
|
277
258
|
export function settingsPermissionBucketRefusalFromError(err) {
|
|
259
|
+
const r = fieldLimitRefusalFromError(err);
|
|
260
|
+
if (r === null)
|
|
261
|
+
return null;
|
|
262
|
+
const bucket = Object.hasOwn(BUCKET_OF_FIELD, r.field) ? BUCKET_OF_FIELD[r.field] : undefined;
|
|
263
|
+
if (bucket === undefined || (r.reason !== 'over_cap' && r.reason !== 'bad_entry'))
|
|
264
|
+
return null;
|
|
265
|
+
if (r.reason === 'over_cap') {
|
|
266
|
+
return Object.freeze({
|
|
267
|
+
bucket,
|
|
268
|
+
reason: r.reason,
|
|
269
|
+
...(r.count !== undefined ? { count: r.count } : {}),
|
|
270
|
+
...(r.cap !== undefined ? { cap: r.cap } : {}),
|
|
271
|
+
...(r.folded === true ? { folded: true } : {}),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return Object.freeze({ bucket, reason: r.reason, ...(r.index !== undefined ? { index: r.index } : {}), ...(r.folded === true ? { folded: true } : {}) });
|
|
275
|
+
}
|
|
276
|
+
export function fieldLimitRefusalFromError(err) {
|
|
278
277
|
try {
|
|
279
278
|
if (typeof err !== 'object' || err === null)
|
|
280
279
|
return null;
|
|
@@ -288,72 +287,166 @@ export function settingsPermissionBucketRefusalFromError(err) {
|
|
|
288
287
|
return null;
|
|
289
288
|
}
|
|
290
289
|
const field = readErrorString(err, 'field');
|
|
291
|
-
|
|
292
|
-
if (bucket === undefined)
|
|
290
|
+
if (field === undefined || field.length === 0)
|
|
293
291
|
return null;
|
|
294
292
|
const reason = readErrorString(err, 'reason');
|
|
295
|
-
if (reason !== 'over_cap' && reason !== 'bad_entry')
|
|
293
|
+
if (reason !== 'over_cap' && reason !== 'too_long' && reason !== 'bad_entry')
|
|
296
294
|
return null;
|
|
297
295
|
const folded = outer === RESUME_POLICY_FOLD_CODE;
|
|
298
|
-
if (reason === '
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
296
|
+
if (reason === 'bad_entry') {
|
|
297
|
+
const index = nonNegInt(readErrorNumber(err, 'index'));
|
|
298
|
+
return Object.freeze({ field, reason, ...(index !== undefined ? { index } : {}), ...(folded ? { folded: true } : {}) });
|
|
299
|
+
}
|
|
300
|
+
const count = nonNegInt(readErrorNumber(err, 'count'));
|
|
301
|
+
const cap = posInt(readErrorNumber(err, 'cap'));
|
|
302
|
+
return Object.freeze({
|
|
303
|
+
field,
|
|
304
|
+
reason,
|
|
305
|
+
...(count !== undefined ? { count } : {}),
|
|
306
|
+
...(cap !== undefined ? { cap } : {}),
|
|
307
|
+
...(folded ? { folded: true } : {}),
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const FIELD_LIMIT_REFUSAL_UNKNOWN = 'The engine refused this request: a list in it has too many entries, or a text in it is too long · Nothing was trimmed or dropped — shorten it, then send the request again';
|
|
315
|
+
const FIELD_LIMIT_FIELD_MAX = 120;
|
|
316
|
+
export function fieldLimitRefusalContent(detail, lang) {
|
|
317
|
+
try {
|
|
318
|
+
if (typeof detail !== 'object' || detail === null)
|
|
319
|
+
return FIELD_LIMIT_REFUSAL_UNKNOWN;
|
|
320
|
+
const field = detail.field;
|
|
321
|
+
const reason = detail.reason;
|
|
322
|
+
if (typeof field !== 'string' || field.length === 0)
|
|
323
|
+
return FIELD_LIMIT_REFUSAL_UNKNOWN;
|
|
324
|
+
const folded = detail.folded === true;
|
|
325
|
+
const bucket = Object.hasOwn(BUCKET_OF_FIELD, field) ? BUCKET_OF_FIELD[field] : undefined;
|
|
326
|
+
if (bucket !== undefined && (reason === 'over_cap' || reason === 'bad_entry')) {
|
|
327
|
+
return settingsPermissionBucketRefusalContent({
|
|
302
328
|
bucket,
|
|
303
329
|
reason,
|
|
304
|
-
...(count !== undefined ? { count } : {}),
|
|
305
|
-
...(cap !== undefined ? { cap } : {}),
|
|
330
|
+
...(reason === 'over_cap' && nonNegInt(detail.count) !== undefined ? { count: detail.count } : {}),
|
|
331
|
+
...(reason === 'over_cap' && posInt(detail.cap) !== undefined ? { cap: detail.cap } : {}),
|
|
332
|
+
...(reason === 'bad_entry' && nonNegInt(detail.index) !== undefined ? { index: detail.index } : {}),
|
|
306
333
|
...(folded ? { folded: true } : {}),
|
|
307
|
-
});
|
|
334
|
+
}, lang);
|
|
308
335
|
}
|
|
309
|
-
|
|
310
|
-
|
|
336
|
+
if (reason !== 'over_cap' && reason !== 'too_long' && reason !== 'bad_entry')
|
|
337
|
+
return FIELD_LIMIT_REFUSAL_UNKNOWN;
|
|
338
|
+
const where = `the request field ${capForDisplay(field, FIELD_LIMIT_FIELD_MAX)}`;
|
|
339
|
+
const subject = folded ? 'The engine refused to continue this parked work: in the request stored for it,' : 'The engine refused this request:';
|
|
340
|
+
let what;
|
|
341
|
+
if (reason === 'bad_entry') {
|
|
342
|
+
const index = nonNegInt(detail.index);
|
|
343
|
+
what = index !== undefined ? `entry ${index + 1} of ${where} is not valid` : `${where} is not valid`;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
const count = nonNegInt(detail.count);
|
|
347
|
+
const cap = posInt(detail.cap);
|
|
348
|
+
const unit = reason === 'over_cap' ? 'entries' : 'characters';
|
|
349
|
+
what =
|
|
350
|
+
count !== undefined && cap !== undefined
|
|
351
|
+
? count > cap
|
|
352
|
+
? `${where} has ${count} ${unit}, ${count - cap} more than the ${cap} the engine accepts`
|
|
353
|
+
: `${where} has ${count} ${unit}, and the engine accepts at most ${cap}`
|
|
354
|
+
: reason === 'over_cap'
|
|
355
|
+
? `${where} has more entries than the engine accepts`
|
|
356
|
+
: `${where} is longer than the engine accepts`;
|
|
357
|
+
}
|
|
358
|
+
const fix = reason === 'bad_entry' ? 'fix or remove that entry' : reason === 'over_cap' ? 'remove some entries or merge them' : 'shorten it';
|
|
359
|
+
const next = folded
|
|
360
|
+
? `It cannot continue as stored, and the engine refuses rather than silently trimming — ${fix}, then submit the work again as a new request`
|
|
361
|
+
: `Nothing was trimmed or dropped, because the engine refuses rather than silently trimming — ${fix}, then send the request again`;
|
|
362
|
+
return `${subject} ${what} · ${next}`;
|
|
311
363
|
}
|
|
312
364
|
catch {
|
|
313
|
-
return
|
|
365
|
+
return FIELD_LIMIT_REFUSAL_UNKNOWN;
|
|
314
366
|
}
|
|
315
367
|
}
|
|
316
|
-
const BUCKET_REFUSAL_UNKNOWN =
|
|
317
|
-
export function settingsPermissionBucketRefusalContent(detail) {
|
|
368
|
+
const BUCKET_REFUSAL_UNKNOWN = 'notice.wireRefusal.bucket.unknown';
|
|
369
|
+
export function settingsPermissionBucketRefusalContent(detail, lang) {
|
|
318
370
|
try {
|
|
319
371
|
if (typeof detail !== 'object' || detail === null)
|
|
320
|
-
return BUCKET_REFUSAL_UNKNOWN;
|
|
372
|
+
return renderMessage(msg(BUCKET_REFUSAL_UNKNOWN), lang);
|
|
321
373
|
const bucket = detail.bucket;
|
|
322
374
|
const reason = detail.reason;
|
|
323
375
|
if (bucket !== 'allow' && bucket !== 'deny' && bucket !== 'ask')
|
|
324
|
-
return BUCKET_REFUSAL_UNKNOWN;
|
|
376
|
+
return renderMessage(msg(BUCKET_REFUSAL_UNKNOWN), lang);
|
|
325
377
|
if (reason !== 'over_cap' && reason !== 'bad_entry')
|
|
326
|
-
return BUCKET_REFUSAL_UNKNOWN;
|
|
378
|
+
return renderMessage(msg(BUCKET_REFUSAL_UNKNOWN), lang);
|
|
327
379
|
const folded = detail.folded === true;
|
|
328
|
-
const subject = folded ? '
|
|
329
|
-
const list =
|
|
380
|
+
const subject = renderMessage(folded ? msg('notice.wireRefusal.bucket.subject.stored') : msg('notice.wireRefusal.bucket.subject.fresh'), lang);
|
|
381
|
+
const list = msg('notice.wireRefusal.bucket.list', { bucket });
|
|
330
382
|
let what;
|
|
331
383
|
let fix;
|
|
332
384
|
if (reason === 'over_cap') {
|
|
333
385
|
const count = nonNegInt(detail.count);
|
|
334
386
|
const cap = posInt(detail.cap);
|
|
335
|
-
what =
|
|
336
|
-
count
|
|
337
|
-
? count
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
fix = 'merge rules into broader patterns or remove some';
|
|
387
|
+
what = renderMessage(count !== undefined && cap !== undefined
|
|
388
|
+
? count > cap
|
|
389
|
+
? msg('notice.wireRefusal.bucket.what.overCap.more', { list, count, excess: count - cap, cap })
|
|
390
|
+
: msg('notice.wireRefusal.bucket.what.overCap.atMost', { list, count, cap })
|
|
391
|
+
: msg('notice.wireRefusal.bucket.what.overCap.unknown', { list }), lang);
|
|
392
|
+
fix = renderMessage(msg('notice.wireRefusal.bucket.fix.merge'), lang);
|
|
342
393
|
}
|
|
343
394
|
else {
|
|
344
395
|
const index = nonNegInt(detail.index);
|
|
345
|
-
what = index !== undefined ?
|
|
346
|
-
fix = index !== undefined ? 'fix
|
|
396
|
+
what = renderMessage(index !== undefined ? msg('notice.wireRefusal.bucket.what.badEntry.at', { position: index + 1, list }) : msg('notice.wireRefusal.bucket.what.badEntry.notList', { list }), lang);
|
|
397
|
+
fix = renderMessage(msg(index !== undefined ? 'notice.wireRefusal.bucket.fix.entry' : 'notice.wireRefusal.bucket.fix.list'), lang);
|
|
347
398
|
}
|
|
348
|
-
const next = folded
|
|
349
|
-
? `It cannot continue as stored, and the engine refuses the list rather than silently losing rules — ${fix}, then submit the work again as a new request`
|
|
350
|
-
: `Nothing was trimmed or dropped, because the engine refuses the list rather than silently losing rules — ${fix}, then send the request again`;
|
|
399
|
+
const next = renderMessage(msg(folded ? 'notice.wireRefusal.bucket.next.stored' : 'notice.wireRefusal.bucket.next.fresh', { fix }), lang);
|
|
351
400
|
return `${subject} ${what} · ${next}`;
|
|
352
401
|
}
|
|
353
402
|
catch {
|
|
354
|
-
return BUCKET_REFUSAL_UNKNOWN;
|
|
403
|
+
return renderMessage(msg(BUCKET_REFUSAL_UNKNOWN), lang);
|
|
355
404
|
}
|
|
356
405
|
}
|
|
406
|
+
const PAYLOAD_TOO_LARGE = 'request.payload_too_large';
|
|
407
|
+
const BLOB_TOO_LARGE_FOR_SQL = 'blob_too_large_for_sql';
|
|
408
|
+
export function admissionWallRefusalFromError(err) {
|
|
409
|
+
try {
|
|
410
|
+
if (typeof err !== 'object' || err === null)
|
|
411
|
+
return null;
|
|
412
|
+
const code = readThrownSlot(err, 'errorCode', 'data');
|
|
413
|
+
if (code !== PAYLOAD_TOO_LARGE && code !== BLOB_TOO_LARGE_FOR_SQL)
|
|
414
|
+
return null;
|
|
415
|
+
const wallSource = readErrorString(err, 'wallSource');
|
|
416
|
+
if (wallSource === 'reported' || wallSource === 'assumed')
|
|
417
|
+
return Object.freeze({ code, wallSource });
|
|
418
|
+
if (wallSource === 'operator' && code === BLOB_TOO_LARGE_FOR_SQL)
|
|
419
|
+
return Object.freeze({ code, wallSource });
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
catch {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
export function admissionWallRefusalContent(detail) {
|
|
427
|
+
let code;
|
|
428
|
+
let source;
|
|
429
|
+
try {
|
|
430
|
+
code = detail.code;
|
|
431
|
+
source = detail.wallSource;
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
code = source = undefined;
|
|
435
|
+
}
|
|
436
|
+
const subject = code === BLOB_TOO_LARGE_FOR_SQL ? 'This snapshot file' : 'This request';
|
|
437
|
+
if (source === 'assumed') {
|
|
438
|
+
return (`${subject} was refused at the most conservative size limit, because this deployment has not read its database’s actual limit yet · ` +
|
|
439
|
+
'Nothing was stored · Try again shortly; if it keeps happening, ask whoever operates the engine to let the service read the database’s size limit');
|
|
440
|
+
}
|
|
441
|
+
if (source === 'operator' && code === BLOB_TOO_LARGE_FOR_SQL) {
|
|
442
|
+
return ('This snapshot file is larger than the cap whoever operates the engine set for snapshots stored in the database · Nothing was stored · ' +
|
|
443
|
+
'Ask them to configure object storage for large snapshots, or to raise that cap');
|
|
444
|
+
}
|
|
445
|
+
return code === BLOB_TOO_LARGE_FOR_SQL
|
|
446
|
+
? 'This snapshot file is larger than this deployment’s database can store in one piece · Nothing was stored · Ask whoever operates the engine to configure object storage for large snapshots, or to raise the database’s limit'
|
|
447
|
+
: 'This request is larger than this deployment’s database accepts for one submitted task · Nothing was stored · ' +
|
|
448
|
+
'Shrink the inline images or attachments, or ask whoever operates the engine to raise the database’s limit (the engine’s own message names which one), then send it again';
|
|
449
|
+
}
|
|
357
450
|
export function toolDeclarationRefusalFromError(err) {
|
|
358
451
|
try {
|
|
359
452
|
if (typeof err !== 'object' || err === null)
|
|
@@ -367,10 +460,9 @@ export function toolDeclarationRefusalFromError(err) {
|
|
|
367
460
|
return null;
|
|
368
461
|
}
|
|
369
462
|
}
|
|
370
|
-
const TOOL_DECLARATION_REFUSAL =
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
return TOOL_DECLARATION_REFUSAL;
|
|
463
|
+
const TOOL_DECLARATION_REFUSAL = 'notice.wireRefusal.toolDeclaration';
|
|
464
|
+
export function toolDeclarationRefusalContent(_detail, lang) {
|
|
465
|
+
return renderMessage(msg(TOOL_DECLARATION_REFUSAL), lang);
|
|
374
466
|
}
|
|
375
467
|
const BODY_SHAPE = 'request.body_shape';
|
|
376
468
|
const SETTINGS_KEY_PREFIX = 'settings.';
|
|
@@ -523,33 +615,54 @@ export function hostPostureRefusalFromError(err, sentRequest) {
|
|
|
523
615
|
return null;
|
|
524
616
|
}
|
|
525
617
|
}
|
|
526
|
-
const HOST_POSTURE_NOT_LOCAL = '
|
|
527
|
-
const HOST_POSTURE_WHOLE_ENV =
|
|
528
|
-
|
|
529
|
-
const
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const HOST_POSTURE_UNATTRIBUTED = "The engine refused this request before anything ran: this deployment does not accept a setting in it that only a single-user deployment may use; the engine's own message names it · " +
|
|
534
|
-
`${HOST_POSTURE_NOT_LOCAL}; send it again without that setting`;
|
|
535
|
-
export function hostPostureRefusalContent(detail) {
|
|
618
|
+
const HOST_POSTURE_NOT_LOCAL = 'notice.wireRefusal.hostPosture.notLocal';
|
|
619
|
+
const HOST_POSTURE_WHOLE_ENV = 'notice.wireRefusal.hostPosture.wholeEnv';
|
|
620
|
+
const HOST_POSTURE_WRITE_FACE = 'notice.wireRefusal.hostPosture.writeFace';
|
|
621
|
+
const HOST_POSTURE_BOTH = 'notice.wireRefusal.hostPosture.both';
|
|
622
|
+
const HOST_POSTURE_UNATTRIBUTED = 'notice.wireRefusal.hostPosture.unattributed';
|
|
623
|
+
export function hostPostureRefusalContent(detail, lang) {
|
|
624
|
+
const say = (key) => renderMessage(msg(key, { notLocal: msg(HOST_POSTURE_NOT_LOCAL) }), lang);
|
|
536
625
|
try {
|
|
537
626
|
const env = readProp(detail, 'askedWholeEnvironment') === true;
|
|
538
627
|
const write = readProp(detail, 'askedOpenWriteFace') === true;
|
|
539
628
|
if (env && write)
|
|
540
|
-
return HOST_POSTURE_BOTH;
|
|
629
|
+
return say(HOST_POSTURE_BOTH);
|
|
541
630
|
if (env)
|
|
542
|
-
return HOST_POSTURE_WHOLE_ENV;
|
|
631
|
+
return say(HOST_POSTURE_WHOLE_ENV);
|
|
543
632
|
if (write)
|
|
544
|
-
return HOST_POSTURE_WRITE_FACE;
|
|
545
|
-
return HOST_POSTURE_UNATTRIBUTED;
|
|
633
|
+
return say(HOST_POSTURE_WRITE_FACE);
|
|
634
|
+
return say(HOST_POSTURE_UNATTRIBUTED);
|
|
546
635
|
}
|
|
547
636
|
catch {
|
|
548
|
-
return HOST_POSTURE_UNATTRIBUTED;
|
|
637
|
+
return say(HOST_POSTURE_UNATTRIBUTED);
|
|
549
638
|
}
|
|
550
639
|
}
|
|
551
640
|
const HOOK_MATCHER_REFUSAL_FIELD = 'settings.hooks';
|
|
552
641
|
export function hookMatcherRefusalFromError(err) {
|
|
642
|
+
return settingsHooksRefusalFromError(err)?.matcher;
|
|
643
|
+
}
|
|
644
|
+
function hooksRefusalPathOf(detail) {
|
|
645
|
+
try {
|
|
646
|
+
const raw = readOwnDataValue(detail, 'path');
|
|
647
|
+
if (!Array.isArray(raw))
|
|
648
|
+
return undefined;
|
|
649
|
+
const out = [];
|
|
650
|
+
for (let i = 0; i < raw.length; i++) {
|
|
651
|
+
if (!Object.hasOwn(raw, i))
|
|
652
|
+
return undefined;
|
|
653
|
+
const v = raw[i];
|
|
654
|
+
if (typeof v === 'string' || (typeof v === 'number' && Number.isSafeInteger(v) && v >= 0))
|
|
655
|
+
out.push(v);
|
|
656
|
+
else
|
|
657
|
+
return undefined;
|
|
658
|
+
}
|
|
659
|
+
return Object.freeze(out);
|
|
660
|
+
}
|
|
661
|
+
catch {
|
|
662
|
+
return undefined;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
export function settingsHooksRefusalFromError(err) {
|
|
553
666
|
try {
|
|
554
667
|
if (typeof err !== 'object' || err === null)
|
|
555
668
|
return undefined;
|
|
@@ -560,31 +673,43 @@ export function hookMatcherRefusalFromError(err) {
|
|
|
560
673
|
const detail = readErrorRecord(err, 'detail');
|
|
561
674
|
if (detail === undefined)
|
|
562
675
|
return undefined;
|
|
563
|
-
const event = readOwnNonEmptyString(detail, 'event');
|
|
564
|
-
if (event === undefined)
|
|
565
|
-
return undefined;
|
|
566
676
|
const reasonRaw = readOwnDataValue(detail, 'reason');
|
|
677
|
+
const path = hooksRefusalPathOf(detail);
|
|
678
|
+
const withPath = (o) => Object.freeze({ ...o, ...(path !== undefined ? { path } : {}) });
|
|
679
|
+
const family = (reason, rest = {}) => Object.freeze({ reason, ...(path !== undefined ? { path } : {}), ...rest });
|
|
680
|
+
const event = readOwnNonEmptyString(detail, 'event');
|
|
567
681
|
if (reasonRaw === undefined || reasonRaw === 'dead_alias') {
|
|
568
682
|
const alias = readOwnNonEmptyString(detail, 'alias');
|
|
569
683
|
const canonical = readOwnNonEmptyString(detail, 'canonical');
|
|
570
|
-
|
|
684
|
+
const matcher = event !== undefined && alias !== undefined && canonical !== undefined ? withPath({ reason: 'alias_without_canonical', event, alias, canonical }) : undefined;
|
|
685
|
+
if (reasonRaw === undefined && matcher === undefined)
|
|
571
686
|
return undefined;
|
|
572
|
-
return
|
|
687
|
+
return family('dead_alias', matcher !== undefined ? { matcher } : {});
|
|
573
688
|
}
|
|
574
|
-
if (reasonRaw !== '
|
|
575
|
-
return undefined;
|
|
576
|
-
const groupIndex = readOwnDataValue(detail, 'groupIndex');
|
|
577
|
-
if (typeof groupIndex !== 'number' || !Number.isInteger(groupIndex) || groupIndex < 0)
|
|
689
|
+
if (typeof reasonRaw !== 'string' || reasonRaw.length === 0)
|
|
578
690
|
return undefined;
|
|
579
|
-
if (reasonRaw === 'invalid_regex')
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
691
|
+
if (reasonRaw === 'invalid_regex' || reasonRaw === 'over_budget' || reasonRaw === 'budget_exceeded') {
|
|
692
|
+
const groupIndex = readOwnDataValue(detail, 'groupIndex');
|
|
693
|
+
const okIndex = typeof groupIndex === 'number' && Number.isInteger(groupIndex) && groupIndex >= 0;
|
|
694
|
+
let matcher;
|
|
695
|
+
if (event !== undefined && okIndex) {
|
|
696
|
+
if (reasonRaw === 'invalid_regex')
|
|
697
|
+
matcher = withPath({ reason: 'invalid_regex', event, groupIndex });
|
|
698
|
+
else {
|
|
699
|
+
const key = reasonRaw === 'over_budget' ? 'budgetMs' : 'totalMs';
|
|
700
|
+
const ms = readOwnDataValue(detail, key);
|
|
701
|
+
const msBit = typeof ms === 'number' && Number.isFinite(ms) && ms > 0 ? { [key]: ms } : {};
|
|
702
|
+
matcher = reasonRaw === 'over_budget' ? withPath({ reason: 'over_budget', event, groupIndex, ...msBit }) : withPath({ reason: 'budget_exceeded', event, groupIndex, ...msBit });
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
return family(reasonRaw, matcher !== undefined ? { matcher } : {});
|
|
706
|
+
}
|
|
707
|
+
if (reasonRaw === 'over_cap' || reasonRaw === 'too_long') {
|
|
708
|
+
const count = nonNegInt(readOwnDataValue(detail, 'count'));
|
|
709
|
+
const cap = posInt(readOwnDataValue(detail, 'cap'));
|
|
710
|
+
return family(reasonRaw, { ...(count !== undefined ? { count } : {}), ...(cap !== undefined ? { cap } : {}) });
|
|
711
|
+
}
|
|
712
|
+
return family(reasonRaw);
|
|
588
713
|
}
|
|
589
714
|
catch {
|
|
590
715
|
return undefined;
|
|
@@ -593,21 +718,59 @@ export function hookMatcherRefusalFromError(err) {
|
|
|
593
718
|
export function autonomyLaneRefusalFromError(err) {
|
|
594
719
|
return effectiveWireErrorCode(err) === REQUEST_AUTONOMY_LANE_REFUSED ? { code: REQUEST_AUTONOMY_LANE_REFUSED } : null;
|
|
595
720
|
}
|
|
596
|
-
export function autonomyLaneRefusalContent() {
|
|
597
|
-
return ('
|
|
598
|
-
'so nothing was started · Submit the work as a regular run instead, or ask whoever operates the engine to change its autonomy setting');
|
|
721
|
+
export function autonomyLaneRefusalContent(lang) {
|
|
722
|
+
return renderMessage(msg('notice.wireRefusal.autonomyLane'), lang);
|
|
599
723
|
}
|
|
600
724
|
export function userAttachmentRefusalFromError(err) {
|
|
601
|
-
|
|
725
|
+
try {
|
|
726
|
+
if (typeof err !== 'object' || err === null)
|
|
727
|
+
return null;
|
|
728
|
+
let facts;
|
|
729
|
+
const kind = readOwnDataValue(err, 'kind');
|
|
730
|
+
const plane = readOwnDataValue(err, 'plane');
|
|
731
|
+
if (kind === 'failed' && (plane === 'cause' || plane === 'flat')) {
|
|
732
|
+
if (readOwnDataValue(err, 'code') !== USER_ATTACHMENT_INVALID_ERROR_CODE)
|
|
733
|
+
return null;
|
|
734
|
+
const cause = readOwnDataValue(err, 'detail');
|
|
735
|
+
const inner = typeof cause === 'object' && cause !== null && readOwnDataValue(cause, 'kind') === 'coded' ? readOwnDataValue(cause, 'detail') : undefined;
|
|
736
|
+
facts = typeof inner === 'object' && inner !== null && !Array.isArray(inner) ? inner : undefined;
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
if (effectiveWireErrorCode(err) !== USER_ATTACHMENT_INVALID_ERROR_CODE)
|
|
740
|
+
return null;
|
|
741
|
+
facts = readErrorRecord(err, 'detail');
|
|
742
|
+
}
|
|
743
|
+
let index;
|
|
744
|
+
let path;
|
|
745
|
+
try {
|
|
746
|
+
index = facts === undefined ? undefined : readOwnDataValue(facts, 'index');
|
|
747
|
+
}
|
|
748
|
+
catch {
|
|
749
|
+
index = undefined;
|
|
750
|
+
}
|
|
751
|
+
try {
|
|
752
|
+
path = facts === undefined ? undefined : readOwnDataValue(facts, 'path');
|
|
753
|
+
}
|
|
754
|
+
catch {
|
|
755
|
+
path = undefined;
|
|
756
|
+
}
|
|
757
|
+
return {
|
|
758
|
+
code: USER_ATTACHMENT_INVALID_ERROR_CODE,
|
|
759
|
+
retryable: false,
|
|
760
|
+
...(typeof index === 'number' && Number.isSafeInteger(index) && index >= 0 ? { index } : {}),
|
|
761
|
+
...(typeof path === 'string' && path.length > 0 ? { path } : {}),
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
catch {
|
|
765
|
+
return null;
|
|
766
|
+
}
|
|
602
767
|
}
|
|
603
|
-
export function userAttachmentRefusalContent() {
|
|
604
|
-
return (
|
|
605
|
-
'or one of them is in a form it does not accept · Nothing was started and your draft is kept · Remove some attachments or attach smaller parts, then send it again');
|
|
768
|
+
export function userAttachmentRefusalContent(detail) {
|
|
769
|
+
return prepareRefusalNoteOf(USER_ATTACHMENT_INVALID_ERROR_CODE, detail);
|
|
606
770
|
}
|
|
607
771
|
export function userInvokedSkillRefusalFromError(err) {
|
|
608
772
|
return effectiveWireErrorCode(err) === USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE ? { code: USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE, retryable: false } : null;
|
|
609
773
|
}
|
|
610
774
|
export function userInvokedSkillRefusalContent() {
|
|
611
|
-
return (
|
|
612
|
-
'Nothing was started and your draft is kept · Check the skill name, or load that skill, then send it again');
|
|
775
|
+
return prepareRefusalNoteOf(USER_INVOKED_SKILL_UNKNOWN_ERROR_CODE);
|
|
613
776
|
}
|