@sema-agent/client-core 0.90.0 → 0.92.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 (172) hide show
  1. package/CHANGELOG.md +365 -0
  2. package/README.md +48 -32
  3. package/dist/adapt/arms.js +13 -12
  4. package/dist/adapt/panelTasks.d.ts +0 -2
  5. package/dist/adapt/panelTasks.js +6 -26
  6. package/dist/adapt.js +2 -2
  7. package/dist/adapter/activeRunSelfHeal.d.ts +0 -2
  8. package/dist/adapter/activeRunSelfHeal.js +5 -27
  9. package/dist/adapter/downstream/eventToSdkMessage.js +4 -2
  10. package/dist/adapter/downstream/terminalToSdkResult.js +16 -7
  11. package/dist/adapter/downstream/wiringManifestView.d.ts +6 -0
  12. package/dist/adapter/downstream/wiringManifestView.js +16 -0
  13. package/dist/adapter/runStream.js +39 -20
  14. package/dist/askSurvivesStandingAnswer.d.ts +13 -0
  15. package/dist/askSurvivesStandingAnswer.js +53 -0
  16. package/dist/attachmentSeatCapability.d.ts +11 -0
  17. package/dist/attachmentSeatCapability.js +27 -0
  18. package/dist/attachmentsWireCaps.d.ts +9 -0
  19. package/dist/attachmentsWireCaps.js +74 -21
  20. package/dist/autoModeUnavailable.js +3 -2
  21. package/dist/cloudConfigWireCaps.js +5 -4
  22. package/dist/compensations.js +13 -17
  23. package/dist/controlRouter.d.ts +32 -25
  24. package/dist/controlRouter.js +166 -63
  25. package/dist/coreValuePorts.d.ts +4 -2
  26. package/dist/coreValuePorts.js +5 -0
  27. package/dist/decideFailureNote.js +7 -3
  28. package/dist/decideReceipt.d.ts +9 -0
  29. package/dist/decideReceipt.js +62 -1
  30. package/dist/disableSkillsWire.d.ts +1 -0
  31. package/dist/disableSkillsWire.js +8 -1
  32. package/dist/displayUntrusted.js +155 -5
  33. package/dist/effectiveFacts.d.ts +14 -4
  34. package/dist/effectiveFacts.js +45 -5
  35. package/dist/engineAgentAbsence.js +2 -1
  36. package/dist/engineCapReader.js +16 -10
  37. package/dist/engineCapsCache.d.ts +5 -1
  38. package/dist/engineCapsCache.js +69 -8
  39. package/dist/engineClosedSets.d.ts +2 -0
  40. package/dist/engineClosedSets.js +3 -0
  41. package/dist/engineErrorCodes.d.ts +17 -0
  42. package/dist/engineErrorCodes.js +47 -0
  43. package/dist/engineNoticeCodes.d.ts +14 -0
  44. package/dist/engineNoticeCodes.js +71 -0
  45. package/dist/executionLaneCapability.js +2 -0
  46. package/dist/gateOutcome.js +2 -17
  47. package/dist/gateVocabulary.d.ts +2 -4
  48. package/dist/gateVocabulary.js +3 -11
  49. package/dist/generated/engineFactTables.d.ts +27 -0
  50. package/dist/generated/engineFactTables.js +128 -0
  51. package/dist/generated/engineNoticeTables.js +3 -0
  52. package/dist/generated/settingsSchemaTables.d.ts +8 -0
  53. package/dist/generated/settingsSchemaTables.js +40 -0
  54. package/dist/hitl/allowRuleShadow.d.ts +21 -0
  55. package/dist/hitl/allowRuleShadow.js +167 -0
  56. package/dist/hitl/askClassPair.d.ts +14 -0
  57. package/dist/hitl/askClassPair.js +42 -0
  58. package/dist/hitl/askGateWire.d.ts +1 -1
  59. package/dist/hitl/askGateWire.js +2 -1
  60. package/dist/hitl/askSurvivesPosture.d.ts +5 -0
  61. package/dist/hitl/askSurvivesPosture.js +17 -0
  62. package/dist/hitl/automaticAnswerVerdict.d.ts +21 -0
  63. package/dist/hitl/automaticAnswerVerdict.js +143 -0
  64. package/dist/hitl/crashConverged.d.ts +8 -0
  65. package/dist/hitl/crashConverged.js +58 -1
  66. package/dist/hitl/crashConvergedNotice.d.ts +4 -0
  67. package/dist/hitl/crashConvergedNotice.js +57 -0
  68. package/dist/hitl/frameRouter.d.ts +2 -0
  69. package/dist/hitl/frameRouter.js +66 -14
  70. package/dist/hitl/gateLedger.d.ts +6 -0
  71. package/dist/hitl/gateLedger.js +34 -5
  72. package/dist/hitl/hitlBridge.d.ts +7 -4
  73. package/dist/hitl/hitlHostSurface.d.ts +2 -0
  74. package/dist/hitl/hitlHostSurface.js +7 -0
  75. package/dist/hitl/livePendingAsk.js +24 -5
  76. package/dist/hitl/parkResolver.d.ts +7 -2
  77. package/dist/hitl/parkResolver.js +21 -7
  78. package/dist/hitl/persistedRulesWire.d.ts +4 -1
  79. package/dist/hitl/persistedRulesWire.js +9 -2
  80. package/dist/hitl/planReviewWire.d.ts +1 -1
  81. package/dist/hitl/planReviewWire.js +19 -5
  82. package/dist/hitl/replayedApproval.d.ts +21 -0
  83. package/dist/hitl/replayedApproval.js +89 -0
  84. package/dist/hitl/sessionPolicyDeliverable.js +20 -2
  85. package/dist/hitl/sessionPolicyWire.d.ts +13 -0
  86. package/dist/hitl/sessionPolicyWire.js +75 -2
  87. package/dist/hitl/suspendedReopen.js +2 -2
  88. package/dist/hitl/toolApprovalWire.d.ts +9 -1
  89. package/dist/hitl/toolApprovalWire.js +40 -40
  90. package/dist/hookMatcherVerdict.d.ts +29 -0
  91. package/dist/hookMatcherVerdict.js +266 -0
  92. package/dist/humanTurn.d.ts +91 -0
  93. package/dist/humanTurn.js +252 -0
  94. package/dist/humanTurnRead.d.ts +105 -0
  95. package/dist/humanTurnRead.js +331 -0
  96. package/dist/index.d.ts +38 -11
  97. package/dist/index.js +27 -8
  98. package/dist/inheritEnvWire.js +4 -5
  99. package/dist/liveModelCatalog.d.ts +2 -0
  100. package/dist/liveModelCatalog.js +51 -3
  101. package/dist/mcpLiveness.js +2 -1
  102. package/dist/memoryVerbsWire.d.ts +1 -1
  103. package/dist/memoryVerbsWire.js +3 -0
  104. package/dist/model/catalog.js +2 -1
  105. package/dist/model/providerPresets.d.ts +3 -1
  106. package/dist/model/tierVocabulary.d.ts +2 -1
  107. package/dist/model/tierVocabulary.js +3 -8
  108. package/dist/peerFrames.js +2 -2
  109. package/dist/permissionRuleIssue.d.ts +1 -1
  110. package/dist/permissionRuleIssue.js +31 -9
  111. package/dist/permissionsAllowGrantCapability.d.ts +2 -1
  112. package/dist/permissionsAllowGrantCapability.js +11 -2
  113. package/dist/permissionsDeclaration.d.ts +29 -0
  114. package/dist/permissionsDeclaration.js +155 -66
  115. package/dist/pluginHooksWire.js +2 -11
  116. package/dist/promptDelivery.d.ts +11 -3
  117. package/dist/promptDelivery.js +164 -29
  118. package/dist/promptProfileWireCaps.d.ts +2 -1
  119. package/dist/protocolSegment.d.ts +9 -0
  120. package/dist/protocolSegment.js +28 -0
  121. package/dist/providerRejection.d.ts +1 -0
  122. package/dist/providerRejection.js +20 -0
  123. package/dist/readDenyTiers.d.ts +10 -0
  124. package/dist/readDenyTiers.js +29 -0
  125. package/dist/request/taskRequest.js +3 -17
  126. package/dist/resumeRefusalCopy.d.ts +11 -0
  127. package/dist/resumeRefusalCopy.js +61 -4
  128. package/dist/rewindArchiveCapability.js +4 -4
  129. package/dist/rewindWireCaps.d.ts +2 -1
  130. package/dist/rewindWireCaps.js +19 -2
  131. package/dist/ruleCompileVerdict.d.ts +2 -0
  132. package/dist/ruleCompileVerdict.js +13 -0
  133. package/dist/ruleRemovalConsequence.d.ts +2 -1
  134. package/dist/runCancelContext.d.ts +12 -0
  135. package/dist/runCancelContext.js +83 -1
  136. package/dist/seam.d.ts +2 -0
  137. package/dist/seam.js +1 -1
  138. package/dist/seatContract.d.ts +2 -1
  139. package/dist/sessionMemoryStatus.d.ts +2 -4
  140. package/dist/sessionSyncFileHistoryCapability.d.ts +18 -0
  141. package/dist/sessionSyncFileHistoryCapability.js +50 -0
  142. package/dist/skillToolListsCapability.d.ts +18 -0
  143. package/dist/skillToolListsCapability.js +50 -0
  144. package/dist/sqlEngineCapability.js +1 -8
  145. package/dist/steerPriorityCapability.d.ts +18 -0
  146. package/dist/steerPriorityCapability.js +80 -0
  147. package/dist/steerReceipt.d.ts +9 -0
  148. package/dist/steerReceipt.js +25 -0
  149. package/dist/subagent/engineSubagentSteer.js +2 -9
  150. package/dist/supportFloor.js +2 -2
  151. package/dist/taskRequestWords.d.ts +7 -1
  152. package/dist/taskRequestWords.js +18 -8
  153. package/dist/toolHistoryBadTurn.d.ts +1 -0
  154. package/dist/toolHistoryBadTurn.js +89 -0
  155. package/dist/toolHistoryMismatch.d.ts +2 -1
  156. package/dist/toolHistoryMismatch.js +19 -6
  157. package/dist/toolResult.d.ts +8 -0
  158. package/dist/toolResult.js +47 -3
  159. package/dist/types/engineState.d.ts +2 -12
  160. package/dist/userAttachmentEnvelope.d.ts +61 -0
  161. package/dist/userAttachmentEnvelope.js +204 -0
  162. package/dist/userInvokedSkillsCapability.d.ts +18 -0
  163. package/dist/userInvokedSkillsCapability.js +50 -0
  164. package/dist/wireFailureShape.d.ts +3 -0
  165. package/dist/wireFailureShape.js +8 -0
  166. package/dist/wireRefusalCopy.d.ts +6 -0
  167. package/dist/wireRefusalCopy.js +26 -3
  168. package/dist/workflowsJournalCapability.d.ts +18 -0
  169. package/dist/workflowsJournalCapability.js +50 -0
  170. package/dist/writeProtectionCapability.d.ts +2 -4
  171. package/docs/INTEGRATION-CLIENTS.md +1489 -16
  172. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import { hostEnv } from './hostEnv.js';
