@sema-agent/client-core 0.85.1 → 0.86.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +242 -0
  2. package/README.md +21 -14
  3. package/dist/adapt/arms.js +5 -1
  4. package/dist/adapter/activeRunSelfHeal.d.ts +3 -0
  5. package/dist/adapter/activeRunSelfHeal.js +126 -36
  6. package/dist/adapter/downstream/terminalToSdkResult.d.ts +3 -3
  7. package/dist/agentSession/backgroundView.js +7 -1
  8. package/dist/agentSession/contract.d.ts +1 -1
  9. package/dist/centerWiringCapability.d.ts +38 -0
  10. package/dist/centerWiringCapability.js +202 -0
  11. package/dist/decideFailureNote.js +3 -0
  12. package/dist/engineCapReader.d.ts +8 -0
  13. package/dist/engineCapReader.js +15 -0
  14. package/dist/engineErrorCodes.d.ts +3 -0
  15. package/dist/engineErrorCodes.js +8 -0
  16. package/dist/engineNoticeCodes.d.ts +62 -0
  17. package/dist/engineNoticeCodes.js +247 -29
  18. package/dist/executionLaneCapability.d.ts +6 -0
  19. package/dist/executionLaneCapability.js +55 -2
  20. package/dist/fleet/fleetProjection.js +6 -8
  21. package/dist/fleet/workflowSizeWarning.js +2 -5
  22. package/dist/gateOutcome.d.ts +13 -0
  23. package/dist/gateOutcome.js +48 -1
  24. package/dist/gateVocabulary.d.ts +6 -3
  25. package/dist/gateVocabulary.js +7 -15
  26. package/dist/generated/engineFactTables.d.ts +10 -0
  27. package/dist/generated/engineFactTables.js +113 -0
  28. package/dist/generated/engineNoticeTables.js +14 -0
  29. package/dist/hitl/refusedToolNameProse.d.ts +4 -0
  30. package/dist/hitl/refusedToolNameProse.js +7 -0
  31. package/dist/hitl/sessionPolicyDeliverable.js +9 -5
  32. package/dist/hitl/sessionPolicyWire.d.ts +16 -0
  33. package/dist/hitl/sessionPolicyWire.js +49 -1
  34. package/dist/index.d.ts +5 -1
  35. package/dist/index.js +5 -1
  36. package/dist/inheritEnvWire.d.ts +22 -0
  37. package/dist/inheritEnvWire.js +84 -0
  38. package/dist/peerFrames.js +2 -10
  39. package/dist/printInitToolFace.d.ts +6 -0
  40. package/dist/printInitToolFace.js +115 -2
  41. package/dist/readCredentialRefusal.d.ts +2 -0
  42. package/dist/readCredentialRefusal.js +7 -0
  43. package/dist/request/taskRequest.d.ts +4 -5
  44. package/dist/request/taskRequest.js +33 -23
  45. package/dist/runTerminal.js +2 -6
  46. package/dist/sqlEngineCapability.js +15 -2
  47. package/dist/storePostureCapability.d.ts +25 -0
  48. package/dist/storePostureCapability.js +132 -0
  49. package/dist/toolResult.js +2 -47
  50. package/dist/wireErrorTriage.d.ts +1 -0
  51. package/dist/wireErrorTriage.js +3 -0
  52. package/dist/wireFailureShape.d.ts +3 -0
  53. package/dist/wireFailureShape.js +44 -0
  54. package/dist/wireRefusalCopy.d.ts +39 -1
  55. package/dist/wireRefusalCopy.js +350 -2
  56. package/dist/workflowClient.d.ts +4 -0
  57. package/dist/workflowClient.js +12 -4
  58. package/docs/INTEGRATION-CLIENTS.md +853 -14
  59. package/package.json +2 -2
