@sema-agent/client-core 0.111.0 → 0.112.1
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 +98 -0
- package/README.md +16 -7
- package/dist/agentSession/engineSessionBackgroundStop.js +2 -2
- package/dist/checkpointRowVerdict.d.ts +3 -0
- package/dist/checkpointRowVerdict.js +14 -1
- package/dist/consoleCaPin.d.ts +136 -0
- package/dist/consoleCaPin.js +827 -0
- package/dist/decideReceipt.d.ts +2 -1
- package/dist/deviceRebind.js +3 -3
- package/dist/effectiveFacts.d.ts +9 -0
- package/dist/effectiveFacts.js +33 -0
- package/dist/engineAddress.d.ts +1 -0
- package/dist/engineAddress.js +4 -1
- package/dist/engineCredentialRelease.d.ts +54 -0
- package/dist/engineCredentialRelease.js +146 -0
- package/dist/engineErrorCodes.d.ts +1 -0
- package/dist/engineErrorCodes.js +1 -0
- package/dist/engineHealthFacts.d.ts +0 -11
- package/dist/engineHealthFacts.js +0 -21
- package/dist/engineHealthProbeVerdict.d.ts +1 -0
- package/dist/engineHealthProbeVerdict.js +21 -13
- package/dist/engineUnavailable.d.ts +3 -2
- package/dist/engineUnavailable.js +16 -12
- package/dist/engineUrl.js +4 -2
- package/dist/gateFailureCodes.js +2 -2
- package/dist/generated/sdkFactTables.d.ts +1 -0
- package/dist/generated/sdkFactTables.js +13 -0
- package/dist/generated/settingsSchemaFns.d.ts +1 -0
- package/dist/generated/settingsSchemaFns.js +3 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +38 -9
- package/dist/generated/settingsSchemaTables.d.ts +52 -0
- package/dist/generated/settingsSchemaTables.js +18 -0
- package/dist/generated/settingsSchemaTypes.d.ts +23 -13
- package/dist/generated/settingsSchemaUrlShape.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlShape.js +17 -0
- package/dist/hitl/decisionRefusal.d.ts +4 -0
- package/dist/hitl/decisionRefusal.js +12 -2
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +17 -4
- package/dist/hitl/localAllowRedemption.d.ts +9 -6
- package/dist/hitl/localAllowRedemption.js +20 -0
- package/dist/hitl/parkOwnership.js +2 -1
- package/dist/hitl/parkResolver.js +7 -0
- package/dist/hitl/planReviewCard.d.ts +3 -2
- package/dist/hitl/planReviewCard.js +2 -0
- package/dist/hitl/planReviewWire.d.ts +4 -2
- package/dist/hitl/planReviewWire.js +134 -97
- package/dist/hitl/screenDecisionCards.js +3 -2
- package/dist/hitl/sessionPolicyWire.js +2 -2
- package/dist/hitl/standingRows.d.ts +4 -2
- package/dist/hitl/standingRows.js +10 -3
- package/dist/hooksReaderGenerations.js +1 -1
- package/dist/i18n/messages.en.d.ts +165 -0
- package/dist/i18n/messages.en.js +166 -1
- package/dist/i18n/messages.zh.js +177 -1
- package/dist/index.d.ts +30 -5
- package/dist/index.js +15 -2
- package/dist/liveModelCatalog.d.ts +4 -0
- package/dist/liveModelCatalog.js +10 -1
- package/dist/localConfig/documents.d.ts +61 -0
- package/dist/localConfig/documents.js +51 -0
- package/dist/localConfig/kernel.d.ts +149 -0
- package/dist/localConfig/kernel.js +597 -0
- package/dist/localConfig/mcp/edit.d.ts +161 -0
- package/dist/localConfig/mcp/edit.js +846 -0
- package/dist/localConfig/mcp/servers.d.ts +165 -0
- package/dist/localConfig/mcp/servers.js +776 -0
- package/dist/localConfig/mcp/views.d.ts +170 -0
- package/dist/localConfig/mcp/views.js +429 -0
- package/dist/localConfig/modelPool.d.ts +262 -0
- package/dist/localConfig/modelPool.js +1489 -0
- package/dist/localConfig/modelPoolWords.d.ts +13 -0
- package/dist/localConfig/modelPoolWords.js +20 -0
- package/dist/localConfig/receiptShape.d.ts +7 -0
- package/dist/localConfig/receiptShape.js +135 -0
- package/dist/localConfig/settingsWrite.d.ts +127 -0
- package/dist/localConfig/settingsWrite.js +237 -0
- package/dist/localConfig/skills.d.ts +124 -0
- package/dist/localConfig/skills.js +397 -0
- package/dist/localConfig/skillsWords.d.ts +10 -0
- package/dist/localConfig/skillsWords.js +5 -0
- package/dist/mcpProbeWire.js +2 -1
- package/dist/mcpWireCaps.js +1 -1
- package/dist/memoryVerbsWire.js +3 -2
- package/dist/model/onboardJudgement.d.ts +14 -4
- package/dist/model/onboardJudgement.js +91 -139
- package/dist/modelConfigGapNotice.d.ts +20 -0
- package/dist/modelConfigGapNotice.js +102 -0
- package/dist/modsKernelIdentity.js +2 -47
- package/dist/notifications.js +14 -12
- package/dist/ownKey.d.ts +1 -0
- package/dist/ownKey.js +40 -8
- package/dist/permissionsDeclaration.d.ts +2 -1
- package/dist/permissionsDeclaration.js +31 -17
- package/dist/planReviewOutcomeCause.d.ts +2 -0
- package/dist/planReviewOutcomeCause.js +12 -0
- package/dist/promptBlockedCopy.js +2 -2
- package/dist/resumeRefusalCopy.d.ts +3 -1
- package/dist/resumeRefusalCopy.js +12 -4
- package/dist/runLedgerSnapshot.js +3 -3
- package/dist/runPermissionModeSwitch.js +2 -3
- package/dist/seatContract.d.ts +154 -4
- package/dist/seatContract.js +228 -2
- package/dist/sessionIdSegment.d.ts +1 -0
- package/dist/sessionIdSegment.js +4 -1
- package/dist/sessionMemoryErase.js +2 -1
- package/dist/sha256Bytes.d.ts +1 -0
- package/dist/sha256Bytes.js +46 -0
- package/dist/skillOverrideChain.d.ts +83 -0
- package/dist/skillOverrideChain.js +378 -0
- package/dist/skillsWireCaps.d.ts +3 -0
- package/dist/skillsWireCaps.js +16 -1
- package/dist/turnFailurePresentation.js +4 -10
- package/docs/INTEGRATION-CLIENTS.md +680 -14
- package/package.json +3 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { inferFamily } from './providerPresets.js';
|
|
1
2
|
import { ONBOARD_REFUSALS } from '../seatContract.js';
|
|
2
|
-
import { joinRequestUrl, routeKeyOf } from '../coreValuePorts.js';
|
|
3
|
-
import {
|
|
3
|
+
import { adjudicateModelRoute, joinRequestUrl, routeKeyOf } from '../coreValuePorts.js';
|
|
4
|
+
import { settleWithinDeadline } from '../abortableSleep.js';
|
|
5
|
+
import { probeModelLiveness, probeVerdictNotice } from '../modelCapabilityProbe.js';
|
|
4
6
|
import { ownDataField } from '../ownKey.js';
|
|
5
7
|
import { msg, renderMessage } from '../i18n/translate.js';
|
|
6
8
|
const field = (v, key) => {
|
|
@@ -57,6 +59,9 @@ function safeDecode(t) {
|
|
|
57
59
|
return t;
|
|
58
60
|
}
|
|
59
61
|
}
|
|
62
|
+
export function onboardKeyCarriedBy(text, key) {
|
|
63
|
+
return carriesKey(text, key);
|
|
64
|
+
}
|
|
60
65
|
function carriesKey(text, key) {
|
|
61
66
|
if (key === undefined || key === '')
|
|
62
67
|
return false;
|
|
@@ -69,6 +74,9 @@ function carriesKey(text, key) {
|
|
|
69
74
|
function looksLikeSecret(val) {
|
|
70
75
|
return /^(sk|ak|pk|rk)[-_]/i.test(val) || (val.length >= 20 && /[A-Za-z]/.test(val) && /[0-9]/.test(val) && /^[A-Za-z0-9._~+/=-]+$/.test(val));
|
|
71
76
|
}
|
|
77
|
+
export function onboardRedactKey(text, key) {
|
|
78
|
+
return redact(text, key);
|
|
79
|
+
}
|
|
72
80
|
function redact(text, key) {
|
|
73
81
|
if (key === undefined || key === '')
|
|
74
82
|
return text;
|
|
@@ -197,7 +205,71 @@ export async function probeModelEndpoint(target, deps) {
|
|
|
197
205
|
});
|
|
198
206
|
if (v.verdict === 'unreachable' && seen.redirected !== undefined)
|
|
199
207
|
return out('unreachable', seen.redirected);
|
|
200
|
-
|
|
208
|
+
const firstOutputMs = v.verdict === 'ok' && typeof v.waitedMs === 'number' && Number.isFinite(v.waitedMs) && v.waitedMs >= 0 ? Math.round(v.waitedMs) : undefined;
|
|
209
|
+
const r = out(v.verdict, probeDetailOf(v));
|
|
210
|
+
return firstOutputMs === undefined ? r : Object.freeze({ ...r, firstOutputMs });
|
|
211
|
+
}
|
|
212
|
+
const DISCOVERY_MAX = 512;
|
|
213
|
+
export async function discoverEndpointModels(target, deps) {
|
|
214
|
+
const apiKey = field(target, 'apiKey');
|
|
215
|
+
const key = typeof apiKey === 'string' && apiKey !== '' ? apiKey : undefined;
|
|
216
|
+
const fail = (verdict, detail) => Object.freeze({ ok: false, verdict, detail: capText(redact(detail, key?.trim() || undefined)) });
|
|
217
|
+
const baseUrl = field(target, 'baseUrl');
|
|
218
|
+
const api = field(target, 'api');
|
|
219
|
+
const auth = field(target, 'auth');
|
|
220
|
+
if (typeof baseUrl !== 'string' || (api !== 'anthropic-messages' && api !== 'openai-completions'))
|
|
221
|
+
return fail('other', en('onboard.probe.incomplete'));
|
|
222
|
+
const f = (field(deps, 'fetchImpl') ?? globalThis.fetch);
|
|
223
|
+
if (typeof f !== 'function')
|
|
224
|
+
return fail('unreachable', en('onboard.probe.noFetch'));
|
|
225
|
+
const root = baseUrl.trim();
|
|
226
|
+
let url;
|
|
227
|
+
try {
|
|
228
|
+
url = joinRequestUrl(root, 'models');
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return fail('other', en('onboard.baseUrl.invalid'));
|
|
232
|
+
}
|
|
233
|
+
if (url === undefined)
|
|
234
|
+
return fail('other', en('onboard.probe.judgeAbsent'));
|
|
235
|
+
const t = field(deps, 'timeoutMs');
|
|
236
|
+
const budget = typeof t === 'number' && Number.isFinite(t) && t > 0 ? t : 10_000;
|
|
237
|
+
const headers = { ...(api === 'anthropic-messages' ? { 'anthropic-version': '2023-06-01' } : {}), ...keyHeaders(api, key, auth === 'bearer' || auth === 'x-api-key' ? auth : undefined) };
|
|
238
|
+
const settled = await settleWithinDeadline(budget, async (signal) => {
|
|
239
|
+
const res = await f(url, { method: 'GET', headers, redirect: 'manual', signal });
|
|
240
|
+
const redirected = redirectRefusal(res, url, key);
|
|
241
|
+
if (redirected !== undefined)
|
|
242
|
+
return fail('unreachable', redirected);
|
|
243
|
+
if (res.status === 401 || res.status === 403)
|
|
244
|
+
return fail('auth', en('model.pool.discover.status', { status: res.status }));
|
|
245
|
+
if (res.status < 200 || res.status >= 300)
|
|
246
|
+
return fail('other', en('model.pool.discover.status', { status: res.status }));
|
|
247
|
+
let body;
|
|
248
|
+
try {
|
|
249
|
+
body = JSON.parse(await res.text());
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return fail('shape', en('model.pool.discover.notList'));
|
|
253
|
+
}
|
|
254
|
+
const data = field(body, 'data');
|
|
255
|
+
if (!Array.isArray(data))
|
|
256
|
+
return fail('shape', en('model.pool.discover.notList'));
|
|
257
|
+
const out = [];
|
|
258
|
+
for (let i = 0; i < data.length && out.length < DISCOVERY_MAX; i++) {
|
|
259
|
+
const id = field(field(data, String(i)), 'id');
|
|
260
|
+
if (typeof id !== 'string' || id.trim() === '' || id.length > 512 || carriesKey(id, key) || out.some((c) => c.id === id))
|
|
261
|
+
continue;
|
|
262
|
+
const fam = inferFamily(id);
|
|
263
|
+
const exact = fam !== undefined && fam.perModelCap !== undefined;
|
|
264
|
+
out.push(Object.freeze({ id, ...(exact ? { contextWindow: fam.contextWindow, maxTokens: fam.maxTokens } : {}) }));
|
|
265
|
+
}
|
|
266
|
+
return Object.freeze({ ok: true, candidates: Object.freeze(out) });
|
|
267
|
+
});
|
|
268
|
+
if (settled.kind === 'deadline')
|
|
269
|
+
return fail('unreachable', en('model.pool.discover.timeout'));
|
|
270
|
+
if (settled.kind === 'error')
|
|
271
|
+
return fail('unreachable', en('model.pool.discover.unreachable', { cause: settled.detail }));
|
|
272
|
+
return settled.value;
|
|
201
273
|
}
|
|
202
274
|
export function onboardWriteVerdict(verdict, acceptUnverified) {
|
|
203
275
|
if (verdict === 'ok')
|
|
@@ -224,6 +296,9 @@ export function poolEntryNameOf(modelId, channel, taken) {
|
|
|
224
296
|
candidate = `${name}-${channel}-${i}`;
|
|
225
297
|
return candidate;
|
|
226
298
|
}
|
|
299
|
+
export function onboardEntryCredentialIssue(m, env) {
|
|
300
|
+
return entryCredentialIssue(m, env);
|
|
301
|
+
}
|
|
227
302
|
function entryCredentialIssue(m, env) {
|
|
228
303
|
const name = typeof m['name'] === 'string' ? m['name'] : '?';
|
|
229
304
|
if (m['sealedApiKey'] !== undefined && m['sealedApiKey'] !== null)
|
|
@@ -239,6 +314,19 @@ function entryCredentialIssue(m, env) {
|
|
|
239
314
|
const api = typeof m['api'] === 'string' ? m['api'] : 'openai-completions';
|
|
240
315
|
const rootKey = api === 'anthropic-messages' ? 'ANTHROPIC_BASE_URL' : 'MODEL_GATEWAY_BASEURL';
|
|
241
316
|
const root = env[rootKey];
|
|
317
|
+
if (api !== 'anthropic-messages' && (typeof root !== 'string' || root.trim() === '')) {
|
|
318
|
+
let keyless;
|
|
319
|
+
try {
|
|
320
|
+
keyless = adjudicateModelRoute({ id: typeof m['id'] === 'string' ? m['id'] : name, baseUrl: base }, { source: 'absent' }, {});
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
keyless = undefined;
|
|
324
|
+
}
|
|
325
|
+
if (keyless === undefined)
|
|
326
|
+
return en('onboard.catalog.judgeAbsent', { name });
|
|
327
|
+
if (keyless.ok)
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
242
330
|
let paired;
|
|
243
331
|
try {
|
|
244
332
|
const a = routeKeyOf(base);
|
|
@@ -262,142 +350,6 @@ function entryCredentialIssue(m, env) {
|
|
|
262
350
|
const rootText = typeof root === 'string' && root !== '' ? `${rootKey} (${hostOf(root)})` : en('onboard.catalog.noRoot', { rootKey });
|
|
263
351
|
return en('onboard.catalog.unpaired', { name, host: hostOf(base), root: rootText });
|
|
264
352
|
}
|
|
265
|
-
function migrateLegacyDefaultKey(doc) {
|
|
266
|
-
const legacy = doc['default'];
|
|
267
|
-
if (typeof legacy !== 'string' || legacy.length === 0)
|
|
268
|
-
return doc;
|
|
269
|
-
const { default: _legacy, ...rest } = doc;
|
|
270
|
-
void _legacy;
|
|
271
|
-
const prevRoles = rest['roles'];
|
|
272
|
-
const roles = prevRoles !== null && typeof prevRoles === 'object' && !Array.isArray(prevRoles) ? { ...prevRoles } : {};
|
|
273
|
-
roles['default'] = { model: legacy };
|
|
274
|
-
return { ...rest, roles };
|
|
275
|
-
}
|
|
276
|
-
export function onboardWritePlan(input) {
|
|
277
|
-
const rawKey = field(field(input, 'entry'), 'apiKey');
|
|
278
|
-
const planKey = typeof rawKey === 'string' && rawKey !== '' ? rawKey : undefined;
|
|
279
|
-
const say = (text) => redact(text, planKey);
|
|
280
|
-
const refuse = (refusal, detail) => Object.freeze({ ok: false, refusal, detail: say(detail) });
|
|
281
|
-
try {
|
|
282
|
-
if (input.engineMode === 'cloud')
|
|
283
|
-
return refuse('engine_is_remote', en('onboard.refusal.engineIsRemote'));
|
|
284
|
-
const rawDoc = input.modelsDoc;
|
|
285
|
-
if (rawDoc !== undefined && (rawDoc === null || typeof rawDoc !== 'object' || Array.isArray(rawDoc)))
|
|
286
|
-
return refuse('catalog_unreadable', en('onboard.plan.notObject'));
|
|
287
|
-
const doc = migrateLegacyDefaultKey(rawDoc === undefined ? {} : { ...rawDoc });
|
|
288
|
-
const rawModels = doc['models'];
|
|
289
|
-
if (rawModels !== undefined && !Array.isArray(rawModels))
|
|
290
|
-
return refuse('catalog_unreadable', en('onboard.plan.modelsNotList'));
|
|
291
|
-
const list = Array.isArray(rawModels) ? rawModels : [];
|
|
292
|
-
if (list.some((m) => m === null || typeof m !== 'object' || Array.isArray(m)))
|
|
293
|
-
return refuse('catalog_unreadable', en('onboard.plan.modelsItemNotObject'));
|
|
294
|
-
const models = list.map((m) => ({ ...m }));
|
|
295
|
-
const envModel = [input.effectiveEnv?.['MODEL_ID'], input.effectiveEnv?.['MODEL_CHEAP_ID']].find((v) => typeof v === 'string' && v.trim() !== '');
|
|
296
|
-
if (envModel !== undefined && !models.some((m) => m['enabled'] !== false)) {
|
|
297
|
-
return refuse('env_catalog_present', en('onboard.plan.envCatalogPresent', { model: envModel }));
|
|
298
|
-
}
|
|
299
|
-
const rawEnv = input.settingsEnv;
|
|
300
|
-
if (rawEnv !== undefined && (rawEnv === null || typeof rawEnv !== 'object' || Array.isArray(rawEnv)))
|
|
301
|
-
return refuse('catalog_unreadable', en('onboard.plan.envNotObject'));
|
|
302
|
-
const prevEnv = rawEnv === undefined ? {} : { ...rawEnv };
|
|
303
|
-
const e = input.entry;
|
|
304
|
-
const isShellSlot = (ref) => typeof ref === 'string' && ref.startsWith(KEY_SLOT_PREFIX) && typeof prevEnv[ref] === 'string';
|
|
305
|
-
const targetKey = routeKeyOf(e.baseUrl);
|
|
306
|
-
if (targetKey === undefined)
|
|
307
|
-
return refuse('credential_unpaired', en('onboard.catalog.judgeAbsent', { name: e.modelId }));
|
|
308
|
-
const sameTarget = (m) => m['id'] === e.modelId && m['api'] === e.api && typeof m['baseUrl'] === 'string' && routeKeyOf(m['baseUrl']) === targetKey;
|
|
309
|
-
const existingIdx = models.findIndex((m) => sameTarget(m) && m['enabled'] !== false && m['sealedApiKey'] === undefined && (m['apiKeyEnv'] === undefined || isShellSlot(m['apiKeyEnv'])));
|
|
310
|
-
const taken = new Set(models.map((m) => (typeof m['name'] === 'string' ? m['name'] : '')).filter((n) => n !== ''));
|
|
311
|
-
const name = existingIdx >= 0 ? String(models[existingIdx]['name']) : poolEntryNameOf(e.modelId, e.channel, taken);
|
|
312
|
-
const existingRef = existingIdx >= 0 ? models[existingIdx]['apiKeyEnv'] : undefined;
|
|
313
|
-
const sharedByOther = typeof existingRef === 'string' &&
|
|
314
|
-
models.some((m, i) => i !== existingIdx && typeof m['apiKeyEnv'] === 'string' && m['apiKeyEnv'].toUpperCase() === existingRef.toUpperCase());
|
|
315
|
-
let keyEnv;
|
|
316
|
-
if (isShellSlot(existingRef) && !sharedByOther) {
|
|
317
|
-
keyEnv = existingRef;
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
const used = new Set();
|
|
321
|
-
for (const m of models)
|
|
322
|
-
if (typeof m['apiKeyEnv'] === 'string')
|
|
323
|
-
used.add(m['apiKeyEnv'].toUpperCase());
|
|
324
|
-
for (const k of Object.keys(prevEnv))
|
|
325
|
-
used.add(k.toUpperCase());
|
|
326
|
-
for (const [k, v] of Object.entries(input.effectiveEnv ?? {}))
|
|
327
|
-
if (typeof v === 'string')
|
|
328
|
-
used.add(k.toUpperCase());
|
|
329
|
-
const baseSlot = keyEnvNameForEntry(name);
|
|
330
|
-
keyEnv = baseSlot;
|
|
331
|
-
for (let i = 2; used.has(keyEnv.toUpperCase()); i++)
|
|
332
|
-
keyEnv = `${baseSlot}_${i}`;
|
|
333
|
-
}
|
|
334
|
-
if (carriesKey(name, e.apiKey) || carriesKey(keyEnv, e.apiKey))
|
|
335
|
-
return refuse('input', en('onboard.input.keyInFields'));
|
|
336
|
-
const base = existingIdx >= 0 ? models[existingIdx] : {};
|
|
337
|
-
let entry = {
|
|
338
|
-
...base,
|
|
339
|
-
name,
|
|
340
|
-
id: e.modelId,
|
|
341
|
-
provider: e.api === 'anthropic-messages' ? 'anthropic' : 'gateway',
|
|
342
|
-
api: e.api,
|
|
343
|
-
baseUrl: e.baseUrl,
|
|
344
|
-
contextWindow: typeof base['contextWindow'] === 'number' ? base['contextWindow'] : e.contextWindow,
|
|
345
|
-
maxTokens: typeof base['maxTokens'] === 'number' ? base['maxTokens'] : e.maxTokens,
|
|
346
|
-
apiKeyEnv: keyEnv,
|
|
347
|
-
semaChannel: typeof base['semaChannel'] === 'string' ? base['semaChannel'] : e.channel,
|
|
348
|
-
semaLabel: typeof base['semaLabel'] === 'string' ? base['semaLabel'] : e.providerName,
|
|
349
|
-
semaProbe: input.probe.verdict,
|
|
350
|
-
semaProbeAt: input.now,
|
|
351
|
-
};
|
|
352
|
-
if (input.thinking !== undefined) {
|
|
353
|
-
const probed = applyProbeToEntry({ ...(typeof entry['reasoning'] === 'boolean' ? { reasoning: entry['reasoning'] } : {}), ...(entry['compat'] !== undefined ? { compat: entry['compat'] } : {}) }, input.thinking);
|
|
354
|
-
const next = { ...entry };
|
|
355
|
-
if (typeof probed.reasoning === 'boolean')
|
|
356
|
-
next['reasoning'] = probed.reasoning;
|
|
357
|
-
if (probed.compat !== undefined)
|
|
358
|
-
next['compat'] = probed.compat;
|
|
359
|
-
else
|
|
360
|
-
delete next['compat'];
|
|
361
|
-
entry = next;
|
|
362
|
-
}
|
|
363
|
-
const envView = { ...input.effectiveEnv, [keyEnv]: e.apiKey };
|
|
364
|
-
const issue = entryCredentialIssue(entry, envView);
|
|
365
|
-
if (issue !== undefined)
|
|
366
|
-
return refuse('credential_unpaired', issue);
|
|
367
|
-
if (existingIdx >= 0)
|
|
368
|
-
models[existingIdx] = entry;
|
|
369
|
-
else
|
|
370
|
-
models.push(entry);
|
|
371
|
-
const nextDoc = { ...doc, models };
|
|
372
|
-
if (input.makeDefault) {
|
|
373
|
-
const prevRoles = doc['roles'];
|
|
374
|
-
const roles = prevRoles !== null && typeof prevRoles === 'object' && !Array.isArray(prevRoles) ? { ...prevRoles } : {};
|
|
375
|
-
roles['default'] = { model: name };
|
|
376
|
-
nextDoc['roles'] = roles;
|
|
377
|
-
}
|
|
378
|
-
const otherIssues = [];
|
|
379
|
-
for (const m of models) {
|
|
380
|
-
if (m['enabled'] === false || m['name'] === name)
|
|
381
|
-
continue;
|
|
382
|
-
const other = entryCredentialIssue(m, envView);
|
|
383
|
-
if (other !== undefined) {
|
|
384
|
-
otherIssues.push(Object.freeze({ name: typeof m['name'] === 'string' ? m['name'] : '?', modelId: typeof m['id'] === 'string' ? m['id'] : '?', issue: say(other) }));
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
return Object.freeze({
|
|
388
|
-
ok: true,
|
|
389
|
-
entryName: name,
|
|
390
|
-
keyEnv,
|
|
391
|
-
updatedExisting: existingIdx >= 0,
|
|
392
|
-
nextModelsDoc: nextDoc,
|
|
393
|
-
nextSettingsEnv: { ...prevEnv, [keyEnv]: e.apiKey },
|
|
394
|
-
otherIssues: Object.freeze(otherIssues),
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
catch {
|
|
398
|
-
return refuse('input', en('onboard.refusal.input'));
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
353
|
const REFUSAL_KEYS = {
|
|
402
354
|
input: 'onboard.refusal.input',
|
|
403
355
|
probe_failed: 'onboard.refusal.probeFailed',
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
2
|
+
type ModelConfigPartTuple = readonly ['model', 'gateway-url', 'api-key'];
|
|
3
|
+
export type ModelConfigPart = ModelConfigPartTuple[number];
|
|
4
|
+
export type ModelConfigKeyChannel = 'anthropic';
|
|
5
|
+
export interface ModelConfigGap {
|
|
6
|
+
readonly parts: readonly ModelConfigPart[];
|
|
7
|
+
readonly keyChannel?: ModelConfigKeyChannel;
|
|
8
|
+
readonly catalogEntries?: number;
|
|
9
|
+
}
|
|
10
|
+
export type ModelConfigGapNotice = {
|
|
11
|
+
readonly kind: 'gap';
|
|
12
|
+
readonly head: string;
|
|
13
|
+
readonly detail: string;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'none';
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: 'malformed';
|
|
18
|
+
};
|
|
19
|
+
export declare function modelConfigGapNotice(missing: ModelConfigGap, lang?: UiLanguage): ModelConfigGapNotice;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
2
|
+
import { guardedRead, ownDataField } from './ownKey.js';
|
|
3
|
+
function partOrder() {
|
|
4
|
+
return ['model', 'gateway-url', 'api-key'];
|
|
5
|
+
}
|
|
6
|
+
function isPart(v) {
|
|
7
|
+
return v === 'model' || v === 'gateway-url' || v === 'api-key';
|
|
8
|
+
}
|
|
9
|
+
const MALFORMED = Object.freeze({ kind: 'malformed' });
|
|
10
|
+
const NONE = Object.freeze({ kind: 'none' });
|
|
11
|
+
function readGap(missing) {
|
|
12
|
+
try {
|
|
13
|
+
if (missing === null || typeof missing !== 'object' || Array.isArray(missing))
|
|
14
|
+
return undefined;
|
|
15
|
+
const raw = ownDataField(missing, 'parts');
|
|
16
|
+
if (!Array.isArray(raw))
|
|
17
|
+
return undefined;
|
|
18
|
+
const order = partOrder();
|
|
19
|
+
const length = ownDataField(raw, 'length');
|
|
20
|
+
if (typeof length !== 'number' || !Number.isSafeInteger(length) || length < 0 || length > order.length)
|
|
21
|
+
return undefined;
|
|
22
|
+
const present = new Set();
|
|
23
|
+
for (let i = 0; i < length; i++) {
|
|
24
|
+
const word = ownDataField(raw, String(i));
|
|
25
|
+
if (!isPart(word) || present.has(word))
|
|
26
|
+
return undefined;
|
|
27
|
+
present.add(word);
|
|
28
|
+
}
|
|
29
|
+
const parts = order.filter((p) => present.has(p));
|
|
30
|
+
const channel = guardedRead(() => ownDataField(missing, 'keyChannel'));
|
|
31
|
+
const count = guardedRead(() => ownDataField(missing, 'catalogEntries'));
|
|
32
|
+
return {
|
|
33
|
+
parts,
|
|
34
|
+
anthropicKey: channel === 'anthropic' && present.has('api-key'),
|
|
35
|
+
entries: typeof count === 'number' && Number.isSafeInteger(count) && count >= 1 ? count : undefined,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const HEAD_KEYS = Object.freeze({
|
|
43
|
+
model: 'model.configGap.head.model',
|
|
44
|
+
gatewayUrl: 'model.configGap.head.gatewayUrl',
|
|
45
|
+
apiKey: 'model.configGap.head.apiKey',
|
|
46
|
+
anthropicKey: 'model.configGap.head.anthropicKey',
|
|
47
|
+
incomplete: 'model.configGap.head.incomplete',
|
|
48
|
+
});
|
|
49
|
+
function headKeyOf(r) {
|
|
50
|
+
if (r.parts.includes('model'))
|
|
51
|
+
return HEAD_KEYS.model;
|
|
52
|
+
if (r.parts.includes('gateway-url'))
|
|
53
|
+
return r.parts.includes('api-key') ? HEAD_KEYS.incomplete : HEAD_KEYS.gatewayUrl;
|
|
54
|
+
return r.anthropicKey ? HEAD_KEYS.anthropicKey : HEAD_KEYS.apiKey;
|
|
55
|
+
}
|
|
56
|
+
function itemRef(part, anthropicKey) {
|
|
57
|
+
switch (part) {
|
|
58
|
+
case 'model':
|
|
59
|
+
return msg('model.configGap.item.model');
|
|
60
|
+
case 'gateway-url':
|
|
61
|
+
return msg('model.configGap.item.gatewayUrl');
|
|
62
|
+
case 'api-key':
|
|
63
|
+
return msg(anthropicKey ? 'model.configGap.item.anthropicKey' : 'model.configGap.item.apiKey');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function leadRef(first, second, third, anthropicKey) {
|
|
67
|
+
const a = itemRef(first, anthropicKey);
|
|
68
|
+
if (second === undefined)
|
|
69
|
+
return msg('model.configGap.lead.one', { a });
|
|
70
|
+
const b = itemRef(second, anthropicKey);
|
|
71
|
+
if (third === undefined)
|
|
72
|
+
return msg('model.configGap.lead.two', { a, b });
|
|
73
|
+
return msg('model.configGap.lead.three', { a, b, c: itemRef(third, anthropicKey) });
|
|
74
|
+
}
|
|
75
|
+
function reasonRef(r) {
|
|
76
|
+
if (r.parts.includes('model'))
|
|
77
|
+
return msg('model.configGap.reason.noModel');
|
|
78
|
+
const n = r.entries;
|
|
79
|
+
if (n === undefined)
|
|
80
|
+
return undefined;
|
|
81
|
+
if (r.anthropicKey)
|
|
82
|
+
return n === 1 ? msg('model.configGap.reason.anthropicCatalog.one') : msg('model.configGap.reason.anthropicCatalog.other', { count: n });
|
|
83
|
+
if (r.parts.includes('gateway-url'))
|
|
84
|
+
return n === 1 ? msg('model.configGap.reason.gatewayCatalog.one') : msg('model.configGap.reason.gatewayCatalog.other', { count: n });
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
export function modelConfigGapNotice(missing, lang) {
|
|
88
|
+
const r = readGap(missing);
|
|
89
|
+
if (r === undefined)
|
|
90
|
+
return MALFORMED;
|
|
91
|
+
const [first, second, third] = r.parts;
|
|
92
|
+
if (first === undefined)
|
|
93
|
+
return NONE;
|
|
94
|
+
const lead = leadRef(first, second, third, r.anthropicKey);
|
|
95
|
+
const reason = reasonRef(r);
|
|
96
|
+
const detail = reason === undefined ? lead : msg('model.configGap.detail.withReason', { missing: lead, reason });
|
|
97
|
+
return Object.freeze({
|
|
98
|
+
kind: 'gap',
|
|
99
|
+
head: renderMessage(msg(headKeyOf(r)), lang),
|
|
100
|
+
detail: renderMessage(detail, lang),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KERNEL_CONTRACT_VERSION, MOD_EVENT_TABLE } from '@sema-agent/mods-kernel';
|
|
2
|
+
import { sha256BytesHex } from './sha256Bytes.js';
|
|
2
3
|
const MAX_DEPTH = 16;
|
|
3
4
|
const MAX_NODES = 100_000;
|
|
4
5
|
function canonical(v, depth, budget) {
|
|
@@ -35,52 +36,6 @@ function canonical(v, depth, budget) {
|
|
|
35
36
|
}
|
|
36
37
|
throw new TypeError('modsKernelIdentity: the event table holds a value that is not plain data');
|
|
37
38
|
}
|
|
38
|
-
function sha256Hex(msg) {
|
|
39
|
-
const k = [
|
|
40
|
-
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
41
|
-
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
42
|
-
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
43
|
-
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
44
|
-
];
|
|
45
|
-
const h = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
|
|
46
|
-
const len = msg.length;
|
|
47
|
-
const padded = new Uint8Array(((len + 8) >>> 6) * 64 + 64);
|
|
48
|
-
padded.set(msg);
|
|
49
|
-
padded[len] = 0x80;
|
|
50
|
-
const view = new DataView(padded.buffer);
|
|
51
|
-
view.setUint32(padded.length - 8, Math.floor(len / 0x20000000));
|
|
52
|
-
view.setUint32(padded.length - 4, (len << 3) >>> 0);
|
|
53
|
-
const w = new Array(64).fill(0);
|
|
54
|
-
const rotr = (x, n) => (x >>> n) | (x << (32 - n));
|
|
55
|
-
for (let off = 0; off < padded.length; off += 64) {
|
|
56
|
-
for (let t = 0; t < 16; t++)
|
|
57
|
-
w[t] = view.getUint32(off + t * 4);
|
|
58
|
-
for (let t = 16; t < 64; t++) {
|
|
59
|
-
const x = w[t - 15] ?? 0;
|
|
60
|
-
const y = w[t - 2] ?? 0;
|
|
61
|
-
const s0 = rotr(x, 7) ^ rotr(x, 18) ^ (x >>> 3);
|
|
62
|
-
const s1 = rotr(y, 17) ^ rotr(y, 19) ^ (y >>> 10);
|
|
63
|
-
w[t] = ((w[t - 16] ?? 0) + s0 + (w[t - 7] ?? 0) + s1) | 0;
|
|
64
|
-
}
|
|
65
|
-
let [a, b, c, d, e, f, g, hh] = h;
|
|
66
|
-
for (let t = 0; t < 64; t++) {
|
|
67
|
-
const t1 = (hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ (~e & g)) + (k[t] ?? 0) + (w[t] ?? 0)) | 0;
|
|
68
|
-
const t2 = ((rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) | 0;
|
|
69
|
-
hh = g;
|
|
70
|
-
g = f;
|
|
71
|
-
f = e;
|
|
72
|
-
e = (d + t1) | 0;
|
|
73
|
-
d = c;
|
|
74
|
-
c = b;
|
|
75
|
-
b = a;
|
|
76
|
-
a = (t1 + t2) | 0;
|
|
77
|
-
}
|
|
78
|
-
const next = [a, b, c, d, e, f, g, hh];
|
|
79
|
-
for (let i = 0; i < 8; i++)
|
|
80
|
-
h[i] = ((h[i] ?? 0) + (next[i] ?? 0)) | 0;
|
|
81
|
-
}
|
|
82
|
-
return h.map((x) => (x >>> 0).toString(16).padStart(8, '0')).join('');
|
|
83
|
-
}
|
|
84
39
|
export function modsKernelIdentity(kernel = { KERNEL_CONTRACT_VERSION, MOD_EVENT_TABLE }) {
|
|
85
40
|
try {
|
|
86
41
|
if (typeof kernel !== 'object' || kernel === null)
|
|
@@ -93,7 +48,7 @@ export function modsKernelIdentity(kernel = { KERNEL_CONTRACT_VERSION, MOD_EVENT
|
|
|
93
48
|
if (typeof table !== 'object' || table === null || Array.isArray(table)) {
|
|
94
49
|
throw new TypeError('modsKernelIdentity: the source carries no readable event table');
|
|
95
50
|
}
|
|
96
|
-
return { contractVersion, tableDigest:
|
|
51
|
+
return { contractVersion, tableDigest: sha256BytesHex(new TextEncoder().encode(canonical(table, 0, { nodes: 0 }))) };
|
|
97
52
|
}
|
|
98
53
|
catch (e) {
|
|
99
54
|
if (e instanceof TypeError)
|
package/dist/notifications.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hostEnv } from './hostEnv.js';
|
|
2
|
+
import { planReviewOutcomeCauseOf } from './planReviewOutcomeCause.js';
|
|
2
3
|
import { unrefTimer } from './unrefTimer.js';
|
|
3
4
|
import { clearEnginePanelTaskResidentByWire, publishEngineAgentPanelEvent, } from './engineAgentPanelStore.js';
|
|
4
5
|
import { panelEndFact } from './panelReduce.js';
|
|
@@ -432,21 +433,22 @@ export function enqueuePlanReviewOutcome(value, meta) {
|
|
|
432
433
|
priority: 'later',
|
|
433
434
|
isMeta: true,
|
|
434
435
|
workload: 'plan-review',
|
|
435
|
-
...(meta !== undefined
|
|
436
|
-
? {
|
|
437
|
-
_sema_planReviewOutcome: Object.freeze({
|
|
438
|
-
taskId: meta.taskId,
|
|
439
|
-
dispatchNo: meta.dispatchNo,
|
|
440
|
-
decision: meta.decision,
|
|
441
|
-
effect: meta.effect,
|
|
442
|
-
...(meta.effect === 'still_parked' && meta.cause === 'stored_form_unsupported' ? { cause: meta.cause } : {}),
|
|
443
|
-
...(questionId !== undefined ? { questionId } : {}),
|
|
444
|
-
}),
|
|
445
|
-
}
|
|
446
|
-
: {}),
|
|
436
|
+
...(meta !== undefined ? { _sema_planReviewOutcome: planReviewOutcomeRefrozen(meta, questionId) } : {}),
|
|
447
437
|
});
|
|
448
438
|
return true;
|
|
449
439
|
}
|
|
440
|
+
function planReviewOutcomeRefrozen(meta, questionId) {
|
|
441
|
+
const effect = meta.effect;
|
|
442
|
+
const cause = planReviewOutcomeCauseOf(effect, meta.cause);
|
|
443
|
+
return Object.freeze({
|
|
444
|
+
taskId: meta.taskId,
|
|
445
|
+
dispatchNo: meta.dispatchNo,
|
|
446
|
+
decision: meta.decision,
|
|
447
|
+
effect,
|
|
448
|
+
...(cause !== undefined ? { cause } : {}),
|
|
449
|
+
...(questionId !== undefined ? { questionId } : {}),
|
|
450
|
+
});
|
|
451
|
+
}
|
|
450
452
|
export function resupplyTruncatedSentence(facts, lang) {
|
|
451
453
|
try {
|
|
452
454
|
const f = resupplyTruncatedFactsOf(facts);
|
package/dist/ownKey.d.ts
CHANGED
|
@@ -75,6 +75,7 @@ export interface SampledRecord {
|
|
|
75
75
|
export declare function ownSnapshotWhenTyped<V>(value: V, word: string): SampledJson;
|
|
76
76
|
export declare function ownSnapshotTyped<T extends object>(value: T): T | undefined;
|
|
77
77
|
export declare function ownSnapshotRecord<V>(value: V): SampledRecord | undefined;
|
|
78
|
+
export declare function ownSnapshotRecordFaithful<V>(value: V): SampledRecord | undefined;
|
|
78
79
|
export declare function workflowCompletionExtrasOf(c: object): {
|
|
79
80
|
completionId?: string;
|
|
80
81
|
diagnostics?: string;
|
package/dist/ownKey.js
CHANGED
|
@@ -291,6 +291,7 @@ export function promptManifestIdentityOf(raw) {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
const SAMPLED = new WeakSet();
|
|
294
|
+
const LOSSY = new WeakSet();
|
|
294
295
|
const SAMPLE_MAX_DEPTH = 256;
|
|
295
296
|
export function isOwnSnapshot(v) {
|
|
296
297
|
return isBranded(v);
|
|
@@ -311,7 +312,7 @@ function snapshotOf(value) {
|
|
|
311
312
|
if (typeof value === 'object' && value !== null) {
|
|
312
313
|
if (SAMPLED.has(value))
|
|
313
314
|
return value;
|
|
314
|
-
return sampleObject(value, 0, { done: new Map(), path: new Set(), seen: new Set(), rework: 0, depthCuts: 0 });
|
|
315
|
+
return sampleObject(value, 0, { done: new Map(), path: new Set(), seen: new Set(), rework: 0, depthCuts: 0, lost: 0 });
|
|
315
316
|
}
|
|
316
317
|
return samplePrimitive(value);
|
|
317
318
|
}
|
|
@@ -342,6 +343,10 @@ export function ownSnapshotTyped(value) {
|
|
|
342
343
|
export function ownSnapshotRecord(value) {
|
|
343
344
|
return recordOf(value);
|
|
344
345
|
}
|
|
346
|
+
export function ownSnapshotRecordFaithful(value) {
|
|
347
|
+
const s = recordOf(value);
|
|
348
|
+
return s === undefined || LOSSY.has(s) ? undefined : s;
|
|
349
|
+
}
|
|
345
350
|
function recordOf(value) {
|
|
346
351
|
const s = snapshotOf(value);
|
|
347
352
|
return typeof s === 'object' && s !== null && !Array.isArray(s) ? s : undefined;
|
|
@@ -357,19 +362,29 @@ function sampleValue(v, depth, run) {
|
|
|
357
362
|
}
|
|
358
363
|
function sampleObject(src, depth, run) {
|
|
359
364
|
const hit = run.done.get(src);
|
|
360
|
-
if (hit !== undefined)
|
|
365
|
+
if (hit !== undefined) {
|
|
366
|
+
if (hit === null || LOSSY.has(hit))
|
|
367
|
+
run.lost++;
|
|
361
368
|
return hit ?? undefined;
|
|
362
|
-
|
|
369
|
+
}
|
|
370
|
+
if (SAMPLED.has(src)) {
|
|
371
|
+
if (LOSSY.has(src))
|
|
372
|
+
run.lost++;
|
|
363
373
|
return src;
|
|
364
|
-
|
|
374
|
+
}
|
|
375
|
+
if (run.path.has(src)) {
|
|
376
|
+
run.lost++;
|
|
365
377
|
return undefined;
|
|
378
|
+
}
|
|
366
379
|
if (depth >= SAMPLE_MAX_DEPTH) {
|
|
367
380
|
run.depthCuts++;
|
|
381
|
+
run.lost++;
|
|
368
382
|
return undefined;
|
|
369
383
|
}
|
|
370
384
|
if (run.seen.has(src)) {
|
|
371
385
|
if (++run.rework > SAMPLE_MAX_REWORK) {
|
|
372
386
|
run.depthCuts++;
|
|
387
|
+
run.lost++;
|
|
373
388
|
return undefined;
|
|
374
389
|
}
|
|
375
390
|
}
|
|
@@ -384,10 +399,12 @@ function sampleObject(src, depth, run) {
|
|
|
384
399
|
}
|
|
385
400
|
catch {
|
|
386
401
|
run.done.set(src, null);
|
|
402
|
+
run.lost++;
|
|
387
403
|
return undefined;
|
|
388
404
|
}
|
|
389
405
|
run.path.add(src);
|
|
390
406
|
const cutsBefore = run.depthCuts;
|
|
407
|
+
const lostBefore = run.lost;
|
|
391
408
|
try {
|
|
392
409
|
const rec = {};
|
|
393
410
|
const arr = [];
|
|
@@ -409,18 +426,29 @@ function sampleObject(src, depth, run) {
|
|
|
409
426
|
const index = isArray ? arrayIndexOfKey(k) : undefined;
|
|
410
427
|
if (isArray && index === undefined)
|
|
411
428
|
continue;
|
|
412
|
-
if (index !== undefined && index >= SAMPLE_MAX_INDEX)
|
|
429
|
+
if (index !== undefined && index >= SAMPLE_MAX_INDEX) {
|
|
430
|
+
run.lost++;
|
|
413
431
|
continue;
|
|
432
|
+
}
|
|
414
433
|
if (index !== undefined && index + 1 > tail)
|
|
415
434
|
tail = index + 1;
|
|
416
435
|
const d = guardedRead(() => Object.getOwnPropertyDescriptor(src, k));
|
|
417
|
-
if (d === undefined)
|
|
436
|
+
if (d === undefined) {
|
|
437
|
+
run.lost++;
|
|
418
438
|
continue;
|
|
419
|
-
|
|
439
|
+
}
|
|
440
|
+
if (d.enumerable !== true)
|
|
441
|
+
continue;
|
|
442
|
+
if (!Object.hasOwn(d, 'value')) {
|
|
443
|
+
run.lost++;
|
|
420
444
|
continue;
|
|
445
|
+
}
|
|
421
446
|
const child = sampleValue(d.value, depth + 1, run);
|
|
422
|
-
if (child === undefined)
|
|
447
|
+
if (child === undefined) {
|
|
448
|
+
if (typeof d.value === 'bigint')
|
|
449
|
+
run.lost++;
|
|
423
450
|
continue;
|
|
451
|
+
}
|
|
424
452
|
if (index !== undefined) {
|
|
425
453
|
Object.defineProperty(arr, index, { value: child, writable: true, enumerable: true, configurable: true });
|
|
426
454
|
if (index + 1 > good)
|
|
@@ -431,12 +459,16 @@ function sampleObject(src, depth, run) {
|
|
|
431
459
|
}
|
|
432
460
|
if (isArray) {
|
|
433
461
|
const want = Math.max(good, Math.min(Math.max(tail, declared), good + SAMPLE_MAX_TRAILING_HOLES));
|
|
462
|
+
if (Math.max(tail, declared) > want)
|
|
463
|
+
run.lost++;
|
|
434
464
|
if (arr.length < want)
|
|
435
465
|
arr.length = want;
|
|
436
466
|
}
|
|
437
467
|
const out = isArray ? arr : rec;
|
|
438
468
|
Object.freeze(out);
|
|
439
469
|
SAMPLED.add(out);
|
|
470
|
+
if (run.lost !== lostBefore)
|
|
471
|
+
LOSSY.add(out);
|
|
440
472
|
if (run.depthCuts === cutsBefore)
|
|
441
473
|
run.done.set(src, out);
|
|
442
474
|
return out;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CoreValuePortName } from './coreValuePorts.js';
|
|
2
2
|
import { type PermissionsAllowGrantReading } from './permissionsAllowGrantCapability.js';
|
|
3
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
3
4
|
declare const SETTINGS_SOURCE_TIERS: Readonly<{
|
|
4
5
|
readonly policySettings: "managed";
|
|
5
6
|
readonly flagSettings: "global";
|
|
@@ -118,5 +119,5 @@ export interface PermissionsAllowKeptFacts {
|
|
|
118
119
|
readonly managedPolicyFetch?: 'in_progress' | 'failed' | 'unknown';
|
|
119
120
|
readonly where?: string;
|
|
120
121
|
}
|
|
121
|
-
export declare function permissionsAllowKeptNotice(report: Pick<PermissionsDeclarationReport, 'kept'>, settingsRead: 'clean' | 'partial' | 'unreadable', facts?: PermissionsAllowKeptFacts): string | undefined;
|
|
122
|
+
export declare function permissionsAllowKeptNotice(report: Pick<PermissionsDeclarationReport, 'kept'>, settingsRead: 'clean' | 'partial' | 'unreadable', facts?: PermissionsAllowKeptFacts, lang?: UiLanguage): string | undefined;
|
|
122
123
|
export {};
|