@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/hostTurnSettings.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { SETTINGS_CLASSIFY_HOOKS_CONFIG } from './generated/settingsSchemaFns.js';
|
|
2
2
|
import { hooksWirePlanShapeOf } from './pluginHooksWire.js';
|
|
3
|
-
|
|
3
|
+
import { resolveWebSearchVerdict, webSearchVerdictMessage } from './webSearchWireCaps.js';
|
|
4
|
+
import { fileHistoryTightenVerdict, fileHistoryUnjudgedRefusal } from './fileHistoryCaptureCapability.js';
|
|
5
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
6
|
+
export const HOST_SUPPLIED_KEYS = Object.freeze(['settings.hooks', 'settings.resolved', 'settings.webSearch', 'settings.outputStyle', 'memory', 'fileHistory']);
|
|
4
7
|
export const HOST_SETTING_CAUSES = Object.freeze([
|
|
5
8
|
'carried',
|
|
6
9
|
'entries_dropped',
|
|
@@ -10,6 +13,7 @@ export const HOST_SETTING_CAUSES = Object.freeze([
|
|
|
10
13
|
'empty',
|
|
11
14
|
'no_source',
|
|
12
15
|
'host_port_missing',
|
|
16
|
+
'value_malformed',
|
|
13
17
|
]);
|
|
14
18
|
export const HOST_SETTING_DISPOSITIONS = Object.freeze(['carry', 'carry_partial', 'withhold_notice', 'refuse_turn', 'unwired', 'nothing_to_carry']);
|
|
15
19
|
const HOST_SETTING_NOTICE_TEXT = {
|
|
@@ -17,12 +21,17 @@ const HOST_SETTING_NOTICE_TEXT = {
|
|
|
17
21
|
'HS-MANAGED-REJECTED': () => 'Managed settings: the hooks your administrator configured could not be loaded, so requests are not sent until the managed settings are fixed.',
|
|
18
22
|
'HS-PROJECTION': () => 'The hooks for this request could not be checked before sending, so the request is not sent. Reload your settings and try again.',
|
|
19
23
|
'HS-SOURCE-UNREADABLE': (what) => `This app could not read ${what} from your settings, so the request is not sent. Reload your settings and try again.`,
|
|
24
|
+
'HS-WEBSEARCH-MALFORMED': (sentence) => sentence,
|
|
25
|
+
'HS-SWITCH-MALFORMED': () => renderMessage(msg('session.hostSettings.memorySwitchMalformed')),
|
|
26
|
+
'HS-FILEHISTORY-UNJUDGED': (sentence) => sentence,
|
|
20
27
|
};
|
|
21
28
|
const KEY_NOUN = {
|
|
22
29
|
'settings.hooks': 'the hooks',
|
|
23
30
|
'settings.resolved': 'the permission rules',
|
|
24
31
|
'settings.webSearch': 'the web search setup',
|
|
25
32
|
'settings.outputStyle': 'the output style',
|
|
33
|
+
memory: 'auto-memory',
|
|
34
|
+
fileHistory: 'file checkpoints',
|
|
26
35
|
};
|
|
27
36
|
const BASE_DISPOSITION = {
|
|
28
37
|
carried: 'carry',
|
|
@@ -33,6 +42,7 @@ const BASE_DISPOSITION = {
|
|
|
33
42
|
empty: 'nothing_to_carry',
|
|
34
43
|
no_source: 'nothing_to_carry',
|
|
35
44
|
host_port_missing: 'unwired',
|
|
45
|
+
value_malformed: 'refuse_turn',
|
|
36
46
|
};
|
|
37
47
|
const freeze = (o) => Object.freeze(o);
|
|
38
48
|
const mint = (o) => o;
|
|
@@ -69,8 +79,11 @@ function hooksPassJudge(wire) {
|
|
|
69
79
|
return false;
|
|
70
80
|
}
|
|
71
81
|
}
|
|
82
|
+
class HostSourceShapeError extends TypeError {
|
|
83
|
+
code = 'host_source_shape';
|
|
84
|
+
}
|
|
72
85
|
function badSource(key, want) {
|
|
73
|
-
return new
|
|
86
|
+
return new HostSourceShapeError(`hostTurnSettings: sources.${key.replace(/^settings\./, '')} must be 'none' or ${want} — got something else (the value is not echoed).`);
|
|
74
87
|
}
|
|
75
88
|
const missingArm = (key) => ({
|
|
76
89
|
row: freeze({ key, cause: 'host_port_missing', disposition: BASE_DISPOSITION.host_port_missing }),
|
|
@@ -132,6 +145,131 @@ function hooksArm(src) {
|
|
|
132
145
|
return { row: freeze({ key, cause: 'empty', disposition: BASE_DISPOSITION.empty }), notices: [], plan };
|
|
133
146
|
return { ...carriedArm(key, carried), plan };
|
|
134
147
|
}
|
|
148
|
+
function webSearchArm(src) {
|
|
149
|
+
const key = 'settings.webSearch';
|
|
150
|
+
if (src.kind === 'missing')
|
|
151
|
+
return missingArm(key);
|
|
152
|
+
if (src.kind === 'threw')
|
|
153
|
+
return unreadableArm(key);
|
|
154
|
+
const v = src.value;
|
|
155
|
+
if (v === 'none')
|
|
156
|
+
return noSourceArm(key);
|
|
157
|
+
let section;
|
|
158
|
+
let env;
|
|
159
|
+
let apiKeyFor;
|
|
160
|
+
try {
|
|
161
|
+
if (!isRecordShape(v) || !Object.hasOwn(v, 'env') || Object.hasOwn(v, 'settings'))
|
|
162
|
+
throw badSource(key, "{ section, env } with the raw webSearch section of the settings and the environment (since 0.100.0 the entry judges it; do not pass the judged settings)");
|
|
163
|
+
section = v.section;
|
|
164
|
+
env = v.env;
|
|
165
|
+
apiKeyFor = v.apiKeyFor;
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
if (e instanceof HostSourceShapeError)
|
|
169
|
+
throw e;
|
|
170
|
+
return unreadableArm(key);
|
|
171
|
+
}
|
|
172
|
+
if (!isRecordShape(env))
|
|
173
|
+
throw badSource(key, '{ section, env } where env is the environment record (pass {} where there is none)');
|
|
174
|
+
if (apiKeyFor !== undefined && typeof apiKeyFor !== 'function')
|
|
175
|
+
throw badSource(key, '{ section, env, apiKeyFor? } where apiKeyFor is a function');
|
|
176
|
+
const verdict = resolveWebSearchVerdict(env, section, apiKeyFor);
|
|
177
|
+
if (verdict.kind === 'absent')
|
|
178
|
+
return { row: freeze({ key, cause: 'empty', disposition: BASE_DISPOSITION.empty }), notices: [] };
|
|
179
|
+
if (verdict.kind === 'honored')
|
|
180
|
+
return carriedArm(key, freeze({ ...verdict.settings }));
|
|
181
|
+
return {
|
|
182
|
+
row: freeze({ key, cause: 'value_malformed', disposition: BASE_DISPOSITION.value_malformed }),
|
|
183
|
+
notices: [notice('HS-WEBSEARCH-MALFORMED', 'turn', webSearchVerdictMessage(verdict, 'submit') ?? '')],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function memoryArm(src, judge) {
|
|
187
|
+
const key = 'memory';
|
|
188
|
+
if (src.kind === 'missing')
|
|
189
|
+
return missingArm(key);
|
|
190
|
+
if (src.kind === 'threw')
|
|
191
|
+
return unreadableArm(key);
|
|
192
|
+
const v = src.value;
|
|
193
|
+
if (v === 'none')
|
|
194
|
+
return noSourceArm(key);
|
|
195
|
+
let flag;
|
|
196
|
+
let settingsMemory;
|
|
197
|
+
try {
|
|
198
|
+
if (!isRecordShape(v))
|
|
199
|
+
throw badSource(key, '{ flag?, settingsMemory? } with the --memory flag word and the memory section of the settings');
|
|
200
|
+
flag = v.flag;
|
|
201
|
+
settingsMemory = v.settingsMemory;
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
if (e instanceof HostSourceShapeError)
|
|
205
|
+
throw e;
|
|
206
|
+
return unreadableArm(key);
|
|
207
|
+
}
|
|
208
|
+
if (judge({ flag }))
|
|
209
|
+
return carriedArm(key, 'off');
|
|
210
|
+
let bySettings;
|
|
211
|
+
try {
|
|
212
|
+
bySettings = judge({ settingsMemory });
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return { row: freeze({ key, cause: 'value_malformed', disposition: 'withhold_notice' }), notices: [notice('HS-SWITCH-MALFORMED', 'session')] };
|
|
216
|
+
}
|
|
217
|
+
if (bySettings)
|
|
218
|
+
return carriedArm(key, 'off');
|
|
219
|
+
return { row: freeze({ key, cause: 'empty', disposition: BASE_DISPOSITION.empty }), notices: [] };
|
|
220
|
+
}
|
|
221
|
+
const UNOBSERVED_READING = Object.freeze({ kind: 'unobserved' });
|
|
222
|
+
function fileHistoryReadingSnapshot(reading) {
|
|
223
|
+
try {
|
|
224
|
+
if (typeof reading !== 'object' || reading === null)
|
|
225
|
+
return UNOBSERVED_READING;
|
|
226
|
+
const kind = reading.kind;
|
|
227
|
+
if (kind === 'present') {
|
|
228
|
+
const word = reading.word;
|
|
229
|
+
return Object.freeze({ kind, word });
|
|
230
|
+
}
|
|
231
|
+
return Object.freeze({ kind });
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return UNOBSERVED_READING;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function fileHistoryArm(src) {
|
|
238
|
+
const key = 'fileHistory';
|
|
239
|
+
if (src.kind === 'missing')
|
|
240
|
+
return missingArm(key);
|
|
241
|
+
if (src.kind === 'threw')
|
|
242
|
+
return unreadableArm(key);
|
|
243
|
+
const v = src.value;
|
|
244
|
+
if (v === 'none')
|
|
245
|
+
return noSourceArm(key);
|
|
246
|
+
let reading;
|
|
247
|
+
let captureOff;
|
|
248
|
+
try {
|
|
249
|
+
if (!isRecordShape(v) || !Object.hasOwn(v, 'captureOff'))
|
|
250
|
+
throw badSource(key, '{ reading, captureOff } with the engine capability reading and the switch');
|
|
251
|
+
reading = v.reading;
|
|
252
|
+
captureOff = v.captureOff;
|
|
253
|
+
}
|
|
254
|
+
catch (e) {
|
|
255
|
+
if (e instanceof HostSourceShapeError)
|
|
256
|
+
throw e;
|
|
257
|
+
return unreadableArm(key);
|
|
258
|
+
}
|
|
259
|
+
if (typeof captureOff !== 'boolean')
|
|
260
|
+
throw badSource(key, '{ reading, captureOff } where captureOff is a boolean');
|
|
261
|
+
const snap = fileHistoryReadingSnapshot(reading);
|
|
262
|
+
const verdict = fileHistoryTightenVerdict(snap, captureOff);
|
|
263
|
+
if (verdict === 'declare')
|
|
264
|
+
return carriedArm(key, 'disabled');
|
|
265
|
+
if (verdict === 'unjudged') {
|
|
266
|
+
return {
|
|
267
|
+
row: freeze({ key, cause: 'value_malformed', disposition: 'refuse_turn' }),
|
|
268
|
+
notices: [notice('HS-FILEHISTORY-UNJUDGED', 'turn', fileHistoryUnjudgedRefusal(snap, true) ?? fileHistoryUnjudgedRefusal(UNOBSERVED_READING, true) ?? '')],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return { row: freeze({ key, cause: 'empty', disposition: BASE_DISPOSITION.empty }), notices: [] };
|
|
272
|
+
}
|
|
135
273
|
function passArm(key, field, src, want) {
|
|
136
274
|
if (src.kind === 'missing')
|
|
137
275
|
return missingArm(key);
|
|
@@ -155,7 +293,8 @@ export function rethrowHostResolvedDeferred(product) {
|
|
|
155
293
|
if (box !== undefined)
|
|
156
294
|
throw box.error;
|
|
157
295
|
}
|
|
158
|
-
export function buildHostTurnSettings(input,
|
|
296
|
+
export function buildHostTurnSettings(input, judges) {
|
|
297
|
+
const materialize = judges.materialize;
|
|
159
298
|
let sources;
|
|
160
299
|
let sourcesThrew = false;
|
|
161
300
|
try {
|
|
@@ -177,9 +316,11 @@ export function buildHostTurnSettings(input, materialize) {
|
|
|
177
316
|
}
|
|
178
317
|
}
|
|
179
318
|
const hooks = hooksArm(read('hooks'));
|
|
180
|
-
const webSearch =
|
|
319
|
+
const webSearch = webSearchArm(read('webSearch'));
|
|
181
320
|
const outputStyle = passArm('settings.outputStyle', 'name', read('outputStyle'), '{ name } with the output style name');
|
|
182
|
-
const
|
|
321
|
+
const memory = memoryArm(read('memory'), judges.memoryOffDeclared);
|
|
322
|
+
const fileHistory = fileHistoryArm(read('fileHistory'));
|
|
323
|
+
const arms = [hooks, resolved, webSearch, outputStyle, memory, fileHistory];
|
|
183
324
|
const rows = freeze(arms.map((a) => a.row));
|
|
184
325
|
const notices = freeze(arms.flatMap((a) => a.notices));
|
|
185
326
|
const refusal = arms.find((a) => a.row.disposition === 'refuse_turn');
|
|
@@ -189,6 +330,8 @@ export function buildHostTurnSettings(input, materialize) {
|
|
|
189
330
|
...(resolvedCarried !== undefined ? { resolved: resolvedCarried } : {}),
|
|
190
331
|
...(webSearch.carried !== undefined ? { webSearch: webSearch.carried } : {}),
|
|
191
332
|
...(outputStyle.carried !== undefined ? { outputStyle: outputStyle.carried } : {}),
|
|
333
|
+
...(memory.carried !== undefined ? { memory: 'off' } : {}),
|
|
334
|
+
...(fileHistory.carried !== undefined ? { fileHistory: 'disabled' } : {}),
|
|
192
335
|
});
|
|
193
336
|
const product = { verdict, rows, notices, hooks: hooks.plan, carried };
|
|
194
337
|
if (resolvedError !== undefined)
|
|
@@ -218,6 +361,7 @@ export function hostSettingsSelfCheck(product) {
|
|
|
218
361
|
return HOST_SUPPLIED_KEYS;
|
|
219
362
|
}
|
|
220
363
|
}
|
|
364
|
+
export const hostProjectionNotice = () => notice('HS-PROJECTION', 'turn');
|
|
221
365
|
export class HostSettingsRefused extends Error {
|
|
222
366
|
notice;
|
|
223
367
|
constructor(n) {
|
|
@@ -260,9 +404,13 @@ export function hostTurnSettingsOf(v, depth = 'full') {
|
|
|
260
404
|
const p = view;
|
|
261
405
|
const rows = p.rows;
|
|
262
406
|
const carried = p.carried;
|
|
263
|
-
const subs = HOST_SUPPLIED_KEYS.map(
|
|
407
|
+
const subs = HOST_SUPPLIED_KEYS.map(carriedKeyOf);
|
|
264
408
|
if (Object.keys(carried).some((k) => !subs.includes(k)))
|
|
265
409
|
return undefined;
|
|
410
|
+
if (carried.memory !== undefined && carried.memory !== 'off')
|
|
411
|
+
return undefined;
|
|
412
|
+
if (carried.fileHistory !== undefined && carried.fileHistory !== 'disabled')
|
|
413
|
+
return undefined;
|
|
266
414
|
let refuses = false;
|
|
267
415
|
for (const [i, r] of rows.entries()) {
|
|
268
416
|
const disposition = r.disposition;
|
|
@@ -288,4 +436,257 @@ export function hostTurnSettingsOf(v, depth = 'full') {
|
|
|
288
436
|
return undefined;
|
|
289
437
|
}
|
|
290
438
|
}
|
|
291
|
-
|
|
439
|
+
function wireFormOf(v) {
|
|
440
|
+
const text = JSON.stringify(v);
|
|
441
|
+
return text === undefined ? undefined : JSON.parse(text);
|
|
442
|
+
}
|
|
443
|
+
function sameJson(a, b) {
|
|
444
|
+
if (a === b)
|
|
445
|
+
return true;
|
|
446
|
+
if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)
|
|
447
|
+
return false;
|
|
448
|
+
if (Array.isArray(a) !== Array.isArray(b))
|
|
449
|
+
return false;
|
|
450
|
+
if (Array.isArray(a) && Array.isArray(b))
|
|
451
|
+
return a.length === b.length && a.every((x, i) => sameJson(x, b[i]));
|
|
452
|
+
const ra = a;
|
|
453
|
+
const rb = b;
|
|
454
|
+
const ka = Object.keys(ra);
|
|
455
|
+
if (ka.length !== Object.keys(rb).length)
|
|
456
|
+
return false;
|
|
457
|
+
return ka.every((k) => Object.hasOwn(rb, k) && sameJson(ra[k], rb[k]));
|
|
458
|
+
}
|
|
459
|
+
function groupHead(g) {
|
|
460
|
+
if (!isRecordShape(g))
|
|
461
|
+
return undefined;
|
|
462
|
+
const head = {};
|
|
463
|
+
for (const k of Object.keys(g))
|
|
464
|
+
if (k !== 'hooks')
|
|
465
|
+
head[k] = g[k];
|
|
466
|
+
return head;
|
|
467
|
+
}
|
|
468
|
+
export function intersectHostHooks(sent, now) {
|
|
469
|
+
try {
|
|
470
|
+
return intersectHostHooksUnguarded(sent, now);
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
return { hooks: undefined, dropped: 0, judged: false };
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function intersectHostHooksUnguarded(sentIn, nowIn) {
|
|
477
|
+
const sent = wireFormOf(sentIn);
|
|
478
|
+
const now = nowIn === undefined ? undefined : wireFormOf(nowIn);
|
|
479
|
+
const entriesOf = (cfg) => {
|
|
480
|
+
if (!isRecordShape(cfg))
|
|
481
|
+
return 0;
|
|
482
|
+
let n = 0;
|
|
483
|
+
for (const ev of Object.keys(cfg)) {
|
|
484
|
+
const groups = cfg[ev];
|
|
485
|
+
if (!Array.isArray(groups))
|
|
486
|
+
continue;
|
|
487
|
+
for (const g of groups)
|
|
488
|
+
if (isRecordShape(g) && Array.isArray(g.hooks))
|
|
489
|
+
n += g.hooks.length;
|
|
490
|
+
}
|
|
491
|
+
return n;
|
|
492
|
+
};
|
|
493
|
+
const total = entriesOf(sent);
|
|
494
|
+
if (!isRecordShape(sent))
|
|
495
|
+
return { hooks: undefined, dropped: 0, judged: true };
|
|
496
|
+
if (!isRecordShape(now))
|
|
497
|
+
return { hooks: undefined, dropped: total, judged: true };
|
|
498
|
+
const out = {};
|
|
499
|
+
let kept = 0;
|
|
500
|
+
for (const ev of Object.keys(sent)) {
|
|
501
|
+
const groups = sent[ev];
|
|
502
|
+
const nowGroups = now[ev];
|
|
503
|
+
if (!Array.isArray(groups) || !Array.isArray(nowGroups))
|
|
504
|
+
continue;
|
|
505
|
+
const pool = nowGroups.map((g) => ({ head: groupHead(g), left: isRecordShape(g) && Array.isArray(g.hooks) ? [...g.hooks] : [] }));
|
|
506
|
+
const evOut = [];
|
|
507
|
+
for (const g of groups) {
|
|
508
|
+
const head = groupHead(g);
|
|
509
|
+
if (head === undefined || !isRecordShape(g) || !Array.isArray(g.hooks))
|
|
510
|
+
continue;
|
|
511
|
+
const keep = [];
|
|
512
|
+
for (const entry of g.hooks) {
|
|
513
|
+
for (const slot of pool) {
|
|
514
|
+
if (slot.head === undefined || !sameJson(slot.head, head))
|
|
515
|
+
continue;
|
|
516
|
+
const at = slot.left.findIndex((x) => sameJson(x, entry));
|
|
517
|
+
if (at < 0)
|
|
518
|
+
continue;
|
|
519
|
+
slot.left.splice(at, 1);
|
|
520
|
+
keep.push(entry);
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
if (keep.length > 0)
|
|
525
|
+
evOut.push({ ...head, hooks: keep });
|
|
526
|
+
kept += keep.length;
|
|
527
|
+
}
|
|
528
|
+
if (evOut.length > 0)
|
|
529
|
+
out[ev] = evOut;
|
|
530
|
+
}
|
|
531
|
+
const hooks = Object.keys(out).length > 0 ? out : undefined;
|
|
532
|
+
return { hooks, dropped: total - kept, judged: hooks === undefined || hooksPassJudge(hooks) };
|
|
533
|
+
}
|
|
534
|
+
function ownDataOf(o, k) {
|
|
535
|
+
try {
|
|
536
|
+
if (typeof o !== 'object' || o === null)
|
|
537
|
+
return { ok: false };
|
|
538
|
+
const d = Object.getOwnPropertyDescriptor(o, k);
|
|
539
|
+
if (d === undefined)
|
|
540
|
+
return { ok: true, value: undefined };
|
|
541
|
+
if (!('value' in d))
|
|
542
|
+
return { ok: false };
|
|
543
|
+
return { ok: true, value: d.value };
|
|
544
|
+
}
|
|
545
|
+
catch {
|
|
546
|
+
return { ok: false };
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
function noticeCopyOf(n) {
|
|
550
|
+
const id = ownDataOf(n, 'id');
|
|
551
|
+
const plane = ownDataOf(n, 'plane');
|
|
552
|
+
const text = ownDataOf(n, 'text');
|
|
553
|
+
if (!id.ok || !plane.ok || !text.ok || typeof id.value !== 'string' || typeof plane.value !== 'string' || typeof text.value !== 'string')
|
|
554
|
+
return undefined;
|
|
555
|
+
return freeze({ id: id.value, plane: plane.value, text: text.value });
|
|
556
|
+
}
|
|
557
|
+
function turnNoticesOf(product) {
|
|
558
|
+
try {
|
|
559
|
+
return turnNoticesUnguarded(product);
|
|
560
|
+
}
|
|
561
|
+
catch {
|
|
562
|
+
return undefined;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
function turnNoticesUnguarded(product) {
|
|
566
|
+
const ns = ownDataOf(product, 'notices');
|
|
567
|
+
if (!ns.ok || !Array.isArray(ns.value))
|
|
568
|
+
return undefined;
|
|
569
|
+
const len = ownDataOf(ns.value, 'length');
|
|
570
|
+
if (!len.ok || typeof len.value !== 'number')
|
|
571
|
+
return undefined;
|
|
572
|
+
const out = [];
|
|
573
|
+
for (let i = 0; i < len.value; i++) {
|
|
574
|
+
const e = ownDataOf(ns.value, String(i));
|
|
575
|
+
const copy = e.ok ? noticeCopyOf(e.value) : undefined;
|
|
576
|
+
if (copy === undefined)
|
|
577
|
+
return undefined;
|
|
578
|
+
if (copy.plane === 'turn')
|
|
579
|
+
out.push(copy);
|
|
580
|
+
}
|
|
581
|
+
return freeze(out);
|
|
582
|
+
}
|
|
583
|
+
function deepFreeze(v) {
|
|
584
|
+
if (typeof v === 'object' && v !== null) {
|
|
585
|
+
for (const x of Object.values(v))
|
|
586
|
+
deepFreeze(x);
|
|
587
|
+
Object.freeze(v);
|
|
588
|
+
}
|
|
589
|
+
return v;
|
|
590
|
+
}
|
|
591
|
+
export function hostIntakeSnapshotOf(product, onResolved) {
|
|
592
|
+
try {
|
|
593
|
+
return intakeSnapshotUnguarded(product, onResolved);
|
|
594
|
+
}
|
|
595
|
+
catch {
|
|
596
|
+
return undefined;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function intakeSnapshotUnguarded(product, onResolved) {
|
|
600
|
+
if (product === UNWIRED_HOST_TURN_SETTINGS) {
|
|
601
|
+
return freeze({
|
|
602
|
+
carried: freeze({}),
|
|
603
|
+
refuses: false,
|
|
604
|
+
dispositions: freeze(Object.fromEntries(HOST_SUPPLIED_KEYS.map((k) => [k, 'unwired']))),
|
|
605
|
+
refusingKeys: freeze([]),
|
|
606
|
+
turnNotices: freeze([]),
|
|
607
|
+
notice: undefined,
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
const c = ownDataOf(product, 'carried');
|
|
611
|
+
if (!c.ok || !isRecordShape(c.value))
|
|
612
|
+
return undefined;
|
|
613
|
+
const carriedIn = c.value;
|
|
614
|
+
const subs = HOST_SUPPLIED_KEYS.map(carriedKeyOf);
|
|
615
|
+
let keys;
|
|
616
|
+
try {
|
|
617
|
+
keys = Reflect.ownKeys(carriedIn);
|
|
618
|
+
}
|
|
619
|
+
catch {
|
|
620
|
+
return undefined;
|
|
621
|
+
}
|
|
622
|
+
if (keys.some((k) => typeof k !== 'string' || !subs.includes(k)))
|
|
623
|
+
return undefined;
|
|
624
|
+
const values = {};
|
|
625
|
+
const resolvedR = ownDataOf(carriedIn, 'resolved');
|
|
626
|
+
if (!resolvedR.ok)
|
|
627
|
+
return undefined;
|
|
628
|
+
onResolved?.(resolvedR.value);
|
|
629
|
+
if (resolvedR.value !== undefined)
|
|
630
|
+
values.resolved = resolvedR.value;
|
|
631
|
+
for (const sub of subs.filter((x) => x !== 'resolved')) {
|
|
632
|
+
const r = ownDataOf(carriedIn, sub);
|
|
633
|
+
if (!r.ok)
|
|
634
|
+
return undefined;
|
|
635
|
+
const copy = deepFreeze(wireFormOf(r.value));
|
|
636
|
+
if (copy !== undefined)
|
|
637
|
+
values[sub] = copy;
|
|
638
|
+
}
|
|
639
|
+
const rowsR = ownDataOf(product, 'rows');
|
|
640
|
+
if (!rowsR.ok || !Array.isArray(rowsR.value) || rowsR.value.length !== HOST_SUPPLIED_KEYS.length)
|
|
641
|
+
return undefined;
|
|
642
|
+
let refuses = false;
|
|
643
|
+
const refusingKeys = [];
|
|
644
|
+
const dispositions = {};
|
|
645
|
+
for (const [i, key] of HOST_SUPPLIED_KEYS.entries()) {
|
|
646
|
+
const rowR = ownDataOf(rowsR.value, String(i));
|
|
647
|
+
if (!rowR.ok)
|
|
648
|
+
return undefined;
|
|
649
|
+
const k = ownDataOf(rowR.value, 'key');
|
|
650
|
+
const d = ownDataOf(rowR.value, 'disposition');
|
|
651
|
+
if (!k.ok || !d.ok || k.value !== key || !HOST_SETTING_DISPOSITIONS.includes(d.value))
|
|
652
|
+
return undefined;
|
|
653
|
+
if (d.value === 'refuse_turn') {
|
|
654
|
+
refuses = true;
|
|
655
|
+
refusingKeys.push(key);
|
|
656
|
+
}
|
|
657
|
+
dispositions[key] = d.value;
|
|
658
|
+
if ((values[carriedKeyOf(key)] !== undefined) !== CARRYING.has(d.value))
|
|
659
|
+
return undefined;
|
|
660
|
+
}
|
|
661
|
+
if (values.memory !== undefined && values.memory !== 'off')
|
|
662
|
+
return undefined;
|
|
663
|
+
if (values.fileHistory !== undefined && values.fileHistory !== 'disabled')
|
|
664
|
+
return undefined;
|
|
665
|
+
if (values.hooks !== undefined && !hooksPassJudge(values.hooks))
|
|
666
|
+
return undefined;
|
|
667
|
+
const v = ownDataOf(product, 'verdict');
|
|
668
|
+
if (!v.ok)
|
|
669
|
+
return undefined;
|
|
670
|
+
const kind = ownDataOf(v.value, 'kind');
|
|
671
|
+
if (!kind.ok || kind.value !== (refuses ? 'refuse' : 'send'))
|
|
672
|
+
return undefined;
|
|
673
|
+
const noticeR = refuses ? ownDataOf(v.value, 'notice') : undefined;
|
|
674
|
+
const notice = noticeR === undefined ? undefined : ((noticeR.ok ? noticeCopyOf(noticeR.value) : undefined) ?? hostProjectionNotice());
|
|
675
|
+
return freeze({
|
|
676
|
+
carried: freeze(values),
|
|
677
|
+
refuses,
|
|
678
|
+
dispositions: freeze(dispositions),
|
|
679
|
+
refusingKeys: freeze(refusingKeys),
|
|
680
|
+
turnNotices: turnNoticesOf(product),
|
|
681
|
+
notice,
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
export const UNWIRED_HOST_TURN_SETTINGS = buildHostTurnSettings({ sources: {} }, {
|
|
685
|
+
materialize: (snapshot) => snapshot,
|
|
686
|
+
memoryOffDeclared: () => false,
|
|
687
|
+
});
|
|
688
|
+
function carriedKeyOf(k) {
|
|
689
|
+
return k.startsWith('settings.') ? k.slice('settings.'.length) : k;
|
|
690
|
+
}
|
|
691
|
+
const _armsPin = [true, true, true, true];
|
|
692
|
+
void _armsPin;
|
package/dist/humanTurn.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { ImageInput } from './imagesWireCaps.js';
|
|
|
3
3
|
import type { ImageVision } from './liveModelCatalog.js';
|
|
4
4
|
import { type UserAttachmentDescriptor } from './userAttachmentEnvelope.js';
|
|
5
5
|
import type { UserAttachmentSeatReading } from './userAttachmentSeat.js';
|
|
6
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
6
7
|
export interface HumanTurnRider {
|
|
7
8
|
readonly uuid: string;
|
|
8
9
|
readonly role: 'image_meta' | 'attachment' | 'skill_body' | (string & {});
|
|
@@ -98,7 +99,7 @@ export interface HumanTurnDelivered {
|
|
|
98
99
|
readonly full: readonly string[];
|
|
99
100
|
readonly partial: readonly string[];
|
|
100
101
|
}
|
|
101
|
-
export declare function imageSentOnUnknownVision(notices: readonly HumanTurnNotice[] | undefined): string | undefined;
|
|
102
|
+
export declare function imageSentOnUnknownVision(notices: readonly HumanTurnNotice[] | undefined, lang?: UiLanguage): string | undefined;
|
|
102
103
|
export declare function encodeHumanTurn(input: HumanTurnInput): HumanTurnEncoding;
|
|
103
104
|
export declare function deliveredUuidsOf(encoding: HumanTurnEncoding): HumanTurnDelivered;
|
|
104
105
|
export {};
|
package/dist/humanTurn.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CORE_MAX_PENDING_STEER_CHARS, CORE_MCP_IMAGE_MAX_BASE64, CORE_USER_ATTACHMENT_LABEL_MAX } from './generated/engineFactTables.js';
|
|
2
2
|
import { mintEnvelopeOf, mintReferenceOf, seatTextOf } from './userAttachmentEnvelope.js';
|
|
3
3
|
import { readEncodingShares, readHumanTurnInput } from './humanTurnRead.js';
|
|
4
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
4
5
|
const REQUEST_BODY_MAX_BYTES = 8 * 1024 * 1024;
|
|
5
6
|
const IMAGE_SEAT_MAX_COUNT = 20;
|
|
6
7
|
const IMAGE_SEAT_MAX_BASE64_CHARS_TOTAL = 6 * 1024 * 1024;
|
|
@@ -172,7 +173,7 @@ function noticesKey(v, items, placements) {
|
|
|
172
173
|
}
|
|
173
174
|
return notices.length > 0 ? { notices } : {};
|
|
174
175
|
}
|
|
175
|
-
export function imageSentOnUnknownVision(notices) {
|
|
176
|
+
export function imageSentOnUnknownVision(notices, lang) {
|
|
176
177
|
let n = 0;
|
|
177
178
|
try {
|
|
178
179
|
if (!Array.isArray(notices))
|
|
@@ -186,8 +187,7 @@ export function imageSentOnUnknownVision(notices) {
|
|
|
186
187
|
}
|
|
187
188
|
if (n === 0)
|
|
188
189
|
return undefined;
|
|
189
|
-
|
|
190
|
-
return `${what} sent with this message, although the engine's model list does not say whether the model this message uses accepts image input — if it does not, the images may be dropped or the message may be refused`;
|
|
190
|
+
return renderMessage(n === 1 ? msg('session.humanTurn.imageUnknownVision.one') : msg('session.humanTurn.imageUnknownVision.other', { count: n }), lang);
|
|
191
191
|
}
|
|
192
192
|
function encodeObjective(v) {
|
|
193
193
|
const { items } = v;
|