2
2
  import { envFlagOff } from './envFlag.js';
3
- import { retiredAttachmentsKeyWhy } from './taskRequestWords.js';
3
+ import { retiredAttachmentsKeyOf } from './taskRequestWords.js';
4
4
  export const ATTACHMENTS_ENV = 'SEMA_ATTACHMENTS';
5
5
  export const ATTACHMENTS_SPEC_KEYS = Object.freeze([
6
6
  'todoReminder',
@@ -48,25 +48,27 @@ function refuse(token, why) {
48
48
  const allowed = legalAttachmentsTokens();
49
49
  throw new AttachmentsSpecRefused(`${ATTACHMENTS_ENV}: refusing token "${token}" — ${why}. Legal tokens: ${allowed.join(' | ')}`, { token, why, allowed });
50
50
  }
51
- export function attachmentsForRequest(env = hostEnv()) {
52
- const raw = (env[ATTACHMENTS_ENV] ?? '').trim().toLowerCase();
51
+ function deny(kind, token, why, index, key) {
52
+ return { ok: false, refusal: { kind, token, why, entry: index + 1, key } };
53
+ }
54
+ function judgeAttachmentsEnv(raw) {
53
55
  if (envFlagOff(raw))
54
- return allDefaultOnOff();
56
+ return { ok: true, spec: allDefaultOnOff() };
55
57
  const tokens = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
56
- for (const token of tokens) {
57
- const named = retiredAttachmentsKeyWhy(token);
58
+ for (const [i, token] of tokens.entries()) {
59
+ const named = retiredAttachmentsKeyOf(token);
58
60
  if (named !== undefined)
59
- refuse(token, named);
61
+ return { ok: false, refusal: { kind: 'retired_key', token, why: named.why, entry: i + 1, key: named.key, retired: named } };
60
62
  }
61
63
  if (tokens.length === 0)
62
- return { backgroundTasks: true, toolsDelta: true };
64
+ return { ok: true, spec: { backgroundTasks: true, toolsDelta: true } };
63
65
  if (tokens.length === 1 && (tokens[0] === 'full' || tokens[0] === 'all'))
64
- return allLiteralTrue();
66
+ return { ok: true, spec: allLiteralTrue() };
65
67
  if (tokens.length === 1 && !isKnownToken(tokens[0])) {
66
- return { backgroundTasks: true, toolsDelta: true };
68
+ return { ok: true, spec: { backgroundTasks: true, toolsDelta: true } };
67
69
  }
68
70
  const spec = {};
69
- for (const token of tokens) {
71
+ for (const [i, token] of tokens.entries()) {
70
72
  if (token === 'full' || token === 'all') {
71
73
  Object.assign(spec, allLiteralTrue());
72
74
  continue;
@@ -79,11 +81,11 @@ export function attachmentsForRequest(env = hostEnv()) {
79
81
  if (token.startsWith('-')) {
80
82
  const key = canonicalKey(token.slice(1));
81
83
  if (key === undefined)
82
- refuse(token, 'unknown attachments key');
84
+ return deny('unknown_key', token, 'unknown attachments key', i, undefined);
83
85
  if (!isDefaultOnKey(key)) {
84
- refuse(token, `"${key}" belongs to the literal-true family whose OFF is "delete the key", not "send false" ` +
86
+ return deny('minus_on_literal_true_key', token, `"${key}" belongs to the literal-true family whose OFF is "delete the key", not "send false" ` +
85
87
  '(core wire contract, board [479] ask-2) — simply do not turn it on. ' +
86
- `Only the core DEFAULT-ON keys (${ATTACHMENTS_DEFAULT_ON_KEYS.join(' / ')}) accept an explicit false`);
88
+ `Only the core DEFAULT-ON keys (${ATTACHMENTS_DEFAULT_ON_KEYS.join(' / ')}) accept an explicit false`, i, key);
87
89
  }
88
90
  spec[key] = false;
89
91
  continue;
@@ -91,25 +93,76 @@ export function attachmentsForRequest(env = hostEnv()) {
91
93
  const [lhs, rhs] = splitAssign(token);
92
94
  if (rhs !== undefined) {
93
95
  if (canonicalKey(lhs) !== 'todoReminderMode')
94
- refuse(token, 'only `todoReminderMode` takes a `key=value` form');
96
+ return deny('value_form_on_other_key', token, 'only `todoReminderMode` takes a `key=value` form', i, canonicalKey(lhs));
95
97
  const mode = TODO_REMINDER_MODES.find(v => v === rhs);
96
98
  if (mode === undefined)
97
- refuse(token, `todoReminderMode must be one of ${TODO_REMINDER_MODES.join('|')}`);
99
+ return deny('todo_mode_bad_value', token, `todoReminderMode must be one of ${TODO_REMINDER_MODES.join('|')}`, i, 'todoReminderMode');
98
100
  spec.todoReminderMode = mode;
99
101
  continue;
100
102
  }
101
103
  const key = canonicalKey(lhs.startsWith('+') ? lhs.slice(1) : lhs);
102
104
  if (key === undefined)
103
- refuse(token, 'unknown attachments key');
105
+ return deny('unknown_key', token, 'unknown attachments key', i, undefined);
104
106
  if (isDefaultOnOnlyKey(key)) {
105
- refuse(token, `"${key}" is core DEFAULT-ON — turning it "on" is a no-op that would send a redundant true; ` +
106
- `use "-${key}" to turn it OFF`);
107
+ return deny('plus_on_default_on_key', token, `"${key}" is core DEFAULT-ON — turning it "on" is a no-op that would send a redundant true; ` + `use "-${key}" to turn it OFF`, i, key);
107
108
  }
108
109
  if (key === 'todoReminderMode')
109
- refuse(token, 'todoReminderMode needs a value: `todoReminderMode=baseline|off`');
110
+ return deny('todo_mode_needs_value', token, 'todoReminderMode needs a value: `todoReminderMode=baseline|off`', i, key);
110
111
  spec[key] = true;
111
112
  }
112
- return spec;
113
+ return { ok: true, spec };
114
+ }
115
+ function envRawOf(env) {
116
+ return (env[ATTACHMENTS_ENV] ?? '').trim().toLowerCase();
117
+ }
118
+ export function attachmentsForRequest(env = hostEnv()) {
119
+ const judged = judgeAttachmentsEnv(envRawOf(env));
120
+ if (!judged.ok)
121
+ return refuse(judged.refusal.token, judged.refusal.why);
122
+ return judged.spec;
123
+ }
124
+ function attachmentsWayOut() {
125
+ const on = OPT_IN_KEYS.join(', ');
126
+ const off = ATTACHMENTS_DEFAULT_ON_KEYS.join(', ');
127
+ return (`Accepted writing is either the single word off on its own (every attachment off; it cannot be combined with other entries), or a comma-separated list of: ` +
128
+ `full or all (every opt-in attachment on), default, the name of an attachment to turn on (${on}), a leading minus to turn off one of ${off}, and todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}. ` +
129
+ `To drop the setting altogether, unset ${ATTACHMENTS_ENV}; the defaults then apply.`);
130
+ }
131
+ function attachmentsRefusalSentence(r) {
132
+ const head = `The attachments setting (${ATTACHMENTS_ENV}) cannot be used as it is set: entry ${r.entry} of the list`;
133
+ const key = r.key ?? '';
134
+ switch (r.kind) {
135
+ case 'retired_key':
136
+ return `${head} names "${key}", a key that no longer exists — ${r.retired?.because ?? 'it was retired'}, and a request carrying that key is refused by the server. Remove that entry${r.retired === undefined ? '' : `; ${r.retired.remedy}`}. ${attachmentsWayOut()}`;
137
+ case 'unknown_key':
138
+ return `${head} is not an attachment this version knows. ${attachmentsWayOut()}`;
139
+ case 'minus_on_literal_true_key':
140
+ return key === 'todoReminderMode'
141
+ ? `${head} puts a minus on todoReminderMode, which is a setting with a value rather than something to turn off — write todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}, or leave it out of the list. A minus only works on ${ATTACHMENTS_DEFAULT_ON_KEYS.join(', ')}, which are on by default. ${attachmentsWayOut()}`
142
+ : `${head} puts a minus on ${key}, and a minus cannot switch that attachment off — it is on only when it is named, or when full, all or default switches it on. A minus only works on ${ATTACHMENTS_DEFAULT_ON_KEYS.join(', ')}, which are on by default. To leave ${key} out, do not name it, and if full, all or default is what switches it on, list the attachments you want one by one instead. ${attachmentsWayOut()}`;
143
+ case 'plus_on_default_on_key':
144
+ return `${head} turns on ${key}, which is already on by default. To turn it off write -${key}; otherwise leave it out of the list. ${attachmentsWayOut()}`;
145
+ case 'value_form_on_other_key':
146
+ return `${head} uses a name=value form, and only todoReminderMode takes one. ${attachmentsWayOut()}`;
147
+ case 'todo_mode_bad_value':
148
+ return `${head} gives todoReminderMode a value it does not accept; the values are ${TODO_REMINDER_MODES.join(' and ')}. ${attachmentsWayOut()}`;
149
+ case 'todo_mode_needs_value':
150
+ return `${head} names todoReminderMode without a value; write todoReminderMode=${TODO_REMINDER_MODES.join(' or todoReminderMode=')}. ${attachmentsWayOut()}`;
151
+ }
152
+ }
153
+ function attachmentsUnreadableSentence() {
154
+ return `The attachments setting (${ATTACHMENTS_ENV}) could not be read as text, so it cannot be used as it is set. Set it to a plain comma-separated list, or unset it. ${attachmentsWayOut()}`;
155
+ }
156
+ export function attachmentsSubmitVerdict(env = hostEnv()) {
157
+ try {
158
+ const judged = judgeAttachmentsEnv(envRawOf(env));
159
+ if (judged.ok)
160
+ return { ok: true, attachments: judged.spec };
161
+ return { ok: false, sentence: attachmentsRefusalSentence(judged.refusal), refusedKey: judged.refusal.key };
162
+ }
163
+ catch {
164
+ return { ok: false, sentence: attachmentsUnreadableSentence(), refusedKey: undefined };
165
+ }
113
166
  }
114
167
  function allDefaultOnOff() {
115
168
  const out = {};
@@ -1,4 +1,5 @@
1
- export const CLASSIFIER_DENY_CAUSES = Object.freeze(['unavailable', 'parse_error']);
1
+ import { CORE_AUTO_MODE_UNAVAILABLE_CAUSES, CORE_CLASSIFIER_DENY_CAUSES } from './generated/engineFactTables.js';
2
+ export const CLASSIFIER_DENY_CAUSES = CORE_CLASSIFIER_DENY_CAUSES;
2
3
  const DENY_CAUSE_SET = new Set(CLASSIFIER_DENY_CAUSES);
3
4
  export function isClassifierDenyCause(v) {
4
5
  return typeof v === 'string' && DENY_CAUSE_SET.has(v);
@@ -26,7 +27,7 @@ function gateRecordOf(v) {
26
27
  return undefined;
27
28
  return g;
28
29
  }
29
- export const AUTO_MODE_UNAVAILABLE_CAUSES = Object.freeze(['error', 'timeout']);
30
+ export const AUTO_MODE_UNAVAILABLE_CAUSES = CORE_AUTO_MODE_UNAVAILABLE_CAUSES;
30
31
  const DENY_CAUSE_SENTENCES = Object.freeze({
31
32
  unavailable: 'denied because the auto-mode classifier could not run this round (the call may be retried later)',
32
33
  parse_error: 'denied because the auto-mode classifier answered outside its contract (its reply could not be parsed, so the call was blocked)',
@@ -1,6 +1,7 @@
1
1
  import { MCP_CAPS } from './mcpWireCaps.js';
2
2
  import { toCappedSpec } from './skillsWireCaps.js';
3
3
  import { TIER_ORDER } from './model/tierVocabulary.js';
4
+ import { SETTINGS_BUDGET_NUMBER_KEYS, SETTINGS_BUDGET_PER_MODEL_NUMBER_KEYS, SETTINGS_BUDGET_STRING_KEYS, SETTINGS_TIER_GROUP_NAME_RE, } from './generated/settingsSchemaTables.js';
4
5
  const asRec = (v) => (typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined);
5
6
  const asArr = (v) => (Array.isArray(v) ? v : []);
6
7
  const asStr = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
@@ -129,7 +130,7 @@ function withoutRegistryAnnotations(e) {
129
130
  return out;
130
131
  }
131
132
  const TIER_WORDS = TIER_ORDER;
132
- const TIER_GROUP_NAME = /^[a-z0-9][a-z0-9._-]*$/i;
133
+ const TIER_GROUP_NAME = SETTINGS_TIER_GROUP_NAME_RE;
133
134
  const setOwn = (o, k, v) => {
134
135
  Object.defineProperty(o, k, { value: v, enumerable: true, writable: true, configurable: true });
135
136
  };
@@ -319,9 +320,9 @@ export function cloudRosterNames(rostersValue) {
319
320
  .map((e) => asStr(asRec(e)?.name))
320
321
  .filter((n) => !!n);
321
322
  }
322
- const BUDGET_NUMBER_KEYS = ['maxBudgetUsd', 'tpmLimit', 'rpmLimit', 'maxParallelRequests', 'maxRunCostUsd', 'maxIterations'];
323
- const BUDGET_STRING_KEYS = ['mode', 'budgetDuration', 'enforcement'];
324
- const PER_MODEL_NUMBER_KEYS = ['maxBudgetUsd', 'tpmLimit', 'rpmLimit'];
323
+ const BUDGET_NUMBER_KEYS = SETTINGS_BUDGET_NUMBER_KEYS;
324
+ const BUDGET_STRING_KEYS = SETTINGS_BUDGET_STRING_KEYS;
325
+ const PER_MODEL_NUMBER_KEYS = SETTINGS_BUDGET_PER_MODEL_NUMBER_KEYS;
325
326
  const _budgetKeysCovered = true;
326
327
  const _budgetKeysReal = true;
327
328
  const _perModelKeysCovered = true;
@@ -2,13 +2,12 @@ import { CHROME_ARMS } from './seam.js';
2
2
  export const MIGRATED_COMPENSATIONS = [
3
3
  {
4
4
  id: 'T32',
5
- what: 'bindTaskCard —— 把引擎子代行绑到它的委派工具卡上(显式父 / FIFO 猜父 / 含糊即 unbound)',
5
+ what: 'bindTaskCard —— 子代行按 typed 父键绑到委派工具卡上(点名的卡不合格 / 父键缺席即 unbound)',
6
6
  disposition: 'in-library',
7
7
  libraryHalf: 'adapt.ts bindTaskCard()',
8
8
  chromeArm: null,
9
9
  hostHalf: null,
10
- retireOn: 'P1-2 到货且达标线 ≥ server 1.290(typed parentToolCallId 在每条 tick 上恒在)后,' +
11
- 'FIFO 回落臂可删 —— 但只在**确认不再支持老引擎**时删,见 bindTaskCard 的 old-engine fallback 注释',
10
+ retireOn: null,
12
11
  },
13
12
  {
14
13
  id: 'T34',
@@ -26,7 +25,7 @@ export const MIGRATED_COMPENSATIONS = [
26
25
  libraryHalf: 'adapt.ts fireSubagentStart()(类型恒记 + 一生一次去重 + if-started 门)',
27
26
  chromeArm: 'subagent_lifecycle',
28
27
  hostHalf: '真执行用户 hook 进程(浏览器宿主根本不能执行 ⇒ 这一半必须留端)',
29
- retireOn: 'G21 / P3a(引擎侧发正式的 subagent 生命周期事件)后,壳替 fire 整条退役',
28
+ retireOn: 'RL-32',
30
29
  },
31
30
  {
32
31
  id: 'T36',
@@ -35,7 +34,7 @@ export const MIGRATED_COMPENSATIONS = [
35
34
  libraryHalf: 'adapt.ts settlePanelTasks 的四个调用点(tool_end 关卡 / result / turn 末 / abort)',
36
35
  chromeArm: 'inline_task_stats',
37
36
  hostHalf: null,
38
- retireOn: 'W6(引擎为每条子代发终态 tick)后,防御 sweep 降为纯兜底',
37
+ retireOn: 'RL-33',
39
38
  },
40
39
  {
41
40
  id: 'T44',
@@ -48,12 +47,12 @@ export const MIGRATED_COMPENSATIONS = [
48
47
  },
49
48
  {
50
49
  id: 'T47',
51
- what: 'workflow lane 三级判据门 —— workflow 子代的 tick 绝不进前台 subagent lane',
50
+ what: 'workflow lane 判据门(帧带 workflowRunId)—— workflow 子代的 tick 绝不进前台 subagent lane',
52
51
  disposition: 'in-library',
53
- libraryHalf: 'adapt.ts task_progress 臂的 workflowRunId / wa-id / workflow-card-parent 三级门',
52
+ libraryHalf: 'adapt.ts task_progress 臂的 workflowRunId 门',
54
53
  chromeArm: null,
55
54
  hostHalf: null,
56
- retireOn: 'P1-2 到货后判据②③(形状嗅探 + 实例台账)可删,只留判据①(帧带 workflowRunId)',
55
+ retireOn: null,
57
56
  },
58
57
  {
59
58
  id: 'T48',
@@ -63,7 +62,7 @@ export const MIGRATED_COMPENSATIONS = [
63
62
  chromeArm: null,
64
63
  hostHalf: 'footer 行过滤 isFooterTaskRow/filterFooterTaskRows —— 含「丢弃所有无 parentId 顶层行」' +
65
64
  '这条**端专属决策**(主 run 头部行由端自己合成渲染),留 TUI',
66
- retireOn: 'P1-2 到货后 fleet 行自带 parentToolCallId ⇒ 双生行不需要按尾段查',
65
+ retireOn: 'RL-35',
67
66
  },
68
67
  {
69
68
  id: 'T1',
@@ -83,8 +82,7 @@ export const MIGRATED_COMPENSATIONS = [
83
82
  libraryHalf: 'notifications.ts taskNotificationDedupKey + taskNotificationDedupKeyFromWire(裸 wire 入口)',
84
83
  chromeArm: null,
85
84
  hostHalf: null,
86
- retireOn: 'P1-3 到货(帧带 completionId)⇒ 键改成**读** completionId,重算算法整条删;' +
87
- '删之前要先有一批「同一完成在两条通道上 completionId 相同」的实测(否则换成了一把更差的键)',
85
+ retireOn: 'RL-36',
88
86
  },
89
87
  {
90
88
  id: 'T3',
@@ -95,8 +93,7 @@ export const MIGRATED_COMPENSATIONS = [
95
93
  'adapt.ts importLedgerFromTranscript(消费口)',
96
94
  chromeArm: null,
97
95
  hostHalf: null,
98
- retireOn: 'P1-3 到货 ⇒ **回植仍要做**(crash 窗口客观存在),但不必再解 XML —— 转录里直接带 ' +
99
- 'completionId。所以退的是「XML 反解」这一段,不是整条回植',
96
+ retireOn: 'RL-37',
100
97
  },
101
98
  {
102
99
  id: 'T25',
@@ -106,7 +103,7 @@ export const MIGRATED_COMPENSATIONS = [
106
103
  libraryHalf: 'toolResult.ts 终态轮询卡臂的预 seed + notifications.markEngineWorkflowNotified',
107
104
  chromeArm: null,
108
105
  hostHalf: null,
109
- retireOn: 'P1-3 到货 ⇒ 两个方向带同一个 completionId,预 seed 这一手(按 runId 抢跑)可删',
106
+ retireOn: 'RL-38',
110
107
  },
111
108
  {
112
109
  id: 'T53',
@@ -115,8 +112,7 @@ export const MIGRATED_COMPENSATIONS = [
115
112
  libraryHalf: 'adapt.ts task_notification / workflow_complete 两臂的四道门(逐道说明见本行上方注释)',
116
113
  chromeArm: null,
117
114
  hostHalf: null,
118
- retireOn: 'P1-3 到货 ⇒ 降到「①渲染去重(键换 completionId)+ ④队列撤单」两道;②③ 删。' +
119
- '🔴 判据不是「四变一」而是逐道过一遍上面那四行 —— 把 ④ 当成去重删掉会让队列里的旧条目重新上屏',
115
+ retireOn: 'RL-39',
120
116
  },
121
117
  {
122
118
  id: 'T49',
@@ -125,7 +121,7 @@ export const MIGRATED_COMPENSATIONS = [
125
121
  libraryHalf: 'adapt.ts task_progress 臂 registerSubagentAlias(explicitParent, taskId)',
126
122
  chromeArm: null,
127
123
  hostHalf: null,
128
- retireOn: 'P1-2 到货后 content 帧自带 taskId ⇒ alias 学习整条可删',
124
+ retireOn: 'RL-40',
129
125
  },
130
126
  ];
131
127
  export function compensationSplitViolations() {
@@ -1,13 +1,11 @@
1
- import type { TaskRequest, RunReceipt, CancelAck, Scenario } from '@sema-agent/sdk';
1
+ import type { TaskRequest, RunReceipt, CancelAck, Scenario, SteerPriority } from '@sema-agent/sdk';
2
+ import { type SteerPriorityReading } from './steerPriorityCapability.js';
2
3
  export interface RunsResourceLike {
3
4
  create(req: TaskRequest, opts?: {
4
5
  idempotencyKey?: string | null;
5
6
  signal?: AbortSignal;
6
7
  }): Promise<RunReceipt>;
7
- steer(taskId: string, steer: {
8
- text: string;
9
- mode?: 'all' | 'one-at-a-time';
10
- }, opts?: {
8
+ steer(taskId: string, steer: SteerBodyInput, opts?: {
11
9
  signal?: AbortSignal;
12
10
  }): Promise<unknown>;
13
11
  cancel(taskId: string, opts?: {
@@ -17,17 +15,21 @@ export interface RunsResourceLike {
17
15
  export interface ControlClientLike {
18
16
  runs: RunsResourceLike;
19
17
  }
20
- export type ControlSafetyCode = 'not_running' | 'invalid_content' | 'queue_full' | 'duplicate_input_id' | 'ambiguous_target' | 'still_running' | 'blocked_by_hook' | 'ledger_unavailable' | 'steering_other' | 'cancel_lost_race' | 'cancel_run_not_running' | 'not_found';
18
+ export type ControlSafetyCode = 'not_running' | 'invalid_content' | 'queue_full' | 'duplicate_input_id' | 'ambiguous_target' | 'still_running' | 'blocked_by_hook' | 'ledger_unavailable' | 'steering_other' | 'cancel_lost_race' | 'cancel_run_not_running' | 'not_found' | 'priority_not_applied' | 'steer_input_invalid';
21
19
  export declare class ControlSafetyError extends Error {
22
20
  readonly code: ControlSafetyCode;
23
21
  readonly cause?: unknown | undefined;
24
- constructor(message: string, code: ControlSafetyCode, cause?: unknown | undefined);
22
+ readonly advice?: string;
23
+ readonly status?: number;
24
+ constructor(message: string, code: ControlSafetyCode, cause?: unknown | undefined, detail?: {
25
+ readonly advice?: string;
26
+ readonly status?: number;
27
+ });
25
28
  }
26
- export type QueuePriority = 'now' | 'next' | 'later';
27
- export interface QueuedCommand {
28
- id: string;
29
- text: string;
30
- priority: QueuePriority;
29
+ export interface ControlRouterSteerOptions {
30
+ signal?: AbortSignal;
31
+ priority?: SteerPriority;
32
+ steerPriority?: SteerPriorityReading;
31
33
  }
32
34
  export interface ControlRouterOptions {
33
35
  sessionId?: string;
@@ -42,8 +44,6 @@ export declare class ControlRouter {
42
44
  private readonly jobId;
43
45
  private readonly scenario;
44
46
  private readonly systemPrompt;
45
- private readonly queue;
46
- private seq;
47
47
  constructor(client: ControlClientLike, opts?: ControlRouterOptions);
48
48
  activeTaskId(): string | null;
49
49
  activeSessionId(): string | undefined;
@@ -51,19 +51,10 @@ export declare class ControlRouter {
51
51
  signal?: AbortSignal;
52
52
  }): Promise<RunReceipt>;
53
53
  private buildTaskRequest;
54
- steer(text: string, mode?: 'all' | 'one-at-a-time', opts?: {
55
- signal?: AbortSignal;
56
- }): Promise<unknown>;
54
+ steer(text: string, mode?: 'all' | 'one-at-a-time', opts?: ControlRouterSteerOptions): Promise<unknown>;
57
55
  cancel(opts?: {
58
56
  signal?: AbortSignal;
59
57
  }): Promise<CancelAck>;
60
- enqueue(text: string, priority?: QueuePriority): QueuedCommand;
61
- dequeue(id: string): boolean;
62
- pending(): readonly QueuedCommand[];
63
- drainNext(opts?: {
64
- signal?: AbortSignal;
65
- }): Promise<RunReceipt | null>;
66
- private nextId;
67
58
  }
68
59
  export interface ErrCodes {
69
60
  code?: string | undefined;
@@ -72,8 +63,24 @@ export interface ErrCodes {
72
63
  }
73
64
  export declare function errCodes(e: unknown): ErrCodes;
74
65
  export declare function steeringStatusIs4xx(e: object): boolean;
75
- export interface SteeringRefusedBeforeEngine {
66
+ export interface SteerRefusalAdvice {
76
67
  safety: ControlSafetyCode;
77
68
  advice: string;
69
+ happened: string;
70
+ nextStep: string;
78
71
  }
72
+ export type SteeringRefusedBeforeEngine = SteerRefusalAdvice;
79
73
  export declare function steeringRefusedBeforeEngine(e: object): SteeringRefusedBeforeEngine | undefined;
74
+ export declare function steerRefusalAdviceOf(e: object): SteerRefusalAdvice | undefined;
75
+ export interface SteerBody {
76
+ readonly text: string;
77
+ readonly mode?: 'all' | 'one-at-a-time';
78
+ readonly priority?: 'now' | 'later';
79
+ }
80
+ export interface SteerBodyInput {
81
+ text: string;
82
+ mode?: 'all' | 'one-at-a-time';
83
+ priority?: SteerPriority;
84
+ }
85
+ export declare const UNOBSERVED_STEER_PRIORITY: SteerPriorityReading;
86
+ export declare function steerBodyOf(input: SteerBodyInput, reading: SteerPriorityReading): SteerBody;