@deepwhale/coding-agent 1.0.12 → 1.0.13
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/agent/agent-compaction.d.ts +74 -0
- package/dist/agent/agent-compaction.d.ts.map +1 -0
- package/dist/agent/agent-compaction.js +145 -0
- package/dist/agent/agent-compaction.js.map +1 -0
- package/dist/agent/index.d.ts +16 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +17 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/session-adapter.d.ts +177 -0
- package/dist/agent/session-adapter.d.ts.map +1 -0
- package/dist/agent/session-adapter.js +365 -0
- package/dist/agent/session-adapter.js.map +1 -0
- package/dist/agent/tool-loop.d.ts +123 -0
- package/dist/agent/tool-loop.d.ts.map +1 -0
- package/dist/agent/tool-loop.js +436 -0
- package/dist/agent/tool-loop.js.map +1 -0
- package/dist/env/load-project-env.d.ts +40 -0
- package/dist/env/load-project-env.d.ts.map +1 -0
- package/dist/env/load-project-env.js +80 -0
- package/dist/env/load-project-env.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-factory.d.ts +50 -0
- package/dist/llm-factory.d.ts.map +1 -0
- package/dist/llm-factory.js +110 -0
- package/dist/llm-factory.js.map +1 -0
- package/dist/modes/index.d.ts +14 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +14 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/print.d.ts +50 -0
- package/dist/modes/print.d.ts.map +1 -0
- package/dist/modes/print.js +236 -0
- package/dist/modes/print.js.map +1 -0
- package/dist/modes/rpc.d.ts +52 -0
- package/dist/modes/rpc.d.ts.map +1 -0
- package/dist/modes/rpc.js +316 -0
- package/dist/modes/rpc.js.map +1 -0
- package/dist/modes/tui.d.ts +107 -0
- package/dist/modes/tui.d.ts.map +1 -0
- package/dist/modes/tui.js +680 -0
- package/dist/modes/tui.js.map +1 -0
- package/dist/policy/args-digest.d.ts +13 -0
- package/dist/policy/args-digest.d.ts.map +1 -0
- package/dist/policy/args-digest.js +29 -0
- package/dist/policy/args-digest.js.map +1 -0
- package/dist/policy/chain.d.ts +19 -0
- package/dist/policy/chain.d.ts.map +1 -0
- package/dist/policy/chain.js +24 -0
- package/dist/policy/chain.js.map +1 -0
- package/dist/policy/index.d.ts +17 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +16 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/sanitize-reason.d.ts +11 -0
- package/dist/policy/sanitize-reason.d.ts.map +1 -0
- package/dist/policy/sanitize-reason.js +24 -0
- package/dist/policy/sanitize-reason.js.map +1 -0
- package/dist/policy/static-rules.d.ts +32 -0
- package/dist/policy/static-rules.d.ts.map +1 -0
- package/dist/policy/static-rules.js +106 -0
- package/dist/policy/static-rules.js.map +1 -0
- package/dist/policy/types.d.ts +56 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +13 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/repl/repl-command-router.d.ts +78 -0
- package/dist/repl/repl-command-router.d.ts.map +1 -0
- package/dist/repl/repl-command-router.js +112 -0
- package/dist/repl/repl-command-router.js.map +1 -0
- package/dist/repl/repl-confirm.d.ts +49 -0
- package/dist/repl/repl-confirm.d.ts.map +1 -0
- package/dist/repl/repl-confirm.js +88 -0
- package/dist/repl/repl-confirm.js.map +1 -0
- package/dist/repl/repl-session.d.ts +79 -0
- package/dist/repl/repl-session.d.ts.map +1 -0
- package/dist/repl/repl-session.js +129 -0
- package/dist/repl/repl-session.js.map +1 -0
- package/dist/repl/repl-signal-coordinator.d.ts +74 -0
- package/dist/repl/repl-signal-coordinator.d.ts.map +1 -0
- package/dist/repl/repl-signal-coordinator.js +73 -0
- package/dist/repl/repl-signal-coordinator.js.map +1 -0
- package/dist/repl.d.ts +117 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +626 -0
- package/dist/repl.js.map +1 -0
- package/dist/sandbox/docker-runner.d.ts +147 -0
- package/dist/sandbox/docker-runner.d.ts.map +1 -0
- package/dist/sandbox/docker-runner.js +426 -0
- package/dist/sandbox/docker-runner.js.map +1 -0
- package/dist/sandbox/env-gate.d.ts +28 -0
- package/dist/sandbox/env-gate.d.ts.map +1 -0
- package/dist/sandbox/env-gate.js +65 -0
- package/dist/sandbox/env-gate.js.map +1 -0
- package/dist/sandbox/local-runner.d.ts +29 -0
- package/dist/sandbox/local-runner.d.ts.map +1 -0
- package/dist/sandbox/local-runner.js +79 -0
- package/dist/sandbox/local-runner.js.map +1 -0
- package/dist/sandbox/types.d.ts +80 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +25 -0
- package/dist/sandbox/types.js.map +1 -0
- package/dist/tools/bash.d.ts +35 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +233 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit-file.d.ts +22 -0
- package/dist/tools/edit-file.d.ts.map +1 -0
- package/dist/tools/edit-file.js +79 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/find.d.ts +21 -0
- package/dist/tools/find.d.ts.map +1 -0
- package/dist/tools/find.js +168 -0
- package/dist/tools/find.js.map +1 -0
- package/dist/tools/grep.d.ts +19 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +170 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/read-file.d.ts +18 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +52 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +67 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/write-file.d.ts +18 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +47 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/tui-ink-bundle.js +38587 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/util/index.d.ts +16 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +16 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/tui-history.d.ts +37 -0
- package/dist/util/tui-history.d.ts.map +1 -0
- package/dist/util/tui-history.js +93 -0
- package/dist/util/tui-history.js.map +1 -0
- package/dist/verify/format-report.d.ts +57 -0
- package/dist/verify/format-report.d.ts.map +1 -0
- package/dist/verify/format-report.js +128 -0
- package/dist/verify/format-report.js.map +1 -0
- package/dist/verify/index.d.ts +8 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +8 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/verify-runner.d.ts +186 -0
- package/dist/verify/verify-runner.d.ts.map +1 -0
- package/dist/verify/verify-runner.js +707 -0
- package/dist/verify/verify-runner.js.map +1 -0
- package/package.json +1 -1
package/dist/repl.js
ADDED
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deepwhale REPL — Sprint 1a 接入 tool loop + session
|
|
3
|
+
*
|
|
4
|
+
* Sprint 0.3 范围:单轮 chat + 内建命令。
|
|
5
|
+
* Sprint 1a 扩展:
|
|
6
|
+
* - 接 Session JSONL:启动时 load(可选路径),退出时 close(flush)
|
|
7
|
+
* - 接 runToolLoop:每轮 user → tool loop → 持久化 steps
|
|
8
|
+
* - 流式:onChunk 实时打印 final.content(assistant 增量)
|
|
9
|
+
* - 命令:保留 /help / /exit / exit / quit
|
|
10
|
+
*
|
|
11
|
+
* Sprint 1a 简化:
|
|
12
|
+
* - 不做 plan mode、recovery、自动压缩
|
|
13
|
+
* - 不做 multi-session 切换
|
|
14
|
+
* - 错误用 i18n + 不污染 messages
|
|
15
|
+
*
|
|
16
|
+
* 文件职责:
|
|
17
|
+
* - runOneTurn: 仍保留为低层单轮 API(不持久化,无 tool loop)
|
|
18
|
+
* - startRepl: 接 tool loop + session 的入口
|
|
19
|
+
*/
|
|
20
|
+
import { createInterface } from 'node:readline';
|
|
21
|
+
import { stdin, stdout, stderr } from 'node:process';
|
|
22
|
+
import { t } from '@deepwhale/core';
|
|
23
|
+
import { SessionReader, SessionWriter } from '@deepwhale/core';
|
|
24
|
+
import { APIKeyMissingError, isLLMError, LLMAuthError, LLMNetworkError, LLMRateLimitError, LLMStreamError, LLMUnknownError, } from '@deepwhale/llm';
|
|
25
|
+
import { isToolLoopError, loadSession, persistToolLoopSteps, runToolLoop, runToolLoopWithCompaction, ToolLoopLimitError, } from './agent/index.js';
|
|
26
|
+
import { CompactionState } from '@deepwhale/core';
|
|
27
|
+
import { createDefaultRegistry } from './tools/registry.js';
|
|
28
|
+
import { createDefaultClient } from './llm-factory.js';
|
|
29
|
+
import { resolveSandboxRunnerFromEnv } from './sandbox/env-gate.js';
|
|
30
|
+
import { staticToolPolicy } from './policy/static-rules.js';
|
|
31
|
+
import { createReplConfirm } from './repl/repl-confirm.js'; // D-15: REPL y/N confirm 工厂
|
|
32
|
+
export { createReplConfirm } from './repl/repl-confirm.js'; // Sprint 1c-revive-2-D-24.2: re-export for tui-ink
|
|
33
|
+
import { createSignalCoordinator } from './repl/repl-signal-coordinator.js'; // D-29.1.1: SIGINT + turn AbortController 抽
|
|
34
|
+
import { appendUsageStatus } from './repl/repl-session.js'; // D-29.1.2: EMA state + usage status 抽
|
|
35
|
+
export { formatUsageStatus, appendUsageStatus } from './repl/repl-session.js'; // D-29.1.2: re-export 保公共 API 1:1
|
|
36
|
+
import { dispatchSlashBuiltin } from './repl/repl-command-router.js'; // D-29.1.3: slash builtin 派发抽 (1ceef94 + D-19.6.1 guard)
|
|
37
|
+
const VERSION = '0.1.0';
|
|
38
|
+
/**
|
|
39
|
+
* 单轮 chat 工具函数:把 user 输入 → LLM chat → 输出 assistant 文本。
|
|
40
|
+
* 不修改 messages;不调工具;不持久化。
|
|
41
|
+
*
|
|
42
|
+
* Sprint 1a 保留作为低层 API。Sprint 1a 之后 REPL 入口推荐用 startRepl +
|
|
43
|
+
* enableToolLoop=true 走完整 agent loop。
|
|
44
|
+
*/
|
|
45
|
+
export async function runOneTurn(client, line, messages, options = {}) {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (trimmed === '')
|
|
48
|
+
return { kind: 'empty' };
|
|
49
|
+
const userMessage = { role: 'user', content: trimmed };
|
|
50
|
+
const allMessages = [...messages, userMessage];
|
|
51
|
+
try {
|
|
52
|
+
const result = await client.chat(allMessages, options.signal !== undefined ? { signal: options.signal } : {});
|
|
53
|
+
return { kind: 'chat', assistant: result.content };
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
return { kind: 'error', error: formatError(e) };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 启动 REPL。返回 Promise,resolve 时为退出码。
|
|
61
|
+
*/
|
|
62
|
+
export async function startRepl(options = {}) {
|
|
63
|
+
const out = options.output ?? stdout;
|
|
64
|
+
const err = options.errorOutput ?? stderr;
|
|
65
|
+
// Sprint 1b.5 Step 2 (2.5 C3 拍板): provider 由 options.client / options.provider / env 推断
|
|
66
|
+
// - client 显式给 → 走 client (单测路径)
|
|
67
|
+
// - client 未给 + provider 显式给 → 走 createDefaultClient({provider})
|
|
68
|
+
// - client 未给 + provider 未给 → 走 createDefaultClient() (env 推断 + 双设报错)
|
|
69
|
+
// 任何抛 APIKeyMissingError 都被 catch 后写到 stderr (跟 1b 时代行为一致)
|
|
70
|
+
//
|
|
71
|
+
// Sprint 1c-revive-2-D-11-4 review P1 修复 (2026-06-04): **lazy** client 初始化.
|
|
72
|
+
// 之前 146 行抢创 createDefaultClient() 在无 LLM key 时抛 APIKeyMissingError,
|
|
73
|
+
// REPL 根本进不去 → 跟 README "/verify 不依赖 key" 承诺冲突. 修复:
|
|
74
|
+
// 1. options.client 显式给 → 立即 bind (单测路径不变)
|
|
75
|
+
// 2. options.client 未给 → 走 tryCreateClient, 失败存 clientError, 不抛
|
|
76
|
+
// 3. /verify 路径完全跳过 client 引用 (跟 deepwhale --verify 同语义)
|
|
77
|
+
// 4. chat 路径首次调 getClient() 时才真创, clientError 走 i18n 输出
|
|
78
|
+
const clientFromOptions = options.client;
|
|
79
|
+
let client = clientFromOptions ?? null;
|
|
80
|
+
let clientError = clientFromOptions ? null : null;
|
|
81
|
+
// Sprint 1c-revive-2-D-21.1 (2026-06-06, 修默认走 Anthropic 误判 bug):
|
|
82
|
+
// tryCreateClient 之前 catch 静默存 clientError, stderr 啥都不说, 用户根本
|
|
83
|
+
// 不知道. 现在 catch 时显式 stderr 写一行 [deepwhale] init error, 跟 chat
|
|
84
|
+
// 路径 (L494 error.api_key_missing) 互补. 走 createDefaultClient → resolveProvider
|
|
85
|
+
// "Both set" 错时, 显式 message 让用户立刻看到 "改用 --provider 决断".
|
|
86
|
+
let initErrorReported = false;
|
|
87
|
+
const tryCreateClient = () => {
|
|
88
|
+
if (clientFromOptions)
|
|
89
|
+
return { client: clientFromOptions, error: null };
|
|
90
|
+
if (client !== null || clientError !== null) {
|
|
91
|
+
return { client, error: clientError };
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const c = createDefaultClient({
|
|
95
|
+
...(options.provider !== undefined ? { provider: options.provider } : {}),
|
|
96
|
+
...(options.model !== undefined ? { model: options.model } : {}),
|
|
97
|
+
});
|
|
98
|
+
client = c;
|
|
99
|
+
clientError = null;
|
|
100
|
+
return { client: c, error: null };
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
104
|
+
clientError = err;
|
|
105
|
+
if (!initErrorReported) {
|
|
106
|
+
initErrorReported = true;
|
|
107
|
+
// 走 stderr, 跟 chat 路径保持一致, 避免用户看不到. 拍板: message 含
|
|
108
|
+
// 原始 err.message (有 "Both set" 关键信息), 不强行套 i18n (i18n 太泛
|
|
109
|
+
// 用户看不出是 Both set 还是 No key).
|
|
110
|
+
stderr.write(`[deepwhale] init error: ${err.message}\n`);
|
|
111
|
+
}
|
|
112
|
+
return { client: null, error: err };
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
// Sprint 1c-revive-2-D-6 (review P2 修复, 2026-06-04): 拿掉 anthropic × tool loop
|
|
116
|
+
// 温柔降级. 拍板: D-4 (commit 80d3fd7/bbf1bf6) 已实装 AnthropicClient tool
|
|
117
|
+
// schema 转换 (toAnthropicMessages 合并连续 tool 消息), --provider anthropic
|
|
118
|
+
// 选了 anthropic 就该跑 tool loop. 旧 1b.5 Step 2.5 时代 'Sprint 1b.5 does not
|
|
119
|
+
// support tool loop' 拍板已废 (Step 2.5 → 1c, Anthropic tool protocol 已 ship).
|
|
120
|
+
// 兜底: requestedToolLoop 默认 true, caller 显式 false 才不跑.
|
|
121
|
+
const enableToolLoop = options.enableToolLoop ?? true;
|
|
122
|
+
const sessionPath = options.sessionPath;
|
|
123
|
+
// Sprint 1c-revive-3-D-12 review P1 修复 (2026-06-05): 入口解析 sandbox env.
|
|
124
|
+
// 未知值 throw (fail-closed), 由 CLI `main().catch` 写到 stderr + exit 1.
|
|
125
|
+
const sandboxRunner = resolveSandboxRunnerFromEnv({ sandboxRoot: process.cwd() });
|
|
126
|
+
// Sprint 1c-revive-3-D-13: REPL = 交互模式 (isInteractive=true), --yes 标志透传.
|
|
127
|
+
const policyYes = options.yes ?? false;
|
|
128
|
+
// Sprint 1c-revive-3-D-19 (2026-06-05): P1 修法 — 不再开第二个 readline 抢同一 input.
|
|
129
|
+
// createReplConfirm 现在返回 controller (confirm + offerLine + hasPending + dismiss),
|
|
130
|
+
// 主 rl.on('line') 是 stdin 唯一消费者, 确认期间用 offerLine() 串行化.
|
|
131
|
+
// 拍板 (D-19): 单 readline 路径, 删 D-15 R-1 "子 rl 短窗口" 妥协.
|
|
132
|
+
// 拍板红线: --yes 永远先于 confirm (D-13.5 P1 重排), replPolicy.confirm 只在 yes=false
|
|
133
|
+
// 才被 tool-loop 调. runAgentTurn 加可选 policy 参数透传 (默认 staticToolPolicy 向后兼容).
|
|
134
|
+
const confirmController = createReplConfirm({
|
|
135
|
+
output: options.output ?? stdout,
|
|
136
|
+
});
|
|
137
|
+
const replPolicy = {
|
|
138
|
+
...staticToolPolicy,
|
|
139
|
+
confirm: confirmController.confirm,
|
|
140
|
+
};
|
|
141
|
+
// greeting — Sprint 1c-revive-2-D-11-4 review P1 修复: 不依赖 client.model (lazy 化后
|
|
142
|
+
// client 可能未创). 真创只在 chat 首次发生; 创失败 i18n 错误到 stderr. 这里 greeting
|
|
143
|
+
// 只显示 ready + 版本号, 跟 1b.5 时代 'model 在 greeting 显示' 比, 牺牲一点 UX
|
|
144
|
+
// (用户得 chat 一次才能看到 model 名) 换 REPL 可在无 key 状态启动.
|
|
145
|
+
const initialClientState = tryCreateClient();
|
|
146
|
+
out.write(`${t('cli.greeting', VERSION, initialClientState.client?.model ?? 'not-configured')}\n`);
|
|
147
|
+
if (initialClientState.error) {
|
|
148
|
+
// 无 key 提示沿用 1b.5 时代 163-166 行的 stderr 警告语义, 但挪到 lazy create 之后
|
|
149
|
+
err.write(`${t('error.api_key_missing')}\n`);
|
|
150
|
+
}
|
|
151
|
+
out.write(`${t('cli.no_api_key_hint')}\n\n`);
|
|
152
|
+
// session 加载
|
|
153
|
+
let workingMessages = [];
|
|
154
|
+
// Sprint 1c-revive-2-D-21.1 (2026-06-06, 修 cache 96%↔85% 跳变 footer 焦虑):
|
|
155
|
+
// EMA 平滑闭包 state. appendUsageStatus 每 turn in-place 更新, formatUsageStatus
|
|
156
|
+
// 读 ema 显示 (avg NN%). 跨 turn 累积, 闭包内 mutable, 不持久化 (session reload
|
|
157
|
+
// 后 sampleCount 重置为 0, 避免误导 — user 看到 avg 段消失就知道 reload 过了).
|
|
158
|
+
const emaState = { sampleCount: 0 };
|
|
159
|
+
const writer = sessionPath ? new SessionWriter(sessionPath) : null;
|
|
160
|
+
const reader = sessionPath ? new SessionReader(sessionPath) : null;
|
|
161
|
+
if (writer && reader) {
|
|
162
|
+
try {
|
|
163
|
+
await writer.open();
|
|
164
|
+
const loaded = await loadSession(reader);
|
|
165
|
+
workingMessages = [...loaded.messages];
|
|
166
|
+
if (workingMessages.length > 0) {
|
|
167
|
+
out.write(`${t('cli.session_resumed', workingMessages.length, sessionPath)}\n\n`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
err.write(`${t('cli.session_load_warning', String(e))}\n\n`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Sprint 1c-revive-2-D-6 (review P1 修复, 2026-06-04): CompactionState 闭包持有,
|
|
175
|
+
// 跨 turn 持续累计 failures (paused 状态跨 turn 生效, 跟 test 1c-revive-2-D-5-2 拍板).
|
|
176
|
+
// - 传 options.compactionConfig + writer 存在 → 构造完整 AgentCompactionConfig 注入
|
|
177
|
+
// - 不传 / writer 缺失 → 走 baseline 行为, compactionConfig = null
|
|
178
|
+
let compactionConfig = null;
|
|
179
|
+
if (options.compactionConfig && writer) {
|
|
180
|
+
compactionConfig = {
|
|
181
|
+
...options.compactionConfig,
|
|
182
|
+
writer,
|
|
183
|
+
state: new CompactionState(options.compactionConfig.pauseAfterFailures ?? 2),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
else if (options.compactionConfig && !writer) {
|
|
187
|
+
err.write('warning: compactionConfig requires sessionPath; falling back to baseline (no compaction).\n');
|
|
188
|
+
}
|
|
189
|
+
const rl = createInterface({
|
|
190
|
+
input: options.input ?? stdin,
|
|
191
|
+
terminal: false,
|
|
192
|
+
output: options.output ?? stdout,
|
|
193
|
+
});
|
|
194
|
+
return new Promise((resolve) => {
|
|
195
|
+
let exiting = false;
|
|
196
|
+
// === Sprint 1c-revive-3-D-19.5 (2026-06-05): P2-SIGINT 修法 — finish 移除全局 listener ===
|
|
197
|
+
// 拍板 (D-19.5, user review 2026-06-05 P2): repl.ts:307 每次 startRepl() 挂全局
|
|
198
|
+
// process.on('SIGINT'), finish() 没 process.off, 嵌入式/测试多次启动 REPL → 累积
|
|
199
|
+
// listener. 后 Ctrl+C 触发已退出 REPL 的闭包. 修法: finish() 入口先 .off 一次.
|
|
200
|
+
// 顺序: .off 必须在 rl.close() 之前, 否则 close 派发 'close' event 期间 Ctrl+C 还能
|
|
201
|
+
// 触达 onSigint 闭包. 红线: 跟 D-19 P2-Ctrl+C 拍板不冲突 — finish 才清理, SIGINT
|
|
202
|
+
// 触发的 dismiss + abort 仍由 onSigint 兜底 (D-19 行为不变).
|
|
203
|
+
const finish = async (code) => {
|
|
204
|
+
if (exiting)
|
|
205
|
+
return;
|
|
206
|
+
exiting = true;
|
|
207
|
+
// === Sprint 1c-revive-3-D-19.6 (2026-06-05): 清 exitTimer 防止 P1 兜底 timer 泄漏 ===
|
|
208
|
+
if (exitTimer) {
|
|
209
|
+
clearTimeout(exitTimer);
|
|
210
|
+
exitTimer = null;
|
|
211
|
+
}
|
|
212
|
+
// === Sprint 1c-revive-3-D-29.1.1 (2026-06-07): SIGINT 清理走 coordinator dispose() ===
|
|
213
|
+
// 红线 (D-19.5): off 必须在 rl.close() 之前, 否则 close 派发 'close' event 期间
|
|
214
|
+
// Ctrl+C 还能触达 onSigint 闭包. coordinator.dispose() 内部按此顺序处理, 幂等.
|
|
215
|
+
signalCoordinator.dispose();
|
|
216
|
+
rl.close();
|
|
217
|
+
if (writer) {
|
|
218
|
+
try {
|
|
219
|
+
await writer.close();
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
/* 关闭失败 best-effort,REPL 退出码仍按 caller 决定 */
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
out.write(`${t('cli.goodbye')}\n`);
|
|
226
|
+
resolve(code);
|
|
227
|
+
};
|
|
228
|
+
// === Sprint 1c-revive-3-D-19.5 (2026-06-05): P1 turn guard + 排队 + SIGINT/dismiss 链路 ===
|
|
229
|
+
// 拍板 (D-19.5, user review 2026-06-05 P1): 旧 line handler 在 confirm settle 之后, 紧
|
|
230
|
+
// 跟的下一行 (e.g. /exit\n) 立刻 leak 到 main chat/builtin 分支, /exit 提前 close
|
|
231
|
+
// writer, 第二轮 chat 用旧 workingMessages 并发跑. 修法: turnInFlight 闭包标志 +
|
|
232
|
+
// lineQueue 排队, 关键时序:
|
|
233
|
+
// - 派发前检查 turnInFlight, true → 入队不入 chat
|
|
234
|
+
// - turn 跑完在 finally 块: 检查 pendingExit (走 finish) → 否则 drain 下一条
|
|
235
|
+
// - /exit fast-path: turn 在跑时只标 pendingExit, finally 兜底; turn 不在跑时直接
|
|
236
|
+
// finish (exiting 守卫幂等)
|
|
237
|
+
// - confirm 期间: 旧 D-19 offerLine 派发仍走, 但 line 不能 leak 到 chat 分支
|
|
238
|
+
// - drain 用 setImmediate 避免同步递归爆栈 (P-verify-4 实测, 同步 emit 在大量排队
|
|
239
|
+
// 时撞 V8 10000 帧限制)
|
|
240
|
+
let turnInFlight = false;
|
|
241
|
+
let pendingExit = false;
|
|
242
|
+
// === Sprint 1c-revive-3-D-19.6 (2026-06-05): P1 close-during-turn 30s 兜底 timer ===
|
|
243
|
+
// 拍板 (D-19.6, user review 2026-06-05 P1): close handler 走 pendingExit + finally
|
|
244
|
+
// 兜底 finish() 后, 若 in-flight turn 永远不收束 (e.g. 网络卡死/无限 retry), REPL
|
|
245
|
+
// 永远不退出. exitTimer 启动 30s 硬 timeout, 触发时 stderr warning (i18n) +
|
|
246
|
+
// 强制 finish. 变量与 pendingExit 同 scope (Q2=方案 2): REPL 单次生命周期状态,
|
|
247
|
+
// 模块级会让嵌入式/并行多 REPL 实例互相污染. 仅 turnInFlight=true 启动 (Q3=b):
|
|
248
|
+
// 没有 in-flight turn 时直接 finish, 不需要兜底.
|
|
249
|
+
let exitTimer = null;
|
|
250
|
+
const lineQueue = [];
|
|
251
|
+
// === Sprint 1c-revive-3-D-29.1.1 (2026-06-07): SIGINT + turn AbortController 抽 ===
|
|
252
|
+
// 拍板 (D-29.1.1): signal-coordinator 持有 turnAbortController 闭包 + SIGINT listener
|
|
253
|
+
// 生命周期, repl.ts 通过 getSignal() / refresh() / abortIfActive() / dispose() 4 方法
|
|
254
|
+
// 跟它交互. 行为 1:1 等价 D-19 P1/P2 拍板: dismiss in-flight confirm 先 (落 user_denied
|
|
255
|
+
// 审计), 再 abort turn; 进程不退出, 用户可继续. dispose() 幂等, finish() 入口调
|
|
256
|
+
// (D-19.5 顺序红线: off 必须在 rl.close() 之前, coordinator 内部按此顺序处理).
|
|
257
|
+
const signalCoordinator = createSignalCoordinator({
|
|
258
|
+
confirmController,
|
|
259
|
+
});
|
|
260
|
+
rl.on('line', async (rawLine) => {
|
|
261
|
+
const line = rawLine.trim();
|
|
262
|
+
// 拍板 (D-19 + D-19.5): 主 rl 是 stdin 唯一消费者, 确认期间 line 喂 confirm resolver.
|
|
263
|
+
// D-19.5 P2-dismiss 修: confirm 期间 /exit 先 dismiss confirm 再 pendingExit, finally 兜底.
|
|
264
|
+
if (confirmController.hasPending()) {
|
|
265
|
+
if (line === 'exit' || line === 'quit' || line === '/exit' || line === '/quit') {
|
|
266
|
+
confirmController.dismiss();
|
|
267
|
+
pendingExit = true;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const consumed = confirmController.offerLine(line);
|
|
271
|
+
if (consumed) {
|
|
272
|
+
// confirm resolver 已 settle, 等待 promise 走完; 调 prompt() 让用户看见下一轮.
|
|
273
|
+
// 注意: confirmController 内部在 offerLine 同步 settle, 但 await 仍在 tool-loop 端.
|
|
274
|
+
// 拍板 (D-19): 不在这里 await confirm 本身, 避免阻塞 rl 内部 line queue.
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// 拍板 (D-19.6.1 + 6afccc8): slash builtin guard. turnInFlight 时除 /exit /quit
|
|
279
|
+
// 之外的 slash builtin (/verify /help /unknown) 走 deny, 不入 lineQueue.
|
|
280
|
+
// lineQueue 只排 chat line (D-19.5 红线), defer 会让 finally drain 还要判
|
|
281
|
+
// builtin vs chat. 位置: confirm 守卫后, 内建 dispatcher 前.
|
|
282
|
+
if (turnInFlight &&
|
|
283
|
+
line.startsWith('/') &&
|
|
284
|
+
line !== '/exit' &&
|
|
285
|
+
line !== '/quit') {
|
|
286
|
+
out.write(`${t('cli.turn_in_flight_deny')}\n\n`);
|
|
287
|
+
prompt();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
// 内建命令 — 全部 fast-path, 不走 turnInFlight (内建不等 chat turn)
|
|
291
|
+
if (line === '') {
|
|
292
|
+
prompt();
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (line === 'exit' || line === 'quit' || line === '/exit' || line === '/quit') {
|
|
296
|
+
// 拍板 (D-19.5): turn 不在跑直接 finish; 在跑标 pendingExit, finally 兜底.
|
|
297
|
+
if (turnInFlight) {
|
|
298
|
+
pendingExit = true;
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
await finish(0);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
// === Sprint 1c-revive-3-D-29.1.3 (2026-06-07): slash builtin 派发抽到 dispatchSlashBuiltin ===
|
|
305
|
+
// 拍板 (D-29.1.3): router 派发顺序保 1:1 (跟原 L434-481): /help → /verify → /unknown slash.
|
|
306
|
+
// 5 红线 0 改: turnInFlight guard (D-19.6.1 + 6afccc8) 仍在本函数 L409-418,
|
|
307
|
+
// /verify try/finally (1ceef94) 走 router 内部 try/catch 等价.
|
|
308
|
+
// confirm 期间 /exit dismiss (D-19.5 P2-dismiss) 仍在本函数 L370-373.
|
|
309
|
+
// /exit fast-path (D-19.5 P1) 走 L412 exclude, 不入 router.
|
|
310
|
+
const slashCtx = {
|
|
311
|
+
out,
|
|
312
|
+
err,
|
|
313
|
+
writer,
|
|
314
|
+
verifyChecks: options.verifyChecks,
|
|
315
|
+
prompt,
|
|
316
|
+
};
|
|
317
|
+
if ((await dispatchSlashBuiltin(line, slashCtx)).handled)
|
|
318
|
+
return;
|
|
319
|
+
// === Sprint 1c-revive-3-D-19.5 (2026-06-05): P1 turn guard — 排队 turnInFlight 期间 line ===
|
|
320
|
+
// 拍板 (D-19.5, user review 2026-06-05 P1): 旧逻辑紧跟 chat turn 的下一行 (紧贴
|
|
321
|
+
// y\n 或 turn 还没跑完时 stdin 排队的行) 立刻进 chat 分支, 用旧 workingMessages
|
|
322
|
+
// 并发跑第二轮, /exit 提前 close writer. 修法: 派发前检查 turnInFlight, true
|
|
323
|
+
// → 入队不入 chat. finally 块跑完 turn, 检查 pendingExit (走 finish) → 否则
|
|
324
|
+
// drain lineQueue 下一条 (setImmediate 避免爆栈). 红线: pendingExit 优先级高于
|
|
325
|
+
// drain, 因为 /exit 应该是"不处理后续, 立刻走"语义, 不应该 drain 排队行.
|
|
326
|
+
if (turnInFlight) {
|
|
327
|
+
lineQueue.push(line);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
turnInFlight = true;
|
|
331
|
+
// chat — client lazy 化 (D-11-4), refresh AbortController 走 signalCoordinator (D-29.1.1).
|
|
332
|
+
// 红线: 不要 add 多份 SIGINT listener (coordinator 内部 process.on 一次).
|
|
333
|
+
signalCoordinator.refresh();
|
|
334
|
+
const c = clientFromOptions ? { client: clientFromOptions, error: null } : tryCreateClient();
|
|
335
|
+
if (c.client === null) {
|
|
336
|
+
err.write(`${t('error.api_key_missing')}\n\n`);
|
|
337
|
+
turnInFlight = false;
|
|
338
|
+
prompt();
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const liveClient = c.client;
|
|
342
|
+
try {
|
|
343
|
+
if (enableToolLoop) {
|
|
344
|
+
await runAgentTurn(liveClient, line, workingMessages, writer, out, err, signalCoordinator.getSignal(), compactionConfig, sandboxRunner, policyYes, replPolicy, // D-15: 注入 y/N confirm; 默认 staticToolPolicy 向后兼容
|
|
345
|
+
emaState);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
const turn = await runOneTurn(liveClient, line, [], { signal: signalCoordinator.getSignal() });
|
|
349
|
+
if (turn.kind === 'error') {
|
|
350
|
+
err.write(`${turn.error}\n\n`);
|
|
351
|
+
}
|
|
352
|
+
else if (turn.kind === 'chat') {
|
|
353
|
+
out.write(`${turn.assistant}\n\n`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
// 拍板 (D-19.5): pendingExit 优先 (走 finish, 丢弃排队) → drain 下一条
|
|
359
|
+
// (setImmediate 防同步递归爆栈) → prompt 继续. finally 不能 return
|
|
360
|
+
// (no-unsafe-finally), 用 if/else if/else 链.
|
|
361
|
+
turnInFlight = false;
|
|
362
|
+
if (pendingExit) {
|
|
363
|
+
pendingExit = false;
|
|
364
|
+
void finish(0);
|
|
365
|
+
}
|
|
366
|
+
else if (lineQueue.length > 0 && !exiting) {
|
|
367
|
+
const next = lineQueue.shift();
|
|
368
|
+
setImmediate(() => rl.emit('line', next));
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
prompt();
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
rl.on('close', () => {
|
|
376
|
+
// stdin EOF (管道/Ctrl-D) → 优雅退出.
|
|
377
|
+
// 红线 (D-19.5 P2-dismiss + D-19.6 P1): dismiss 先于 abort (audit 顺序),
|
|
378
|
+
// pendingExit 让 finally 兜底 finish, exitTimer 30s 兜底卡死 turn.
|
|
379
|
+
if (confirmController.hasPending()) {
|
|
380
|
+
confirmController.dismiss();
|
|
381
|
+
}
|
|
382
|
+
if (turnInFlight && !signalCoordinator.getSignal().aborted) {
|
|
383
|
+
signalCoordinator.abortIfActive();
|
|
384
|
+
}
|
|
385
|
+
pendingExit = true;
|
|
386
|
+
if (turnInFlight) {
|
|
387
|
+
if (exitTimer)
|
|
388
|
+
clearTimeout(exitTimer);
|
|
389
|
+
exitTimer = setTimeout(() => {
|
|
390
|
+
// 30s 兜底: turn 卡死时强制 finish, stderr warning 走 i18n (Q1=A).
|
|
391
|
+
// 注: t() 是位置参数, 模板用 {0}, 不是 {ms}.
|
|
392
|
+
if (exiting)
|
|
393
|
+
return;
|
|
394
|
+
err.write(`${t('cli.repl_force_exit_timeout', 30000)}\n`);
|
|
395
|
+
void finish(0);
|
|
396
|
+
}, 30_000);
|
|
397
|
+
// unref: 不让 timer 阻止进程退出 (finish 自己会调 process.exit / resolve).
|
|
398
|
+
exitTimer.unref?.();
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// turn 没在跑, 直接 finish (Q3=b 的 else 分支).
|
|
402
|
+
void finish(0);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
const prompt = () => {
|
|
406
|
+
if (exiting)
|
|
407
|
+
return;
|
|
408
|
+
out.write(t('cli.prompt'));
|
|
409
|
+
};
|
|
410
|
+
// 第一个 prompt
|
|
411
|
+
prompt();
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* 跑一轮 agent turn:append user → runToolLoop → 持久化 → 打印 final content。
|
|
416
|
+
*
|
|
417
|
+
* workingMessages 由 caller 持有(startRepl 闭包),turn 跑完后 caller 用新 messages 覆盖。
|
|
418
|
+
*
|
|
419
|
+
* Sprint 1a 修 P1:user 必须进 LLM。Sprint 1a 修 P2-A:流式不再重复打印 final content。
|
|
420
|
+
* Sprint 1c-revive-2-D-6 (review P1 修复, 2026-06-04): 可选 compactionConfig — 传
|
|
421
|
+
* 时调 runToolLoopWithCompaction (入口测 token, 触发则 compact + 写 event),
|
|
422
|
+
* 不传 = 走裸 runToolLoop (向后兼容, 单测 baseline 244 不变). summaryFn 内部
|
|
423
|
+
* 用 client + 固定 prompt 模板生成, 跟 test 1c-revive-2-D-5 cluster 拍板一致.
|
|
424
|
+
* 单测通过 export 暴露,直接注入 mock LLMClient + WritableStream 验证行为。
|
|
425
|
+
*/
|
|
426
|
+
export async function runAgentTurn(client, userInput, workingMessages, writer, out, err, signal, compactionConfig = null,
|
|
427
|
+
// Sprint 1c-revive-3-D-12 review P1 修复: startRepl 把 env 解析的 runner
|
|
428
|
+
// 传进来, 工具注册表跟 env 状态对齐. 不传 = 用 LocalSandboxRunner (向后兼容).
|
|
429
|
+
sandboxRunner,
|
|
430
|
+
// Sprint 1c-revive-3-D-13: 透传 yes 进 turn.
|
|
431
|
+
yes,
|
|
432
|
+
// Sprint 1c-revive-3-D-15: 透传 policy 进 turn (REPL 注入 replPolicy; 单测传
|
|
433
|
+
// staticToolPolicy 走 baseline). undefined = 默认 staticToolPolicy (向后兼容).
|
|
434
|
+
policy,
|
|
435
|
+
// Sprint 1c-revive-2-D-21.1 (2026-06-06, 修 cache 96%↔85% 跳变 footer 焦虑):
|
|
436
|
+
// EMA state 透传 (闭包持有). 旧 caller 不传 = 默认 { sampleCount: 0 }, 行为兼容
|
|
437
|
+
// (不显示 avg 段). REPL 路径必传, 跨 turn 累积.
|
|
438
|
+
emaState) {
|
|
439
|
+
// 1) 持久化 user 输入
|
|
440
|
+
if (writer) {
|
|
441
|
+
const userEvent = {
|
|
442
|
+
kind: 'user',
|
|
443
|
+
ts: Date.now(),
|
|
444
|
+
content: userInput,
|
|
445
|
+
};
|
|
446
|
+
await writer.append(userEvent);
|
|
447
|
+
}
|
|
448
|
+
// 2) 构造 turn 消息:历史 + 本轮 user。Sprint 1a 修 P1 — user 必须进 LLM。
|
|
449
|
+
const turnMessages = [...workingMessages, { role: 'user', content: userInput }];
|
|
450
|
+
// 3) 调 tool loop. Sprint 1c-revive-2-D-6: 传 compactionConfig 时走
|
|
451
|
+
// runToolLoopWithCompaction (带入口 compaction + 写 compaction event),
|
|
452
|
+
// 不传 = 裸 runToolLoop (向后兼容, baseline 244 不变).
|
|
453
|
+
const summaryFn = compactionConfig
|
|
454
|
+
? makeLlmSummarizeFn(client, compactionConfig.protocol)
|
|
455
|
+
: null;
|
|
456
|
+
// 拍板 (D-15, 2026-06-05): REPL 注入 replPolicy; 显式传 policy 也用, 默认 staticToolPolicy.
|
|
457
|
+
// 拍板红线 (D-13.5 P1 重排): --yes 永远先于 confirm, replPolicy.confirm 只在 yes=false 才被调.
|
|
458
|
+
const resolvedPolicy = policy ?? staticToolPolicy;
|
|
459
|
+
let result;
|
|
460
|
+
try {
|
|
461
|
+
if (compactionConfig !== null && summaryFn !== null) {
|
|
462
|
+
result = await runToolLoopWithCompaction(client, turnMessages, {
|
|
463
|
+
registry: createDefaultRegistry({
|
|
464
|
+
...(sandboxRunner !== undefined ? { sandboxRunner } : {}),
|
|
465
|
+
}),
|
|
466
|
+
onChunk: (chunk) => {
|
|
467
|
+
if (chunk.content)
|
|
468
|
+
out.write(chunk.content);
|
|
469
|
+
},
|
|
470
|
+
signal,
|
|
471
|
+
policy: resolvedPolicy,
|
|
472
|
+
isInteractive: true, // REPL = 交互模式 (D-13 拍板)
|
|
473
|
+
yes: yes ?? false,
|
|
474
|
+
...(writer ? { writer } : {}),
|
|
475
|
+
}, compactionConfig, summaryFn);
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
result = await runToolLoop(client, turnMessages, {
|
|
479
|
+
registry: createDefaultRegistry({
|
|
480
|
+
...(sandboxRunner !== undefined ? { sandboxRunner } : {}),
|
|
481
|
+
}),
|
|
482
|
+
onChunk: (chunk) => {
|
|
483
|
+
if (chunk.content)
|
|
484
|
+
out.write(chunk.content);
|
|
485
|
+
},
|
|
486
|
+
signal,
|
|
487
|
+
policy: resolvedPolicy,
|
|
488
|
+
isInteractive: true, // REPL = 交互模式 (D-13 拍板)
|
|
489
|
+
yes: yes ?? false,
|
|
490
|
+
...(writer ? { writer } : {}),
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
catch (e) {
|
|
495
|
+
// === Sprint 1c-revive-3-D-19.6.1 (2026-06-05): Q3 修法 — abort-aware 分支 ===
|
|
496
|
+
// 拍板 (D-19.6.1, user review 2026-06-05 P2.1): D-19.6 P1 修法让 close 路径 abort
|
|
497
|
+
// in-flight turn, runToolLoop 内部 throw "Tool loop aborted by caller", 老 catch
|
|
498
|
+
// 走 cli.error.unknown ("Unexpected error: {0}") 污染 stderr 为 unexpected error.
|
|
499
|
+
// 修法: 检测 signal.aborted 优先于 isToolLoopError/isLLMError, 走专门 i18n key
|
|
500
|
+
// (cli.turn_aborted_shutdown). 文案 "no audit gap" 强调 user_denied 该落的都
|
|
501
|
+
// 落了 (D-19.6 P1 dismiss+abort+pendingExit 链路已保审计). 不走 unexpected
|
|
502
|
+
// 路径, stderr 不再被 intentional shutdown 污染.
|
|
503
|
+
//
|
|
504
|
+
// 顺序红线: signal.aborted 检查必须在 isToolLoopError 之前 — runToolLoop 内部
|
|
505
|
+
// abort 时 throw Error('Tool loop aborted by caller'), 这 Error 满足 isToolLoopError
|
|
506
|
+
// 的某些宽松判定 (e.g. 有 .message 但无 .steps) 是不稳的. signal.aborted 是
|
|
507
|
+
// 最直接的真相, 优先.
|
|
508
|
+
if (signal.aborted) {
|
|
509
|
+
err.write(`${t('cli.turn_aborted_shutdown')}\n\n`);
|
|
510
|
+
}
|
|
511
|
+
else if (isToolLoopError(e)) {
|
|
512
|
+
err.write(`${t('cli.tool_loop_limit', e.steps)}\n\n`);
|
|
513
|
+
}
|
|
514
|
+
else if (isLLMError(e)) {
|
|
515
|
+
err.write(`${formatError(e)}\n\n`);
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
err.write(`${t('cli.error.unknown', String(e))}\n\n`);
|
|
519
|
+
}
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
// 4) 流式已实时打印;非流式分支此处补打印 final content(给上层 caller 留 fallback)。
|
|
523
|
+
// Sprint 1a REPL 总是传 onChunk 走流式,所以这里不再重复打印。
|
|
524
|
+
// 4) 持久化 steps
|
|
525
|
+
if (writer) {
|
|
526
|
+
try {
|
|
527
|
+
await persistToolLoopSteps(writer, result.steps);
|
|
528
|
+
}
|
|
529
|
+
catch (e) {
|
|
530
|
+
err.write(`${t('cli.session_write_warning', String(e))}\n`);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
// 5) 更新 working messages(startRepl 闭包会保留新值)
|
|
534
|
+
workingMessages.length = 0;
|
|
535
|
+
workingMessages.push(...result.messages);
|
|
536
|
+
// 6) Step summary(人类可读)
|
|
537
|
+
for (const step of result.steps) {
|
|
538
|
+
appendStepSummary(step, out, err);
|
|
539
|
+
}
|
|
540
|
+
// 7) Sprint 1b: Prefix-cache 可观测性 — 每 turn 打印一行 status 到 stderr
|
|
541
|
+
// 风格: 分两行(跟 plan 拍板), 不污染 stdout 流式输出, 不打 prompt 前面
|
|
542
|
+
// 字段: cache_hit_rate / cost_turn / prompt / completion, 多字段同值时去冗余(Hermes footer 教训)
|
|
543
|
+
// Sprint 1c-revive-2-D-21.1 (2026-06-06, 修 cache 96%↔85% 跳变 footer 焦虑):
|
|
544
|
+
// 加 EMA 滚动平均 5-turn 平滑, 显示 "cache: 90% (avg 85%)". per-turn 数字
|
|
545
|
+
// 仍是真实值, avg 是过去 5 turn 平滑趋势. user 不会被单 turn 抖动骗.
|
|
546
|
+
// === Sprint 1c-revive-3-D-29.1.2 (2026-06-07): EMPTY_EMA 内联, repl-session.ts 内私有 ===
|
|
547
|
+
// 行为 1:1: 旧 EMPTY_EMA = { sampleCount: 0 }, 旧 caller 兜底 = 内联值保持.
|
|
548
|
+
appendUsageStatus(result.final.usage, err, emaState ?? { sampleCount: 0 });
|
|
549
|
+
}
|
|
550
|
+
function appendStepSummary(step, out, err) {
|
|
551
|
+
if (step.kind === 'tool') {
|
|
552
|
+
const status = step.result.success ? '✓' : '✗';
|
|
553
|
+
out.write(` ${status} ${step.tool_call.name} (${step.duration_ms}ms)\n`);
|
|
554
|
+
if (!step.result.success && step.result.error) {
|
|
555
|
+
err.write(` ${step.result.error}\n`);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
// 'assistant' / 'limit' / 'error' 的 summary 留 Sprint 1b(不污染 Sprint 1a 验收面)
|
|
559
|
+
}
|
|
560
|
+
// === Sprint 1c-revive-3-D-29.1.2 (2026-06-07): UsageEmaState / formatUsageStatus / appendUsageStatus 抽到 repl-session.ts ===
|
|
561
|
+
// 公共 API re-export 在 L58-59 (跟 signal-coordinator re-export 形态对齐). 1:1 行为保:
|
|
562
|
+
// formatUsageStatus 输出字符串逐字保持, appendUsageStatus in-place update 顺序 (update ema →
|
|
563
|
+
// format → write) 保持. EMPTY_EMA 在 repl-session.ts 内私有, 旧 caller 兜底 = 内联 { sampleCount: 0 }.
|
|
564
|
+
function formatError(e) {
|
|
565
|
+
if (e instanceof APIKeyMissingError)
|
|
566
|
+
return t('error.api_key_missing');
|
|
567
|
+
if (e instanceof LLMAuthError) {
|
|
568
|
+
// Sprint 1b.5 Step 2.5 修: tsc strict 看 LLMAuthError.status 在 .status 上
|
|
569
|
+
return t('cli.error.auth', String(e.status));
|
|
570
|
+
}
|
|
571
|
+
if (e instanceof LLMRateLimitError)
|
|
572
|
+
return t('cli.error.rate_limit');
|
|
573
|
+
if (e instanceof LLMNetworkError) {
|
|
574
|
+
const err = e;
|
|
575
|
+
const msg = err.cause instanceof Error ? err.cause.message : err.message;
|
|
576
|
+
return t('cli.error.network', msg);
|
|
577
|
+
}
|
|
578
|
+
if (e instanceof LLMStreamError) {
|
|
579
|
+
return t('cli.error.stream', e.message);
|
|
580
|
+
}
|
|
581
|
+
if (e instanceof LLMUnknownError) {
|
|
582
|
+
const err = e;
|
|
583
|
+
const detail = err.status !== undefined ? `HTTP ${err.status}` : err.message;
|
|
584
|
+
return t('cli.error.unknown', detail);
|
|
585
|
+
}
|
|
586
|
+
if (e instanceof ToolLoopLimitError) {
|
|
587
|
+
return t('cli.tool_loop_limit', e.steps);
|
|
588
|
+
}
|
|
589
|
+
if (isLLMError(e))
|
|
590
|
+
return t('cli.error.unknown', e.message);
|
|
591
|
+
if (e instanceof Error)
|
|
592
|
+
return t('cli.error.unknown', e.message);
|
|
593
|
+
return t('cli.error.unknown', String(e));
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* 生成 LLM summary callback (Sprint 1c-revive-2-D-6).
|
|
597
|
+
*
|
|
598
|
+
* 跟 1c-revive-2-D-5 cluster test (compaction-cross-protocol-2d5.test.ts:231)
|
|
599
|
+
* 拍板一致: 走 client.chat 调 LLM 生成 1 short paragraph summary. 跨
|
|
600
|
+
* openai/anthropic 同形态, 因为 client.chat 是 LLMClient 契约的统一入口.
|
|
601
|
+
*
|
|
602
|
+
* 不**在**这里拼 protocol-specific system prompt: Anthropic protocol
|
|
603
|
+
* 走 client.chat 时已由 client 内部加 (跟 agent-compaction.ts protocol
|
|
604
|
+
* 字段对齐). 1c-revive-2-D-6 拍板: protocol 字段保留供未来 system
|
|
605
|
+
* prompt 模板差异化用, 当前 D-6 默认用同 system prompt 模板 (跨协议一致).
|
|
606
|
+
*/
|
|
607
|
+
function makeLlmSummarizeFn(client, _protocol) {
|
|
608
|
+
return async (toSummarize) => {
|
|
609
|
+
const summaryMessages = [
|
|
610
|
+
{
|
|
611
|
+
role: 'system',
|
|
612
|
+
content: 'You are a concise summarizer. Compress the following conversation into 1 short paragraph ' +
|
|
613
|
+
'(max 200 words). Preserve key arithmetic results, tool calls, and final answers.',
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
role: 'user',
|
|
617
|
+
content: toSummarize
|
|
618
|
+
.map((m, i) => `[${i}] ${m.role}: ${m.content ?? '(empty)'}`)
|
|
619
|
+
.join('\n'),
|
|
620
|
+
},
|
|
621
|
+
];
|
|
622
|
+
const r = await client.chat(summaryMessages, {});
|
|
623
|
+
return r.content;
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
//# sourceMappingURL=repl.js.map
|
package/dist/repl.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repl.js","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,eAAe,EAAiC,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAqB,MAAM,iBAAiB,CAAC;AAClF,OAAO,EACL,kBAAkB,EAElB,UAAU,EACV,YAAY,EAEZ,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,eAAe,GAEhB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,yBAAyB,EACzB,kBAAkB,GAInB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAoB,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAiB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC,CAAC,4BAA4B;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC,CAAC,mDAAmD;AAC/G,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC,CAAC,4CAA4C;AACzH,OAAO,EAAqB,iBAAiB,EAAsB,MAAM,wBAAwB,CAAC,CAAC,uCAAuC;AAC1I,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAsB,MAAM,wBAAwB,CAAC,CAAC,kCAAkC;AACrI,OAAO,EAAE,oBAAoB,EAAqB,MAAM,+BAA+B,CAAC,CAAC,yDAAyD;AAIlJ,MAAM,OAAO,GAAG,OAAO,CAAC;AAwDxB;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAiB,EACjB,IAAY,EACZ,QAAuB,EACvB,UAAoC,EAAE;IAItC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC7C,MAAM,WAAW,GAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IACpE,MAAM,WAAW,GAAG,CAAC,GAAG,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAC9B,WAAW,EACX,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAC/D,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,UAAuB,EAAE;IACvD,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;IACrC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC;IAC1C,wFAAwF;IACxF,iCAAiC;IACjC,iEAAiE;IACjE,sEAAsE;IACtE,2DAA2D;IAC3D,EAAE;IACF,4EAA4E;IAC5E,qEAAqE;IACrE,oDAAoD;IACpD,6CAA6C;IAC7C,kEAAkE;IAClE,2DAA2D;IAC3D,0DAA0D;IAC1D,MAAM,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IACzC,IAAI,MAAM,GAAqB,iBAAiB,IAAI,IAAI,CAAC;IACzD,IAAI,WAAW,GAAiB,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,iEAAiE;IACjE,8DAA8D;IAC9D,8DAA8D;IAC9D,8EAA8E;IAC9E,wDAAwD;IACxD,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,MAAM,eAAe,GAAG,GAAsD,EAAE;QAC9E,IAAI,iBAAiB;YAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzE,IAAI,MAAM,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QACxC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,mBAAmB,CAAC;gBAC5B,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzE,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjE,CAAC,CAAC;YACH,MAAM,GAAG,CAAC,CAAC;YACX,WAAW,GAAG,IAAI,CAAC;YACnB,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACpC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,WAAW,GAAG,GAAG,CAAC;YAClB,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,iBAAiB,GAAG,IAAI,CAAC;gBACzB,kDAAkD;gBAClD,yDAAyD;gBACzD,8BAA8B;gBAC9B,MAAM,CAAC,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YAC3D,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;IACF,8EAA8E;IAC9E,kEAAkE;IAClE,qEAAqE;IACrE,uEAAuE;IACvE,2EAA2E;IAC3E,sDAAsD;IACtD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;IACtD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAExC,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,aAAa,GAAG,2BAA2B,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAClF,yEAAyE;IACzE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,IAAI,KAAK,CAAC;IACvC,2EAA2E;IAC3E,kFAAkF;IAClF,wDAAwD;IACxD,sDAAsD;IACtD,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;QAC1C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;KACjC,CAAC,CAAC;IACH,MAAM,UAAU,GAAe;QAC7B,GAAG,gBAAgB;QACnB,OAAO,EAAE,iBAAiB,CAAC,OAAO;KACnC,CAAC;IAEF,+EAA+E;IAC/E,iEAAiE;IACjE,8DAA8D;IAC9D,iDAAiD;IACjD,MAAM,kBAAkB,GAAG,eAAe,EAAE,CAAC;IAC7C,GAAG,CAAC,KAAK,CACP,GAAG,CAAC,CAAC,cAAc,EAAE,OAAO,EAAE,kBAAkB,CAAC,MAAM,EAAE,KAAK,IAAI,gBAAgB,CAAC,IAAI,CACxF,CAAC;IACF,IAAI,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAC7B,gEAAgE;QAChE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE7C,aAAa;IACb,IAAI,eAAe,GAAkB,EAAE,CAAC;IACxC,wEAAwE;IACxE,0EAA0E;IAC1E,mEAAmE;IACnE,6DAA6D;IAC7D,MAAM,QAAQ,GAAkB,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;YACzC,eAAe,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,qBAAqB,EAAE,eAAe,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,4DAA4D;IAC5D,IAAI,gBAAgB,GAAiC,IAAI,CAAC;IAC1D,IAAI,OAAO,CAAC,gBAAgB,IAAI,MAAM,EAAE,CAAC;QACvC,gBAAgB,GAAG;YACjB,GAAG,OAAO,CAAC,gBAAgB;YAC3B,MAAM;YACN,KAAK,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,IAAI,CAAC,CAAC;SAC7E,CAAC;IACJ,CAAC;SAAM,IAAI,OAAO,CAAC,gBAAgB,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/C,GAAG,CAAC,KAAK,CACP,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAgB,eAAe,CAAC;QACtC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK;QAC7B,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;KACjC,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACrC,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,sFAAsF;QACtF,yEAAyE;QACzE,qEAAqE;QACrE,+DAA+D;QAC/D,qEAAqE;QACrE,kEAAkE;QAClE,kDAAkD;QAClD,MAAM,MAAM,GAAG,KAAK,EAAE,IAAY,EAAiB,EAAE;YACnD,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,gFAAgF;YAChF,IAAI,SAAS,EAAE,CAAC;gBACd,YAAY,CAAC,SAAS,CAAC,CAAC;gBACxB,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YACD,qFAAqF;YACrF,mEAAmE;YACnE,+DAA+D;YAC/D,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC5B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBACvB,CAAC;gBAAC,MAAM,CAAC;oBACP,2CAA2C;gBAC7C,CAAC;YACH,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC;QAEF,yFAAyF;QACzF,gFAAgF;QAChF,sEAAsE;QACtE,mEAAmE;QACnE,sBAAsB;QACtB,2CAA2C;QAC3C,mEAAmE;QACnE,uEAAuE;QACvE,4BAA4B;QAC5B,kEAAkE;QAClE,kEAAkE;QAClE,uBAAuB;QACvB,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,oFAAoF;QACpF,gFAAgF;QAChF,mEAAmE;QACnE,iEAAiE;QACjE,+DAA+D;QAC/D,2DAA2D;QAC3D,uCAAuC;QACvC,IAAI,SAAS,GAA0B,IAAI,CAAC;QAC5C,MAAM,SAAS,GAAa,EAAE,CAAC;QAE/B,oFAAoF;QACpF,gFAAgF;QAChF,8EAA8E;QAC9E,4EAA4E;QAC5E,8DAA8D;QAC9D,8DAA8D;QAC9D,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;YAChD,iBAAiB;SAClB,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;YACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAE5B,wEAAwE;YACxE,qFAAqF;YACrF,IAAI,iBAAiB,CAAC,UAAU,EAAE,EAAE,CAAC;gBACnC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC/E,iBAAiB,CAAC,OAAO,EAAE,CAAC;oBAC5B,WAAW,GAAG,IAAI,CAAC;oBACnB,OAAO;gBACT,CAAC;gBACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACnD,IAAI,QAAQ,EAAE,CAAC;oBACb,iEAAiE;oBACjE,yEAAyE;oBACzE,2DAA2D;oBAC3D,OAAO;gBACT,CAAC;YACH,CAAC;YAED,4EAA4E;YAC5E,mEAAmE;YACnE,iEAAiE;YACjE,qDAAqD;YACrD,IACE,YAAY;gBACZ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBACpB,IAAI,KAAK,OAAO;gBAChB,IAAI,KAAK,OAAO,EAChB,CAAC;gBACD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;gBACjD,MAAM,EAAE,CAAC;gBACT,OAAO;YACT,CAAC;YAED,wDAAwD;YACxD,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;gBAChB,MAAM,EAAE,CAAC;gBACT,OAAO;YACT,CAAC;YACD,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC/E,+DAA+D;gBAC/D,IAAI,YAAY,EAAE,CAAC;oBACjB,WAAW,GAAG,IAAI,CAAC;oBACnB,OAAO;gBACT,CAAC;gBACD,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YACD,4FAA4F;YAC5F,mFAAmF;YACnF,oEAAoE;YACpE,uEAAuE;YACvE,4EAA4E;YAC5E,sEAAsE;YACtE,MAAM,QAAQ,GAAiB;gBAC7B,GAAG;gBACH,GAAG;gBACH,MAAM;gBACN,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,MAAM;aACP,CAAC;YACF,IAAI,CAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO;gBAAE,OAAO;YAEjE,0FAA0F;YAC1F,mEAAmE;YACnE,+DAA+D;YAC/D,8DAA8D;YAC9D,gEAAgE;YAChE,iEAAiE;YACjE,oDAAoD;YACpD,IAAI,YAAY,EAAE,CAAC;gBACjB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,YAAY,GAAG,IAAI,CAAC;YAEpB,yFAAyF;YACzF,gEAAgE;YAChE,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;YAC7F,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBACtB,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;gBAC/C,YAAY,GAAG,KAAK,CAAC;gBACrB,MAAM,EAAE,CAAC;gBACT,OAAO;YACT,CAAC;YACD,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;YAC5B,IAAI,CAAC;gBACH,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,YAAY,CAChB,UAAU,EACV,IAAI,EACJ,eAAe,EACf,MAAM,EACN,GAAG,EACH,GAAG,EACH,iBAAiB,CAAC,SAAS,EAAE,EAC7B,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,UAAU,EAAE,iDAAiD;oBAC7D,QAAQ,CACT,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,iBAAiB,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;oBAC/F,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;wBAC1B,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC;oBACjC,CAAC;yBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBAChC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,MAAM,CAAC,CAAC;oBACrC,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,2DAA2D;gBAC3D,wDAAwD;gBACxD,4CAA4C;gBAC5C,YAAY,GAAG,KAAK,CAAC;gBACrB,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,GAAG,KAAK,CAAC;oBACpB,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;gBACjB,CAAC;qBAAM,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAC5C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAG,CAAC;oBAChC,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,MAAM,EAAE,CAAC;gBACX,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,gCAAgC;YAChC,mEAAmE;YACnE,4DAA4D;YAC5D,IAAI,iBAAiB,CAAC,UAAU,EAAE,EAAE,CAAC;gBACnC,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC9B,CAAC;YACD,IAAI,YAAY,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC;gBAC3D,iBAAiB,CAAC,aAAa,EAAE,CAAC;YACpC,CAAC;YACD,WAAW,GAAG,IAAI,CAAC;YACnB,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,SAAS;oBAAE,YAAY,CAAC,SAAS,CAAC,CAAC;gBACvC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC1B,2DAA2D;oBAC3D,kCAAkC;oBAClC,IAAI,OAAO;wBAAE,OAAO;oBACpB,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,6BAA6B,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC1D,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;gBACjB,CAAC,EAAE,MAAM,CAAC,CAAC;gBACX,+DAA+D;gBAC/D,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,OAAO;gBAAE,OAAO;YACpB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC;QAEF,aAAa;QACb,MAAM,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAiB,EACjB,SAAiB,EACjB,eAA8B,EAC9B,MAA4B,EAC5B,GAA0B,EAC1B,GAA0B,EAC1B,MAAmB,EACnB,mBAAiD,IAAI;AACrD,mEAAmE;AACnE,0DAA0D;AAC1D,aAA6B;AAC7B,0CAA0C;AAC1C,GAAa;AACb,qEAAqE;AACrE,wEAAwE;AACxE,MAAmB;AACnB,wEAAwE;AACxE,iEAAiE;AACjE,qCAAqC;AACrC,QAAwB;IAExB,iBAAiB;IACjB,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,SAAS,GAAiB;YAC9B,IAAI,EAAE,MAAM;YACZ,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;YACd,OAAO,EAAE,SAAS;SACnB,CAAC;QACF,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,4DAA4D;IAC5D,MAAM,YAAY,GAAkB,CAAC,GAAG,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAE/F,gEAAgE;IAChE,sEAAsE;IACtE,iDAAiD;IACjD,MAAM,SAAS,GAAuB,gBAAgB;QACpD,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC;QACvD,CAAC,CAAC,IAAI,CAAC;IACT,iFAAiF;IACjF,gFAAgF;IAChF,MAAM,cAAc,GAAe,MAAM,IAAI,gBAAgB,CAAC;IAC9D,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,IAAI,gBAAgB,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,GAAG,MAAM,yBAAyB,CACtC,MAAM,EACN,YAAY,EACZ;gBACE,QAAQ,EAAE,qBAAqB,CAAC;oBAC9B,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC1D,CAAC;gBACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBACjB,IAAI,KAAK,CAAC,OAAO;wBAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC9C,CAAC;gBACD,MAAM;gBACN,MAAM,EAAE,cAAc;gBACtB,aAAa,EAAE,IAAI,EAAE,wBAAwB;gBAC7C,GAAG,EAAE,GAAG,IAAI,KAAK;gBACjB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9B,EACD,gBAAgB,EAChB,SAAS,CACV,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE;gBAC/C,QAAQ,EAAE,qBAAqB,CAAC;oBAC9B,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC1D,CAAC;gBACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBACjB,IAAI,KAAK,CAAC,OAAO;wBAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC9C,CAAC;gBACD,MAAM;gBACN,MAAM,EAAE,cAAc;gBACtB,aAAa,EAAE,IAAI,EAAE,wBAAwB;gBAC7C,GAAG,EAAE,GAAG,IAAI,KAAK;gBACjB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,2EAA2E;QAC3E,2EAA2E;QAC3E,8EAA8E;QAC9E,8EAA8E;QAC9E,qEAAqE;QACrE,qEAAqE;QACrE,iEAAiE;QACjE,0CAA0C;QAC1C,EAAE;QACF,iEAAiE;QACjE,iFAAiF;QACjF,6DAA6D;QAC7D,cAAc;QACd,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,qBAAqB,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC;QACD,OAAO;IACT,CAAC;IAED,8DAA8D;IAC9D,gDAAgD;IAEhD,eAAe;IACf,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YACH,MAAM,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,eAAe,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEzC,wBAAwB;IACxB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,gEAAgE;IAChE,oDAAoD;IACpD,oFAAoF;IACpF,wEAAwE;IACxE,+DAA+D;IAC/D,kDAAkD;IAClD,sFAAsF;IACtF,iEAAiE;IACjE,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,iBAAiB,CACxB,IAAkB,EAClB,GAA0B,EAC1B,GAA0B;IAE1B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC/C,GAAG,CAAC,KAAK,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,OAAO,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC9C,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,2EAA2E;AAC7E,CAAC;AAED,6HAA6H;AAC7H,4EAA4E;AAC5E,kFAAkF;AAClF,4FAA4F;AAE5F,SAAS,WAAW,CAAC,CAAU;IAC7B,IAAI,CAAC,YAAY,kBAAkB;QAAE,OAAO,CAAC,CAAC,uBAAuB,CAAC,CAAC;IACvE,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;QAC9B,uEAAuE;QACvE,OAAO,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAE,CAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,YAAY,iBAAiB;QAAE,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC;IACrE,IAAI,CAAC,YAAY,eAAe,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,CAAyC,CAAC;QACtD,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QACzE,OAAO,CAAC,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,YAAY,cAAc,EAAE,CAAC;QAChC,OAAO,CAAC,CAAC,kBAAkB,EAAG,CAAW,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,CAAC,YAAY,eAAe,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,CAAyC,CAAC;QACtD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC7E,OAAO,CAAC,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,YAAY,kBAAkB,EAAE,CAAC;QACpC,OAAO,CAAC,CAAC,qBAAqB,EAAG,CAAuB,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,YAAY,KAAK;QAAE,OAAO,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,kBAAkB,CAAC,MAAiB,EAAE,SAAiC;IAC9E,OAAO,KAAK,EAAE,WAAuC,EAAmB,EAAE;QACxE,MAAM,eAAe,GAAkB;YACrC;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EACL,2FAA2F;oBAC3F,kFAAkF;aACrF;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,WAAW;qBACjB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC;qBAC5D,IAAI,CAAC,IAAI,CAAC;aACd;SACF,CAAC;QACF,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,CAAC,OAAO,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC"}
|