@sema-agent/client-core 0.90.0 → 0.91.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 (88) hide show
  1. package/CHANGELOG.md +193 -0
  2. package/README.md +24 -18
  3. package/dist/adapt/arms.js +9 -0
  4. package/dist/adapter/downstream/eventToSdkMessage.js +4 -2
  5. package/dist/adapter/downstream/wiringManifestView.d.ts +6 -0
  6. package/dist/adapter/downstream/wiringManifestView.js +16 -0
  7. package/dist/adapter/runStream.js +37 -20
  8. package/dist/askSurvivesStandingAnswer.d.ts +10 -0
  9. package/dist/askSurvivesStandingAnswer.js +40 -0
  10. package/dist/attachmentSeatCapability.d.ts +11 -0
  11. package/dist/attachmentSeatCapability.js +27 -0
  12. package/dist/attachmentsWireCaps.d.ts +9 -0
  13. package/dist/attachmentsWireCaps.js +74 -21
  14. package/dist/compensations.js +10 -14
  15. package/dist/controlRouter.d.ts +9 -2
  16. package/dist/controlRouter.js +66 -28
  17. package/dist/decideFailureNote.js +4 -2
  18. package/dist/disableSkillsWire.d.ts +1 -0
  19. package/dist/disableSkillsWire.js +8 -1
  20. package/dist/displayUntrusted.js +153 -4
  21. package/dist/engineCapsCache.d.ts +3 -1
  22. package/dist/engineCapsCache.js +56 -6
  23. package/dist/engineClosedSets.d.ts +2 -0
  24. package/dist/engineClosedSets.js +3 -0
  25. package/dist/engineErrorCodes.d.ts +3 -0
  26. package/dist/engineErrorCodes.js +10 -0
  27. package/dist/generated/engineFactTables.d.ts +12 -0
  28. package/dist/generated/engineFactTables.js +47 -0
  29. package/dist/hitl/askGateWire.d.ts +1 -1
  30. package/dist/hitl/askGateWire.js +1 -1
  31. package/dist/hitl/crashConverged.d.ts +7 -0
  32. package/dist/hitl/crashConverged.js +57 -0
  33. package/dist/hitl/crashConvergedNotice.d.ts +4 -0
  34. package/dist/hitl/crashConvergedNotice.js +57 -0
  35. package/dist/hitl/hitlBridge.d.ts +7 -4
  36. package/dist/hitl/parkResolver.d.ts +7 -2
  37. package/dist/hitl/parkResolver.js +19 -7
  38. package/dist/hitl/planReviewWire.d.ts +1 -1
  39. package/dist/hitl/planReviewWire.js +18 -4
  40. package/dist/hitl/sessionPolicyWire.d.ts +5 -0
  41. package/dist/hitl/sessionPolicyWire.js +63 -0
  42. package/dist/hitl/suspendedReopen.js +2 -2
  43. package/dist/hitl/toolApprovalWire.d.ts +4 -1
  44. package/dist/hitl/toolApprovalWire.js +20 -0
  45. package/dist/hookMatcherVerdict.d.ts +29 -0
  46. package/dist/hookMatcherVerdict.js +265 -0
  47. package/dist/humanTurn.d.ts +91 -0
  48. package/dist/humanTurn.js +253 -0
  49. package/dist/humanTurnRead.d.ts +105 -0
  50. package/dist/humanTurnRead.js +331 -0
  51. package/dist/index.d.ts +25 -8
  52. package/dist/index.js +16 -6
  53. package/dist/inheritEnvWire.js +1 -1
  54. package/dist/liveModelCatalog.d.ts +2 -0
  55. package/dist/liveModelCatalog.js +51 -3
  56. package/dist/permissionRuleIssue.d.ts +1 -1
  57. package/dist/permissionRuleIssue.js +22 -3
  58. package/dist/permissionsAllowGrantCapability.d.ts +2 -1
  59. package/dist/permissionsAllowGrantCapability.js +11 -2
  60. package/dist/permissionsDeclaration.d.ts +23 -0
  61. package/dist/permissionsDeclaration.js +133 -53
  62. package/dist/promptDelivery.d.ts +11 -3
  63. package/dist/promptDelivery.js +164 -29
  64. package/dist/providerRejection.d.ts +1 -0
  65. package/dist/providerRejection.js +20 -0
  66. package/dist/readDenyTiers.d.ts +10 -0
  67. package/dist/readDenyTiers.js +29 -0
  68. package/dist/request/taskRequest.js +2 -2
  69. package/dist/resumeRefusalCopy.d.ts +11 -0
  70. package/dist/resumeRefusalCopy.js +61 -4
  71. package/dist/rewindArchiveCapability.js +4 -4
  72. package/dist/rewindWireCaps.d.ts +2 -1
  73. package/dist/rewindWireCaps.js +19 -2
  74. package/dist/seam.d.ts +2 -0
  75. package/dist/taskRequestWords.d.ts +7 -1
  76. package/dist/taskRequestWords.js +18 -8
  77. package/dist/toolHistoryBadTurn.d.ts +1 -0
  78. package/dist/toolHistoryBadTurn.js +89 -0
  79. package/dist/toolHistoryMismatch.d.ts +2 -1
  80. package/dist/toolHistoryMismatch.js +19 -6
  81. package/dist/userAttachmentEnvelope.d.ts +61 -0
  82. package/dist/userAttachmentEnvelope.js +204 -0
  83. package/dist/wireFailureShape.d.ts +1 -0
  84. package/dist/wireFailureShape.js +4 -0
  85. package/dist/wireRefusalCopy.d.ts +6 -0
  86. package/dist/wireRefusalCopy.js +26 -3
  87. package/docs/INTEGRATION-CLIENTS.md +875 -14
  88. package/package.json +2 -2
