@sema-agent/client-core 0.83.6 → 0.84.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +176 -0
  2. package/README.md +20 -13
  3. package/dist/abortableSleep.d.ts +10 -0
  4. package/dist/abortableSleep.js +37 -0
  5. package/dist/adapt/wireShapes.js +3 -2
  6. package/dist/adapter/activeRunSelfHeal.js +7 -7
  7. package/dist/adapter/downstream/eventToSdkMessage.js +6 -2
  8. package/dist/adapter/downstream/terminalToSdkResult.d.ts +1 -0
  9. package/dist/adapter/downstream/terminalToSdkResult.js +10 -5
  10. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  11. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  12. package/dist/agentSession/engineAgentRegistryRead.d.ts +18 -0
  13. package/dist/agentSession/engineAgentRegistryRead.js +167 -0
  14. package/dist/agentsWireCaps.js +10 -1
  15. package/dist/attachmentsWireCaps.js +2 -2
  16. package/dist/controlRouter.js +1 -1
  17. package/dist/decideFailureNote.d.ts +2 -1
  18. package/dist/decideFailureNote.js +5 -3
  19. package/dist/detachWire.d.ts +1 -0
  20. package/dist/detachWire.js +13 -5
  21. package/dist/displayUntrusted.js +114 -18
  22. package/dist/engineAgentAbsence.d.ts +37 -0
  23. package/dist/engineAgentAbsence.js +142 -0
  24. package/dist/engineErrorCodes.d.ts +2 -0
  25. package/dist/engineErrorCodes.js +9 -5
  26. package/dist/engineNoticeCodes.d.ts +43 -0
  27. package/dist/engineNoticeCodes.js +118 -5
  28. package/dist/engineWireSdk.d.ts +2 -0
  29. package/dist/fleet/fleetProjection.js +3 -2
  30. package/dist/frozenSet.d.ts +1 -0
  31. package/dist/frozenSet.js +20 -0
  32. package/dist/handsSeam.d.ts +3 -0
  33. package/dist/handsSeam.js +19 -0
  34. package/dist/hitl/askGateWire.d.ts +1 -1
  35. package/dist/hitl/askGateWire.js +1 -1
  36. package/dist/hitl/hitlHostSurface.js +1 -1
  37. package/dist/hitl/parkResolver.d.ts +1 -0
  38. package/dist/hitl/parkResolver.js +9 -3
  39. package/dist/hitl/planReviewWire.d.ts +30 -3
  40. package/dist/hitl/planReviewWire.js +139 -32
  41. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  42. package/dist/hitl/sessionPolicyDeliverable.js +14 -3
  43. package/dist/hitl/sessionPolicyWire.d.ts +40 -0
  44. package/dist/hitl/sessionPolicyWire.js +210 -0
  45. package/dist/hitl/toolApprovalWire.js +2 -2
  46. package/dist/index.d.ts +24 -13
  47. package/dist/index.js +13 -13
  48. package/dist/liveInitToolFace.js +28 -10
  49. package/dist/model/catalogLoader.js +3 -3
  50. package/dist/model/tierVocabulary.js +1 -1
  51. package/dist/request/taskRequest.js +15 -5
  52. package/dist/resumeRefusalCopy.d.ts +11 -0
  53. package/dist/resumeRefusalCopy.js +39 -1
  54. package/dist/rewindWireCaps.d.ts +0 -1
  55. package/dist/seam.d.ts +2 -1
  56. package/dist/seatContract.js +2 -2
  57. package/dist/systemReminderTag.d.ts +5 -0
  58. package/dist/systemReminderTag.js +20 -9
  59. package/dist/toolResult.js +2 -6
  60. package/dist/toolRoster.d.ts +16 -0
  61. package/dist/toolRoster.js +46 -5
  62. package/dist/wireErrorTriage.js +1 -11
  63. package/dist/workflowClient.js +4 -3
  64. package/dist/workflowMonitor.d.ts +1 -1
  65. package/docs/INTEGRATION-CLIENTS.md +701 -37
  66. package/package.json +3 -3
@@ -1,3 +1,5 @@
1
+ import { displayUntrusted } from './displayUntrusted.js';
2
+ import { HANDS_REASON_NO_EXECUTION_ENV, projectHandsSection } from './handsSeam.js';
1
3
  const str = (v) => typeof v === 'string' && v.length > 0 ? v : undefined;
2
4
  const strArr = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
3
5
  const obj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined;
