@sema-agent/client-core 0.88.0 → 0.89.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.
@@ -20,6 +20,27 @@ function pauseOf(v) {
20
20
  ...(restoreMode !== undefined ? { restoreMode } : {}),
21
21
  };
22
22
  }
23
+ const PROVIDER_REJECTED_DETAIL_KIND = 'provider_rejected';
24
+ function failureDetailOf(cause) {
25
+ try {
26
+ const own = (o, k) => (Object.prototype.hasOwnProperty.call(o, k) ? o[k] : undefined);
27
+ const v = own(cause, 'detail');
28
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
29
+ return undefined;
30
+ const kind = str(own(v, 'kind'));
31
+ if (kind === undefined)
32
+ return undefined;
33
+ const rawStatus = own(v, 'status');
34
+ const status = typeof rawStatus === 'number' && Number.isInteger(rawStatus) && rawStatus >= 100 && rawStatus <= 599 ? rawStatus : undefined;
35
+ if (kind === PROVIDER_REJECTED_DETAIL_KIND && (status === undefined || status < 400))
36
+ return undefined;
37
+ const code = str(own(v, 'code'));
38
+ return { kind, ...(status !== undefined ? { status } : {}), ...(code !== undefined ? { code } : {}) };
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ }
23
44
  const FLAT_PAUSED_STATUSES = ['suspended', 'needs_review'];
24
45
  export function readRunTerminal(result) {
25
46
  if (typeof result !== 'object' || result === null || Array.isArray(result))
@@ -44,12 +65,14 @@ export function readRunTerminal(result) {
44
65
  const code = str(c.code);
45
66
  const message = str(c.message);
46
67
  const nestedPause = c.nestedPause !== undefined ? pauseOf(c.nestedPause) : undefined;
68
+ const detail = failureDetailOf(c);
47
69
  return {
48
70
  kind: 'failed',
49
71
  plane: 'cause',
50
72
  ...(code !== undefined ? { code } : {}),
51
73
  ...(message !== undefined ? { message } : {}),
52
74
  ...(nestedPause !== undefined ? { nestedPause } : {}),
75
+ ...(detail !== undefined ? { detail } : {}),
53
76
  };
54
77
  }
55
78
  case 'blocked': {
package/dist/seam.d.ts CHANGED
@@ -174,6 +174,9 @@ export interface WiringManifestChromeEvent {
174
174
  readDeny?: WiringManifestReadDenyView;
175
175
  hands?: WiringManifestHandsView;
176
176
  fileHistory?: string;
177
+ instructions?: {
178
+ readonly selected: readonly string[];
179
+ };
177
180
  eventId?: string;
178
181
  }
179
182
  export interface TextSegmentCommittedRow {
@@ -61,6 +61,8 @@ export interface ToolPermissionRequest {
61
61
  mandate?: ApprovalMandateWord;
62
62
  origin?: string;
63
63
  ruleOffersAbsence?: string;
64
+ askClass?: string;
65
+ classes?: readonly string[];
64
66
  }
65
67
  declare const SEAT_EVENT_TYPE_TUPLE: readonly ["start", "close", "session_updated", "message", "stream_event", "chrome_event", "error", "tool_permission_resolved"];
66
68
  export type SeatEventType = (typeof SEAT_EVENT_TYPE_TUPLE)[number];
@@ -261,7 +263,7 @@ export declare const SEAT_METHOD_NAMES: readonly ["start", "sendMessage", "inter
261
263
  export declare const SEAT_STORE_PROPS: readonly ["sessionsStateStore", "focusedSessionStateStore", "settingsStateStore"];
262
264
  export declare const SEAT_EVENT_METHOD_NAMES: readonly ["onEvent", "onToolPermissionRequest"];
263
265
  export declare const LOCAL_SESSION_EVENT_KEYS: readonly ["type", "sessionId", "message", "messages", "error", "errorCategory", "code", "request", "data", "sources", "permissionMode", "session", "userMessageUuid", "hasPreClearSession", "requestId", "outcome", "chrome"];
264
- export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence"];
266
+ export declare const TOOL_PERMISSION_REQUEST_KEYS: readonly ["requestId", "sessionId", "toolName", "toolCallId", "input", "message", "toctouBinding", "createdAtMs", "governanceForced", "delegation", "mandated", "mandate", "origin", "ruleOffersAbsence", "askClass", "classes"];
265
267
  export declare const LOCAL_SESSION_RECORD_KEYS: readonly ["sessionId", "engineSessionId", "model", "title", "isRunning", "createdAt", "lastActivityAt", "queuedMessages", "parked"];
266
268
  export declare const SEND_MESSAGE_REQUEST_KEYS: readonly ["sessionId", "text", "model", "userMessageUuid", "permissionMode", "attachmentIds", "reasoningEffort", "retainBackgroundProcesses", "forwardSubagentEvents", "retainSubagentSessions", "settings", "scenario"];
267
269
  export declare const SEAT_SEND_MESSAGE_KEY_ORIGINS: {
@@ -333,6 +335,12 @@ export declare const SEAT_VALIDATOR_KEY_COVERAGE: {
333
335
  }, {
334
336
  readonly key: "origin";
335
337
  readonly why: "喂姿态谓词 askSurvivesPosture 的安全位(CC-203),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口 toolPermissionRequestAskBits,座位门不设第二判官(为一个位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。坏形的两种失效方向:非串 / 空串读成缺席 ⇒ 宿主报了没命中时姿态谓词可答可以放(放宽方向:真出身若是必问词就丢了);表外串读成不认识的词 ⇒ 答 unknown,宿主退回自己的规则(不放宽)。不经过境口自铸座位请求的宿主要自己按同一把窄读。";
338
+ }, {
339
+ readonly key: "askClass";
340
+ readonly why: "展示位(CC-284),权威成对窄读在卡口与过境口 toolPermissionRequestAskBits(与 classes 同在同缺、首员等于 askClass、不判成员、不重排);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎超时拒)。坏形读成缺席 ⇒ 卡上不显示问类,不改决断;缺席不是「普通问」。不经过境口自铸座位请求的宿主要自己按同一把成对窄读。";
341
+ }, {
342
+ readonly key: "classes";
343
+ readonly why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。";
336
344
  }, {
337
345
  readonly key: "ruleOffersAbsence";
338
346
  readonly why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。";
@@ -478,6 +478,8 @@ export const TOOL_PERMISSION_REQUEST_KEYS = [
478
478
  "mandate",
479
479
  "origin",
480
480
  "ruleOffersAbsence",
481
+ "askClass",
482
+ "classes",
481
483
  ];
482
484
  export const LOCAL_SESSION_RECORD_KEYS = [
483
485
  "sessionId",
@@ -563,6 +565,14 @@ export const SEAT_VALIDATOR_KEY_COVERAGE = {
563
565
  key: "origin",
564
566
  why: "喂姿态谓词 askSurvivesPosture 的安全位(CC-203),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口 toolPermissionRequestAskBits,座位门不设第二判官(为一个位拒掉整条 request = 把安全 ask 丢给引擎 TTL deny)。坏形的两种失效方向:非串 / 空串读成缺席 ⇒ 宿主报了没命中时姿态谓词可答可以放(放宽方向:真出身若是必问词就丢了);表外串读成不认识的词 ⇒ 答 unknown,宿主退回自己的规则(不放宽)。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
565
567
  },
568
+ {
569
+ key: "askClass",
570
+ why: "展示位(CC-284),权威成对窄读在卡口与过境口 toolPermissionRequestAskBits(与 classes 同在同缺、首员等于 askClass、不判成员、不重排);座位门不设第二判官,理由同 mandated(为一个展示位拒掉整条 request = 把安全 ask 丢给引擎超时拒)。坏形读成缺席 ⇒ 卡上不显示问类,不改决断;缺席不是「普通问」。不经过境口自铸座位请求的宿主要自己按同一把成对窄读。",
571
+ },
572
+ {
573
+ key: "classes",
574
+ why: "与 askClass 同一对(CC-284),同在同缺、同一只成对窄读(非空、每员非空串、无重复、首员等于 askClass;开集、原样顺序);座位门不设第二判官,理由同 askClass。",
575
+ },
566
576
  {
567
577
  key: "ruleOffersAbsence",
568
578
  why: "喂强制判据口 approvalIsMandated 的位(CC-203;寄存行那条腿的强制只以缺席词 mandated 表达),按开集读(非空串原文字节、词表不校);权威窄读在卡口与过境口,座位门不设第二判官,理由同 mandated。坏形读成缺席 ⇒ 这一路不判强制(放宽方向:寄存行上的强制就丢了;另两路 mandated / mandate 照判);表外串只是不等于 mandated。不经过境口自铸座位请求的宿主要自己按同一把窄读。",
@@ -4,10 +4,17 @@ export type SubagentSteerWireClient = {
4
4
  runs: Pick<AgentClient['runs'], 'steerSubagent'>;
5
5
  };
6
6
  export type SubagentSteerWire = EngineWireInjection<SubagentSteerWireClient>;
7
+ export interface SubagentSteerNotDelivered {
8
+ ok: false;
9
+ reason: 'not-delivered';
10
+ safety: 'ledger_unavailable';
11
+ detail: string;
12
+ }
7
13
  export type SubagentSteerOutcome = {
8
14
  ok: true;
9
15
  receipt: string;
10
- } | {
16
+ messageId?: string;
17
+ } | SubagentSteerNotDelivered | {
11
18
  ok: false;
12
19
  reason: 'no-wire' | 'no-run' | 'not-running' | 'error';
13
20
  detail?: string;
@@ -3,9 +3,21 @@ import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, noAnswerDetailF
3
3
  import { engineSessionParamFor } from '../engineSessionParam.js';
4
4
  import { resolveOwnerContext, resolveOwnerRunId } from './engineSubagentResume.js';
5
5
  import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
6
+ import { errCodes, steeringRefusedBeforeEngine } from '../controlRouter.js';
6
7
  function usableSteerClient(client) {
7
8
  return clientHasVerbs(client, [['runs', 'steerSubagent']]);
8
9
  }
10
+ function steerReceiptMessageId(body) {
11
+ try {
12
+ if (typeof body !== 'object' || body === null || !Object.hasOwn(body, 'messageId'))
13
+ return undefined;
14
+ const v = body.messageId;
15
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
9
21
  export async function steerEngineSubagent(target, text, childTaskId, opts) {
10
22
  const named = typeof childTaskId === 'string' && childTaskId !== '' ? childTaskId : undefined;
11
23
  const { record: owner, key } = resolveOwnerContext(named);
@@ -36,13 +48,24 @@ export async function steerEngineSubagent(target, text, childTaskId, opts) {
36
48
  const copy = body?.note ?? body?.message;
37
49
  if (typeof copy === 'string' && copy.length > 0)
38
50
  receipt = copy;
39
- return { ok: true, receipt };
51
+ const messageId = steerReceiptMessageId(body);
52
+ return messageId === undefined ? { ok: true, receipt } : { ok: true, receipt, messageId };
40
53
  }
41
54
  catch (e) {
42
- const status = e?.status;
43
- if (typeof status === 'number') {
55
+ let status;
56
+ try {
57
+ status = errCodes(e).status;
58
+ }
59
+ catch {
60
+ status = undefined;
61
+ }
62
+ if (status !== undefined) {
44
63
  const detail = e instanceof Error ? e.message : String(e);
45
64
  hostLog('debug', `engineSubagentSteer: ${status} ${detail.slice(0, 200)}`);
65
+ const refused = typeof e === 'object' && e !== null ? steeringRefusedBeforeEngine(e) : undefined;
66
+ if (refused !== undefined && refused.safety === 'ledger_unavailable') {
67
+ return { ok: false, reason: 'not-delivered', safety: refused.safety, detail: refused.advice };
68
+ }
46
69
  if (status === 409 || status === 404) {
47
70
  return { ok: false, reason: 'not-running', detail };
48
71
  }