@sema-agent/client-core 0.6.0 → 0.7.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.
- package/dist/adapt.d.ts +4 -2
- package/dist/adapt.js +192 -25
- package/dist/diff/patch.d.ts +29 -0
- package/dist/diff/patch.js +45 -0
- package/dist/engineSessionParam.d.ts +7 -0
- package/dist/engineSessionParam.js +35 -0
- package/dist/finalVerifyWire.d.ts +74 -0
- package/dist/finalVerifyWire.js +63 -0
- package/dist/headlessPermissionModeWire.d.ts +55 -0
- package/dist/headlessPermissionModeWire.js +111 -0
- package/dist/headlessReconnectWire.d.ts +96 -0
- package/dist/headlessReconnectWire.js +141 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +22 -0
- package/dist/interactiveToolsWire.d.ts +48 -0
- package/dist/interactiveToolsWire.js +86 -0
- package/dist/limitsWire.d.ts +89 -0
- package/dist/limitsWire.js +225 -0
- package/dist/notifications.d.ts +7 -0
- package/dist/notifications.js +32 -0
- package/dist/sandboxWire.d.ts +75 -0
- package/dist/sandboxWire.js +138 -0
- package/dist/scenarioWire.d.ts +62 -0
- package/dist/scenarioWire.js +115 -0
- package/dist/seam.d.ts +33 -2
- package/dist/seam.js +1 -0
- package/dist/toolResult.d.ts +118 -0
- package/dist/toolResult.js +774 -0
- package/package.json +4 -2
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/sema/scenarioWire.ts — `--scenario <name>` wire (clay 拍, 2026-07-15): expose the engine's
|
|
3
|
+
* REQUEST-LEVEL scenario routing axis on the headless `-p` path. The server has shipped scenario
|
|
4
|
+
* routing since day one (ai-agent-service capabilities/scenarios.ts — `TaskRequest.scenario` picks the
|
|
5
|
+
* tool roster + prompt provider per request: default / code-review / scan / oa / team + center-declared
|
|
6
|
+
* overlays); the shell simply never exposed the field to users. This module is the CLI face.
|
|
7
|
+
*
|
|
8
|
+
* PRECEDENCE (flag > settings > default):
|
|
9
|
+
* a) `--scenario <name>` (explicit flag) → stamp `TaskRequest.scenario`.
|
|
10
|
+
* b) `SEMA_HEADLESS_SCENARIO` env — the settings lane: → stamp when no flag. Set it in the user
|
|
11
|
+
* settings.json `env` block (seeded into process.env by the SAME 1a-envseed both the REPL boot and
|
|
12
|
+
* printModeEngine run), the lane every other wire config rides (SEMA_SELF_ORCHESTRATION,
|
|
13
|
+
* SEMA_WEBSEARCH_*, SEMA_ENABLE_FORK). One mechanism serves both "env var" and "settings file".
|
|
14
|
+
* c) neither → NO stamp = today's behaviour, verbatim.
|
|
15
|
+
*
|
|
16
|
+
* VOCABULARY = the server's scenario registry (builtin + center-declared). The shell does NOT
|
|
17
|
+
* pre-validate against it (the registry is deployment-side truth): an UNKNOWN name falls back to the
|
|
18
|
+
* `default` scenario server-side (scenarios.ts selectScenario — safe), and a center allowlist violation
|
|
19
|
+
* comes back as an honest 400 `scenario_not_allowed` (already rendered by scenarioNotAllowedCopy.ts).
|
|
20
|
+
* We only mirror the server's NAME-SHAPE rule (scenarios.ts:318 SCENARIO_NAME_RE) locally — same rule,
|
|
21
|
+
* earlier and cheaper, and it keeps prompt-looking values (whitespace etc.) from being eaten as a name.
|
|
22
|
+
*
|
|
23
|
+
* NOTE (mock-key shadow): the seam also uses `scenario` as the MOCK transcript selector
|
|
24
|
+
* (seamQuery.selectScenario / SEMA_SCENARIO). liveClient strips those mock keys before a live forward;
|
|
25
|
+
* a `--scenario` value that collides with a mock key (e.g. `bash`) is therefore equivalent to `default`
|
|
26
|
+
* on the live engine — which is exactly what the server would resolve for it anyway (no such scenario).
|
|
27
|
+
*
|
|
28
|
+
* SEMA_SCENARIO (the mock harness opt-in — "never spawn a real engine", printModeEngine.ts) is
|
|
29
|
+
* deliberately NOT reused here: it selects offline mock transcripts, not live engine routing.
|
|
30
|
+
*/
|
|
31
|
+
import { hostEnv } from './hostEnv.js';
|
|
32
|
+
/** Mirror of the server's scenario NAME shape (ai-agent-service scenarios.ts:318). */
|
|
33
|
+
export const SCENARIO_NAME_RE = /^[a-z][a-z0-9-]{1,31}$/;
|
|
34
|
+
/** Settings-lane env knob (settings.json `env` block → 1a-envseed → process.env). */
|
|
35
|
+
export const HEADLESS_SCENARIO_ENV = 'SEMA_HEADLESS_SCENARIO';
|
|
36
|
+
const USAGE_HINT = "sema: --scenario expects a scenario name (lowercase letters/digits/hyphens, starting with a letter, ≤32 chars).\n" +
|
|
37
|
+
' --scenario <name> route this run through the named engine scenario (deployment-defined tool\n' +
|
|
38
|
+
' roster + system prompt; unknown names fall back to the default scenario)\n' +
|
|
39
|
+
' (no flag) the default scenario — today\'s behaviour';
|
|
40
|
+
/**
|
|
41
|
+
* Parse `--scenario` out of an argv slice (everything before a bare `--`; both `--scenario <v>` and
|
|
42
|
+
* `--scenario=<v>` forms — the sandboxWire idiom). No flag ⇒ `{ok:true}` with no scenario. Repeated
|
|
43
|
+
* flag ⇒ LAST wins (commander convention). Missing value / flag-shaped value / name-shape violation ⇒
|
|
44
|
+
* fail-LOUD parse error (never a silent default — a mis-typed routing choice must not quietly run on
|
|
45
|
+
* the wrong tool surface; same stance as `--sandbox`).
|
|
46
|
+
*/
|
|
47
|
+
export function parseScenarioArgv(argv) {
|
|
48
|
+
let scenario;
|
|
49
|
+
for (let i = 0; i < argv.length; i++) {
|
|
50
|
+
const a = argv[i];
|
|
51
|
+
if (a === '--')
|
|
52
|
+
break; // positionals — never flags
|
|
53
|
+
let raw;
|
|
54
|
+
if (a === '--scenario') {
|
|
55
|
+
const nxt = argv[i + 1];
|
|
56
|
+
if (nxt === undefined || nxt.startsWith('-')) {
|
|
57
|
+
return { ok: false, error: USAGE_HINT };
|
|
58
|
+
}
|
|
59
|
+
raw = nxt;
|
|
60
|
+
i++; // consume the value token
|
|
61
|
+
}
|
|
62
|
+
else if (a.startsWith('--scenario=')) {
|
|
63
|
+
raw = a.slice('--scenario='.length);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const v = raw.trim();
|
|
69
|
+
// sandboxWire audit #17 lesson: a bare `--scenario` EATS the following positional — a value with
|
|
70
|
+
// whitespace is almost certainly the user's prompt; say exactly that instead of mis-parsing.
|
|
71
|
+
if (/\s/.test(v)) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
error: `sema: --scenario got "${v.length > 48 ? `${v.slice(0, 48)}…` : v}" — that looks like your prompt, not a scenario name.\n` +
|
|
75
|
+
'Put the flag AFTER the value form (--scenario=<name>) or keep the name and prompt as separate tokens.\n' +
|
|
76
|
+
USAGE_HINT,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (!SCENARIO_NAME_RE.test(v)) {
|
|
80
|
+
return { ok: false, error: USAGE_HINT };
|
|
81
|
+
}
|
|
82
|
+
scenario = v;
|
|
83
|
+
}
|
|
84
|
+
return { ok: true, ...(scenario ? { scenario } : {}) };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The settings-lane default (`SEMA_HEADLESS_SCENARIO`). FAIL-SOFT on a bad value (stderr warning +
|
|
88
|
+
* no stamp): a settings-file typo must not hard-brick every headless run the way an explicit flag
|
|
89
|
+
* typo fails the one run it was typed on.
|
|
90
|
+
*/
|
|
91
|
+
export function headlessScenarioFromEnv(env = hostEnv()) {
|
|
92
|
+
const v = env[HEADLESS_SCENARIO_ENV]?.trim();
|
|
93
|
+
if (!v)
|
|
94
|
+
return undefined;
|
|
95
|
+
if (!SCENARIO_NAME_RE.test(v)) {
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.error(`[sema] ${HEADLESS_SCENARIO_ENV}="${v}" is not a valid scenario name (want ${String(SCENARIO_NAME_RE)}) — ignoring the settings default`);
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
return v;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve the scenario for a headless `-p` submit: explicit `--scenario` flag > `SEMA_HEADLESS_SCENARIO`
|
|
104
|
+
* settings default > none (= the engine's default scenario, today's behaviour). Flag parse errors
|
|
105
|
+
* propagate fail-loud; the caller exits.
|
|
106
|
+
*/
|
|
107
|
+
export function scenarioForPrint(argv, env = hostEnv()) {
|
|
108
|
+
const parsed = parseScenarioArgv(argv);
|
|
109
|
+
if (!parsed.ok)
|
|
110
|
+
return parsed;
|
|
111
|
+
if (parsed.scenario)
|
|
112
|
+
return parsed;
|
|
113
|
+
const fromEnv = headlessScenarioFromEnv(env);
|
|
114
|
+
return { ok: true, ...(fromEnv ? { scenario: fromEnv } : {}) };
|
|
115
|
+
}
|
package/dist/seam.d.ts
CHANGED
|
@@ -98,6 +98,20 @@ export type ChromeEvent = {
|
|
|
98
98
|
taskId: string;
|
|
99
99
|
status: string;
|
|
100
100
|
outputPath?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* B5 新臂(#117a,E 层 Bash 分臂的**执行半场**)—— 模型发起的后台 Bash 回执被认出来了。
|
|
104
|
+
* 判定在库(`detectEngineBgShellReceipt`,纯文案锚定 + `run_in_background` 门);执行留宿主:
|
|
105
|
+
* 宿主消费义务 = ① 把 registration 发给自己的后台 shell 面板 store(壳 =
|
|
106
|
+
* `publishEngineBgShellPanelEvent`)② 登记「句柄 → 宿主 run」映射(壳 = `recordBgParentRun(
|
|
107
|
+
* taskId, getActiveEngineTaskId())`,[1501] A/B 寻址的硬证据)。
|
|
108
|
+
* 缺席 = ctrl+B 面板看不到这条后台命令(不是报错,是这一面在该宿主上哑掉)。
|
|
109
|
+
*/
|
|
110
|
+
| {
|
|
111
|
+
kind: 'bgshell_register';
|
|
112
|
+
laneProof: LaneProof;
|
|
113
|
+
taskId: string;
|
|
114
|
+
registration: unknown;
|
|
101
115
|
} | {
|
|
102
116
|
kind: 'tasks_expand';
|
|
103
117
|
laneProof: LaneProof;
|
|
@@ -165,8 +179,11 @@ export type ChromeEvent = {
|
|
|
165
179
|
* 🔴 配对纪律([paired-mechanisms-must-share-premise]):这两件从「宿主义务」改成「库自持」是
|
|
166
180
|
* **整臂让位**,不是两边都做——宿主若仍照旧实现,两次 drop/clear 幂等无害,但**记号必须删**,
|
|
167
181
|
* 否则下一棒会以为库没做。
|
|
168
|
-
* 跨通道去重(「补发通道不得再注入模型一遍」)
|
|
169
|
-
*
|
|
182
|
+
* 跨通道去重(「补发通道不得再注入模型一遍」)由**库自持**,不摊给宿主 —— B5 起台账回到
|
|
183
|
+
* `notifications.ts` 的 **module 级** `notifiedRunIds` / `cardEnqueuedRunIds`(0.6.0 曾放在适配器
|
|
184
|
+
* 实例上,与清账/记账的另一半不共享前提 = [1857] 那个缺口)。
|
|
185
|
+
* 🔴 宿主**不要**再在本臂上调 `markEngineWorkflowNotified` —— 库已在同一位置调过(幂等,
|
|
186
|
+
* 宿主照调无害,但记号该删:整臂让位,不是两边都做)。
|
|
170
187
|
* 注:面板行 end 事件本身走 panel_task 臂、SubagentStop 走 subagent_lifecycle 臂,不重复。
|
|
171
188
|
*/
|
|
172
189
|
| {
|
|
@@ -261,6 +278,20 @@ export type ChromeEvent = {
|
|
|
261
278
|
toolUseId: string;
|
|
262
279
|
input: unknown;
|
|
263
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* B5 —— 同一台账的**第二个来源**:core 1.217([379])的 `task` / `task-list` structured 权威全量态。
|
|
283
|
+
* `source:'tool_use'` 那条是旧引擎兜底(从 input 重建),本条是引擎真实 id 的精确同步。
|
|
284
|
+
* 宿主消费义务:壳 = `handleEngineTaskStructured(structured)`(两路经 engineToShellTaskId 收敛)。
|
|
285
|
+
* 🔴 两条**不是**二选一 —— 旧引擎只有前者、新引擎两者都来且后者更准,宿主按幂等处理即可。
|
|
286
|
+
*/
|
|
287
|
+
| {
|
|
288
|
+
kind: 'task_ledger_sync';
|
|
289
|
+
laneProof: LaneProof;
|
|
290
|
+
source: 'structured';
|
|
291
|
+
/** `'task' | 'task-list'`(白名单已在库内判过)。 */
|
|
292
|
+
structuredType: string;
|
|
293
|
+
structured: unknown;
|
|
294
|
+
}
|
|
264
295
|
/**
|
|
265
296
|
* B3 新臂 ①(T38 三清的第三清 + T57 五处断闸的第五处)—— E12「下一步可问什么」建议**批**。
|
|
266
297
|
* `suggestions: null` = 作废(turn 开场必发一次:上一轮的建议对新上下文是噪声,挂着不掉会让人
|
package/dist/seam.js
CHANGED
|
@@ -13,6 +13,7 @@ export const CHROME_ARMS = [
|
|
|
13
13
|
{ kind: 'retry_status', required: false, duty: '渲/清 spinner 的重试覆盖层' },
|
|
14
14
|
{ kind: 'panel_task', required: true, duty: 'publishEngineAgentPanelEvent(event) 原样转发' },
|
|
15
15
|
{ kind: 'bgshell_settle', required: true, duty: '后台 shell 面板行落终态(含 outputPath)' },
|
|
16
|
+
{ kind: 'bgshell_register', required: true, duty: '后台 shell 面板行建行 + 登记「句柄→宿主 run」' },
|
|
16
17
|
{ kind: 'tasks_expand', required: false, duty: '展开 ctrl+t 任务面板' },
|
|
17
18
|
{ kind: 'thinking_activity', required: false, duty: '开/收活体 "∴ Thinking…" 行' },
|
|
18
19
|
{ kind: 'request_start', required: false, duty: 'spinner 置 requesting 态' },
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 引擎会在 `tool_end.structured` 顶层 `type` 上发的**全部**取值。
|
|
3
|
+
* 用途**不是**「只处理这些」——下面的 switch 只认得其中一部分,认不得的照旧走 text 回落;
|
|
4
|
+
* 用途是「**structured 在场**」这个判据本身:顶层 type 命中白名单 ⇒ 引擎这一版是发结构化的,
|
|
5
|
+
* 于是模型面正文的**正则反解**(T11 bash / T13+T24 task-output / T14 后台回执三代文案)退位。
|
|
6
|
+
* 反过来,一个 `{type:'something-else'}` 或裸对象**不算** structured 在场 —— 宁可回落到正则,
|
|
7
|
+
* 也不许把「有个对象」当成「引擎发了结构化」(判据锚在决定结果的量上:决定的是「该不该信正则」)。
|
|
8
|
+
* ⚠️ 与设计稿的口径差:任务书写「29 项」,[1840] 清单逐条数是 **30 项**(见交接报告「设计稿错漏」)。
|
|
9
|
+
*/
|
|
10
|
+
export declare const STRUCTURED_DETAIL_TYPES: ReadonlySet<string>;
|
|
11
|
+
/** structured 在场判别:顶层 `type` ∈ 白名单 ⇒ 返回该 type,否则 undefined(= 不在场)。 */
|
|
12
|
+
export declare function structuredDetailType(structured: unknown): string | undefined;
|
|
13
|
+
export declare function modelFacingParseCalls(): number;
|
|
14
|
+
export declare function _resetModelFacingParseCountForTest(): void;
|
|
15
|
+
export declare function parseModelFacingBash(text: string): {
|
|
16
|
+
stdout: string;
|
|
17
|
+
stderr: string;
|
|
18
|
+
exitCode: number | null;
|
|
19
|
+
} | null;
|
|
20
|
+
/**
|
|
21
|
+
* T12 —— 剥引擎的 `delimitUntrusted` 围栏(core untrusted-text.ts:118)**仅供渲染**。
|
|
22
|
+
* 围栏是给模型看的注入防护,人类转录卡显示正文(clay 07-03 审计 #1/#9 视觉 bug 的修)。
|
|
23
|
+
*/
|
|
24
|
+
export declare function stripUntrustedFence(text: string): {
|
|
25
|
+
label: string;
|
|
26
|
+
body: string;
|
|
27
|
+
} | null;
|
|
28
|
+
/**
|
|
29
|
+
* T13 回落 —— 引擎 TaskOutput 的模型面正文(core task-registry.ts 的 bash/agent 两形,整体
|
|
30
|
+
* delimitUntrusted 包裹、label = `TaskOutput <id>`)反解回卡片槽位。`kind` 报哪一形命中,
|
|
31
|
+
* 'unknown' ⇒ 调用方回落原文。
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseModelFacingTaskOutput(text: string): {
|
|
34
|
+
kind: 'bash' | 'agent' | 'unknown';
|
|
35
|
+
taskId?: string;
|
|
36
|
+
status?: string;
|
|
37
|
+
output?: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* T14 回落 —— 后台回执**三代文案**正则(#117a:core ≥1.283 的 `Command running in background` 是
|
|
41
|
+
* 第三代)。structured bash 在场时由 `background`/`task_id` 位取代(见 `wireOutputToBody`)。
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseBackgroundReceipt(text: string): {
|
|
44
|
+
taskId: string;
|
|
45
|
+
} | null;
|
|
46
|
+
/**
|
|
47
|
+
* T8 —— 压平非均匀 §E1 `output`(`string` | `(Text|Image)[]`)。
|
|
48
|
+
* ⚠️ 真源在 adapt.ts(A 层 settle 报告也用同一份),本文件只 import,别再写第二份。
|
|
49
|
+
*/
|
|
50
|
+
export type FlattenWireOutput = (output: unknown) => string;
|
|
51
|
+
/** wire 没带 output 时的降级原因码(UI 显示决策留端;客户端绝不编造执行结果)。 */
|
|
52
|
+
export declare const TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT: "wire_carried_no_output";
|
|
53
|
+
export interface ToolResultBody {
|
|
54
|
+
content: unknown;
|
|
55
|
+
isError: boolean;
|
|
56
|
+
toolUseResult?: unknown;
|
|
57
|
+
/** 只在「wire 没带正文」时出现;在场 = 这张卡**没有真实执行结果**,不是空结果。 */
|
|
58
|
+
degraded?: typeof TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* T7 —— `tool_end.output === undefined`(events.d.ts:79 文档化的「工具没有正文」情形)时的卡体。
|
|
62
|
+
*
|
|
63
|
+
* cli 旧形:调 mock 注册表 `synthesizeToolIO(name, input)` **反造**一个结果体(stdout/hunks/匹配列表),
|
|
64
|
+
* 卡片于是显示「看起来像真的、但根本不是这次执行产物」的内容。§8-4 按宪法「诚实优先于产出」裁定
|
|
65
|
+
* 搬的时候就改掉:**输出诚实缺席 + degraded 标记**,由 UI 决定显示「结果不可用」。
|
|
66
|
+
* 🔴 `content` 保持**字符串**(件1:tool_result block content 恒字符串,裸对象经 /compact 直发
|
|
67
|
+
* provider = 400 invalid_request);空串 = 无正文,`degraded` 才是判别位。
|
|
68
|
+
*/
|
|
69
|
+
export declare function degradedToolResultBody(isError: boolean): ToolResultBody;
|
|
70
|
+
/**
|
|
71
|
+
* 真实 §E1 `tool_end.output` → 卡片读的 typed 正文。
|
|
72
|
+
*
|
|
73
|
+
* B5 新增第 5 个入参 `structured`:**structured 在场 ⇒ 正则退位**(①)。
|
|
74
|
+
* 三臂:`bash`(T11/T14)· `taskoutput|task_output`(T13,无 structured 的老腿)· 泛化兜底。
|
|
75
|
+
* 🔴 `truncated` 只做中性提示,截断正文**绝不**回喂模型(events.d.ts:80-85)。
|
|
76
|
+
*/
|
|
77
|
+
export declare function wireOutputToBody(toolName: string, output: unknown, isError: boolean, truncated: boolean, flatten: FlattenWireOutput, structured?: unknown): ToolResultBody;
|
|
78
|
+
/**
|
|
79
|
+
* design/64 CC-parity `toolUseResult`:引擎结构化细节 → 各卡 outputSchema **精确** typed 形
|
|
80
|
+
* (safeParse 过了才渲富卡,不过就回落 12 行文本兜底)。
|
|
81
|
+
* `structuredPatch` 在**这里**算(T20,core 裁定:引擎发 originalFile、客户端算 hunks)。
|
|
82
|
+
* 全部**防御读**:形状不认得 ⇒ null ⇒ 调用方回落 text 路径(降保真,绝不炸)。
|
|
83
|
+
*/
|
|
84
|
+
export declare function structuredToToolUseResult(structured: unknown,
|
|
85
|
+
/** 压平后的模型面正文 —— 有些形(task-output)只带 identity/status,正文仍在模型面。 */
|
|
86
|
+
modelText?: string): {
|
|
87
|
+
toolUseResult: unknown;
|
|
88
|
+
isError?: boolean;
|
|
89
|
+
} | null;
|
|
90
|
+
export interface EngineBgShellRegistration {
|
|
91
|
+
kind: 'register';
|
|
92
|
+
/** 回执上的**引擎** task id(`task_id=…`,TaskOutput/TaskStop 的句柄)。 */
|
|
93
|
+
taskId: string;
|
|
94
|
+
/** Bash tool_use input 的 command(面板行的命令行)。 */
|
|
95
|
+
command: string;
|
|
96
|
+
/** 模型给了 description 才有。 */
|
|
97
|
+
description?: string;
|
|
98
|
+
/** 引擎模型面回执原文,逐字 —— 详情视图显示它(里面的 output-file 路径因此可见可复制)。 */
|
|
99
|
+
receipt: string;
|
|
100
|
+
}
|
|
101
|
+
export declare function detectEngineBgShellReceipt(rawInput: unknown, outputText: string | undefined): EngineBgShellRegistration | null;
|
|
102
|
+
/**
|
|
103
|
+
* TodoWrite 清单卡:引擎不发 todo structured,全量新表骑在 tool_use INPUT 上 ⇒ 从它合成 typed 结果。
|
|
104
|
+
* `oldTodos` = 上一次的活体清单(调用方持:一个 session 一份,正是划删线 diff 要的粒度)。
|
|
105
|
+
*/
|
|
106
|
+
export declare function todoWriteToolUseResult(rawInput: unknown, oldTodos: unknown[], isError: boolean): {
|
|
107
|
+
toolUseResult: unknown;
|
|
108
|
+
isError: boolean;
|
|
109
|
+
newTodos: unknown[];
|
|
110
|
+
} | null;
|
|
111
|
+
/**
|
|
112
|
+
* ReportFindings(core 1.288 [811]b,引擎侧执行的合成回声工具):details 是 `{count, level?, findings}`
|
|
113
|
+
* **没有 type 判别位**(core synthetic-tools.js)⇒ B 层的 type-keyed switch 认领不了,按**工具名**认。
|
|
114
|
+
* 双腿:优先 wire structured;引擎没发就从 tool_use INPUT 合成(回声工具:input.findings ≡ output.findings)。
|
|
115
|
+
*/
|
|
116
|
+
export declare function reportFindingsToolUseResult(structured: unknown, rawInput: unknown): {
|
|
117
|
+
toolUseResult: unknown;
|
|
118
|
+
} | null;
|