@@ -0,0 +1,132 @@
1
+ import { capForDisplay } from './fleetTaskDesc.js';
2
+ import { engineWireTarget } from './engineWireTarget.js';
3
+ import { capsGenerationOf, createEngineCapReader } from './engineCapReader.js';
4
+ import { projectSqlEngineCapability } from './sqlEngineCapability.js';
5
+ const nonEmpty = (v) => typeof v === 'string' && v !== '';
6
+ export function projectStorePostureCapability(caps) {
7
+ try {
8
+ return projectStorePostureOf(caps);
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ function projectStorePostureOf(caps) {
15
+ if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
16
+ return undefined;
17
+ const gen = capsGenerationOf(caps);
18
+ if (gen.generation === 'old')
19
+ return gen.store === 'absent' ? { kind: 'not_reported' } : undefined;
20
+ const store = gen.store;
21
+ const s = store;
22
+ const declared = s.declared;
23
+ const backend = s.backend;
24
+ const durable = s.durable;
25
+ if (!nonEmpty(declared) || !nonEmpty(backend) || typeof durable !== 'boolean')
26
+ return undefined;
27
+ const hasReason = Object.hasOwn(store, 'degradedReason');
28
+ const reason = hasReason ? s.degradedReason : undefined;
29
+ if (hasReason && reason !== undefined && !nonEmpty(reason))
30
+ return undefined;
31
+ const sqlReading = projectSqlEngineCapability({ store });
32
+ if (sqlReading === undefined)
33
+ return undefined;
34
+ return {
35
+ kind: 'present',
36
+ view: {
37
+ declared,
38
+ backend,
39
+ durable,
40
+ ...(nonEmpty(reason) ? { degradedReason: reason } : {}),
41
+ ...(sqlReading.kind === 'present' ? { sql: sqlReading.view } : {}),
42
+ },
43
+ };
44
+ }
45
+ const reader = createEngineCapReader({
46
+ name: 'store',
47
+ project: projectStorePostureCapability,
48
+ makeUnobserved: () => ({ kind: 'unobserved' }),
49
+ });
50
+ export function noteEngineCapsForStorePosture(baseUrl, caps, opts) {
51
+ reader.note(baseUrl, caps, opts);
52
+ }
53
+ export function observedStorePosture(baseUrl = engineWireTarget()?.baseUrl) {
54
+ return reader.observed(baseUrl);
55
+ }
56
+ function presentView(reading) {
57
+ if (typeof reading !== 'object' || reading === null)
58
+ return undefined;
59
+ try {
60
+ const kind = reading.kind;
61
+ if (kind === 'not_reported' || kind === 'unobserved')
62
+ return { kind };
63
+ if (kind !== 'present')
64
+ return undefined;
65
+ const view = reading.view;
66
+ if (typeof view !== 'object' || view === null)
67
+ return undefined;
68
+ return { kind: 'present', view: view };
69
+ }
70
+ catch {
71
+ return undefined;
72
+ }
73
+ }
74
+ export function storePersistence(reading) {
75
+ const r = presentView(reading);
76
+ if (r?.kind !== 'present')
77
+ return 'unknown';
78
+ let durable;
79
+ try {
80
+ durable = r.view.durable;
81
+ }
82
+ catch {
83
+ return 'unknown';
84
+ }
85
+ return durable === true ? 'durable' : durable === false ? 'not_durable' : 'unknown';
86
+ }
87
+ const WORD_DETAIL_MAX = 40;
88
+ const word = (v) => capForDisplay(v, WORD_DETAIL_MAX);
89
+ export function storePostureDoctorDetail(reading) {
90
+ const unobserved = 'store posture not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it, so whether this deployment persists its state is unknown';
91
+ const r = presentView(reading);
92
+ if (r?.kind === 'not_reported') {
93
+ return 'store posture not reported by this engine — only newer engines advertise it; this does not say whether this deployment persists its state';
94
+ }
95
+ if (r?.kind !== 'present')
96
+ return unobserved;
97
+ let declared;
98
+ let backend;
99
+ let durable;
100
+ let reason;
101
+ try {
102
+ declared = r.view.declared;
103
+ backend = r.view.backend;
104
+ durable = r.view.durable;
105
+ reason = r.view.degradedReason;
106
+ }
107
+ catch {
108
+ return unobserved;
109
+ }
110
+ if (!nonEmpty(declared) || !nonEmpty(backend) || typeof durable !== 'boolean')
111
+ return unobserved;
112
+ const assembled = declared === backend ? `store ${word(backend)}` : `store declared ${word(declared)}, running on ${word(backend)}`;
113
+ if (durable) {
114
+ return `${assembled} — durable: this replica persists its state, so it survives a restart`;
115
+ }
116
+ const lost = 'NOT durable: this replica holds its state in memory and loses it on restart';
117
+ if (!nonEmpty(reason))
118
+ return `${assembled} — ${lost}`;
119
+ if (reason === 'db_unreachable') {
120
+ return `${assembled} — ${lost} (degraded: the declared database could not be opened at start-up, so the engine fell back rather than refusing to start)`;
121
+ }
122
+ if (reason === 'local_unwritable') {
123
+ return `${assembled} — ${lost} (degraded: the default local file store could not be created, for example a read-only or full data directory)`;
124
+ }
125
+ return `${assembled} — ${lost} (degraded for a reason this client does not know yet: "${word(reason)}")`;
126
+ }
127
+ export function forgetStorePostureReading(baseUrl) {
128
+ reader.forget(baseUrl);
129
+ }
130
+ export function __resetStorePostureReadingsForTests() {
131
+ reader.__resetForTests();
132
+ }
@@ -3,53 +3,8 @@ import { markEngineWorkflowNotified, registerOutstandingBgTask, registerOutstand
3
3
  import { parseWorkflowPollEnvelope, projectWorkflowTaskOutput } from './workflow.js';
4
4
  import { asModelFallbackReason } from './engineErrorCodes.js';
5
5
  import { frozenSet } from './frozenSet.js';
6
- export const STRUCTURED_DETAIL_TYPES = frozenSet([
7
- 'edit',
8
- 'create',
9
- 'update',
10
- 'bash',
11
- 'notebook-edit',
12
- 'notebook',
13
- 'text',
14
- 'grep',
15
- 'glob',
16
- 'mcp',
17
- 'agent',
18
- 'task',
19
- 'task-list',
20
- 'task-output',
21
- 'workflow-run',
22
- 'web-fetch',
23
- 'web-search',
24
- 'todo',
25
- 'cron-create',
26
- 'cron-delete',
27
- 'cron-list',
28
- 'image',
29
- 'task-stop',
30
- 'tool-search',
31
- 'repo-map',
32
- 'fork',
33
- 'enter-plan-mode',
34
- 'exit-plan-mode',
35
- 'file_unchanged',
36
- 'worktree',
37
- 'monitor-start',
38
- 'path_not_in_root',
39
- 'readonly_out_of_root',
40
- 'report-findings',
41
- 'schedule-wakeup',
42
- 'send-message',
43
- 'agent-transcript',
44
- 'a2a',
45
- 'document',
46
- 'ask-question',
47
- 'bash_invalid_timeout',
48
- 'read_path_denied',
49
- 'list-agents',
50
- 'artifact',
51
- 'read-inbox',
52
- ]);
6
+ import { CORE_ENGINE_CARD_TYPES } from './generated/engineFactTables.js';
7
+ export const STRUCTURED_DETAIL_TYPES = frozenSet(CORE_ENGINE_CARD_TYPES);
53
8
  export function structuredDetailType(structured) {
54
9
  if (typeof structured !== 'object' || structured === null)
55
10
  return undefined;
@@ -6,6 +6,7 @@ export type TurnWireErrorVerdict = {
6
6
  message: string;
7
7
  storedRowWhere?: string;
8
8
  sessionUnreadable?: true;
9
+ leaseUnavailable?: true;
9
10
  } | {
10
11
  kind: 'stream-ended-without-terminal';
11
12
  } | {
@@ -1,5 +1,6 @@
1
1
  import { readErrorNumber, readErrorString, readErrorStringList } from './wireFailureShape.js';
2
2
  import { capForDisplay } from './fleetTaskDesc.js';
3
+ import { fleetLeaseUnavailableFromError } from './wireRefusalCopy.js';
3
4
  import { DRAINING_ERROR_CODE, isCorruptSessionCode, RESUME_AT_ERROR_CODE_PREFIX, RESUME_POLICY_FOLD_CODE, RESUME_RETRY_LATER_CODES, RESUME_USAGE_WINDOW_EXHAUSTED, SCENARIO_NOT_ALLOWED_ERROR_CODE, } from './engineErrorCodes.js';
4
5
  export const WIRE_NETWORK_ERROR_PATTERN = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|EPIPE|socket hang up|UND_ERR|terminated|other side closed/i;
5
6
  function wireErrorDetail(err) {
@@ -16,6 +17,7 @@ export function classifyTurnWireError(err) {
16
17
  const message = typeof e.message === 'string' && e.message.length > 0 ? e.message : String(err);
17
18
  const storedRowWhere = corruptStoredRowWhere(err);
18
19
  const sessionUnreadable = isCorruptSessionCode(effectiveWireErrorCode(err));
20
+ const leaseUnavailable = fleetLeaseUnavailableFromError(err) !== null;
19
21
  return {
20
22
  kind: 'http',
21
23
  status: e.status,
@@ -23,6 +25,7 @@ export function classifyTurnWireError(err) {
23
25
  message,
24
26
  ...(storedRowWhere !== undefined ? { storedRowWhere } : {}),
25
27
  ...(sessionUnreadable ? { sessionUnreadable: true } : {}),
28
+ ...(leaseUnavailable ? { leaseUnavailable: true } : {}),
26
29
  };
27
30
  }
28
31
  const errName = typeof err === 'object' && err !== null && typeof err.name === 'string'
@@ -3,10 +3,13 @@ interface WireFailureShape {
3
3
  errorCode?: string;
4
4
  retryAfterSec?: number;
5
5
  committed?: 'no' | 'unknown' | 'unreadable';
6
+ bodyField?: string;
7
+ bodyName?: string;
6
8
  message: string;
7
9
  }
8
10
  export declare function readErrorNumber(o: object, key: string): number | undefined;
9
11
  export declare function readErrorString(o: object, key: string): string | undefined;
10
12
  export declare function readErrorStringList(o: object, key: string): readonly string[] | undefined;
13
+ export declare function readErrorStrictStringList(o: object, key: string): readonly string[] | undefined;
11
14
  export declare function wireFailureShapeOf(e: unknown): WireFailureShape;
12
15
  export {};
@@ -52,6 +52,33 @@ export function readErrorStringList(o, key) {
52
52
  const v = readErrorSlot(o, key, (x) => Array.isArray(x));
53
53
  return Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
54
54
  }
55
+ export function readErrorStrictStringList(o, key) {
56
+ const strict = (x) => {
57
+ if (!Array.isArray(x))
58
+ return false;
59
+ for (let i = 0; i < x.length; i++)
60
+ if (typeof x[i] !== 'string')
61
+ return false;
62
+ return true;
63
+ };
64
+ const v = readErrorSlot(o, key, strict);
65
+ if (!Array.isArray(v))
66
+ return undefined;
67
+ try {
68
+ const out = [];
69
+ const len = v.length;
70
+ for (let i = 0; i < len; i++) {
71
+ const item = v[i];
72
+ if (typeof item !== 'string')
73
+ return undefined;
74
+ out.push(item);
75
+ }
76
+ return out;
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
81
+ }
55
82
  export function wireFailureShapeOf(e) {
56
83
  const o = e ?? {};
57
84
  const status = readGuarded(o, 'status');
@@ -85,6 +112,21 @@ export function wireFailureShapeOf(e) {
85
112
  }
86
113
  }
87
114
  }
115
+ const ownString = (key) => {
116
+ if (extraObj === undefined)
117
+ return undefined;
118
+ try {
119
+ if (!Object.hasOwn(extraObj, key))
120
+ return undefined;
121
+ const v = extraObj[key];
122
+ return typeof v === 'string' ? v : undefined;
123
+ }
124
+ catch {
125
+ return undefined;
126
+ }
127
+ };
128
+ const bodyField = ownString('field');
129
+ const bodyName = ownString('name');
88
130
  let message;
89
131
  try {
90
132
  message = typeof rawMessage === 'string' && rawMessage !== '' ? rawMessage : String(e);
@@ -107,6 +149,8 @@ export function wireFailureShapeOf(e) {
107
149
  ...(typeof errorCode === 'string' ? { errorCode } : {}),
108
150
  ...(sec !== undefined ? { retryAfterSec: sec } : {}),
109
151
  ...(committed !== undefined ? { committed } : {}),
152
+ ...(bodyField !== undefined ? { bodyField } : {}),
153
+ ...(bodyName !== undefined ? { bodyName } : {}),
110
154
  message,
111
155
  };
112
156
  }
@@ -1,4 +1,5 @@
1
- import { USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
1
+ import { FLEET_LEASE_UNAVAILABLE, USAGE_WINDOW_EXHAUSTED } from './engineErrorCodes.js';
2
+ import type { TaskRequestLike } from './request/taskRequest.js';
2
3
  export declare const CONFLICT_APPROVAL_SETTLED = "conflict.approval_settled";
3
4
  export declare const CONFLICT_RUN_NOT_RUNNING = "conflict.run_not_running";
4
5
  export type CancelConflictKind = 'approval_settled' | 'run_not_running' | 'unrecognized';
@@ -14,6 +15,13 @@ export interface UsageWindowExhaustedDetail {
14
15
  }
15
16
  export declare function usageWindowExhaustedFromError(err: unknown): UsageWindowExhaustedDetail | null;
16
17
  export declare function usageWindowExhaustedContent(detail: UsageWindowExhaustedDetail): string;
18
+ export interface FleetLeaseUnavailableDetail {
19
+ code: typeof FLEET_LEASE_UNAVAILABLE;
20
+ reason?: string;
21
+ retryAfterSec?: number;
22
+ }
23
+ export declare function fleetLeaseUnavailableFromError(err: unknown): FleetLeaseUnavailableDetail | null;
24
+ export declare function fleetLeaseUnavailableContent(detail: FleetLeaseUnavailableDetail): string;
17
25
  export type DenyAttributionRefusalKind = 'not_in_proof' | 'decision_conflict' | 'attribution_rejected';
18
26
  export interface DenyAttributionRefusalDetail {
19
27
  kind: DenyAttributionRefusalKind;
@@ -33,3 +41,33 @@ export interface SessionDeleteConflictDetail {
33
41
  }
34
42
  export declare function sessionDeleteConflictFromError(err: unknown): SessionDeleteConflictDetail | null;
35
43
  export declare function sessionDeleteConflictContent(detail: Pick<SessionDeleteConflictDetail, 'kind' | 'remaining' | 'activeTaskId'>): string;
44
+ export type SettingsPermissionBucket = 'allow' | 'deny' | 'ask';
45
+ export type SettingsPermissionBucketRefusalReason = 'over_cap' | 'bad_entry';
46
+ export interface SettingsPermissionBucketRefusalDetail {
47
+ readonly bucket: SettingsPermissionBucket;
48
+ readonly reason: SettingsPermissionBucketRefusalReason;
49
+ readonly count?: number;
50
+ readonly cap?: number;
51
+ readonly index?: number;
52
+ readonly folded?: true;
53
+ }
54
+ export declare function settingsPermissionBucketRefusalFromError(err: unknown): SettingsPermissionBucketRefusalDetail | null;
55
+ export declare function settingsPermissionBucketRefusalContent(detail: SettingsPermissionBucketRefusalDetail): string;
56
+ export interface ToolDeclarationRefusalDetail {
57
+ readonly code: string;
58
+ }
59
+ export declare function toolDeclarationRefusalFromError(err: unknown): ToolDeclarationRefusalDetail | null;
60
+ export declare function toolDeclarationRefusalContent(_detail: Pick<ToolDeclarationRefusalDetail, 'code'>): string;
61
+ export interface BodyShapeRefusalDetail {
62
+ readonly unknownKeys?: readonly string[];
63
+ readonly unsupportedKeys?: readonly string[];
64
+ }
65
+ export declare function bodyShapeRefusalFromError(err: unknown): BodyShapeRefusalDetail | null;
66
+ export declare function bodyShapeRefusalTouchesSettings(detail: BodyShapeRefusalDetail | null | undefined, sentBody?: TaskRequestLike): boolean | undefined;
67
+ export interface HostPostureRefusalDetail {
68
+ readonly code: string;
69
+ readonly askedWholeEnvironment?: true;
70
+ readonly askedOpenWriteFace?: true;
71
+ }
72
+ export declare function hostPostureRefusalFromError(err: unknown, sentRequest?: TaskRequestLike): HostPostureRefusalDetail | null;
73
+ export declare function hostPostureRefusalContent(detail: Pick<HostPostureRefusalDetail, 'askedWholeEnvironment' | 'askedOpenWriteFace'>): string;