@@ -3,11 +3,17 @@ import { uuid } from './adapter/types.js';
3
3
  export class ControlSafetyError extends Error {
4
4
  code;
5
5
  cause;
6
- constructor(message, code, cause) {
6
+ constructor(message, code, cause, detail) {
7
7
  super(message);
8
8
  this.code = code;
9
9
  this.cause = cause;
10
10
  this.name = 'ControlSafetyError';
11
+ const advice = detail?.advice;
12
+ const status = detail?.status;
13
+ if (typeof advice === 'string' && advice.length > 0)
14
+ this.advice = advice;
15
+ if (typeof status === 'number')
16
+ this.status = status;
11
17
  }
12
18
  }
13
19
  const BAND_RANK = { now: 0, next: 1, later: 2 };
@@ -55,39 +61,38 @@ export class ControlRouter {
55
61
  }
56
62
  async steer(text, mode, opts) {
57
63
  if (this.taskId === null) {
58
- throw new ControlSafetyError('no run in flight to steer — submit a turn first', 'not_running');
64
+ throw controlSafetyRefusal('not_running', 'no run in flight to steer', 'submit a turn first');
59
65
  }
60
66
  const body = mode !== undefined ? { text, mode } : { text };
61
67
  try {
62
68
  return await this.client.runs.steer(this.taskId, body, opts?.signal !== undefined ? { signal: opts.signal } : undefined);
63
69
  }
64
70
  catch (e) {
65
- const verdict = steeringVerdict(e);
66
- if (verdict !== undefined) {
67
- const safety = steeringSafetyOf(e, verdict);
68
- const wireCode = errCodes(e).code ?? errCodes(e).name ?? 'steering.<unknown>';
69
- throw new ControlSafetyError(`${wireCode} — ${steeringAdviceOf(e, safety) ?? 'steering refused'}`, safety, e);
71
+ if (typeof e === 'object' && e !== null) {
72
+ const refusal = steerRefusalAdviceOf(e);
73
+ if (refusal !== undefined)
74
+ throw controlSafetyRefusal(refusal.safety, steerRefusalWireLabel(e), refusal.advice, e);
70
75
  }
71
76
  throw e;
72
77
  }
73
78
  }
74
79
  async cancel(opts) {
75
80
  if (this.taskId === null) {
76
- throw new ControlSafetyError('no run in flight to cancel', 'not_found');
81
+ throw controlSafetyRefusal('not_found', 'no run in flight to cancel');
77
82
  }
78
83
  try {
79
84
  return await this.client.runs.cancel(this.taskId, opts?.signal !== undefined ? { signal: opts.signal } : undefined);
80
85
  }
81
86
  catch (e) {
82
87
  if (cancelConflictFromError(e)?.kind === 'run_not_running') {
83
- throw new ControlSafetyError(`runs.cancel 409 conflict.run_not_running — ${cancelConflictContent({ kind: 'run_not_running' })}`, 'cancel_run_not_running', e);
88
+ throw controlSafetyRefusal('cancel_run_not_running', 'runs.cancel 409 conflict.run_not_running', cancelConflictContent({ kind: 'run_not_running' }), e);
84
89
  }
85
90
  if (isCancelSuspendedConflict(e)) {
86
- throw new ControlSafetyError('runs.cancel 409 — the pending gate was decided or expired concurrently (lost CAS race); ' +
87
- 'check what that decision did to the run before retrying the cancel', 'cancel_lost_race', e);
91
+ throw controlSafetyRefusal('cancel_lost_race', 'runs.cancel 409', 'the pending gate was decided or expired concurrently (lost CAS race); ' +
92
+ 'check what that decision did to the run before retrying the cancel', e);
88
93
  }
89
94
  if (isNotFound(e)) {
90
- throw new ControlSafetyError('runs.cancel 404 — non-owner / unknown run (no existence leak)', 'not_found', e);
95
+ throw controlSafetyRefusal('not_found', 'runs.cancel 404 — non-owner / unknown run (no existence leak)', undefined, e);
91
96
  }
92
97
  throw e;
93
98
  }
@@ -149,17 +154,17 @@ const STEERING_NAME_TO_SAFETY = new Map([
149
154
  ['SteeringLedgerUnavailableError', 'ledger_unavailable'],
150
155
  ['SteeringError', 'steering_other'],
151
156
  ]);
152
- const STEERING_ADVICE = new Map([
153
- ['not_running', 'the run is suspended/terminal/on another replica — resolve its gate via decide, do not steer'],
154
- ['invalid_content', 'the steer text carried a control-plane escape; surface it, do not strip-and-retry'],
155
- ['queue_full', 'the parked steering queue on this checkpoint is full (core fails loud rather than evicting an accepted instruction) — wait for it to drain, do not resend'],
156
- ['duplicate_input_id', 'this Idempotency-Key is already parked with DIFFERENT steering content — reissue with a fresh key, resending verbatim will never succeed'],
157
- ['ambiguous_target', 'more than one live target matches — address it uniquely (sub-agent: parentToolCallId; workflow: a more specific label); retrying verbatim yields the same result'],
158
- ['still_running', 'the target is STILL RUNNING — steer it instead of resuming, or wait for it to settle (this is the exact opposite of not_running: never collapse the two)'],
159
- ['blocked_by_hook', "this deployment's userPromptSubmit gate refused the input (block, timeout and crash all report this one code, fail-closed) — the input was NOT accepted: no human_input frame, the inputId is not on the ledger, so editing the text and sending again is a normal retry, not a duplicate"],
160
- ['ledger_unavailable', 'the server could not record this steer in its user-input ledger and refused it before anything reached the engine — the input was NOT delivered; resend the same text later (the same Idempotency-Key is fine)'],
161
- ['steering_other', 'an unrecognized steering.* refusal (open set) — the steer did NOT land; log the errorCode verbatim, do not guess its meaning'],
162
- ]);
157
+ const STEERING_ADVICE = {
158
+ not_running: 'the run is suspended/terminal/on another replica — resolve its gate via decide, do not steer',
159
+ invalid_content: 'the steer text carried a control-plane escape; surface it, do not strip-and-retry',
160
+ queue_full: 'the parked steering queue on this checkpoint is full (core fails loud rather than evicting an accepted instruction) — wait for it to drain, do not resend',
161
+ duplicate_input_id: 'this Idempotency-Key is already parked with DIFFERENT steering content — reissue with a fresh key, resending verbatim will never succeed',
162
+ ambiguous_target: 'more than one live target matches — address it uniquely (sub-agent: parentToolCallId; workflow: a more specific label); retrying verbatim yields the same result',
163
+ still_running: 'the target is STILL RUNNING — steer it instead of resuming, or wait for it to settle (this is the exact opposite of not_running: never collapse the two)',
164
+ blocked_by_hook: "this deployment's userPromptSubmit gate refused the input (block, timeout and crash all report this one code, fail-closed) — the input was NOT accepted: no human_input frame, the inputId is not on the ledger, so editing the text and sending again is a normal retry, not a duplicate",
165
+ ledger_unavailable: 'the server could not record this steer in its user-input ledger and refused it before anything reached the engine — the input was NOT delivered; resend the same text later (the same Idempotency-Key is fine)',
166
+ steering_other: 'an unrecognized steering.* refusal (open set) — the steer did NOT land; log the errorCode verbatim, do not guess its meaning',
167
+ };
163
168
  const STEERING_OTHER_UNKNOWN_ADVICE = 'an unrecognized steering.* refusal (open set) — treat delivery as unknown (do not resend as if it had certainly been dropped); log the errorCode verbatim, do not guess its meaning';
164
169
  export function steeringStatusIs4xx(e) {
165
170
  let status;
@@ -172,9 +177,9 @@ export function steeringStatusIs4xx(e) {
172
177
  return status !== undefined && status >= 400 && status < 500;
173
178
  }
174
179
  function steeringAdviceOf(e, safety) {
175
- if (safety === 'steering_other' && !(typeof e === 'object' && e !== null && steeringStatusIs4xx(e)))
180
+ if (safety === 'steering_other' && !steeringStatusIs4xx(e))
176
181
  return STEERING_OTHER_UNKNOWN_ADVICE;
177
- return STEERING_ADVICE.get(safety);
182
+ return STEERING_ADVICE[safety];
178
183
  }
179
184
  const STEERING_REFUSED_BEFORE_ENGINE = new Map([['ledger_unavailable', 503]]);
180
185
  export function steeringRefusedBeforeEngine(e) {
@@ -185,8 +190,7 @@ export function steeringRefusedBeforeEngine(e) {
185
190
  const safety = steeringVerdict(e);
186
191
  if (safety === undefined || STEERING_REFUSED_BEFORE_ENGINE.get(safety) !== status)
187
192
  return undefined;
188
- const advice = STEERING_ADVICE.get(safety);
189
- return advice === undefined ? undefined : { safety, advice };
193
+ return { safety, advice: STEERING_ADVICE[safety] };
190
194
  }
191
195
  catch {
192
196
  return undefined;
@@ -195,7 +199,7 @@ export function steeringRefusedBeforeEngine(e) {
195
199
  function steeringSafetyOf(e, verdict) {
196
200
  if (!STEERING_REFUSED_BEFORE_ENGINE.has(verdict))
197
201
  return verdict;
198
- const refused = typeof e === 'object' && e !== null ? steeringRefusedBeforeEngine(e) : undefined;
202
+ const refused = steeringRefusedBeforeEngine(e);
199
203
  return refused !== undefined && refused.safety === verdict ? verdict : 'steering_other';
200
204
  }
201
205
  function steeringVerdict(e) {
@@ -207,6 +211,40 @@ function steeringVerdict(e) {
207
211
  return STEERING_NAME_TO_SAFETY.get(name);
208
212
  return undefined;
209
213
  }
214
+ export function steerRefusalAdviceOf(e) {
215
+ try {
216
+ const verdict = steeringVerdict(e);
217
+ if (verdict === undefined)
218
+ return undefined;
219
+ const safety = steeringSafetyOf(e, verdict);
220
+ return { safety, advice: steeringAdviceOf(e, safety) };
221
+ }
222
+ catch {
223
+ return undefined;
224
+ }
225
+ }
226
+ function steerRefusalWireLabel(e) {
227
+ try {
228
+ const { code, name } = errCodes(e);
229
+ return code ?? name ?? 'steering.<unknown>';
230
+ }
231
+ catch {
232
+ return 'steering.<unknown>';
233
+ }
234
+ }
235
+ function statusOfThrown(e) {
236
+ try {
237
+ return errCodes(e).status;
238
+ }
239
+ catch {
240
+ return undefined;
241
+ }
242
+ }
243
+ function controlSafetyRefusal(code, head, advice, cause) {
244
+ const status = statusOfThrown(cause);
245
+ const detail = { ...(advice !== undefined ? { advice } : {}), ...(status !== undefined ? { status } : {}) };
246
+ return new ControlSafetyError(advice === undefined ? head : `${head} — ${advice}`, code, cause, detail);
247
+ }
210
248
  function isCancelSuspendedConflict(e) {
211
249
  const { name, status } = errCodes(e);
212
250
  return name === 'ConflictError' || status === 409;
@@ -1,5 +1,5 @@
1
1
  import { corruptStoredRowContent, corruptStoredRowWhere } from './wireErrorTriage.js';
2
- import { parkedResumeStartupContent, parkedResumeStartupFromError, resumePolicyBlockContent, resumePolicyBlockFromError, } from './resumeRefusalCopy.js';
2
+ import { checkpointUnsupportedVersionContent, checkpointUnsupportedVersionFromError, parkedResumeStartupContent, parkedResumeStartupFromError, resumePolicyBlockContent, resumePolicyBlockFromError, } from './resumeRefusalCopy.js';
3
3
  import { decideParkMovedContent, decideParkMovedFromError } from './decideReceipt.js';
4
4
  import { settingsPermissionBucketRefusalContent, settingsPermissionBucketRefusalFromError } from './wireRefusalCopy.js';
5
5
  export function decideFailureNote(err, decision) {
@@ -8,9 +8,11 @@ export function decideFailureNote(err, decision) {
8
8
  const startup = parkedResumeStartupFromError(err, decision);
9
9
  const moved = decideParkMovedFromError(err);
10
10
  const bucket = settingsPermissionBucketRefusalFromError(err);
11
+ const unsupported = checkpointUnsupportedVersionFromError(err);
11
12
  return ((where === undefined ? '' : ` — ${corruptStoredRowContent(where)}`) +
12
13
  (fold === null ? '' : ` — ${resumePolicyBlockContent(fold)}`) +
13
14
  (bucket === null ? '' : ` — ${settingsPermissionBucketRefusalContent(bucket)}`) +
14
15
  (startup === null ? '' : ` — ${parkedResumeStartupContent(startup)}`) +
15
- (moved === null ? '' : ` — ${decideParkMovedContent(moved)}`));
16
+ (moved === null ? '' : ` — ${decideParkMovedContent(moved)}`) +
17
+ (unsupported === null ? '' : ` — ${checkpointUnsupportedVersionContent(unsupported)}`));
16
18
  }
@@ -14,4 +14,5 @@ export type DisableSkillsDeclaration = {
14
14
  };
15
15
  };
16
16
  export declare function disableSkillsDeclaration(want: unknown, baseUrl: string | undefined): DisableSkillsDeclaration;
17
+ export declare function disableSkillsDeclarationSettled(want: boolean | null | undefined, baseUrl: string | undefined, withinMs: number): Promise<DisableSkillsDeclaration>;
17
18
  export {};
@@ -1,4 +1,4 @@
1
- import { engineCapState } from './engineCapsCache.js';
1
+ import { engineCapState, engineCapsSettled } from './engineCapsCache.js';
2
2
  const KEY = 'disableSkills';
3
3
  const shapeOf = (v) => {
4
4
  try {
@@ -50,3 +50,10 @@ export function disableSkillsDeclaration(want, baseUrl) {
50
50
  const cause = WITHHELD_CAUSE_OF[state];
51
51
  return Object.freeze({ field: Object.freeze({}), withheld: Object.freeze({ cause, text: WITHHELD_TEXT[cause] }) });
52
52
  }
53
+ export async function disableSkillsDeclarationSettled(want, baseUrl, withinMs) {
54
+ refuseBadDisableSkills(want, 'disableSkillsDeclarationSettled');
55
+ if (want !== true)
56
+ return disableSkillsDeclaration(want, baseUrl);
57
+ await engineCapsSettled(baseUrl, { withinMs: typeof withinMs === 'number' ? withinMs : 0 });
58
+ return disableSkillsDeclaration(want, baseUrl);
59
+ }
@@ -1473,7 +1473,7 @@ function quotedAddressEnd(S, from, to) {
1473
1473
  }
1474
1474
  return to;
1475
1475
  }
1476
- function labelCandidates(S, pass, regions, out) {
1476
+ function labelCandidates(S, pass, regions, out, blocks) {
1477
1477
  const text = S.text;
1478
1478
  const unitAt = (k) => S.unitAt(k);
1479
1479
  const re = pass === 'label' ? SECRET_LABELLED_WORD : SECRET_SCHEME_WORD;
@@ -1642,6 +1642,11 @@ function labelCandidates(S, pass, regions, out) {
1642
1642
  if (schemePass && labelStartsAt(text, hit.index))
1643
1643
  continue;
1644
1644
  const from = hit.index + hit[0].length;
1645
+ if (blocks !== undefined && (text.charCodeAt(from) === 0x7c || text.charCodeAt(from) === 0x3e) && isColonSeparator(hit[0].slice((hit[1] ?? '').length))) {
1646
+ const blk = blockScalarExtent(blocks, S.rawStart(from), S.rawStart(hit.index));
1647
+ if (blk !== null)
1648
+ blocks.out.push({ start: blk.start, end: blk.end, kind: 'secret', cls: 'word', tokenEnd: blk.end, pretrimmed: true });
1649
+ }
1645
1650
  if (credentialWordStartsAt(text, from, idx.tokenInner)) {
1646
1651
  pushInnerRemainder(from);
1647
1652
  re.lastIndex = from;
@@ -1886,6 +1891,149 @@ function lineBreakLengthBefore(text, at) {
1886
1891
  return 2;
1887
1892
  return 0;
1888
1893
  }
1894
+ const isRawBlank = (c) => (isRegexSpace(c) && c !== 0xfeff) || isNameBlank(c);
1895
+ function isColonSeparator(sep) {
1896
+ let colon = false;
1897
+ for (let k = 0; k < sep.length; k++) {
1898
+ const c = sep.charCodeAt(k);
1899
+ if (c === 0x3d || c === 0xff1d)
1900
+ return false;
1901
+ if (c === 0x3a || c === 0xff1a)
1902
+ colon = true;
1903
+ }
1904
+ return colon;
1905
+ }
1906
+ function blockBreakAt(raw, at, escaped) {
1907
+ const n = lineBreakLengthAt(raw, at);
1908
+ return n > 0 && (raw.charCodeAt(at) === 0x5c) === escaped ? n : 0;
1909
+ }
1910
+ function blockMarks(scan) {
1911
+ if (scan.marks !== null)
1912
+ return scan.marks;
1913
+ const V = scan.view;
1914
+ const seq = new Uint8Array(scan.raw.length);
1915
+ const payload = new Uint8Array(scan.raw.length);
1916
+ for (let k = 0; k < V.view.length; k++) {
1917
+ if (V.dropped[k] !== 1 || V.units[k] !== UNIT_SEQUENCE)
1918
+ continue;
1919
+ for (let x = V.starts[k] ?? 0; x < (V.ends[k] ?? 0); x++)
1920
+ seq[x] = 1;
1921
+ }
1922
+ for (const [a, b] of V.contents)
1923
+ for (let x = a; x < b; x++)
1924
+ payload[x] = 1;
1925
+ scan.marks = { seq, payload };
1926
+ return scan.marks;
1927
+ }
1928
+ function blockLines(scan, escaped) {
1929
+ const slot = escaped ? 1 : 0;
1930
+ const have = scan.lines[slot];
1931
+ if (have !== null)
1932
+ return have;
1933
+ const raw = scan.raw;
1934
+ const unit = scan.view.rawUnit;
1935
+ const { seq, payload } = blockMarks(scan);
1936
+ const starts = [];
1937
+ const ends = [];
1938
+ const indent = [];
1939
+ let pos = 0;
1940
+ for (;;) {
1941
+ let k = pos;
1942
+ let n = 0;
1943
+ let width = 0;
1944
+ let lead = true;
1945
+ let visible = false;
1946
+ while (k < raw.length && (n = blockBreakAt(raw, k, escaped)) === 0) {
1947
+ if (lead) {
1948
+ const c = raw.charCodeAt(k);
1949
+ if (payload[k] === 1)
1950
+ visible = true;
1951
+ if (seq[k] === 1) {
1952
+ }
1953
+ else if (isRawBlank(c))
1954
+ width++;
1955
+ else if (unit[k] !== 1) {
1956
+ visible = true;
1957
+ lead = false;
1958
+ }
1959
+ }
1960
+ k++;
1961
+ }
1962
+ starts.push(pos);
1963
+ ends.push(k);
1964
+ indent.push(visible ? width : -1);
1965
+ if (k >= raw.length)
1966
+ break;
1967
+ pos = k + n;
1968
+ }
1969
+ const nextContent = new Int32Array(starts.length + 1);
1970
+ nextContent[starts.length] = starts.length;
1971
+ for (let i = starts.length - 1; i >= 0; i--)
1972
+ nextContent[i] = (indent[i] ?? -1) !== -1 ? i : (nextContent[i + 1] ?? starts.length);
1973
+ const built = { starts, ends, indent, nextContent, memo: new Map() };
1974
+ scan.lines[slot] = built;
1975
+ return built;
1976
+ }
1977
+ function blockLineOf(lines, p) {
1978
+ let lo = 0;
1979
+ let hi = lines.starts.length - 1;
1980
+ while (lo < hi) {
1981
+ const mid = (lo + hi + 1) >> 1;
1982
+ if ((lines.starts[mid] ?? 0) <= p)
1983
+ lo = mid;
1984
+ else
1985
+ hi = mid - 1;
1986
+ }
1987
+ return lo;
1988
+ }
1989
+ function blockScalarExtent(scan, at, labelAt) {
1990
+ const raw = scan.raw;
1991
+ const mark = raw.charCodeAt(at);
1992
+ if (mark !== 0x7c && mark !== 0x3e)
1993
+ return null;
1994
+ const unit = scan.view.rawUnit;
1995
+ let k = at + 1;
1996
+ while (k < raw.length && lineBreakLengthAt(raw, k) === 0) {
1997
+ const c = raw.charCodeAt(k);
1998
+ if (c === 0x2d || c === 0x2b || (c >= 0x30 && c <= 0x39) || (unit[k] === 1 && !isRawBlank(c)))
1999
+ k++;
2000
+ else
2001
+ break;
2002
+ }
2003
+ while (k < raw.length && lineBreakLengthAt(raw, k) === 0 && (isRawBlank(raw.charCodeAt(k)) || unit[k] === 1))
2004
+ k++;
2005
+ if (k >= raw.length)
2006
+ return null;
2007
+ let escaped;
2008
+ if (lineBreakLengthAt(raw, k) > 0)
2009
+ escaped = raw.charCodeAt(k) === 0x5c;
2010
+ else if (raw.charCodeAt(k) === 0x23) {
2011
+ const real = blockLines(scan, false);
2012
+ if ((real.ends[blockLineOf(real, k)] ?? raw.length) < raw.length)
2013
+ escaped = false;
2014
+ else {
2015
+ const lit = blockLines(scan, true);
2016
+ if ((lit.ends[blockLineOf(lit, k)] ?? raw.length) >= raw.length)
2017
+ return null;
2018
+ escaped = true;
2019
+ }
2020
+ }
2021
+ else
2022
+ return null;
2023
+ const lines = blockLines(scan, escaped);
2024
+ const head = blockLineOf(lines, at);
2025
+ const limit = Math.max(0, lines.indent[blockLineOf(lines, labelAt)] ?? 0);
2026
+ const key = head * (raw.length + 1) + limit;
2027
+ let end = lines.memo.get(key);
2028
+ if (end === undefined) {
2029
+ end = lines.ends[head] ?? raw.length;
2030
+ for (let i = lines.nextContent[head + 1] ?? lines.starts.length; i < lines.starts.length && (lines.indent[i] ?? -1) > limit; i = lines.nextContent[i + 1] ?? lines.starts.length) {
2031
+ end = lines.ends[i] ?? end;
2032
+ }
2033
+ lines.memo.set(key, end);
2034
+ }
2035
+ return { start: at, end };
2036
+ }
1889
2037
  function pemBodyEndWithoutTrailer(text, from) {
1890
2038
  let pos = from;
1891
2039
  let inBody = false;
@@ -2779,6 +2927,7 @@ function collectCandidates(text, o, nested) {
2779
2927
  const screen = screenSurfaces(text, o);
2780
2928
  surfaces.push(...screen.surfaces);
2781
2929
  const raw = [];
2930
+ const blocks = { raw: text, view: V, out: raw, lines: [null, null], marks: null };
2782
2931
  const regionSurface = screen.surfaces[0] ?? separated;
2783
2932
  const pemBlocksSeen = [];
2784
2933
  for (const S of surfaces) {
@@ -2792,9 +2941,9 @@ function collectCandidates(text, o, nested) {
2792
2941
  if (o.words) {
2793
2942
  editsToCandidates(pemEdits(S, (blk) => { if (S === regionSurface)
2794
2943
  pemBlocksSeen.push(pemBlockToRaw(S, blk)); }), 'pem', cands);
2795
- labelCandidates(S, 'scheme', regions, cands);
2796
- labelCandidates(S, 'token', regions, cands);
2797
- labelCandidates(S, 'label', regions, cands);
2944
+ labelCandidates(S, 'scheme', regions, cands, blocks);
2945
+ labelCandidates(S, 'token', regions, cands, blocks);
2946
+ labelCandidates(S, 'label', regions, cands, blocks);
2798
2947
  editsToCandidates(authParamEdits(S.text), 'param', cands);
2799
2948
  editsToCandidates(proseLiteralEdits(S.text), 'prose', cands);
2800
2949
  }
@@ -1,6 +1,8 @@
1
1
  export declare function engineCapsGeneration(baseUrl: string): number;
2
2
  export declare function kickEngineCapsProbe(baseUrl: string, probe: () => Promise<unknown>): void;
3
- export declare function engineCapsSettled(baseUrl: string | undefined): Promise<void>;
3
+ export declare function engineCapsSettled(baseUrl: string | undefined, opts?: {
4
+ withinMs?: number;
5
+ }): Promise<'settled' | 'timed_out'>;
4
6
  export type EngineCapState = 'true' | 'false' | 'unprobed' | 'absent' | 'non_boolean';
5
7
  export declare function engineCapState(baseUrl: string | undefined, key: string): EngineCapState;
6
8
  export declare function engineCapTrue(baseUrl: string | undefined, key: string): boolean;
@@ -43,21 +43,71 @@ export function kickEngineCapsProbe(baseUrl, probe) {
43
43
  }
44
44
  })();
45
45
  }
46
- export async function engineCapsSettled(baseUrl) {
47
- if (!baseUrl)
48
- return;
46
+ const MAX_WITHIN_MS = 2_147_483_647;
47
+ function waitBudgetOf(opts) {
48
+ try {
49
+ if (opts === undefined || opts === null)
50
+ return undefined;
51
+ if (typeof opts !== 'object')
52
+ return 0;
53
+ const v = opts.withinMs;
54
+ if (v === undefined)
55
+ return undefined;
56
+ if (typeof v !== 'number' || !Number.isFinite(v) || !(v > 0))
57
+ return 0;
58
+ return v > MAX_WITHIN_MS ? MAX_WITHIN_MS : v;
59
+ }
60
+ catch {
61
+ return 0;
62
+ }
63
+ }
64
+ async function relaySettled(baseUrl, deadline) {
49
65
  for (;;) {
50
66
  const entry = settleByBase.get(baseUrl);
51
67
  if (entry === undefined)
52
- return;
68
+ return 'settled';
53
69
  const awaitedGen = entry.gen;
54
- await Promise.race([
70
+ const landed = Promise.race([
55
71
  entry.promise.then(() => undefined, () => undefined),
56
72
  entry.superseded,
57
73
  ]);
74
+ if (deadline === undefined) {
75
+ await landed;
76
+ }
77
+ else {
78
+ const first = await Promise.race([landed.then(() => 'landed'), deadline]);
79
+ if (first === 'timed_out')
80
+ return 'timed_out';
81
+ }
58
82
  const next = settleByBase.get(baseUrl);
59
83
  if (next === undefined || next.gen <= awaitedGen)
60
- return;
84
+ return 'settled';
85
+ }
86
+ }
87
+ export async function engineCapsSettled(baseUrl, opts) {
88
+ const budget = waitBudgetOf(opts);
89
+ if (!baseUrl)
90
+ return 'settled';
91
+ if (budget === undefined)
92
+ return relaySettled(baseUrl, undefined);
93
+ if (settleByBase.get(baseUrl) === undefined)
94
+ return 'settled';
95
+ if (budget === 0)
96
+ return 'timed_out';
97
+ let timer;
98
+ try {
99
+ const deadline = new Promise((resolve) => {
100
+ timer = setTimeout(() => resolve('timed_out'), budget);
101
+ });
102
+ deadline.catch(() => undefined);
103
+ return await relaySettled(baseUrl, deadline);
104
+ }
105
+ catch {
106
+ return 'timed_out';
107
+ }
108
+ finally {
109
+ if (timer !== undefined)
110
+ clearTimeout(timer);
61
111
  }
62
112
  }
63
113
  export function engineCapState(baseUrl, key) {
@@ -0,0 +1,2 @@
1
+ export declare const ASK_EVIDENCE_ABSENCE_VALUES: readonly ["not_wired", "not_adjudicated", "unavailable", "no_match", "not_reported"];
2
+ export declare const SYSTEM_INJECTION_PRIORITIES: readonly ["now", "next", "later"];
@@ -0,0 +1,3 @@
1
+ import { CORE_ASK_EVIDENCE_ABSENCE_VALUES, CORE_SYSTEM_INJECTION_PRIORITIES } from './generated/engineFactTables.js';
2
+ export const ASK_EVIDENCE_ABSENCE_VALUES = CORE_ASK_EVIDENCE_ABSENCE_VALUES;
3
+ export const SYSTEM_INJECTION_PRIORITIES = CORE_SYSTEM_INJECTION_PRIORITIES;
@@ -49,6 +49,9 @@ export declare function isRewindFamilyCode(code: string | undefined): boolean;
49
49
  export declare const RESUME_USAGE_WINDOW_EXHAUSTED = "resume.usage_window_exhausted";
50
50
  export declare const RESUME_PREFLIGHT_REJECTED = "resume.preflight_rejected";
51
51
  export declare const RESUME_SESSION_NOT_FOUND = "resume.session_not_found";
52
+ export declare const REQUEST_FIELD_CONFLICT = "request.field_conflict";
53
+ export declare const CHECKPOINT_UNSUPPORTED_VERSION = "checkpoint.unsupported_version";
54
+ export declare function refusalSaysStillPending(err: object): boolean;
52
55
  export type StatusDerivedCoarseCode = (typeof STATUS_DERIVED_COARSE_CODES)[number];
53
56
  export declare const RESUME_PLACEMENT_MISMATCH = "resume.placement_mismatch";
54
57
  export declare const RESUME_CONTEXT_UNAVAILABLE = "conflict.resume_context_unavailable";
@@ -107,6 +107,16 @@ export function isRewindFamilyCode(code) {
107
107
  export const RESUME_USAGE_WINDOW_EXHAUSTED = 'resume.usage_window_exhausted';
108
108
  export const RESUME_PREFLIGHT_REJECTED = 'resume.preflight_rejected';
109
109
  export const RESUME_SESSION_NOT_FOUND = 'resume.session_not_found';
110
+ export const REQUEST_FIELD_CONFLICT = 'request.field_conflict';
111
+ export const CHECKPOINT_UNSUPPORTED_VERSION = 'checkpoint.unsupported_version';
112
+ export function refusalSaysStillPending(err) {
113
+ try {
114
+ return Object.hasOwn(err, 'retriable') && err.retriable === true;
115
+ }
116
+ catch {
117
+ return false;
118
+ }
119
+ }
110
120
  export const RESUME_PLACEMENT_MISMATCH = 'resume.placement_mismatch';
111
121
  export const RESUME_CONTEXT_UNAVAILABLE = 'conflict.resume_context_unavailable';
112
122
  export const RESUME_RETRY_LATER_CODES = Object.freeze([
@@ -10,3 +10,15 @@ export declare const CORE_ENGINE_CARD_TYPES: readonly string[];
10
10
  export declare const CORE_TOOL_DECLARATION_CODES: readonly string[];
11
11
  export declare const CORE_MODE_RELEASE_REASONS: readonly ["rule_unreadable"];
12
12
  export declare const CORE_HOOK_TOOL_ALIASES: Readonly<Record<string, string>>;
13
+ export declare const CORE_ASK_EVIDENCE_ABSENCE_VALUES: readonly ["not_wired", "not_adjudicated", "unavailable", "no_match", "not_reported"];
14
+ export declare const CORE_SYSTEM_INJECTION_PRIORITIES: readonly ["now", "next", "later"];
15
+ export declare const CORE_READ_DENY_BUILTIN_TIERS: readonly ["credentials", "shell-history", "browser", "wallet", "agent-config"];
16
+ export declare const CORE_READ_DENY_DEFAULT_TIERS: readonly ["credentials", "agent-config"];
17
+ export interface CoreModeArbitrationRow {
18
+ readonly bypassImmune: boolean;
19
+ readonly classifierEligible: boolean;
20
+ readonly sandboxAdmission: boolean;
21
+ readonly ruleMayClear: boolean;
22
+ readonly hookAskFloor: boolean;
23
+ }
24
+ export declare const CORE_MODE_ARBITRATION: Readonly<Record<"content_question" | "hook" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "operator_forced" | "shell_floor" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "unstated" | "ordinary", CoreModeArbitrationRow>>;
@@ -117,3 +117,50 @@ export const CORE_MODE_RELEASE_REASONS = Object.freeze([
117
117
  export const CORE_HOOK_TOOL_ALIASES = Object.freeze(Object.assign(Object.create(null), Object.fromEntries([
118
118
  ["ListPeers", "ListAgents"],
119
119
  ])));
120
+ export const CORE_ASK_EVIDENCE_ABSENCE_VALUES = Object.freeze([
121
+ "not_wired",
122
+ "not_adjudicated",
123
+ "unavailable",
124
+ "no_match",
125
+ "not_reported",
126
+ ]);
127
+ export const CORE_SYSTEM_INJECTION_PRIORITIES = Object.freeze([
128
+ "now",
129
+ "next",
130
+ "later",
131
+ ]);
132
+ export const CORE_READ_DENY_BUILTIN_TIERS = Object.freeze([
133
+ "credentials",
134
+ "shell-history",
135
+ "browser",
136
+ "wallet",
137
+ "agent-config",
138
+ ]);
139
+ export const CORE_READ_DENY_DEFAULT_TIERS = Object.freeze([
140
+ "credentials",
141
+ "agent-config",
142
+ ]);
143
+ export const CORE_MODE_ARBITRATION = Object.freeze({
144
+ "content_question": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
145
+ "hook": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
146
+ "ancestor": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
147
+ "unverifiable_delete": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
148
+ "transcript_write": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
149
+ "org_rule": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
150
+ "governance_unavailable": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
151
+ "rule_unreadable": Object.freeze({ bypassImmune: false, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
152
+ "ask_rule": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
153
+ "denial_limit_fallback": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
154
+ "operator_forced": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
155
+ "shell_floor": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
156
+ "write_protection_unresolved": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: true }),
157
+ "probe": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
158
+ "write_protection": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: true }),
159
+ "tool_marks_mcp": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
160
+ "tool_marks_a2a": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
161
+ "policy_rra": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
162
+ "artifact_shared_read": Object.freeze({ bypassImmune: false, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
163
+ "mode": Object.freeze({ bypassImmune: false, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
164
+ "unstated": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: false, ruleMayClear: true, hookAskFloor: false }),
165
+ "ordinary": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: true, ruleMayClear: true, hookAskFloor: false }),
166
+ });
@@ -8,7 +8,7 @@ export type { AskAnsweredOutput } from './gateLedger.js';
8
8
  export { SEMA_COLLATERAL_ABORT_KEY } from './gateLedger.js';
9
9
  export { SEMA_DENIAL_KIND_KEY } from './gateLedger.js';
10
10
  export type { GateDenyAttribution } from './gateLedger.js';
11
- export { toAnsweredOutput, isAlreadyResolvedGateReason, isGateStandingErrorCode, isCodeClassifiedGateFailure, GATE_FAILURE_CODES, nextHopBudget, MAX_GATE_HOPS, MAX_TOTAL_PARKS } from './parkResolver.js';
11
+ export { toAnsweredOutput, isAlreadyResolvedFailure, isAlreadyResolvedGateReason, isGateStandingErrorCode, isCodeClassifiedGateFailure, GATE_FAILURE_CODES, nextHopBudget, MAX_GATE_HOPS, MAX_TOTAL_PARKS } from './parkResolver.js';
12
12
  export type { HopBudget, HopRound } from './parkResolver.js';
13
13
  export type { GateOutcome, GateFailureCode } from './parkResolver.js';
14
14
  export declare function bridgeAskUserQuestionGates(source: AsyncGenerator<AgentEvent>, deps: AskGateWireDeps, opts?: {
@@ -6,7 +6,7 @@ export { HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE } from './frameRouter.js';
6
6
  export { HITL_POLICY_DENY_MESSAGE } from './frameRouter.js';
7
7
  export { SEMA_COLLATERAL_ABORT_KEY } from './gateLedger.js';
8
8
  export { SEMA_DENIAL_KIND_KEY } from './gateLedger.js';
9
- export { toAnsweredOutput, isAlreadyResolvedGateReason, isGateStandingErrorCode, isCodeClassifiedGateFailure, GATE_FAILURE_CODES, nextHopBudget, MAX_GATE_HOPS, MAX_TOTAL_PARKS } from './parkResolver.js';
9
+ export { toAnsweredOutput, isAlreadyResolvedFailure, isAlreadyResolvedGateReason, isGateStandingErrorCode, isCodeClassifiedGateFailure, GATE_FAILURE_CODES, nextHopBudget, MAX_GATE_HOPS, MAX_TOTAL_PARKS } from './parkResolver.js';
10
10
  export async function* bridgeAskUserQuestionGates(source, deps, opts) {
11
11
  const led = createGateLedger();
12
12
  const taskId = { current: opts?.taskId };
@@ -28,3 +28,10 @@ export interface CrashConvergedProjection {
28
28
  readonly dropped: number;
29
29
  }
30
30
  export declare function projectCrashConverged(env: unknown): CrashConvergedProjection | undefined;
31
+ export interface CrashConvergedNoticeFacts {
32
+ readonly total: number;
33
+ readonly dropped: number;
34
+ readonly needsHumanReasons: readonly (string | undefined)[];
35
+ readonly causes: readonly CrashConvergedRow['cause'][] | undefined;
36
+ }
37
+ export declare function readCrashConvergedNoticeFacts(projection: CrashConvergedProjection | undefined): CrashConvergedNoticeFacts | undefined;