@aibyzero/byz 0.1.7 → 0.1.9
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/CHANGELOG.md +8 -0
- package/dist/conversation/conversation-extension.js +335 -18
- package/dist/runtime/bundle/chunks/{chunk-JDLZZASY.js → chunk-IUR2NDXL.js} +1 -1
- package/dist/runtime/bundle/cli.js +1 -1
- package/dist/runtime/bundle/index.js +1 -1
- package/dist/runtime/bundle/rpc-entry.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.9 - 2026-08-30
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Changed the default BYZ terminal footer to show the project name, git branch, remaining context percentage, token usage, cost, extension statuses, and current model.
|
|
10
|
+
- Changed long-running BYZ waits to show a compact non-technical progress card by default, with the fuller work-site card available in details mode.
|
|
11
|
+
- Added persistent BYZ detail-mode preferences through `/details remember` and `/details remember compact`.
|
|
12
|
+
|
|
5
13
|
## 0.1.7 - 2026-08-29
|
|
6
14
|
|
|
7
15
|
### Added
|
|
@@ -1,31 +1,281 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
1
4
|
import { createInteractionPolicy, formatDecision, parseConversationControl } from "./interaction-policy.js";
|
|
2
5
|
import { createRoutingPolicy } from "./routing-policy.js";
|
|
3
6
|
|
|
4
7
|
const WELCOME = "BYZ\n\n你想让我帮你做什么?";
|
|
8
|
+
const DETAIL_MODE_COMPACT = "compact";
|
|
9
|
+
const DETAIL_MODE_DETAILS = "details";
|
|
5
10
|
|
|
6
|
-
|
|
11
|
+
function getByzAgentDir() {
|
|
12
|
+
return process.env.BYZ_CODING_AGENT_DIR || join(homedir(), ".byz", "agent");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getConversationConfigPath() {
|
|
16
|
+
return join(getByzAgentDir(), "conversation.json");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function readConversationConfig() {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(getConversationConfigPath(), "utf8"));
|
|
22
|
+
} catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getSavedDetailMode() {
|
|
28
|
+
const mode = readConversationConfig().detailMode;
|
|
29
|
+
return mode === DETAIL_MODE_DETAILS ? DETAIL_MODE_DETAILS : DETAIL_MODE_COMPACT;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function saveDetailMode(mode) {
|
|
33
|
+
const configPath = getConversationConfigPath();
|
|
34
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
35
|
+
writeFileSync(configPath, `${JSON.stringify({ ...readConversationConfig(), detailMode: mode }, null, "\t")}\n`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function formatTokens(count) {
|
|
39
|
+
if (count < 1000) return String(count);
|
|
40
|
+
if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
|
|
41
|
+
if (count < 1000000) return `${Math.round(count / 1000)}k`;
|
|
42
|
+
if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;
|
|
43
|
+
return `${Math.round(count / 1000000)}M`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function truncateText(text, width) {
|
|
47
|
+
if (width <= 0) return "";
|
|
48
|
+
if (text.length <= width) return text;
|
|
49
|
+
if (width <= 1) return "…".slice(0, width);
|
|
50
|
+
return `${text.slice(0, width - 1)}…`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function findProjectRoot(cwd) {
|
|
54
|
+
let dir = cwd;
|
|
55
|
+
while (dir) {
|
|
56
|
+
if (existsSync(join(dir, ".git"))) return dir;
|
|
57
|
+
const parent = dirname(dir);
|
|
58
|
+
if (parent === dir) return cwd;
|
|
59
|
+
dir = parent;
|
|
60
|
+
}
|
|
61
|
+
return cwd;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getProjectName(cwd) {
|
|
65
|
+
return basename(findProjectRoot(cwd)) || basename(cwd) || cwd;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function addUsage(totals, usage) {
|
|
69
|
+
if (!usage) return;
|
|
70
|
+
totals.input += usage.input ?? 0;
|
|
71
|
+
totals.output += usage.output ?? 0;
|
|
72
|
+
totals.cacheRead += usage.cacheRead ?? 0;
|
|
73
|
+
totals.cacheWrite += usage.cacheWrite ?? 0;
|
|
74
|
+
totals.cost += usage.cost?.total ?? 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getUsageTotals(ctx) {
|
|
78
|
+
const totals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 };
|
|
79
|
+
for (const entry of ctx.sessionManager?.getEntries?.() ?? []) {
|
|
80
|
+
if (entry.type === "message" && entry.message?.role === "assistant") {
|
|
81
|
+
addUsage(totals, entry.message.usage);
|
|
82
|
+
} else if (entry.type === "message" && entry.message?.role === "toolResult") {
|
|
83
|
+
addUsage(totals, entry.message.usage);
|
|
84
|
+
} else if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
|
|
85
|
+
addUsage(totals, entry.usage);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return totals;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function shortModelName(modelId) {
|
|
92
|
+
if (!modelId) return "no-model";
|
|
93
|
+
return modelId
|
|
94
|
+
.replace(/^claude-/, "")
|
|
95
|
+
.replace(/^gpt-/, "gpt-")
|
|
96
|
+
.replace(/-20\d{6}$/, "")
|
|
97
|
+
.replace(/-latest$/, "");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function createByzFooter(ctx, tui, theme, footerData) {
|
|
101
|
+
const unsubscribe = footerData.onBranchChange?.(() => tui.requestRender?.());
|
|
102
|
+
return {
|
|
103
|
+
invalidate() {},
|
|
104
|
+
dispose() {
|
|
105
|
+
unsubscribe?.();
|
|
106
|
+
},
|
|
107
|
+
render(width) {
|
|
108
|
+
const safeWidth = Math.max(1, width ?? 80);
|
|
109
|
+
const cwd = ctx.sessionManager?.getCwd?.() ?? ctx.cwd ?? process.cwd();
|
|
110
|
+
const parts = [getProjectName(cwd)];
|
|
111
|
+
const branch = footerData.getGitBranch?.();
|
|
112
|
+
if (branch) parts.push(branch);
|
|
113
|
+
|
|
114
|
+
const contextUsage = ctx.getContextUsage?.();
|
|
115
|
+
if (contextUsage) {
|
|
116
|
+
const left = contextUsage.percent === null ? "?" : `${Math.max(0, 100 - contextUsage.percent).toFixed(0)}%`;
|
|
117
|
+
parts.push(`left ${left}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const usage = getUsageTotals(ctx);
|
|
121
|
+
if (usage.input > 0) parts.push(`↑${formatTokens(usage.input)}`);
|
|
122
|
+
if (usage.output > 0) parts.push(`↓${formatTokens(usage.output)}`);
|
|
123
|
+
if (usage.cacheRead > 0) parts.push(`R${formatTokens(usage.cacheRead)}`);
|
|
124
|
+
if (usage.cacheWrite > 0) parts.push(`W${formatTokens(usage.cacheWrite)}`);
|
|
125
|
+
if (usage.cost > 0) parts.push(`$${usage.cost.toFixed(3)}`);
|
|
126
|
+
|
|
127
|
+
const extensionStatuses = footerData.getExtensionStatuses?.();
|
|
128
|
+
for (const text of extensionStatuses?.values?.() ?? []) {
|
|
129
|
+
const clean = String(text)
|
|
130
|
+
.replace(/[\r\n\t]/g, " ")
|
|
131
|
+
.replace(/ +/g, " ")
|
|
132
|
+
.trim();
|
|
133
|
+
if (clean) parts.push(clean);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const leftText = parts.join(" ");
|
|
137
|
+
const modelText = shortModelName(ctx.model?.id);
|
|
138
|
+
const minGap = 2;
|
|
139
|
+
let line;
|
|
140
|
+
if (leftText.length + minGap + modelText.length <= safeWidth) {
|
|
141
|
+
line = `${leftText}${" ".repeat(safeWidth - leftText.length - modelText.length)}${modelText}`;
|
|
142
|
+
} else {
|
|
143
|
+
const modelBudget = Math.min(modelText.length, Math.max(0, safeWidth - minGap - 12));
|
|
144
|
+
const model = truncateText(modelText, modelBudget);
|
|
145
|
+
const leftBudget = Math.max(1, safeWidth - minGap - model.length);
|
|
146
|
+
line = `${truncateText(leftText, leftBudget)}${" ".repeat(Math.max(minGap, safeWidth - leftBudget - model.length))}${model}`;
|
|
147
|
+
}
|
|
148
|
+
return [theme.fg?.("dim", line) ?? line];
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function createProgressState() {
|
|
154
|
+
return {
|
|
155
|
+
goal: "当前任务",
|
|
156
|
+
stage: "确认目标与边界",
|
|
157
|
+
confirmed: [],
|
|
158
|
+
judgements: [],
|
|
159
|
+
nextSteps: ["完成必要检查", "整理结果给你"],
|
|
160
|
+
safeguards: ["不会提交代码", "不会执行高影响动作"],
|
|
161
|
+
tools: { inspected: 0, edited: 0, commands: 0 },
|
|
162
|
+
visible: false,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function pushUnique(list, value, limit = 3) {
|
|
167
|
+
if (!value || list.includes(value)) return;
|
|
168
|
+
list.push(value);
|
|
169
|
+
if (list.length > limit) list.shift();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function summarizeGoal(prompt) {
|
|
173
|
+
const clean = String(prompt ?? "")
|
|
174
|
+
.replace(/[\r\n\t]/g, " ")
|
|
175
|
+
.replace(/展开细节[,,;;\s]*/g, "")
|
|
176
|
+
.replace(/ +/g, " ")
|
|
177
|
+
.trim();
|
|
178
|
+
if (!clean) return "当前任务";
|
|
179
|
+
return clean.length > 28 ? `${clean.slice(0, 27)}…` : clean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function getActivitySummary(state) {
|
|
183
|
+
const activity = [];
|
|
184
|
+
if (state.tools.inspected > 0) activity.push(`查看 ${state.tools.inspected} 项`);
|
|
185
|
+
if (state.tools.edited > 0) activity.push(`修改 ${state.tools.edited} 项`);
|
|
186
|
+
if (state.tools.commands > 0) activity.push(`命令 ${state.tools.commands} 次`);
|
|
187
|
+
return activity.join(",");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function renderProgressCard(state, options = {}) {
|
|
191
|
+
const activity = getActivitySummary(state);
|
|
192
|
+
if (options.compact) {
|
|
193
|
+
const progress = activity || state.confirmed.at(-1) || state.stage;
|
|
194
|
+
const next = state.nextSteps.at(-1) ?? "整理结果给你";
|
|
195
|
+
const boundary = state.safeguards.at(-1) ?? "不会提交代码";
|
|
196
|
+
return [`处理中:${state.goal}`, `进展:${progress}`, `下一步:${next}`, `边界:${boundary}`].join("\n");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const lines = [`正在处理:${state.goal}`, `当前阶段:${state.stage}`];
|
|
200
|
+
if (activity) lines.push(`现场进展:${activity}`);
|
|
201
|
+
if (state.confirmed.length > 0) lines.push(`已确认:${state.confirmed.join(";")}`);
|
|
202
|
+
if (state.judgements.length > 0) lines.push(`当前判断:${state.judgements.join(";")}`);
|
|
203
|
+
if (state.nextSteps.length > 0) lines.push(`下一步:${state.nextSteps.join(";")}`);
|
|
204
|
+
if (state.safeguards.length > 0) lines.push(`不会做:${state.safeguards.join(";")}`);
|
|
205
|
+
return lines.join("\n");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function stageForTool(toolName) {
|
|
209
|
+
if (["read", "grep", "find", "ls"].includes(toolName)) return "定位和核对相关材料";
|
|
210
|
+
if (["edit", "write"].includes(toolName)) return "执行最小必要修改";
|
|
211
|
+
if (["bash", "powershell"].includes(toolName)) return "运行命令并核对结果";
|
|
212
|
+
return "处理必要步骤";
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function updateProgressFromToolStart(state, toolName) {
|
|
216
|
+
state.stage = stageForTool(toolName);
|
|
217
|
+
if (["read", "grep", "find", "ls"].includes(toolName)) {
|
|
218
|
+
pushUnique(state.nextSteps, "基于证据判断方案");
|
|
219
|
+
} else if (["edit", "write"].includes(toolName)) {
|
|
220
|
+
pushUnique(state.judgements, "优先做小改动,避免扩大范围");
|
|
221
|
+
pushUnique(state.nextSteps, "补充验证");
|
|
222
|
+
} else if (["bash", "powershell"].includes(toolName)) {
|
|
223
|
+
pushUnique(state.nextSteps, "根据命令结果决定是否继续");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function updateProgressFromToolEnd(state, toolName, isError) {
|
|
228
|
+
if (["read", "grep", "find", "ls"].includes(toolName)) {
|
|
229
|
+
state.tools.inspected += 1;
|
|
230
|
+
pushUnique(state.confirmed, "已查看相关项目资料");
|
|
231
|
+
} else if (["edit", "write"].includes(toolName)) {
|
|
232
|
+
state.tools.edited += 1;
|
|
233
|
+
pushUnique(state.confirmed, isError ? "修改步骤需要复核" : "已完成代码层面的变更");
|
|
234
|
+
} else if (["bash", "powershell"].includes(toolName)) {
|
|
235
|
+
state.tools.commands += 1;
|
|
236
|
+
pushUnique(state.confirmed, isError ? "命令结果需要处理" : "已执行验证命令");
|
|
237
|
+
}
|
|
238
|
+
if (isError) {
|
|
239
|
+
state.stage = "处理异常结果";
|
|
240
|
+
pushUnique(state.judgements, "先解释失败原因,再决定是否调整");
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
state.stage = "继续核对并收敛结果";
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function createConversationExtension(options = {}) {
|
|
7
247
|
const policy = createInteractionPolicy();
|
|
8
248
|
const routingPolicy = createRoutingPolicy();
|
|
249
|
+
const progressCardDelayMs = options.progressCardDelayMs ?? 8_000;
|
|
250
|
+
let savedDetailMode = getSavedDetailMode();
|
|
9
251
|
|
|
10
252
|
return function conversationExtension(pi) {
|
|
11
253
|
let progressTimer;
|
|
254
|
+
let progressState = createProgressState();
|
|
255
|
+
let activeCtx;
|
|
12
256
|
|
|
13
257
|
function clearProgressTimer() {
|
|
14
258
|
if (progressTimer) clearTimeout(progressTimer);
|
|
15
259
|
progressTimer = undefined;
|
|
16
260
|
}
|
|
17
261
|
|
|
262
|
+
function publishProgress() {
|
|
263
|
+
if (!activeCtx) return;
|
|
264
|
+
progressState.visible = true;
|
|
265
|
+
activeCtx.ui.setWorkingMessage?.(renderProgressCard(progressState, { compact: !policy.isDetailEnabled() }));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function updateVisibleProgress() {
|
|
269
|
+
if (progressState.visible) publishProgress();
|
|
270
|
+
}
|
|
271
|
+
|
|
18
272
|
pi.on("session_start", (_event, ctx) => {
|
|
19
273
|
routingPolicy.reset();
|
|
274
|
+
policy.setDetailEnabled(savedDetailMode === DETAIL_MODE_DETAILS);
|
|
20
275
|
ctx.ui.setTitle?.("BYZ");
|
|
21
276
|
ctx.ui.setMessagePresenter?.((message) => policy.presentAssistantMessage(message));
|
|
22
|
-
ctx.ui.setToolExecutionVisible?.(
|
|
23
|
-
ctx.ui.setFooter?.(() => (
|
|
24
|
-
invalidate() {},
|
|
25
|
-
render() {
|
|
26
|
-
return [];
|
|
27
|
-
},
|
|
28
|
-
}));
|
|
277
|
+
ctx.ui.setToolExecutionVisible?.(policy.isDetailEnabled());
|
|
278
|
+
ctx.ui.setFooter?.((tui, theme, footerData) => createByzFooter(ctx, tui, theme, footerData));
|
|
29
279
|
ctx.ui.setConfirmationPresenter?.(async ({ title, message, confirm }) => {
|
|
30
280
|
const prompt = formatDecision({
|
|
31
281
|
impact: message,
|
|
@@ -42,33 +292,100 @@ export function createConversationExtension() {
|
|
|
42
292
|
ctx.ui.notify(WELCOME, "info");
|
|
43
293
|
});
|
|
44
294
|
pi.on("agent_start", (_event, ctx) => {
|
|
295
|
+
activeCtx = ctx;
|
|
45
296
|
policy.resetProgress();
|
|
297
|
+
progressState.visible = false;
|
|
46
298
|
clearProgressTimer();
|
|
299
|
+
ctx.ui.setWorkingMessage?.("正在确认目标与边界…");
|
|
47
300
|
progressTimer = setTimeout(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
301
|
+
publishProgress();
|
|
302
|
+
}, progressCardDelayMs);
|
|
303
|
+
});
|
|
304
|
+
pi.on("tool_execution_start", (event) => {
|
|
305
|
+
updateProgressFromToolStart(progressState, event.toolName);
|
|
306
|
+
updateVisibleProgress();
|
|
307
|
+
});
|
|
308
|
+
pi.on("tool_execution_end", (event) => {
|
|
309
|
+
updateProgressFromToolEnd(progressState, event.toolName, event.isError);
|
|
310
|
+
updateVisibleProgress();
|
|
311
|
+
});
|
|
312
|
+
pi.on("message_update", (event) => {
|
|
313
|
+
if (event.message?.role !== "assistant") return;
|
|
314
|
+
progressState.stage = "组织回复";
|
|
315
|
+
pushUnique(progressState.nextSteps, "给出结论和已做验证");
|
|
316
|
+
updateVisibleProgress();
|
|
51
317
|
});
|
|
52
318
|
pi.on("agent_end", () => {
|
|
53
319
|
clearProgressTimer();
|
|
320
|
+
activeCtx?.ui.setWorkingMessage?.();
|
|
321
|
+
activeCtx = undefined;
|
|
54
322
|
});
|
|
55
323
|
pi.on("session_shutdown", () => {
|
|
56
324
|
routingPolicy.reset();
|
|
57
325
|
clearProgressTimer();
|
|
326
|
+
activeCtx?.ui.setWorkingMessage?.();
|
|
327
|
+
activeCtx = undefined;
|
|
58
328
|
});
|
|
59
|
-
function
|
|
60
|
-
policy.setDetailEnabled(
|
|
61
|
-
ctx.ui.setToolExecutionVisible?.(
|
|
62
|
-
|
|
329
|
+
function applyDetailMode(ctx, mode, options = {}) {
|
|
330
|
+
policy.setDetailEnabled(mode === DETAIL_MODE_DETAILS);
|
|
331
|
+
ctx.ui.setToolExecutionVisible?.(policy.isDetailEnabled());
|
|
332
|
+
if (options.remember) {
|
|
333
|
+
saveDetailMode(mode);
|
|
334
|
+
savedDetailMode = mode;
|
|
335
|
+
}
|
|
336
|
+
if (mode === DETAIL_MODE_DETAILS) {
|
|
337
|
+
const scope = options.remember ? "已设为所有会话默认" : "仅当前会话";
|
|
338
|
+
ctx.ui.notify(`已展开细节(${scope})。高级控制:/fast、/prewalk、/workflow。`, "info");
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const scope = options.remember ? "已设为所有会话默认" : "仅当前会话";
|
|
342
|
+
ctx.ui.notify(`已切回紧凑模式(${scope})。`, "info");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function handleDetailsCommand(args, ctx) {
|
|
346
|
+
const action = String(args ?? "")
|
|
347
|
+
.trim()
|
|
348
|
+
.toLowerCase();
|
|
349
|
+
if (!action || action === "on") {
|
|
350
|
+
applyDetailMode(ctx, DETAIL_MODE_DETAILS);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (["off", "compact"].includes(action)) {
|
|
354
|
+
applyDetailMode(ctx, DETAIL_MODE_COMPACT);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (["remember", "save", "details"].includes(action)) {
|
|
358
|
+
applyDetailMode(ctx, DETAIL_MODE_DETAILS, { remember: true });
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (["remember compact", "save compact", "compact remember"].includes(action)) {
|
|
362
|
+
applyDetailMode(ctx, DETAIL_MODE_COMPACT, { remember: true });
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
if (action === "status") {
|
|
366
|
+
const current = policy.isDetailEnabled() ? DETAIL_MODE_DETAILS : DETAIL_MODE_COMPACT;
|
|
367
|
+
ctx.ui.notify(`当前:${current}。默认:${savedDetailMode}。`, "info");
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
ctx.ui.notify("用法:/details [on|off|remember|remember compact|status]", "warning");
|
|
63
371
|
}
|
|
64
372
|
|
|
65
373
|
pi.registerCommand("details", {
|
|
66
|
-
description: "
|
|
67
|
-
handler: async (
|
|
374
|
+
description: "Configure BYZ detail mode",
|
|
375
|
+
handler: async (args, ctx) => handleDetailsCommand(args, ctx),
|
|
68
376
|
});
|
|
69
377
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
70
378
|
const route = routingPolicy.route(event.prompt);
|
|
71
|
-
|
|
379
|
+
progressState = createProgressState();
|
|
380
|
+
progressState.goal = summarizeGoal(event.prompt);
|
|
381
|
+
pushUnique(progressState.confirmed, "已收到目标");
|
|
382
|
+
if (route.kind !== "general") pushUnique(progressState.judgements, `任务类型:${route.kind}`);
|
|
383
|
+
if (route.preferences.autonomy === "confirm-key-actions") {
|
|
384
|
+
pushUnique(progressState.safeguards, "关键动作会先确认");
|
|
385
|
+
}
|
|
386
|
+
if (route.details || parseConversationControl(event.prompt) === "detail") {
|
|
387
|
+
applyDetailMode(ctx, DETAIL_MODE_DETAILS);
|
|
388
|
+
}
|
|
72
389
|
if (policy.isDetailEnabled()) {
|
|
73
390
|
ctx.ui.notify(
|
|
74
391
|
`当前类别:${route.kind}。当前偏好:主动程度 ${route.preferences.autonomy},交付 ${route.preferences.delivery}。`,
|