@@ -135,14 +137,51 @@ export function handsMountedFromManifest(manifest) {
135
137
  const rows = roster.entries.filter((e) => e.mountedBy === 'hands').length;
136
138
  return rows > 0 ? { kind: 'mounted', rows } : { kind: 'not-mounted' };
137
139
  }
138
- export function handsMountedDetail(reading) {
139
- switch (reading.kind) {
140
+ export function handsSeamReadingOf(view) {
141
+ const seam = typeof view === 'object' && view !== null ? projectHandsSection(view) : undefined;
142
+ if (seam === undefined)
143
+ return { kind: 'not_reported' };
144
+ if (seam.mounted)
145
+ return { kind: 'mounted' };
146
+ return seam.reason !== undefined ? { kind: 'not_mounted', reason: seam.reason } : { kind: 'not_mounted' };
147
+ }
148
+ const HANDS_NONE_STEM = 'this leg of the run was assembled with NO built-in file-and-shell tools';
149
+ const HANDS_NONE_TAIL = "so on this leg the model had no tool of the engine's own for editing files or running commands (tools mounted by other conditions, such as external servers, and sub-runs delegated to other legs are not covered by this reading)";
150
+ const HANDS_REASON_DISPLAY_MAX = 64;
151
+ const HANDS_NOT_REPORTED_SENTENCE = 'whether this leg has built-in file-and-shell tools is not stated here — the engine did not report its hands seam (older engines and servers, and the static half of a manifest, never do); the tool roster may still answer it';
152
+ export function handsSeamDetail(reading) {
153
+ const kind = typeof reading === 'object' && reading !== null ? reading.kind : undefined;
154
+ switch (kind) {
140
155
  case 'mounted':
141
- return `this run was assembled with file-and-shell tools mounted (${reading.rows} of them)`;
156
+ return 'this leg of the run was assembled with its built-in file tools mounted — the engine says so; whether a shell is reachable is answered by the tool roster, not by this statement';
157
+ case 'not_mounted': {
158
+ const raw = reading.reason;
159
+ const reason = typeof raw === 'string' && raw.length > 0 ? raw : undefined;
160
+ const why = reason === undefined
161
+ ? 'the engine states it mounted no hands on this leg (it gave no reason)'
162
+ : reason === HANDS_REASON_NO_EXECUTION_ENV
163
+ ? 'the engine states it mounted no hands on this leg because no execution environment was supplied'
164
+ : `the engine states it mounted no hands on this leg (reason: ${displayUntrusted(reason, { max: HANDS_REASON_DISPLAY_MAX })}, a word this build does not know)`;
165
+ return `${HANDS_NONE_STEM} — ${why}, ${HANDS_NONE_TAIL}`;
166
+ }
167
+ default:
168
+ return HANDS_NOT_REPORTED_SENTENCE;
169
+ }
170
+ }
171
+ export function handsMountedDetail(reading) {
172
+ const r = reading;
173
+ const kind = typeof r === 'object' && r !== null ? r.kind : undefined;
174
+ switch (kind) {
175
+ case 'mounted': {
176
+ const rows = r.rows;
177
+ if (typeof rows === 'number' && Number.isInteger(rows) && rows > 0)
178
+ return `this run was assembled with file-and-shell tools mounted (${rows} of them)`;
179
+ return HANDS_NOT_REPORTED_SENTENCE;
180
+ }
142
181
  case 'not-mounted':
143
- return 'this leg of the run was assembled with NO built-in file-and-shell tools — the engine reports a roster and not one row was mounted by that condition, so on this leg the model had no tool of the engine\'s own for editing files or running commands (tools mounted by other conditions, such as external servers, and sub-runs delegated to other legs are not covered by this reading)';
182
+ return `${HANDS_NONE_STEM} — the engine reports a roster and not one row was mounted by that condition, ${HANDS_NONE_TAIL}`;
144
183
  case 'unknown':
145
- switch (reading.why) {
184
+ switch (r.why) {
146
185
  case 'no-manifest':
147
186
  return 'whether this run has file-and-shell tools is unknown — no assembly manifest was observed for it';
148
187
  case 'no-roster':
@@ -152,7 +191,9 @@ export function handsMountedDetail(reading) {
152
191
  case 'mount-condition-absent':
153
192
  return 'whether this run has file-and-shell tools is unknown — this engine does not report which condition mounted each tool, so an empty count here would be a fact about the reader, not about the run';
154
193
  }
194
+ return HANDS_NOT_REPORTED_SENTENCE;
155
195
  }
196
+ return HANDS_NOT_REPORTED_SENTENCE;
156
197
  }
157
198
  export function toolRosterNames(roster) {
158
199
  return roster?.entries.map((e) => e.name) ?? [];
@@ -45,10 +45,6 @@ export function isPreStreamDrainingReject(err) {
45
45
  const e = err;
46
46
  return typeof e?.status === 'number' && e.status === 503 && e.errorCode === DRAINING_ERROR_CODE;
47
47
  }
48
- const RESUME_AT_TEXT_COMPAT = [
49
- { status: 404, marker: `(${RESUME_AT_ERROR_CODE_PREFIX}unknown_event)` },
50
- { status: 422, marker: `(${RESUME_AT_ERROR_CODE_PREFIX}no_session)` },
51
- ];
52
48
  export function effectiveWireErrorCode(err) {
53
49
  if (typeof err !== 'object' || err === null)
54
50
  return undefined;
@@ -75,14 +71,8 @@ export function corruptStoredRowContent(where) {
75
71
  return `The engine could not read a stored record this session needs in order to continue. The unreadable row is ${capForDisplay(where, 200)}; whoever operates this engine has to repair or remove that row before this session can continue.`;
76
72
  }
77
73
  export function isResumeAtRejection(err) {
78
- const e = err;
79
74
  const code = effectiveWireErrorCode(err);
80
- if (code !== undefined && code.startsWith(RESUME_AT_ERROR_CODE_PREFIX))
81
- return true;
82
- const marker = RESUME_AT_TEXT_COMPAT.find((c) => c.status === e?.status)?.marker;
83
- if (marker === undefined)
84
- return false;
85
- return [e?.message, e?.errorMessage].some((t) => typeof t === 'string' && t.endsWith(marker));
75
+ return code !== undefined && code.startsWith(RESUME_AT_ERROR_CODE_PREFIX);
86
76
  }
87
77
  export function drainingRetryDelayMs(err, attempt, opts) {
88
78
  const ra = err?.retryAfterMs;
@@ -240,7 +240,8 @@ function synthPhaseStatus(runStatus, agents) {
240
240
  }
241
241
  export function projectWorkflowRun(run) {
242
242
  const parks = readWorkflowParks(run);
243
- const agents = (run.agents ?? []).map((r, i) => projectAgent(r, i));
243
+ const agentsKnown = Array.isArray(run.agents);
244
+ const agents = (agentsKnown ? run.agents : []).map((r, i) => projectAgent(r, i));
244
245
  const phases = projectPhases(run, agents);
245
246
  const validTokens = (v) => typeof v === 'number' && Number.isInteger(v) && v >= 0 ? v : undefined;
246
247
  const ownTokens = validTokens(run.stats?.tokens);
@@ -265,7 +266,7 @@ export function projectWorkflowRun(run) {
265
266
  ...(parks !== undefined ? { parks } : {}),
266
267
  ...(readWorkflowResumeAdmissionIncomplete(run) ? { resumeAdmissionIncomplete: true } : {}),
267
268
  script: '',
268
- agentCount: agents.length,
269
+ ...(agentsKnown ? { agentCount: agents.length } : {}),
269
270
  ...(totalTokens !== undefined ? { totalTokens } : {}),
270
271
  phases,
271
272
  };
@@ -814,7 +815,7 @@ export function createLiveWorkflowSource(config) {
814
815
  code = null;
815
816
  lastError = null;
816
817
  if (engineWireDebugEnabled()) {
817
- hostLog('debug', `[sema][workflow][perf] get ${Date.now() - t0}ms first=${first} agents=${current.agentCount} phases=${current.phases.length}`);
818
+ hostLog('debug', `[sema][workflow][perf] get ${Date.now() - t0}ms first=${first} agents=${current.agentCount ?? '?'} phases=${current.phases.length}`);
818
819
  }
819
820
  first = false;
820
821
  notify();
@@ -49,7 +49,7 @@ export interface WorkflowRunState {
49
49
  scriptPath?: string;
50
50
  status: 'running' | 'done' | 'failed' | 'stopped' | 'paused' | 'parked' | 'unknown';
51
51
  cloud?: boolean;
52
- agentCount: number;
52
+ agentCount?: number;
53
53
  totalTokens?: number;
54
54
  phases: WorkflowPhase[];
55
55
  parks?: readonly WorkflowParkRowView[];