@oyasmi/pipiclaw 0.2.2 → 0.3.1
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 +11 -0
- package/README.md +48 -16
- package/dist/agent.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +119 -106
- package/dist/agent.js.map +1 -1
- package/dist/command-extension.d.ts +14 -0
- package/dist/command-extension.d.ts.map +1 -0
- package/dist/command-extension.js +112 -0
- package/dist/command-extension.js.map +1 -0
- package/dist/commands.d.ts +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +22 -25
- package/dist/commands.js.map +1 -1
- package/dist/config-loader.d.ts +2 -6
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +4 -60
- package/dist/config-loader.js.map +1 -1
- package/dist/context.d.ts +4 -23
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +7 -122
- package/dist/context.js.map +1 -1
- package/dist/dingtalk.d.ts.map +1 -1
- package/dist/dingtalk.js +5 -0
- package/dist/dingtalk.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +27 -15
- package/dist/main.js.map +1 -1
- package/dist/memory-consolidation.d.ts +22 -0
- package/dist/memory-consolidation.d.ts.map +1 -0
- package/dist/memory-consolidation.js +258 -0
- package/dist/memory-consolidation.js.map +1 -0
- package/dist/memory-files.d.ts +24 -0
- package/dist/memory-files.d.ts.map +1 -0
- package/dist/memory-files.js +131 -0
- package/dist/memory-files.js.map +1 -0
- package/dist/memory-lifecycle.d.ts +27 -0
- package/dist/memory-lifecycle.d.ts.map +1 -0
- package/dist/memory-lifecycle.js +85 -0
- package/dist/memory-lifecycle.js.map +1 -0
- package/dist/prompt-builder.d.ts +1 -2
- package/dist/prompt-builder.d.ts.map +1 -1
- package/dist/prompt-builder.js +35 -88
- package/dist/prompt-builder.js.map +1 -1
- package/dist/store.d.ts +2 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +2 -1
- package/dist/store.js.map +1 -1
- package/package.json +2 -2
package/dist/agent.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { Agent } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import { AgentSession, AuthStorage, convertToLlm, DefaultResourceLoader, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { mkdir, writeFile } from "fs/promises";
|
|
4
|
-
import {
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { COMMAND_RESULT_CUSTOM_TYPE, createCommandExtension } from "./command-extension.js";
|
|
5
6
|
import { renderBuiltInHelp } from "./commands.js";
|
|
6
|
-
import { getAgentConfig, getApiKeyForModel,
|
|
7
|
-
import { PipiclawSettingsManager
|
|
7
|
+
import { getAgentConfig, getApiKeyForModel, getSoul, loadPipiclawSkills } from "./config-loader.js";
|
|
8
|
+
import { PipiclawSettingsManager } from "./context.js";
|
|
8
9
|
import * as log from "./log.js";
|
|
9
|
-
import {
|
|
10
|
+
import { MemoryLifecycle } from "./memory-lifecycle.js";
|
|
11
|
+
import { resolveInitialModel } from "./model-utils.js";
|
|
10
12
|
import { APP_HOME_DIR, AUTH_CONFIG_PATH, MODELS_CONFIG_PATH } from "./paths.js";
|
|
11
|
-
import {
|
|
13
|
+
import { buildAppendSystemPrompt } from "./prompt-builder.js";
|
|
12
14
|
import { createExecutor } from "./sandbox.js";
|
|
13
15
|
import { createPipiclawTools } from "./tools/index.js";
|
|
14
16
|
function isSilentOutcome(outcome) {
|
|
@@ -71,6 +73,18 @@ function extractToolResultText(result) {
|
|
|
71
73
|
}
|
|
72
74
|
return JSON.stringify(result);
|
|
73
75
|
}
|
|
76
|
+
function extractCustomCommandResultText(message) {
|
|
77
|
+
if (!message ||
|
|
78
|
+
typeof message !== "object" ||
|
|
79
|
+
!("role" in message) ||
|
|
80
|
+
!("customType" in message) ||
|
|
81
|
+
message.role !== "custom" ||
|
|
82
|
+
message.customType !== COMMAND_RESULT_CUSTOM_TYPE) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const content = message.content;
|
|
86
|
+
return typeof content === "string" && content.trim() ? content : null;
|
|
87
|
+
}
|
|
74
88
|
function createEmptyRunState() {
|
|
75
89
|
return {
|
|
76
90
|
ctx: null,
|
|
@@ -105,6 +119,8 @@ class ChannelRunner {
|
|
|
105
119
|
sessionManager;
|
|
106
120
|
settingsManager;
|
|
107
121
|
modelRegistry;
|
|
122
|
+
memoryLifecycle;
|
|
123
|
+
sessionReady;
|
|
108
124
|
// --- Mutable across runs ---
|
|
109
125
|
activeModel;
|
|
110
126
|
currentSkills;
|
|
@@ -119,13 +135,9 @@ class ChannelRunner {
|
|
|
119
135
|
this.workspaceDir = join(channelDir, "..");
|
|
120
136
|
// Create tools
|
|
121
137
|
const tools = createPipiclawTools(executor);
|
|
122
|
-
// Initial
|
|
123
|
-
const soul = getSoul(this.workspaceDir);
|
|
124
|
-
const agentConfig = getAgentConfig(channelDir);
|
|
125
|
-
const memory = getMemory(channelDir);
|
|
138
|
+
// Initial skill summaries
|
|
126
139
|
const initialSkills = loadPipiclawSkills(channelDir, this.workspacePath);
|
|
127
140
|
this.currentSkills = initialSkills;
|
|
128
|
-
const systemPrompt = buildSystemPrompt(this.workspacePath, channelId, soul, agentConfig, memory, sandboxConfig, initialSkills);
|
|
129
141
|
// Create session manager
|
|
130
142
|
const contextFile = join(channelDir, "context.jsonl");
|
|
131
143
|
this.sessionManager = SessionManager.open(contextFile, channelDir);
|
|
@@ -139,7 +151,7 @@ class ChannelRunner {
|
|
|
139
151
|
// Create agent
|
|
140
152
|
this.agent = new Agent({
|
|
141
153
|
initialState: {
|
|
142
|
-
systemPrompt,
|
|
154
|
+
systemPrompt: "",
|
|
143
155
|
model: this.activeModel,
|
|
144
156
|
thinkingLevel: "off",
|
|
145
157
|
tools,
|
|
@@ -147,16 +159,52 @@ class ChannelRunner {
|
|
|
147
159
|
convertToLlm,
|
|
148
160
|
getApiKey: async () => getApiKeyForModel(this.modelRegistry, this.activeModel),
|
|
149
161
|
});
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
this.
|
|
154
|
-
|
|
155
|
-
|
|
162
|
+
this.memoryLifecycle = new MemoryLifecycle({
|
|
163
|
+
channelId: this.channelId,
|
|
164
|
+
channelDir: this.channelDir,
|
|
165
|
+
getMessages: () => this.session.messages,
|
|
166
|
+
getSessionEntries: () => this.sessionManager.getBranch(),
|
|
167
|
+
getModel: () => this.session.model ?? this.activeModel,
|
|
168
|
+
resolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),
|
|
169
|
+
});
|
|
156
170
|
const resourceLoader = new DefaultResourceLoader({
|
|
157
171
|
cwd: process.cwd(),
|
|
158
172
|
agentDir: APP_HOME_DIR,
|
|
159
173
|
settingsManager: this.settingsManager,
|
|
174
|
+
extensionFactories: [
|
|
175
|
+
this.memoryLifecycle.createExtensionFactory(),
|
|
176
|
+
createCommandExtension({
|
|
177
|
+
getCurrentModel: () => this.session.model ?? this.activeModel,
|
|
178
|
+
getAvailableModels: async () => {
|
|
179
|
+
this.modelRegistry.refresh();
|
|
180
|
+
return await this.modelRegistry.getAvailable();
|
|
181
|
+
},
|
|
182
|
+
getSessionStats: () => this.session.getSessionStats(),
|
|
183
|
+
getThinkingLevel: () => this.session.thinkingLevel,
|
|
184
|
+
switchModel: async (model) => {
|
|
185
|
+
await this.session.setModel(model);
|
|
186
|
+
this.activeModel = model;
|
|
187
|
+
},
|
|
188
|
+
refreshSessionResources: async () => {
|
|
189
|
+
await this.refreshSessionResources();
|
|
190
|
+
},
|
|
191
|
+
}),
|
|
192
|
+
],
|
|
193
|
+
appendSystemPromptOverride: (base) => {
|
|
194
|
+
const soul = getSoul(this.workspaceDir);
|
|
195
|
+
const sections = [...base];
|
|
196
|
+
if (soul) {
|
|
197
|
+
sections.unshift(soul);
|
|
198
|
+
}
|
|
199
|
+
sections.push(buildAppendSystemPrompt(this.workspacePath, this.channelId, this.sandboxConfig));
|
|
200
|
+
return sections;
|
|
201
|
+
},
|
|
202
|
+
agentsFilesOverride: () => {
|
|
203
|
+
const agentConfig = getAgentConfig(this.channelDir);
|
|
204
|
+
return {
|
|
205
|
+
agentsFiles: agentConfig ? [{ path: `${this.workspacePath}/AGENTS.md`, content: agentConfig }] : [],
|
|
206
|
+
};
|
|
207
|
+
},
|
|
160
208
|
skillsOverride: (base) => ({
|
|
161
209
|
skills: [...base.skills, ...this.currentSkills],
|
|
162
210
|
diagnostics: base.diagnostics,
|
|
@@ -175,6 +223,7 @@ class ChannelRunner {
|
|
|
175
223
|
});
|
|
176
224
|
// Subscribe to session events
|
|
177
225
|
this.subscribeToSessionEvents();
|
|
226
|
+
this.sessionReady = this.initializeSession();
|
|
178
227
|
}
|
|
179
228
|
// === Public API ===
|
|
180
229
|
async run(ctx, _store) {
|
|
@@ -198,49 +247,21 @@ class ChannelRunner {
|
|
|
198
247
|
},
|
|
199
248
|
};
|
|
200
249
|
try {
|
|
250
|
+
await this.ensureSessionReady();
|
|
201
251
|
// Ensure channel directory exists
|
|
202
252
|
await mkdir(this.channelDir, { recursive: true });
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
const agentConfig = getAgentConfig(this.channelDir);
|
|
206
|
-
const memory = getMemory(this.channelDir);
|
|
207
|
-
const skills = loadPipiclawSkills(this.channelDir, this.workspacePath);
|
|
208
|
-
this.currentSkills = skills;
|
|
209
|
-
const systemPrompt = buildSystemPrompt(this.workspacePath, this.channelId, soul, agentConfig, memory, this.sandboxConfig, skills);
|
|
210
|
-
this.session.agent.setSystemPrompt(systemPrompt);
|
|
211
|
-
await this.session.reload();
|
|
212
|
-
// Sync messages from log.jsonl
|
|
213
|
-
const syncedCount = syncLogToSessionManager(this.sessionManager, this.channelDir, ctx.message.ts);
|
|
214
|
-
if (syncedCount > 0) {
|
|
215
|
-
log.logInfo(`[${this.channelId}] Synced ${syncedCount} messages from log.jsonl`);
|
|
216
|
-
}
|
|
217
|
-
// Reload messages from context.jsonl
|
|
218
|
-
const reloadedSession = this.sessionManager.buildSessionContext();
|
|
219
|
-
if (reloadedSession.messages.length > 0) {
|
|
220
|
-
this.agent.replaceMessages(reloadedSession.messages);
|
|
221
|
-
log.logInfo(`[${this.channelId}] Reloaded ${reloadedSession.messages.length} messages from context`);
|
|
222
|
-
}
|
|
223
|
-
// Log context info
|
|
224
|
-
log.logInfo(`Context sizes - system: ${systemPrompt.length} chars, memory: ${memory.length} chars`);
|
|
225
|
-
// Build user message with timestamp and username prefix
|
|
226
|
-
const now = new Date();
|
|
227
|
-
const pad = (n) => n.toString().padStart(2, "0");
|
|
228
|
-
const offset = -now.getTimezoneOffset();
|
|
229
|
-
const offsetSign = offset >= 0 ? "+" : "-";
|
|
230
|
-
const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
|
|
231
|
-
const offsetMins = pad(Math.abs(offset) % 60);
|
|
232
|
-
const timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${offsetSign}${offsetHours}:${offsetMins}`;
|
|
233
|
-
const userMessage = `[${timestamp}] [${ctx.message.userName || "unknown"}]: ${ctx.message.text}`;
|
|
253
|
+
const userMessage = this.formatUserMessage(ctx.message.text, ctx.message.userName);
|
|
254
|
+
const promptText = this.shouldPreserveRawInput(ctx.message.text) ? ctx.message.text.trim() : userMessage;
|
|
234
255
|
// Debug: write context to last_prompt.json (only with PIPICLAW_DEBUG=1)
|
|
235
256
|
if (process.env.PIPICLAW_DEBUG) {
|
|
236
257
|
const debugContext = {
|
|
237
|
-
systemPrompt,
|
|
258
|
+
systemPrompt: this.agent.state.systemPrompt,
|
|
238
259
|
messages: this.session.messages,
|
|
239
|
-
newUserMessage:
|
|
260
|
+
newUserMessage: promptText,
|
|
240
261
|
};
|
|
241
262
|
await writeFile(join(this.channelDir, "last_prompt.json"), JSON.stringify(debugContext, null, 2));
|
|
242
263
|
}
|
|
243
|
-
await this.session.prompt(
|
|
264
|
+
await this.session.prompt(promptText);
|
|
244
265
|
}
|
|
245
266
|
catch (err) {
|
|
246
267
|
this.runState.stopReason = "error";
|
|
@@ -317,26 +338,6 @@ class ChannelRunner {
|
|
|
317
338
|
case "help":
|
|
318
339
|
await this.sendCommandReply(ctx, renderBuiltInHelp());
|
|
319
340
|
return;
|
|
320
|
-
case "new": {
|
|
321
|
-
const completed = await this.session.newSession();
|
|
322
|
-
await this.sendCommandReply(ctx, completed ? `已开启新会话。\n\nSession ID: \`${this.session.sessionId}\`` : "新会话已取消。");
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
case "compact": {
|
|
326
|
-
const result = await this.session.compact(command.args || undefined);
|
|
327
|
-
await this.sendCommandReply(ctx, `已压缩当前会话上下文。\n\n- Tokens before compaction: \`${result.tokensBefore}\`\n- Summary:\n\n\`\`\`text\n${result.summary}\n\`\`\``);
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
case "session": {
|
|
331
|
-
const stats = this.session.getSessionStats();
|
|
332
|
-
const currentModel = this.session.model ? `\`${formatModelReference(this.session.model)}\`` : "(none)";
|
|
333
|
-
const sessionFile = stats.sessionFile ? `\`${basename(stats.sessionFile)}\`` : "(none)";
|
|
334
|
-
await this.sendCommandReply(ctx, `# Session\n\n- Session ID: \`${stats.sessionId}\`\n- Session file: ${sessionFile}\n- Model: ${currentModel}\n- Thinking level: \`${this.session.thinkingLevel}\`\n- User messages: \`${stats.userMessages}\`\n- Assistant messages: \`${stats.assistantMessages}\`\n- Tool calls: \`${stats.toolCalls}\`\n- Tool results: \`${stats.toolResults}\`\n- Total messages: \`${stats.totalMessages}\`\n- Tokens: \`${stats.tokens.total}\` (input \`${stats.tokens.input}\`, output \`${stats.tokens.output}\`, cache read \`${stats.tokens.cacheRead}\`, cache write \`${stats.tokens.cacheWrite}\`)\n- Cost: \`$${stats.cost.toFixed(4)}\``);
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
case "model":
|
|
338
|
-
await this.handleModelCommand(ctx, command.args);
|
|
339
|
-
return;
|
|
340
341
|
case "stop":
|
|
341
342
|
await this.sendCommandReply(ctx, "No task is running. Use `/stop` only while a task is running.");
|
|
342
343
|
return;
|
|
@@ -356,11 +357,11 @@ class ChannelRunner {
|
|
|
356
357
|
await this.sendCommandReply(ctx, `命令执行失败:${errMsg}`);
|
|
357
358
|
}
|
|
358
359
|
}
|
|
359
|
-
async queueSteer(text) {
|
|
360
|
-
await this.queueBusyMessage("steer", this.requireQueuedMessage(text, "steer"));
|
|
360
|
+
async queueSteer(text, userName) {
|
|
361
|
+
await this.queueBusyMessage("steer", this.requireQueuedMessage(text, "steer"), userName);
|
|
361
362
|
}
|
|
362
|
-
async queueFollowUp(text) {
|
|
363
|
-
await this.queueBusyMessage("followUp", this.requireQueuedMessage(text, "followup"));
|
|
363
|
+
async queueFollowUp(text, userName) {
|
|
364
|
+
await this.queueBusyMessage("followUp", this.requireQueuedMessage(text, "followup"), userName);
|
|
364
365
|
}
|
|
365
366
|
abort() {
|
|
366
367
|
this.session.abort();
|
|
@@ -380,40 +381,25 @@ class ChannelRunner {
|
|
|
380
381
|
}
|
|
381
382
|
return trimmedText;
|
|
382
383
|
}
|
|
383
|
-
|
|
384
|
+
shouldPreserveRawInput(text) {
|
|
385
|
+
return text.trim().startsWith("/");
|
|
386
|
+
}
|
|
387
|
+
formatUserMessage(text, userName, now = new Date()) {
|
|
388
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
389
|
+
const offset = -now.getTimezoneOffset();
|
|
390
|
+
const offsetSign = offset >= 0 ? "+" : "-";
|
|
391
|
+
const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
|
|
392
|
+
const offsetMins = pad(Math.abs(offset) % 60);
|
|
393
|
+
const timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${offsetSign}${offsetHours}:${offsetMins}`;
|
|
394
|
+
return `[${timestamp}] [${userName || "unknown"}]: ${text}`;
|
|
395
|
+
}
|
|
396
|
+
async queueBusyMessage(delivery, text, userName) {
|
|
384
397
|
if (!this.session.isStreaming) {
|
|
385
398
|
throw new Error("No task is currently running.");
|
|
386
399
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
await this.session.steer(text);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
async handleModelCommand(ctx, args) {
|
|
395
|
-
this.modelRegistry.refresh();
|
|
396
|
-
const availableModels = await this.modelRegistry.getAvailable();
|
|
397
|
-
const currentModel = this.session.model;
|
|
398
|
-
if (!args.trim()) {
|
|
399
|
-
const current = currentModel ? `\`${formatModelReference(currentModel)}\`` : "(none)";
|
|
400
|
-
const available = availableModels.length > 0 ? formatModelList(availableModels, currentModel) : "- (none)";
|
|
401
|
-
await this.sendCommandReply(ctx, `# Model\n\nCurrent model: ${current}\n\nUse \`/model <provider/modelId>\` or \`/model <modelId>\` to switch. Bare model IDs must resolve uniquely.\n\nAvailable models:\n${available}`);
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
const match = findExactModelReferenceMatch(args, availableModels);
|
|
405
|
-
if (match.match) {
|
|
406
|
-
await this.session.setModel(match.match);
|
|
407
|
-
this.activeModel = match.match;
|
|
408
|
-
await this.sendCommandReply(ctx, `已切换模型到 \`${formatModelReference(match.match)}\`。`);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
const available = availableModels.length > 0 ? formatModelList(availableModels, currentModel, 10) : "- (none)";
|
|
412
|
-
if (match.ambiguous) {
|
|
413
|
-
await this.sendCommandReply(ctx, `未切换模型:\`${args.trim()}\` 匹配到多个模型。请改用精确的 \`provider/modelId\` 形式。\n\nAvailable models:\n${available}`);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
await this.sendCommandReply(ctx, `未找到模型 \`${args.trim()}\`。请使用精确的 \`provider/modelId\` 或唯一的 \`modelId\`。\n\nAvailable models:\n${available}`);
|
|
400
|
+
await this.session.prompt(this.formatUserMessage(text, userName), {
|
|
401
|
+
streamingBehavior: delivery,
|
|
402
|
+
});
|
|
417
403
|
}
|
|
418
404
|
resetRunState(ctx) {
|
|
419
405
|
this.runState = createEmptyRunState();
|
|
@@ -424,6 +410,20 @@ class ChannelRunner {
|
|
|
424
410
|
channelName: ctx.channelName,
|
|
425
411
|
};
|
|
426
412
|
}
|
|
413
|
+
async refreshSessionResources() {
|
|
414
|
+
await this.ensureSessionReady();
|
|
415
|
+
const skills = loadPipiclawSkills(this.channelDir, this.workspacePath);
|
|
416
|
+
this.currentSkills = skills;
|
|
417
|
+
await this.session.reload();
|
|
418
|
+
}
|
|
419
|
+
async initializeSession() {
|
|
420
|
+
const skills = loadPipiclawSkills(this.channelDir, this.workspacePath);
|
|
421
|
+
this.currentSkills = skills;
|
|
422
|
+
await this.session.reload();
|
|
423
|
+
}
|
|
424
|
+
async ensureSessionReady() {
|
|
425
|
+
await this.sessionReady;
|
|
426
|
+
}
|
|
427
427
|
// === Session event subscription ===
|
|
428
428
|
subscribeToSessionEvents() {
|
|
429
429
|
this.session.subscribe(async (event) => {
|
|
@@ -466,6 +466,19 @@ class ChannelRunner {
|
|
|
466
466
|
}
|
|
467
467
|
else if (event.type === "message_end") {
|
|
468
468
|
const agentEvent = event;
|
|
469
|
+
const commandResultText = extractCustomCommandResultText(agentEvent.message);
|
|
470
|
+
if (commandResultText) {
|
|
471
|
+
this.runState.finalOutcome = { kind: "final", text: commandResultText };
|
|
472
|
+
log.logResponse(logCtx, commandResultText);
|
|
473
|
+
queue.enqueue(async () => {
|
|
474
|
+
const delivered = await ctx.respondPlain(commandResultText);
|
|
475
|
+
if (!delivered) {
|
|
476
|
+
await ctx.replaceMessage(commandResultText);
|
|
477
|
+
}
|
|
478
|
+
this.runState.finalResponseDelivered = true;
|
|
479
|
+
}, "command result");
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
469
482
|
if (agentEvent.message.role === "assistant") {
|
|
470
483
|
const assistantMsg = agentEvent.message;
|
|
471
484
|
if (assistantMsg.stopReason) {
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport {\n\tAgentSession,\n\tAuthStorage,\n\tconvertToLlm,\n\tDefaultResourceLoader,\n\tModelRegistry,\n\tSessionManager,\n\ttype Skill,\n} from \"@mariozechner/pi-coding-agent\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport { basename, join } from \"path\";\nimport { type BuiltInCommand, renderBuiltInHelp } from \"./commands.js\";\nimport { getAgentConfig, getApiKeyForModel, getMemory, getSoul, loadPipiclawSkills } from \"./config-loader.js\";\nimport { PipiclawSettingsManager, syncLogToSessionManager } from \"./context.js\";\nimport type { DingTalkContext } from \"./dingtalk.js\";\nimport * as log from \"./log.js\";\nimport {\n\tfindExactModelReferenceMatch,\n\tformatModelList,\n\tformatModelReference,\n\tresolveInitialModel,\n} from \"./model-utils.js\";\nimport { APP_HOME_DIR, AUTH_CONFIG_PATH, MODELS_CONFIG_PATH } from \"./paths.js\";\nimport { buildSystemPrompt } from \"./prompt-builder.js\";\nimport { createExecutor, type SandboxConfig } from \"./sandbox.js\";\nimport type { ChannelStore } from \"./store.js\";\nimport { createPipiclawTools } from \"./tools/index.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AgentRunner {\n\trun(ctx: DingTalkContext, store: ChannelStore): Promise<{ stopReason: string; errorMessage?: string }>;\n\thandleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void>;\n\tqueueSteer(text: string): Promise<void>;\n\tqueueFollowUp(text: string): Promise<void>;\n\tabort(): void;\n}\n\ntype FinalOutcome = { kind: \"none\" } | { kind: \"silent\" } | { kind: \"final\"; text: string };\n\nfunction isSilentOutcome(outcome: FinalOutcome): outcome is { kind: \"silent\" } {\n\treturn outcome.kind === \"silent\";\n}\n\nfunction isFinalOutcome(outcome: FinalOutcome): outcome is { kind: \"final\"; text: string } {\n\treturn outcome.kind === \"final\";\n}\n\nfunction getFinalOutcomeText(outcome: FinalOutcome): string | null {\n\treturn isFinalOutcome(outcome) ? outcome.text : null;\n}\n\n// ============================================================================\n// Text helpers\n// ============================================================================\n\nfunction truncate(text: string, maxLen: number): string {\n\tif (text.length <= maxLen) return text;\n\treturn `${text.substring(0, maxLen - 3)}...`;\n}\n\nfunction sanitizeProgressText(text: string): string {\n\treturn text\n\t\t.replace(/\\uFFFC/g, \"\")\n\t\t.replace(/\\r/g, \"\")\n\t\t.trim();\n}\n\nfunction formatProgressEntry(kind: \"tool\" | \"thinking\" | \"error\" | \"assistant\", text: string): string {\n\tconst cleaned = sanitizeProgressText(text);\n\tif (!cleaned) return \"\";\n\n\tconst normalized = cleaned.replace(/\\n+/g, \" \").trim();\n\tswitch (kind) {\n\t\tcase \"tool\":\n\t\t\treturn `Running: ${normalized}`;\n\t\tcase \"thinking\":\n\t\t\treturn `Thinking: ${normalized}`;\n\t\tcase \"error\":\n\t\t\treturn `Error: ${normalized}`;\n\t\tcase \"assistant\":\n\t\t\treturn normalized;\n\t}\n}\n\nfunction extractToolResultText(result: unknown): string {\n\tif (typeof result === \"string\") {\n\t\treturn result;\n\t}\n\n\tif (\n\t\tresult &&\n\t\ttypeof result === \"object\" &&\n\t\t\"content\" in result &&\n\t\tArray.isArray((result as { content: unknown }).content)\n\t) {\n\t\tconst content = (result as { content: Array<{ type: string; text?: string }> }).content;\n\t\tconst textParts: string[] = [];\n\t\tfor (const part of content) {\n\t\t\tif (part.type === \"text\" && part.text) {\n\t\t\t\ttextParts.push(part.text);\n\t\t\t}\n\t\t}\n\t\tif (textParts.length > 0) {\n\t\t\treturn textParts.join(\"\\n\");\n\t\t}\n\t}\n\n\treturn JSON.stringify(result);\n}\n\n// ============================================================================\n// Run State\n// ============================================================================\n\ninterface PendingTool {\n\ttoolName: string;\n\targs: unknown;\n\tstartTime: number;\n}\n\ninterface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n}\n\ninterface RunQueue {\n\tenqueue(fn: () => Promise<void>, errorContext: string): void;\n\tenqueueMessage(text: string, target: \"main\" | \"thread\", errorContext: string, doLog?: boolean): void;\n}\n\ninterface RunState {\n\tctx: DingTalkContext | null;\n\tlogCtx: { channelId: string; userName?: string; channelName?: string } | null;\n\tqueue: RunQueue | null;\n\tpendingTools: Map<string, PendingTool>;\n\ttotalUsage: UsageTotals;\n\tstopReason: string;\n\terrorMessage: string | undefined;\n\tfinalOutcome: FinalOutcome;\n\tfinalResponseDelivered: boolean;\n}\n\nfunction createEmptyRunState(): RunState {\n\treturn {\n\t\tctx: null,\n\t\tlogCtx: null,\n\t\tqueue: null,\n\t\tpendingTools: new Map(),\n\t\ttotalUsage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\terrorMessage: undefined,\n\t\tfinalOutcome: { kind: \"none\" },\n\t\tfinalResponseDelivered: false,\n\t};\n}\n\n// ============================================================================\n// ChannelRunner\n// ============================================================================\n\nclass ChannelRunner implements AgentRunner {\n\t// --- Constructed once ---\n\tprivate readonly sandboxConfig: SandboxConfig;\n\tprivate readonly channelId: string;\n\tprivate readonly channelDir: string;\n\tprivate readonly workspacePath: string;\n\tprivate readonly workspaceDir: string;\n\tprivate readonly session: AgentSession;\n\tprivate readonly agent: Agent;\n\tprivate readonly sessionManager: SessionManager;\n\tprivate readonly settingsManager: PipiclawSettingsManager;\n\tprivate readonly modelRegistry: ModelRegistry;\n\n\t// --- Mutable across runs ---\n\tprivate activeModel: Model<Api>;\n\tprivate currentSkills: Skill[];\n\n\t// --- Per run ---\n\tprivate runState: RunState = createEmptyRunState();\n\n\tconstructor(sandboxConfig: SandboxConfig, channelId: string, channelDir: string) {\n\t\tthis.sandboxConfig = sandboxConfig;\n\t\tthis.channelId = channelId;\n\t\tthis.channelDir = channelDir;\n\n\t\tconst executor = createExecutor(sandboxConfig);\n\t\tthis.workspacePath = executor.getWorkspacePath(channelDir.replace(`/${channelId}`, \"\"));\n\t\tthis.workspaceDir = join(channelDir, \"..\");\n\n\t\t// Create tools\n\t\tconst tools = createPipiclawTools(executor);\n\n\t\t// Initial system prompt\n\t\tconst soul = getSoul(this.workspaceDir);\n\t\tconst agentConfig = getAgentConfig(channelDir);\n\t\tconst memory = getMemory(channelDir);\n\t\tconst initialSkills = loadPipiclawSkills(channelDir, this.workspacePath);\n\t\tthis.currentSkills = initialSkills;\n\t\tconst systemPrompt = buildSystemPrompt(\n\t\t\tthis.workspacePath,\n\t\t\tchannelId,\n\t\t\tsoul,\n\t\t\tagentConfig,\n\t\t\tmemory,\n\t\t\tsandboxConfig,\n\t\t\tinitialSkills,\n\t\t);\n\n\t\t// Create session manager\n\t\tconst contextFile = join(channelDir, \"context.jsonl\");\n\t\tthis.sessionManager = SessionManager.open(contextFile, channelDir);\n\t\tthis.settingsManager = new PipiclawSettingsManager(APP_HOME_DIR);\n\n\t\t// Create AuthStorage and ModelRegistry\n\t\tconst authStorage = AuthStorage.create(AUTH_CONFIG_PATH);\n\t\tthis.modelRegistry = new ModelRegistry(authStorage, MODELS_CONFIG_PATH);\n\n\t\t// Resolve model: prefer saved global default, fall back to first available model\n\t\tthis.activeModel = resolveInitialModel(this.modelRegistry, this.settingsManager);\n\t\tlog.logInfo(`Using model: ${this.activeModel.provider}/${this.activeModel.id} (${this.activeModel.name})`);\n\n\t\t// Create agent\n\t\tthis.agent = new Agent({\n\t\t\tinitialState: {\n\t\t\t\tsystemPrompt,\n\t\t\t\tmodel: this.activeModel,\n\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\ttools,\n\t\t\t},\n\t\t\tconvertToLlm,\n\t\t\tgetApiKey: async () => getApiKeyForModel(this.modelRegistry, this.activeModel),\n\t\t});\n\n\t\t// Load existing messages\n\t\tconst loadedSession = this.sessionManager.buildSessionContext();\n\t\tif (loadedSession.messages.length > 0) {\n\t\t\tthis.agent.replaceMessages(loadedSession.messages);\n\t\t\tlog.logInfo(`[${channelId}] Loaded ${loadedSession.messages.length} messages from context.jsonl`);\n\t\t}\n\n\t\tconst resourceLoader = new DefaultResourceLoader({\n\t\t\tcwd: process.cwd(),\n\t\t\tagentDir: APP_HOME_DIR,\n\t\t\tsettingsManager: this.settingsManager as any,\n\t\t\tskillsOverride: (base) => ({\n\t\t\t\tskills: [...base.skills, ...this.currentSkills],\n\t\t\t\tdiagnostics: base.diagnostics,\n\t\t\t}),\n\t\t});\n\n\t\tconst baseToolsOverride = Object.fromEntries(tools.map((tool) => [tool.name, tool]));\n\n\t\t// Create AgentSession\n\t\tthis.session = new AgentSession({\n\t\t\tagent: this.agent,\n\t\t\tsessionManager: this.sessionManager,\n\t\t\tsettingsManager: this.settingsManager as any,\n\t\t\tcwd: process.cwd(),\n\t\t\tmodelRegistry: this.modelRegistry,\n\t\t\tresourceLoader,\n\t\t\tbaseToolsOverride,\n\t\t});\n\n\t\t// Subscribe to session events\n\t\tthis.subscribeToSessionEvents();\n\t}\n\n\t// === Public API ===\n\n\tasync run(ctx: DingTalkContext, _store: ChannelStore): Promise<{ stopReason: string; errorMessage?: string }> {\n\t\tthis.resetRunState(ctx);\n\n\t\t// Create queue for this run\n\t\tlet queueChain = Promise.resolve();\n\t\tthis.runState.queue = {\n\t\t\tenqueue: (fn: () => Promise<void>, errorContext: string): void => {\n\t\t\t\tqueueChain = queueChain.then(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait fn();\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(`DingTalk API error (${errorContext})`, errMsg);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tenqueueMessage: function (text: string, target: \"main\" | \"thread\", errorContext: string, doLog = true): void {\n\t\t\t\tthis.enqueue(\n\t\t\t\t\t() => (target === \"main\" ? ctx.respond(text, doLog) : ctx.respondInThread(text)),\n\t\t\t\t\terrorContext,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\t// Ensure channel directory exists\n\t\t\tawait mkdir(this.channelDir, { recursive: true });\n\n\t\t\t// Update system prompt and runtime resources with fresh config\n\t\t\tconst soul = getSoul(this.workspaceDir);\n\t\t\tconst agentConfig = getAgentConfig(this.channelDir);\n\t\t\tconst memory = getMemory(this.channelDir);\n\t\t\tconst skills = loadPipiclawSkills(this.channelDir, this.workspacePath);\n\t\t\tthis.currentSkills = skills;\n\t\t\tconst systemPrompt = buildSystemPrompt(\n\t\t\t\tthis.workspacePath,\n\t\t\t\tthis.channelId,\n\t\t\t\tsoul,\n\t\t\t\tagentConfig,\n\t\t\t\tmemory,\n\t\t\t\tthis.sandboxConfig,\n\t\t\t\tskills,\n\t\t\t);\n\t\t\tthis.session.agent.setSystemPrompt(systemPrompt);\n\t\t\tawait this.session.reload();\n\n\t\t\t// Sync messages from log.jsonl\n\t\t\tconst syncedCount = syncLogToSessionManager(this.sessionManager, this.channelDir, ctx.message.ts);\n\t\t\tif (syncedCount > 0) {\n\t\t\t\tlog.logInfo(`[${this.channelId}] Synced ${syncedCount} messages from log.jsonl`);\n\t\t\t}\n\n\t\t\t// Reload messages from context.jsonl\n\t\t\tconst reloadedSession = this.sessionManager.buildSessionContext();\n\t\t\tif (reloadedSession.messages.length > 0) {\n\t\t\t\tthis.agent.replaceMessages(reloadedSession.messages);\n\t\t\t\tlog.logInfo(`[${this.channelId}] Reloaded ${reloadedSession.messages.length} messages from context`);\n\t\t\t}\n\n\t\t\t// Log context info\n\t\t\tlog.logInfo(`Context sizes - system: ${systemPrompt.length} chars, memory: ${memory.length} chars`);\n\n\t\t\t// Build user message with timestamp and username prefix\n\t\t\tconst now = new Date();\n\t\t\tconst pad = (n: number) => n.toString().padStart(2, \"0\");\n\t\t\tconst offset = -now.getTimezoneOffset();\n\t\t\tconst offsetSign = offset >= 0 ? \"+\" : \"-\";\n\t\t\tconst offsetHours = pad(Math.floor(Math.abs(offset) / 60));\n\t\t\tconst offsetMins = pad(Math.abs(offset) % 60);\n\t\t\tconst timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${offsetSign}${offsetHours}:${offsetMins}`;\n\t\t\tconst userMessage = `[${timestamp}] [${ctx.message.userName || \"unknown\"}]: ${ctx.message.text}`;\n\n\t\t\t// Debug: write context to last_prompt.json (only with PIPICLAW_DEBUG=1)\n\t\t\tif (process.env.PIPICLAW_DEBUG) {\n\t\t\t\tconst debugContext = {\n\t\t\t\t\tsystemPrompt,\n\t\t\t\t\tmessages: this.session.messages,\n\t\t\t\t\tnewUserMessage: userMessage,\n\t\t\t\t};\n\t\t\t\tawait writeFile(join(this.channelDir, \"last_prompt.json\"), JSON.stringify(debugContext, null, 2));\n\t\t\t}\n\n\t\t\tawait this.session.prompt(userMessage);\n\t\t} catch (err) {\n\t\t\tthis.runState.stopReason = \"error\";\n\t\t\tthis.runState.errorMessage = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${this.channelId}] Runner failed`, this.runState.errorMessage);\n\t\t} finally {\n\t\t\tawait queueChain;\n\t\t\tconst finalOutcome = this.runState.finalOutcome;\n\t\t\tconst finalOutcomeText = getFinalOutcomeText(finalOutcome);\n\n\t\t\ttry {\n\t\t\t\tif (\n\t\t\t\t\tthis.runState.stopReason === \"error\" &&\n\t\t\t\t\tthis.runState.errorMessage &&\n\t\t\t\t\t!this.runState.finalResponseDelivered\n\t\t\t\t) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ctx.replaceMessage(\"_Sorry, something went wrong_\");\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(\"Failed to post error message\", errMsg);\n\t\t\t\t\t}\n\t\t\t\t} else if (isSilentOutcome(finalOutcome)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ctx.deleteMessage();\n\t\t\t\t\t\tlog.logInfo(\"Silent response - deleted message\");\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(\"Failed to delete message for silent response\", errMsg);\n\t\t\t\t\t}\n\t\t\t\t} else if (finalOutcomeText && !this.runState.finalResponseDelivered) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ctx.replaceMessage(finalOutcomeText);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(\"Failed to replace message with final text\", errMsg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tawait ctx.flush();\n\t\t\t} finally {\n\t\t\t\tawait ctx.close();\n\t\t\t}\n\n\t\t\t// Log usage summary\n\t\t\tif (this.runState.totalUsage.cost.total > 0) {\n\t\t\t\tconst messages = this.session.messages;\n\t\t\t\tconst lastAssistantMessage = messages\n\t\t\t\t\t.slice()\n\t\t\t\t\t.reverse()\n\t\t\t\t\t.find((m: any) => m.role === \"assistant\" && m.stopReason !== \"aborted\") as any;\n\n\t\t\t\tconst contextTokens = lastAssistantMessage\n\t\t\t\t\t? lastAssistantMessage.usage.input +\n\t\t\t\t\t\tlastAssistantMessage.usage.output +\n\t\t\t\t\t\tlastAssistantMessage.usage.cacheRead +\n\t\t\t\t\t\tlastAssistantMessage.usage.cacheWrite\n\t\t\t\t\t: 0;\n\t\t\t\tconst currentRunModel = this.session.model ?? this.activeModel;\n\t\t\t\tconst contextWindow = currentRunModel.contextWindow || 200000;\n\n\t\t\t\tlog.logUsageSummary(this.runState.logCtx!, this.runState.totalUsage, contextTokens, contextWindow);\n\t\t\t}\n\n\t\t\t// Clear run state\n\t\t\tthis.runState.ctx = null;\n\t\t\tthis.runState.logCtx = null;\n\t\t\tthis.runState.queue = null;\n\t\t}\n\n\t\treturn { stopReason: this.runState.stopReason, errorMessage: this.runState.errorMessage };\n\t}\n\n\tasync handleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void> {\n\t\ttry {\n\t\t\tswitch (command.name) {\n\t\t\t\tcase \"help\":\n\t\t\t\t\tawait this.sendCommandReply(ctx, renderBuiltInHelp());\n\t\t\t\t\treturn;\n\t\t\t\tcase \"new\": {\n\t\t\t\t\tconst completed = await this.session.newSession();\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\tcompleted ? `已开启新会话。\\n\\nSession ID: \\`${this.session.sessionId}\\`` : \"新会话已取消。\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcase \"compact\": {\n\t\t\t\t\tconst result = await this.session.compact(command.args || undefined);\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t`已压缩当前会话上下文。\\n\\n- Tokens before compaction: \\`${result.tokensBefore}\\`\\n- Summary:\\n\\n\\`\\`\\`text\\n${result.summary}\\n\\`\\`\\``,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcase \"session\": {\n\t\t\t\t\tconst stats = this.session.getSessionStats();\n\t\t\t\t\tconst currentModel = this.session.model ? `\\`${formatModelReference(this.session.model)}\\`` : \"(none)\";\n\t\t\t\t\tconst sessionFile = stats.sessionFile ? `\\`${basename(stats.sessionFile)}\\`` : \"(none)\";\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t`# Session\\n\\n- Session ID: \\`${stats.sessionId}\\`\\n- Session file: ${sessionFile}\\n- Model: ${currentModel}\\n- Thinking level: \\`${this.session.thinkingLevel}\\`\\n- User messages: \\`${stats.userMessages}\\`\\n- Assistant messages: \\`${stats.assistantMessages}\\`\\n- Tool calls: \\`${stats.toolCalls}\\`\\n- Tool results: \\`${stats.toolResults}\\`\\n- Total messages: \\`${stats.totalMessages}\\`\\n- Tokens: \\`${stats.tokens.total}\\` (input \\`${stats.tokens.input}\\`, output \\`${stats.tokens.output}\\`, cache read \\`${stats.tokens.cacheRead}\\`, cache write \\`${stats.tokens.cacheWrite}\\`)\\n- Cost: \\`$${stats.cost.toFixed(4)}\\``,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcase \"model\":\n\t\t\t\t\tawait this.handleModelCommand(ctx, command.args);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\tawait this.sendCommandReply(ctx, \"No task is running. Use `/stop` only while a task is running.\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"steer\":\n\t\t\t\t\tthis.requireQueuedMessage(command.args, \"steer\");\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"No task is running. Send the message directly instead of using `/steer`.\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"followup\":\n\t\t\t\t\tthis.requireQueuedMessage(command.args, \"followup\");\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"No task is running. Send the message directly now, or use `/followup` while a task is running.\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${this.channelId}] Built-in command failed`, errMsg);\n\t\t\tawait this.sendCommandReply(ctx, `命令执行失败:${errMsg}`);\n\t\t}\n\t}\n\n\tasync queueSteer(text: string): Promise<void> {\n\t\tawait this.queueBusyMessage(\"steer\", this.requireQueuedMessage(text, \"steer\"));\n\t}\n\n\tasync queueFollowUp(text: string): Promise<void> {\n\t\tawait this.queueBusyMessage(\"followUp\", this.requireQueuedMessage(text, \"followup\"));\n\t}\n\n\tabort(): void {\n\t\tthis.session.abort();\n\t}\n\n\t// === Private helpers ===\n\n\tprivate async sendCommandReply(ctx: DingTalkContext, text: string): Promise<void> {\n\t\tconst delivered = await ctx.respondPlain(text);\n\t\tif (!delivered) {\n\t\t\tawait ctx.replaceMessage(text);\n\t\t\tawait ctx.flush();\n\t\t}\n\t}\n\n\tprivate requireQueuedMessage(text: string, commandName: \"steer\" | \"followup\"): string {\n\t\tconst trimmedText = text.trim();\n\t\tif (!trimmedText) {\n\t\t\tthrow new Error(`/${commandName} requires a message.`);\n\t\t}\n\t\treturn trimmedText;\n\t}\n\n\tprivate async queueBusyMessage(delivery: \"steer\" | \"followUp\", text: string): Promise<void> {\n\t\tif (!this.session.isStreaming) {\n\t\t\tthrow new Error(\"No task is currently running.\");\n\t\t}\n\n\t\tif (delivery === \"followUp\") {\n\t\t\tawait this.session.followUp(text);\n\t\t} else {\n\t\t\tawait this.session.steer(text);\n\t\t}\n\t}\n\n\tprivate async handleModelCommand(ctx: DingTalkContext, args: string): Promise<void> {\n\t\tthis.modelRegistry.refresh();\n\t\tconst availableModels = await this.modelRegistry.getAvailable();\n\t\tconst currentModel = this.session.model;\n\n\t\tif (!args.trim()) {\n\t\t\tconst current = currentModel ? `\\`${formatModelReference(currentModel)}\\`` : \"(none)\";\n\t\t\tconst available = availableModels.length > 0 ? formatModelList(availableModels, currentModel) : \"- (none)\";\n\t\t\tawait this.sendCommandReply(\n\t\t\t\tctx,\n\t\t\t\t`# Model\\n\\nCurrent model: ${current}\\n\\nUse \\`/model <provider/modelId>\\` or \\`/model <modelId>\\` to switch. Bare model IDs must resolve uniquely.\\n\\nAvailable models:\\n${available}`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst match = findExactModelReferenceMatch(args, availableModels);\n\t\tif (match.match) {\n\t\t\tawait this.session.setModel(match.match);\n\t\t\tthis.activeModel = match.match;\n\t\t\tawait this.sendCommandReply(ctx, `已切换模型到 \\`${formatModelReference(match.match)}\\`。`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst available = availableModels.length > 0 ? formatModelList(availableModels, currentModel, 10) : \"- (none)\";\n\t\tif (match.ambiguous) {\n\t\t\tawait this.sendCommandReply(\n\t\t\t\tctx,\n\t\t\t\t`未切换模型:\\`${args.trim()}\\` 匹配到多个模型。请改用精确的 \\`provider/modelId\\` 形式。\\n\\nAvailable models:\\n${available}`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.sendCommandReply(\n\t\t\tctx,\n\t\t\t`未找到模型 \\`${args.trim()}\\`。请使用精确的 \\`provider/modelId\\` 或唯一的 \\`modelId\\`。\\n\\nAvailable models:\\n${available}`,\n\t\t);\n\t}\n\n\tprivate resetRunState(ctx: DingTalkContext): void {\n\t\tthis.runState = createEmptyRunState();\n\t\tthis.runState.ctx = ctx;\n\t\tthis.runState.logCtx = {\n\t\t\tchannelId: ctx.message.channel,\n\t\t\tuserName: ctx.message.userName,\n\t\t\tchannelName: ctx.channelName,\n\t\t};\n\t}\n\n\t// === Session event subscription ===\n\n\tprivate subscribeToSessionEvents(): void {\n\t\tthis.session.subscribe(async (event: any) => {\n\t\t\tif (!this.runState.ctx || !this.runState.logCtx || !this.runState.queue) return;\n\n\t\t\tconst { ctx, logCtx, queue, pendingTools } = this.runState;\n\n\t\t\tif (event.type === \"tool_execution_start\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"tool_execution_start\" };\n\t\t\t\tconst args = agentEvent.args as { label?: string };\n\t\t\t\tconst label = args.label || agentEvent.toolName;\n\n\t\t\t\tpendingTools.set(agentEvent.toolCallId, {\n\t\t\t\t\ttoolName: agentEvent.toolName,\n\t\t\t\t\targs: agentEvent.args,\n\t\t\t\t\tstartTime: Date.now(),\n\t\t\t\t});\n\n\t\t\t\tlog.logToolStart(logCtx, agentEvent.toolName, label, agentEvent.args as Record<string, unknown>);\n\t\t\t\tqueue.enqueue(() => ctx.respond(formatProgressEntry(\"tool\", label), false), \"tool label\");\n\t\t\t} else if (event.type === \"tool_execution_end\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"tool_execution_end\" };\n\t\t\t\tconst resultStr = extractToolResultText(agentEvent.result);\n\t\t\t\tconst pending = pendingTools.get(agentEvent.toolCallId);\n\t\t\t\tpendingTools.delete(agentEvent.toolCallId);\n\n\t\t\t\tconst durationMs = pending ? Date.now() - pending.startTime : 0;\n\n\t\t\t\tif (agentEvent.isError) {\n\t\t\t\t\tlog.logToolError(logCtx, agentEvent.toolName, durationMs, resultStr);\n\t\t\t\t} else {\n\t\t\t\t\tlog.logToolSuccess(logCtx, agentEvent.toolName, durationMs, resultStr);\n\t\t\t\t}\n\n\t\t\t\tif (agentEvent.isError) {\n\t\t\t\t\tqueue.enqueue(\n\t\t\t\t\t\t() => ctx.respond(formatProgressEntry(\"error\", truncate(resultStr, 200)), false),\n\t\t\t\t\t\t\"tool error\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (event.type === \"message_start\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"message_start\" };\n\t\t\t\tif (agentEvent.message.role === \"assistant\") {\n\t\t\t\t\tlog.logResponseStart(logCtx);\n\t\t\t\t}\n\t\t\t} else if (event.type === \"message_end\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"message_end\" };\n\t\t\t\tif (agentEvent.message.role === \"assistant\") {\n\t\t\t\t\tconst assistantMsg = agentEvent.message as any;\n\n\t\t\t\t\tif (assistantMsg.stopReason) {\n\t\t\t\t\t\tthis.runState.stopReason = assistantMsg.stopReason;\n\t\t\t\t\t}\n\t\t\t\t\tif (assistantMsg.errorMessage) {\n\t\t\t\t\t\tthis.runState.errorMessage = assistantMsg.errorMessage;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (assistantMsg.usage) {\n\t\t\t\t\t\tthis.runState.totalUsage.input += assistantMsg.usage.input;\n\t\t\t\t\t\tthis.runState.totalUsage.output += assistantMsg.usage.output;\n\t\t\t\t\t\tthis.runState.totalUsage.cacheRead += assistantMsg.usage.cacheRead;\n\t\t\t\t\t\tthis.runState.totalUsage.cacheWrite += assistantMsg.usage.cacheWrite;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.input += assistantMsg.usage.cost.input;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.output += assistantMsg.usage.cost.output;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.cacheRead += assistantMsg.usage.cost.cacheRead;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.cacheWrite += assistantMsg.usage.cost.cacheWrite;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.total += assistantMsg.usage.cost.total;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst content = agentEvent.message.content;\n\t\t\t\t\tconst thinkingParts: string[] = [];\n\t\t\t\t\tconst textParts: string[] = [];\n\t\t\t\t\tlet hasToolCalls = false;\n\t\t\t\t\tfor (const part of content) {\n\t\t\t\t\t\tif (part.type === \"thinking\") {\n\t\t\t\t\t\t\tthinkingParts.push((part as any).thinking);\n\t\t\t\t\t\t} else if (part.type === \"text\") {\n\t\t\t\t\t\t\ttextParts.push((part as any).text);\n\t\t\t\t\t\t} else if (part.type === \"toolCall\") {\n\t\t\t\t\t\t\thasToolCalls = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst text = textParts.join(\"\\n\");\n\n\t\t\t\t\tfor (const thinking of thinkingParts) {\n\t\t\t\t\t\tlog.logThinking(logCtx, thinking);\n\t\t\t\t\t\tqueue.enqueue(() => ctx.respond(formatProgressEntry(\"thinking\", thinking), false), \"thinking\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (hasToolCalls && text.trim()) {\n\t\t\t\t\t\tqueue.enqueue(() => ctx.respond(formatProgressEntry(\"assistant\", text), false), \"assistant progress\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (event.type === \"turn_end\") {\n\t\t\t\tconst turnEvent = event as any & {\n\t\t\t\t\ttype: \"turn_end\";\n\t\t\t\t\tmessage: { role: string; stopReason?: string; content: Array<{ type: string; text?: string }> };\n\t\t\t\t\ttoolResults: unknown[];\n\t\t\t\t};\n\t\t\t\tif (turnEvent.message.role === \"assistant\" && turnEvent.toolResults.length === 0) {\n\t\t\t\t\tif (turnEvent.message.stopReason === \"error\" || turnEvent.message.stopReason === \"aborted\") {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst finalContent = turnEvent.message.content as Array<{ type: string; text?: string }>;\n\t\t\t\t\tconst finalText = finalContent\n\t\t\t\t\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && !!part.text)\n\t\t\t\t\t\t.map((part) => part.text)\n\t\t\t\t\t\t.join(\"\\n\");\n\n\t\t\t\t\tconst trimmedFinalText = finalText.trim();\n\t\t\t\t\tif (!trimmedFinalText) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (trimmedFinalText === \"[SILENT]\" || trimmedFinalText.startsWith(\"[SILENT]\")) {\n\t\t\t\t\t\tthis.runState.finalOutcome = { kind: \"silent\" };\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.runState.finalOutcome.kind === \"final\" &&\n\t\t\t\t\t\tthis.runState.finalOutcome.text.trim() === trimmedFinalText\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.runState.finalOutcome = { kind: \"final\", text: finalText };\n\t\t\t\t\tlog.logResponse(logCtx, finalText);\n\t\t\t\t\tqueue.enqueue(async () => {\n\t\t\t\t\t\tconst delivered = await ctx.respondPlain(finalText);\n\t\t\t\t\t\tif (delivered) {\n\t\t\t\t\t\t\tthis.runState.finalResponseDelivered = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, \"final response\");\n\t\t\t\t}\n\t\t\t} else if (event.type === \"auto_compaction_start\") {\n\t\t\t\tlog.logInfo(`Auto-compaction started (reason: ${(event as any).reason})`);\n\t\t\t\tqueue.enqueue(\n\t\t\t\t\t() => ctx.respond(formatProgressEntry(\"assistant\", \"Compacting context...\"), false),\n\t\t\t\t\t\"compaction start\",\n\t\t\t\t);\n\t\t\t} else if (event.type === \"auto_compaction_end\") {\n\t\t\t\tconst compEvent = event as any;\n\t\t\t\tif (compEvent.result) {\n\t\t\t\t\tlog.logInfo(`Auto-compaction complete: ${compEvent.result.tokensBefore} tokens compacted`);\n\t\t\t\t} else if (compEvent.aborted) {\n\t\t\t\t\tlog.logInfo(\"Auto-compaction aborted\");\n\t\t\t\t}\n\t\t\t} else if (event.type === \"auto_retry_start\") {\n\t\t\t\tconst retryEvent = event as any;\n\t\t\t\tlog.logWarning(`Retrying (${retryEvent.attempt}/${retryEvent.maxAttempts})`, retryEvent.errorMessage);\n\t\t\t\tqueue.enqueue(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tctx.respond(\n\t\t\t\t\t\t\tformatProgressEntry(\"assistant\", `Retrying (${retryEvent.attempt}/${retryEvent.maxAttempts})...`),\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t),\n\t\t\t\t\t\"retry\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nconst channelRunners = new Map<string, AgentRunner>();\n\nexport function getOrCreateRunner(sandboxConfig: SandboxConfig, channelId: string, channelDir: string): AgentRunner {\n\tconst existing = channelRunners.get(channelId);\n\tif (existing) return existing;\n\n\tconst runner = new ChannelRunner(sandboxConfig, channelId, channelDir);\n\tchannelRunners.set(channelId, runner);\n\treturn runner;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport {\n\tAgentSession,\n\tAuthStorage,\n\tconvertToLlm,\n\tDefaultResourceLoader,\n\tModelRegistry,\n\tSessionManager,\n\ttype Skill,\n} from \"@mariozechner/pi-coding-agent\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport { join } from \"path\";\nimport { COMMAND_RESULT_CUSTOM_TYPE, createCommandExtension } from \"./command-extension.js\";\nimport { type BuiltInCommand, renderBuiltInHelp } from \"./commands.js\";\nimport { getAgentConfig, getApiKeyForModel, getSoul, loadPipiclawSkills } from \"./config-loader.js\";\nimport { PipiclawSettingsManager } from \"./context.js\";\nimport type { DingTalkContext } from \"./dingtalk.js\";\nimport * as log from \"./log.js\";\nimport { MemoryLifecycle } from \"./memory-lifecycle.js\";\nimport { resolveInitialModel } from \"./model-utils.js\";\nimport { APP_HOME_DIR, AUTH_CONFIG_PATH, MODELS_CONFIG_PATH } from \"./paths.js\";\nimport { buildAppendSystemPrompt } from \"./prompt-builder.js\";\nimport { createExecutor, type SandboxConfig } from \"./sandbox.js\";\nimport type { ChannelStore } from \"./store.js\";\nimport { createPipiclawTools } from \"./tools/index.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AgentRunner {\n\trun(ctx: DingTalkContext, store: ChannelStore): Promise<{ stopReason: string; errorMessage?: string }>;\n\thandleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void>;\n\tqueueSteer(text: string, userName?: string): Promise<void>;\n\tqueueFollowUp(text: string, userName?: string): Promise<void>;\n\tabort(): void;\n}\n\ntype FinalOutcome = { kind: \"none\" } | { kind: \"silent\" } | { kind: \"final\"; text: string };\n\nfunction isSilentOutcome(outcome: FinalOutcome): outcome is { kind: \"silent\" } {\n\treturn outcome.kind === \"silent\";\n}\n\nfunction isFinalOutcome(outcome: FinalOutcome): outcome is { kind: \"final\"; text: string } {\n\treturn outcome.kind === \"final\";\n}\n\nfunction getFinalOutcomeText(outcome: FinalOutcome): string | null {\n\treturn isFinalOutcome(outcome) ? outcome.text : null;\n}\n\n// ============================================================================\n// Text helpers\n// ============================================================================\n\nfunction truncate(text: string, maxLen: number): string {\n\tif (text.length <= maxLen) return text;\n\treturn `${text.substring(0, maxLen - 3)}...`;\n}\n\nfunction sanitizeProgressText(text: string): string {\n\treturn text\n\t\t.replace(/\\uFFFC/g, \"\")\n\t\t.replace(/\\r/g, \"\")\n\t\t.trim();\n}\n\nfunction formatProgressEntry(kind: \"tool\" | \"thinking\" | \"error\" | \"assistant\", text: string): string {\n\tconst cleaned = sanitizeProgressText(text);\n\tif (!cleaned) return \"\";\n\n\tconst normalized = cleaned.replace(/\\n+/g, \" \").trim();\n\tswitch (kind) {\n\t\tcase \"tool\":\n\t\t\treturn `Running: ${normalized}`;\n\t\tcase \"thinking\":\n\t\t\treturn `Thinking: ${normalized}`;\n\t\tcase \"error\":\n\t\t\treturn `Error: ${normalized}`;\n\t\tcase \"assistant\":\n\t\t\treturn normalized;\n\t}\n}\n\nfunction extractToolResultText(result: unknown): string {\n\tif (typeof result === \"string\") {\n\t\treturn result;\n\t}\n\n\tif (\n\t\tresult &&\n\t\ttypeof result === \"object\" &&\n\t\t\"content\" in result &&\n\t\tArray.isArray((result as { content: unknown }).content)\n\t) {\n\t\tconst content = (result as { content: Array<{ type: string; text?: string }> }).content;\n\t\tconst textParts: string[] = [];\n\t\tfor (const part of content) {\n\t\t\tif (part.type === \"text\" && part.text) {\n\t\t\t\ttextParts.push(part.text);\n\t\t\t}\n\t\t}\n\t\tif (textParts.length > 0) {\n\t\t\treturn textParts.join(\"\\n\");\n\t\t}\n\t}\n\n\treturn JSON.stringify(result);\n}\n\nfunction extractCustomCommandResultText(message: unknown): string | null {\n\tif (\n\t\t!message ||\n\t\ttypeof message !== \"object\" ||\n\t\t!(\"role\" in message) ||\n\t\t!(\"customType\" in message) ||\n\t\t(message as { role?: unknown }).role !== \"custom\" ||\n\t\t(message as { customType?: unknown }).customType !== COMMAND_RESULT_CUSTOM_TYPE\n\t) {\n\t\treturn null;\n\t}\n\n\tconst content = (message as { content?: unknown }).content;\n\treturn typeof content === \"string\" && content.trim() ? content : null;\n}\n\n// ============================================================================\n// Run State\n// ============================================================================\n\ninterface PendingTool {\n\ttoolName: string;\n\targs: unknown;\n\tstartTime: number;\n}\n\ninterface UsageTotals {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n}\n\ninterface RunQueue {\n\tenqueue(fn: () => Promise<void>, errorContext: string): void;\n\tenqueueMessage(text: string, target: \"main\" | \"thread\", errorContext: string, doLog?: boolean): void;\n}\n\ninterface RunState {\n\tctx: DingTalkContext | null;\n\tlogCtx: { channelId: string; userName?: string; channelName?: string } | null;\n\tqueue: RunQueue | null;\n\tpendingTools: Map<string, PendingTool>;\n\ttotalUsage: UsageTotals;\n\tstopReason: string;\n\terrorMessage: string | undefined;\n\tfinalOutcome: FinalOutcome;\n\tfinalResponseDelivered: boolean;\n}\n\nfunction createEmptyRunState(): RunState {\n\treturn {\n\t\tctx: null,\n\t\tlogCtx: null,\n\t\tqueue: null,\n\t\tpendingTools: new Map(),\n\t\ttotalUsage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\terrorMessage: undefined,\n\t\tfinalOutcome: { kind: \"none\" },\n\t\tfinalResponseDelivered: false,\n\t};\n}\n\n// ============================================================================\n// ChannelRunner\n// ============================================================================\n\nclass ChannelRunner implements AgentRunner {\n\t// --- Constructed once ---\n\tprivate readonly sandboxConfig: SandboxConfig;\n\tprivate readonly channelId: string;\n\tprivate readonly channelDir: string;\n\tprivate readonly workspacePath: string;\n\tprivate readonly workspaceDir: string;\n\tprivate readonly session: AgentSession;\n\tprivate readonly agent: Agent;\n\tprivate readonly sessionManager: SessionManager;\n\tprivate readonly settingsManager: PipiclawSettingsManager;\n\tprivate readonly modelRegistry: ModelRegistry;\n\tprivate readonly memoryLifecycle: MemoryLifecycle;\n\tprivate readonly sessionReady: Promise<void>;\n\n\t// --- Mutable across runs ---\n\tprivate activeModel: Model<Api>;\n\tprivate currentSkills: Skill[];\n\n\t// --- Per run ---\n\tprivate runState: RunState = createEmptyRunState();\n\n\tconstructor(sandboxConfig: SandboxConfig, channelId: string, channelDir: string) {\n\t\tthis.sandboxConfig = sandboxConfig;\n\t\tthis.channelId = channelId;\n\t\tthis.channelDir = channelDir;\n\n\t\tconst executor = createExecutor(sandboxConfig);\n\t\tthis.workspacePath = executor.getWorkspacePath(channelDir.replace(`/${channelId}`, \"\"));\n\t\tthis.workspaceDir = join(channelDir, \"..\");\n\n\t\t// Create tools\n\t\tconst tools = createPipiclawTools(executor);\n\n\t\t// Initial skill summaries\n\t\tconst initialSkills = loadPipiclawSkills(channelDir, this.workspacePath);\n\t\tthis.currentSkills = initialSkills;\n\n\t\t// Create session manager\n\t\tconst contextFile = join(channelDir, \"context.jsonl\");\n\t\tthis.sessionManager = SessionManager.open(contextFile, channelDir);\n\t\tthis.settingsManager = new PipiclawSettingsManager(APP_HOME_DIR);\n\n\t\t// Create AuthStorage and ModelRegistry\n\t\tconst authStorage = AuthStorage.create(AUTH_CONFIG_PATH);\n\t\tthis.modelRegistry = new ModelRegistry(authStorage, MODELS_CONFIG_PATH);\n\n\t\t// Resolve model: prefer saved global default, fall back to first available model\n\t\tthis.activeModel = resolveInitialModel(this.modelRegistry, this.settingsManager);\n\t\tlog.logInfo(`Using model: ${this.activeModel.provider}/${this.activeModel.id} (${this.activeModel.name})`);\n\n\t\t// Create agent\n\t\tthis.agent = new Agent({\n\t\t\tinitialState: {\n\t\t\t\tsystemPrompt: \"\",\n\t\t\t\tmodel: this.activeModel,\n\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\ttools,\n\t\t\t},\n\t\t\tconvertToLlm,\n\t\t\tgetApiKey: async () => getApiKeyForModel(this.modelRegistry, this.activeModel),\n\t\t});\n\n\t\tthis.memoryLifecycle = new MemoryLifecycle({\n\t\t\tchannelId: this.channelId,\n\t\t\tchannelDir: this.channelDir,\n\t\t\tgetMessages: () => this.session.messages,\n\t\t\tgetSessionEntries: () => this.sessionManager.getBranch(),\n\t\t\tgetModel: () => this.session.model ?? this.activeModel,\n\t\t\tresolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),\n\t\t});\n\n\t\tconst resourceLoader = new DefaultResourceLoader({\n\t\t\tcwd: process.cwd(),\n\t\t\tagentDir: APP_HOME_DIR,\n\t\t\tsettingsManager: this.settingsManager as any,\n\t\t\textensionFactories: [\n\t\t\t\tthis.memoryLifecycle.createExtensionFactory(),\n\t\t\t\tcreateCommandExtension({\n\t\t\t\t\tgetCurrentModel: () => this.session.model ?? this.activeModel,\n\t\t\t\t\tgetAvailableModels: async () => {\n\t\t\t\t\t\tthis.modelRegistry.refresh();\n\t\t\t\t\t\treturn await this.modelRegistry.getAvailable();\n\t\t\t\t\t},\n\t\t\t\t\tgetSessionStats: () => this.session.getSessionStats(),\n\t\t\t\t\tgetThinkingLevel: () => this.session.thinkingLevel,\n\t\t\t\t\tswitchModel: async (model) => {\n\t\t\t\t\t\tawait this.session.setModel(model);\n\t\t\t\t\t\tthis.activeModel = model;\n\t\t\t\t\t},\n\t\t\t\t\trefreshSessionResources: async () => {\n\t\t\t\t\t\tawait this.refreshSessionResources();\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t],\n\t\t\tappendSystemPromptOverride: (base) => {\n\t\t\t\tconst soul = getSoul(this.workspaceDir);\n\t\t\t\tconst sections = [...base];\n\t\t\t\tif (soul) {\n\t\t\t\t\tsections.unshift(soul);\n\t\t\t\t}\n\t\t\t\tsections.push(buildAppendSystemPrompt(this.workspacePath, this.channelId, this.sandboxConfig));\n\t\t\t\treturn sections;\n\t\t\t},\n\t\t\tagentsFilesOverride: () => {\n\t\t\t\tconst agentConfig = getAgentConfig(this.channelDir);\n\t\t\t\treturn {\n\t\t\t\t\tagentsFiles: agentConfig ? [{ path: `${this.workspacePath}/AGENTS.md`, content: agentConfig }] : [],\n\t\t\t\t};\n\t\t\t},\n\t\t\tskillsOverride: (base) => ({\n\t\t\t\tskills: [...base.skills, ...this.currentSkills],\n\t\t\t\tdiagnostics: base.diagnostics,\n\t\t\t}),\n\t\t});\n\n\t\tconst baseToolsOverride = Object.fromEntries(tools.map((tool) => [tool.name, tool]));\n\n\t\t// Create AgentSession\n\t\tthis.session = new AgentSession({\n\t\t\tagent: this.agent,\n\t\t\tsessionManager: this.sessionManager,\n\t\t\tsettingsManager: this.settingsManager as any,\n\t\t\tcwd: process.cwd(),\n\t\t\tmodelRegistry: this.modelRegistry,\n\t\t\tresourceLoader,\n\t\t\tbaseToolsOverride,\n\t\t});\n\n\t\t// Subscribe to session events\n\t\tthis.subscribeToSessionEvents();\n\t\tthis.sessionReady = this.initializeSession();\n\t}\n\n\t// === Public API ===\n\n\tasync run(ctx: DingTalkContext, _store: ChannelStore): Promise<{ stopReason: string; errorMessage?: string }> {\n\t\tthis.resetRunState(ctx);\n\n\t\t// Create queue for this run\n\t\tlet queueChain = Promise.resolve();\n\t\tthis.runState.queue = {\n\t\t\tenqueue: (fn: () => Promise<void>, errorContext: string): void => {\n\t\t\t\tqueueChain = queueChain.then(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait fn();\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(`DingTalk API error (${errorContext})`, errMsg);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tenqueueMessage: function (text: string, target: \"main\" | \"thread\", errorContext: string, doLog = true): void {\n\t\t\t\tthis.enqueue(\n\t\t\t\t\t() => (target === \"main\" ? ctx.respond(text, doLog) : ctx.respondInThread(text)),\n\t\t\t\t\terrorContext,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.ensureSessionReady();\n\n\t\t\t// Ensure channel directory exists\n\t\t\tawait mkdir(this.channelDir, { recursive: true });\n\n\t\t\tconst userMessage = this.formatUserMessage(ctx.message.text, ctx.message.userName);\n\t\t\tconst promptText = this.shouldPreserveRawInput(ctx.message.text) ? ctx.message.text.trim() : userMessage;\n\n\t\t\t// Debug: write context to last_prompt.json (only with PIPICLAW_DEBUG=1)\n\t\t\tif (process.env.PIPICLAW_DEBUG) {\n\t\t\t\tconst debugContext = {\n\t\t\t\t\tsystemPrompt: this.agent.state.systemPrompt,\n\t\t\t\t\tmessages: this.session.messages,\n\t\t\t\t\tnewUserMessage: promptText,\n\t\t\t\t};\n\t\t\t\tawait writeFile(join(this.channelDir, \"last_prompt.json\"), JSON.stringify(debugContext, null, 2));\n\t\t\t}\n\n\t\t\tawait this.session.prompt(promptText);\n\t\t} catch (err) {\n\t\t\tthis.runState.stopReason = \"error\";\n\t\t\tthis.runState.errorMessage = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${this.channelId}] Runner failed`, this.runState.errorMessage);\n\t\t} finally {\n\t\t\tawait queueChain;\n\t\t\tconst finalOutcome = this.runState.finalOutcome;\n\t\t\tconst finalOutcomeText = getFinalOutcomeText(finalOutcome);\n\n\t\t\ttry {\n\t\t\t\tif (\n\t\t\t\t\tthis.runState.stopReason === \"error\" &&\n\t\t\t\t\tthis.runState.errorMessage &&\n\t\t\t\t\t!this.runState.finalResponseDelivered\n\t\t\t\t) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ctx.replaceMessage(\"_Sorry, something went wrong_\");\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(\"Failed to post error message\", errMsg);\n\t\t\t\t\t}\n\t\t\t\t} else if (isSilentOutcome(finalOutcome)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ctx.deleteMessage();\n\t\t\t\t\t\tlog.logInfo(\"Silent response - deleted message\");\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(\"Failed to delete message for silent response\", errMsg);\n\t\t\t\t\t}\n\t\t\t\t} else if (finalOutcomeText && !this.runState.finalResponseDelivered) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ctx.replaceMessage(finalOutcomeText);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tlog.logWarning(\"Failed to replace message with final text\", errMsg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tawait ctx.flush();\n\t\t\t} finally {\n\t\t\t\tawait ctx.close();\n\t\t\t}\n\n\t\t\t// Log usage summary\n\t\t\tif (this.runState.totalUsage.cost.total > 0) {\n\t\t\t\tconst messages = this.session.messages;\n\t\t\t\tconst lastAssistantMessage = messages\n\t\t\t\t\t.slice()\n\t\t\t\t\t.reverse()\n\t\t\t\t\t.find((m: any) => m.role === \"assistant\" && m.stopReason !== \"aborted\") as any;\n\n\t\t\t\tconst contextTokens = lastAssistantMessage\n\t\t\t\t\t? lastAssistantMessage.usage.input +\n\t\t\t\t\t\tlastAssistantMessage.usage.output +\n\t\t\t\t\t\tlastAssistantMessage.usage.cacheRead +\n\t\t\t\t\t\tlastAssistantMessage.usage.cacheWrite\n\t\t\t\t\t: 0;\n\t\t\t\tconst currentRunModel = this.session.model ?? this.activeModel;\n\t\t\t\tconst contextWindow = currentRunModel.contextWindow || 200000;\n\n\t\t\t\tlog.logUsageSummary(this.runState.logCtx!, this.runState.totalUsage, contextTokens, contextWindow);\n\t\t\t}\n\n\t\t\t// Clear run state\n\t\t\tthis.runState.ctx = null;\n\t\t\tthis.runState.logCtx = null;\n\t\t\tthis.runState.queue = null;\n\t\t}\n\n\t\treturn { stopReason: this.runState.stopReason, errorMessage: this.runState.errorMessage };\n\t}\n\n\tasync handleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void> {\n\t\ttry {\n\t\t\tswitch (command.name) {\n\t\t\t\tcase \"help\":\n\t\t\t\t\tawait this.sendCommandReply(ctx, renderBuiltInHelp());\n\t\t\t\t\treturn;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\tawait this.sendCommandReply(ctx, \"No task is running. Use `/stop` only while a task is running.\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"steer\":\n\t\t\t\t\tthis.requireQueuedMessage(command.args, \"steer\");\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"No task is running. Send the message directly instead of using `/steer`.\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"followup\":\n\t\t\t\t\tthis.requireQueuedMessage(command.args, \"followup\");\n\t\t\t\t\tawait this.sendCommandReply(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"No task is running. Send the message directly now, or use `/followup` while a task is running.\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${this.channelId}] Built-in command failed`, errMsg);\n\t\t\tawait this.sendCommandReply(ctx, `命令执行失败:${errMsg}`);\n\t\t}\n\t}\n\n\tasync queueSteer(text: string, userName?: string): Promise<void> {\n\t\tawait this.queueBusyMessage(\"steer\", this.requireQueuedMessage(text, \"steer\"), userName);\n\t}\n\n\tasync queueFollowUp(text: string, userName?: string): Promise<void> {\n\t\tawait this.queueBusyMessage(\"followUp\", this.requireQueuedMessage(text, \"followup\"), userName);\n\t}\n\n\tabort(): void {\n\t\tthis.session.abort();\n\t}\n\n\t// === Private helpers ===\n\n\tprivate async sendCommandReply(ctx: DingTalkContext, text: string): Promise<void> {\n\t\tconst delivered = await ctx.respondPlain(text);\n\t\tif (!delivered) {\n\t\t\tawait ctx.replaceMessage(text);\n\t\t\tawait ctx.flush();\n\t\t}\n\t}\n\n\tprivate requireQueuedMessage(text: string, commandName: \"steer\" | \"followup\"): string {\n\t\tconst trimmedText = text.trim();\n\t\tif (!trimmedText) {\n\t\t\tthrow new Error(`/${commandName} requires a message.`);\n\t\t}\n\t\treturn trimmedText;\n\t}\n\n\tprivate shouldPreserveRawInput(text: string): boolean {\n\t\treturn text.trim().startsWith(\"/\");\n\t}\n\n\tprivate formatUserMessage(text: string, userName?: string, now: Date = new Date()): string {\n\t\tconst pad = (n: number) => n.toString().padStart(2, \"0\");\n\t\tconst offset = -now.getTimezoneOffset();\n\t\tconst offsetSign = offset >= 0 ? \"+\" : \"-\";\n\t\tconst offsetHours = pad(Math.floor(Math.abs(offset) / 60));\n\t\tconst offsetMins = pad(Math.abs(offset) % 60);\n\t\tconst timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${offsetSign}${offsetHours}:${offsetMins}`;\n\t\treturn `[${timestamp}] [${userName || \"unknown\"}]: ${text}`;\n\t}\n\n\tprivate async queueBusyMessage(delivery: \"steer\" | \"followUp\", text: string, userName?: string): Promise<void> {\n\t\tif (!this.session.isStreaming) {\n\t\t\tthrow new Error(\"No task is currently running.\");\n\t\t}\n\n\t\tawait this.session.prompt(this.formatUserMessage(text, userName), {\n\t\t\tstreamingBehavior: delivery,\n\t\t});\n\t}\n\n\tprivate resetRunState(ctx: DingTalkContext): void {\n\t\tthis.runState = createEmptyRunState();\n\t\tthis.runState.ctx = ctx;\n\t\tthis.runState.logCtx = {\n\t\t\tchannelId: ctx.message.channel,\n\t\t\tuserName: ctx.message.userName,\n\t\t\tchannelName: ctx.channelName,\n\t\t};\n\t}\n\n\tprivate async refreshSessionResources(): Promise<void> {\n\t\tawait this.ensureSessionReady();\n\t\tconst skills = loadPipiclawSkills(this.channelDir, this.workspacePath);\n\t\tthis.currentSkills = skills;\n\t\tawait this.session.reload();\n\t}\n\n\tprivate async initializeSession(): Promise<void> {\n\t\tconst skills = loadPipiclawSkills(this.channelDir, this.workspacePath);\n\t\tthis.currentSkills = skills;\n\t\tawait this.session.reload();\n\t}\n\n\tprivate async ensureSessionReady(): Promise<void> {\n\t\tawait this.sessionReady;\n\t}\n\n\t// === Session event subscription ===\n\n\tprivate subscribeToSessionEvents(): void {\n\t\tthis.session.subscribe(async (event: any) => {\n\t\t\tif (!this.runState.ctx || !this.runState.logCtx || !this.runState.queue) return;\n\n\t\t\tconst { ctx, logCtx, queue, pendingTools } = this.runState;\n\n\t\t\tif (event.type === \"tool_execution_start\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"tool_execution_start\" };\n\t\t\t\tconst args = agentEvent.args as { label?: string };\n\t\t\t\tconst label = args.label || agentEvent.toolName;\n\n\t\t\t\tpendingTools.set(agentEvent.toolCallId, {\n\t\t\t\t\ttoolName: agentEvent.toolName,\n\t\t\t\t\targs: agentEvent.args,\n\t\t\t\t\tstartTime: Date.now(),\n\t\t\t\t});\n\n\t\t\t\tlog.logToolStart(logCtx, agentEvent.toolName, label, agentEvent.args as Record<string, unknown>);\n\t\t\t\tqueue.enqueue(() => ctx.respond(formatProgressEntry(\"tool\", label), false), \"tool label\");\n\t\t\t} else if (event.type === \"tool_execution_end\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"tool_execution_end\" };\n\t\t\t\tconst resultStr = extractToolResultText(agentEvent.result);\n\t\t\t\tconst pending = pendingTools.get(agentEvent.toolCallId);\n\t\t\t\tpendingTools.delete(agentEvent.toolCallId);\n\n\t\t\t\tconst durationMs = pending ? Date.now() - pending.startTime : 0;\n\n\t\t\t\tif (agentEvent.isError) {\n\t\t\t\t\tlog.logToolError(logCtx, agentEvent.toolName, durationMs, resultStr);\n\t\t\t\t} else {\n\t\t\t\t\tlog.logToolSuccess(logCtx, agentEvent.toolName, durationMs, resultStr);\n\t\t\t\t}\n\n\t\t\t\tif (agentEvent.isError) {\n\t\t\t\t\tqueue.enqueue(\n\t\t\t\t\t\t() => ctx.respond(formatProgressEntry(\"error\", truncate(resultStr, 200)), false),\n\t\t\t\t\t\t\"tool error\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (event.type === \"message_start\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"message_start\" };\n\t\t\t\tif (agentEvent.message.role === \"assistant\") {\n\t\t\t\t\tlog.logResponseStart(logCtx);\n\t\t\t\t}\n\t\t\t} else if (event.type === \"message_end\") {\n\t\t\t\tconst agentEvent = event as any & { type: \"message_end\" };\n\t\t\t\tconst commandResultText = extractCustomCommandResultText(agentEvent.message);\n\t\t\t\tif (commandResultText) {\n\t\t\t\t\tthis.runState.finalOutcome = { kind: \"final\", text: commandResultText };\n\t\t\t\t\tlog.logResponse(logCtx, commandResultText);\n\t\t\t\t\tqueue.enqueue(async () => {\n\t\t\t\t\t\tconst delivered = await ctx.respondPlain(commandResultText);\n\t\t\t\t\t\tif (!delivered) {\n\t\t\t\t\t\t\tawait ctx.replaceMessage(commandResultText);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.runState.finalResponseDelivered = true;\n\t\t\t\t\t}, \"command result\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (agentEvent.message.role === \"assistant\") {\n\t\t\t\t\tconst assistantMsg = agentEvent.message as any;\n\n\t\t\t\t\tif (assistantMsg.stopReason) {\n\t\t\t\t\t\tthis.runState.stopReason = assistantMsg.stopReason;\n\t\t\t\t\t}\n\t\t\t\t\tif (assistantMsg.errorMessage) {\n\t\t\t\t\t\tthis.runState.errorMessage = assistantMsg.errorMessage;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (assistantMsg.usage) {\n\t\t\t\t\t\tthis.runState.totalUsage.input += assistantMsg.usage.input;\n\t\t\t\t\t\tthis.runState.totalUsage.output += assistantMsg.usage.output;\n\t\t\t\t\t\tthis.runState.totalUsage.cacheRead += assistantMsg.usage.cacheRead;\n\t\t\t\t\t\tthis.runState.totalUsage.cacheWrite += assistantMsg.usage.cacheWrite;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.input += assistantMsg.usage.cost.input;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.output += assistantMsg.usage.cost.output;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.cacheRead += assistantMsg.usage.cost.cacheRead;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.cacheWrite += assistantMsg.usage.cost.cacheWrite;\n\t\t\t\t\t\tthis.runState.totalUsage.cost.total += assistantMsg.usage.cost.total;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst content = agentEvent.message.content;\n\t\t\t\t\tconst thinkingParts: string[] = [];\n\t\t\t\t\tconst textParts: string[] = [];\n\t\t\t\t\tlet hasToolCalls = false;\n\t\t\t\t\tfor (const part of content) {\n\t\t\t\t\t\tif (part.type === \"thinking\") {\n\t\t\t\t\t\t\tthinkingParts.push((part as any).thinking);\n\t\t\t\t\t\t} else if (part.type === \"text\") {\n\t\t\t\t\t\t\ttextParts.push((part as any).text);\n\t\t\t\t\t\t} else if (part.type === \"toolCall\") {\n\t\t\t\t\t\t\thasToolCalls = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst text = textParts.join(\"\\n\");\n\n\t\t\t\t\tfor (const thinking of thinkingParts) {\n\t\t\t\t\t\tlog.logThinking(logCtx, thinking);\n\t\t\t\t\t\tqueue.enqueue(() => ctx.respond(formatProgressEntry(\"thinking\", thinking), false), \"thinking\");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (hasToolCalls && text.trim()) {\n\t\t\t\t\t\tqueue.enqueue(() => ctx.respond(formatProgressEntry(\"assistant\", text), false), \"assistant progress\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (event.type === \"turn_end\") {\n\t\t\t\tconst turnEvent = event as any & {\n\t\t\t\t\ttype: \"turn_end\";\n\t\t\t\t\tmessage: { role: string; stopReason?: string; content: Array<{ type: string; text?: string }> };\n\t\t\t\t\ttoolResults: unknown[];\n\t\t\t\t};\n\t\t\t\tif (turnEvent.message.role === \"assistant\" && turnEvent.toolResults.length === 0) {\n\t\t\t\t\tif (turnEvent.message.stopReason === \"error\" || turnEvent.message.stopReason === \"aborted\") {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst finalContent = turnEvent.message.content as Array<{ type: string; text?: string }>;\n\t\t\t\t\tconst finalText = finalContent\n\t\t\t\t\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\" && !!part.text)\n\t\t\t\t\t\t.map((part) => part.text)\n\t\t\t\t\t\t.join(\"\\n\");\n\n\t\t\t\t\tconst trimmedFinalText = finalText.trim();\n\t\t\t\t\tif (!trimmedFinalText) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (trimmedFinalText === \"[SILENT]\" || trimmedFinalText.startsWith(\"[SILENT]\")) {\n\t\t\t\t\t\tthis.runState.finalOutcome = { kind: \"silent\" };\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.runState.finalOutcome.kind === \"final\" &&\n\t\t\t\t\t\tthis.runState.finalOutcome.text.trim() === trimmedFinalText\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.runState.finalOutcome = { kind: \"final\", text: finalText };\n\t\t\t\t\tlog.logResponse(logCtx, finalText);\n\t\t\t\t\tqueue.enqueue(async () => {\n\t\t\t\t\t\tconst delivered = await ctx.respondPlain(finalText);\n\t\t\t\t\t\tif (delivered) {\n\t\t\t\t\t\t\tthis.runState.finalResponseDelivered = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, \"final response\");\n\t\t\t\t}\n\t\t\t} else if (event.type === \"auto_compaction_start\") {\n\t\t\t\tlog.logInfo(`Auto-compaction started (reason: ${(event as any).reason})`);\n\t\t\t\tqueue.enqueue(\n\t\t\t\t\t() => ctx.respond(formatProgressEntry(\"assistant\", \"Compacting context...\"), false),\n\t\t\t\t\t\"compaction start\",\n\t\t\t\t);\n\t\t\t} else if (event.type === \"auto_compaction_end\") {\n\t\t\t\tconst compEvent = event as any;\n\t\t\t\tif (compEvent.result) {\n\t\t\t\t\tlog.logInfo(`Auto-compaction complete: ${compEvent.result.tokensBefore} tokens compacted`);\n\t\t\t\t} else if (compEvent.aborted) {\n\t\t\t\t\tlog.logInfo(\"Auto-compaction aborted\");\n\t\t\t\t}\n\t\t\t} else if (event.type === \"auto_retry_start\") {\n\t\t\t\tconst retryEvent = event as any;\n\t\t\t\tlog.logWarning(`Retrying (${retryEvent.attempt}/${retryEvent.maxAttempts})`, retryEvent.errorMessage);\n\t\t\t\tqueue.enqueue(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tctx.respond(\n\t\t\t\t\t\t\tformatProgressEntry(\"assistant\", `Retrying (${retryEvent.attempt}/${retryEvent.maxAttempts})...`),\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t),\n\t\t\t\t\t\"retry\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nconst channelRunners = new Map<string, AgentRunner>();\n\nexport function getOrCreateRunner(sandboxConfig: SandboxConfig, channelId: string, channelDir: string): AgentRunner {\n\tconst existing = channelRunners.get(channelId);\n\tif (existing) return existing;\n\n\tconst runner = new ChannelRunner(sandboxConfig, channelId, channelDir);\n\tchannelRunners.set(channelId, runner);\n\treturn runner;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ThinkingLevel } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
3
|
+
import type { ExtensionFactory, SessionStats } from "@mariozechner/pi-coding-agent";
|
|
4
|
+
export declare const COMMAND_RESULT_CUSTOM_TYPE = "pipiclaw.command_result";
|
|
5
|
+
export interface PipiclawCommandExtensionOptions {
|
|
6
|
+
getCurrentModel: () => Model<Api> | undefined;
|
|
7
|
+
getAvailableModels: () => Promise<Model<Api>[]>;
|
|
8
|
+
getSessionStats: () => SessionStats;
|
|
9
|
+
getThinkingLevel: () => ThinkingLevel;
|
|
10
|
+
switchModel: (model: Model<Api>) => Promise<void>;
|
|
11
|
+
refreshSessionResources: () => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createCommandExtension(options: PipiclawCommandExtensionOptions): ExtensionFactory;
|
|
14
|
+
//# sourceMappingURL=command-extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-extension.d.ts","sourceRoot":"","sources":["../src/command-extension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAIX,gBAAgB,EAChB,YAAY,EACZ,MAAM,+BAA+B,CAAC;AAIvC,eAAO,MAAM,0BAA0B,4BAA4B,CAAC;AAEpE,MAAM,WAAW,+BAA+B;IAC/C,eAAe,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9C,kBAAkB,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChD,eAAe,EAAE,MAAM,YAAY,CAAC;IACpC,gBAAgB,EAAE,MAAM,aAAa,CAAC;IACtC,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,uBAAuB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AA6CD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,+BAA+B,GAAG,gBAAgB,CAsGjG","sourcesContent":["import type { ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport type {\n\tCompactionResult,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionFactory,\n\tSessionStats,\n} from \"@mariozechner/pi-coding-agent\";\nimport { basename } from \"path\";\nimport { findExactModelReferenceMatch, formatModelList, formatModelReference } from \"./model-utils.js\";\n\nexport const COMMAND_RESULT_CUSTOM_TYPE = \"pipiclaw.command_result\";\n\nexport interface PipiclawCommandExtensionOptions {\n\tgetCurrentModel: () => Model<Api> | undefined;\n\tgetAvailableModels: () => Promise<Model<Api>[]>;\n\tgetSessionStats: () => SessionStats;\n\tgetThinkingLevel: () => ThinkingLevel;\n\tswitchModel: (model: Model<Api>) => Promise<void>;\n\trefreshSessionResources: () => Promise<void>;\n}\n\nfunction buildSessionText(\n\tstats: SessionStats,\n\tcurrentModel: Model<Api> | undefined,\n\tthinkingLevel: ThinkingLevel,\n): string {\n\tconst modelText = currentModel ? `\\`${formatModelReference(currentModel)}\\`` : \"(none)\";\n\tconst sessionFile = stats.sessionFile ? `\\`${basename(stats.sessionFile)}\\`` : \"(none)\";\n\treturn `# Session\n\n- Session ID: \\`${stats.sessionId}\\`\n- Session file: ${sessionFile}\n- Model: ${modelText}\n- Thinking level: \\`${thinkingLevel}\\`\n- User messages: \\`${stats.userMessages}\\`\n- Assistant messages: \\`${stats.assistantMessages}\\`\n- Tool calls: \\`${stats.toolCalls}\\`\n- Tool results: \\`${stats.toolResults}\\`\n- Total messages: \\`${stats.totalMessages}\\`\n- Tokens: \\`${stats.tokens.total}\\` (input \\`${stats.tokens.input}\\`, output \\`${stats.tokens.output}\\`, cache read \\`${stats.tokens.cacheRead}\\`, cache write \\`${stats.tokens.cacheWrite}\\`)\n- Cost: \\`$${stats.cost.toFixed(4)}\\``;\n}\n\nasync function runCompact(\n\tctx: ExtensionCommandContext,\n\tcustomInstructions: string | undefined,\n): Promise<CompactionResult> {\n\treturn await new Promise<CompactionResult>((resolve, reject) => {\n\t\tctx.compact({\n\t\t\tcustomInstructions,\n\t\t\tonComplete: resolve,\n\t\t\tonError: reject,\n\t\t});\n\t});\n}\n\nfunction sendCommandResult(pi: Pick<ExtensionAPI, \"sendMessage\">, text: string): void {\n\tpi.sendMessage({\n\t\tcustomType: COMMAND_RESULT_CUSTOM_TYPE,\n\t\tcontent: text,\n\t\tdisplay: true,\n\t});\n}\n\nexport function createCommandExtension(options: PipiclawCommandExtensionOptions): ExtensionFactory {\n\treturn (pi) => {\n\t\tpi.registerCommand(\"session\", {\n\t\t\tdescription: \"Show current session state, usage, and model info\",\n\t\t\thandler: async () => {\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\tbuildSessionText(options.getSessionStats(), options.getCurrentModel(), options.getThinkingLevel()),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tpi.registerCommand(\"model\", {\n\t\t\tdescription: \"Show the current model or switch models using an exact match\",\n\t\t\thandler: async (args) => {\n\t\t\t\tconst availableModels = await options.getAvailableModels();\n\t\t\t\tconst currentModel = options.getCurrentModel();\n\n\t\t\t\tif (!args.trim()) {\n\t\t\t\t\tconst current = currentModel ? `\\`${formatModelReference(currentModel)}\\`` : \"(none)\";\n\t\t\t\t\tconst available =\n\t\t\t\t\t\tavailableModels.length > 0 ? formatModelList(availableModels, currentModel) : \"- (none)\";\n\t\t\t\t\tsendCommandResult(\n\t\t\t\t\t\tpi,\n\t\t\t\t\t\t`# Model\n\nCurrent model: ${current}\n\nUse \\`/model <provider/modelId>\\` or \\`/model <modelId>\\` to switch. Bare model IDs must resolve uniquely.\n\nAvailable models:\n${available}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst match = findExactModelReferenceMatch(args, availableModels);\n\t\t\t\tconst available =\n\t\t\t\t\tavailableModels.length > 0 ? formatModelList(availableModels, currentModel, 10) : \"- (none)\";\n\n\t\t\t\tif (match.match) {\n\t\t\t\t\tawait options.switchModel(match.match);\n\t\t\t\t\tsendCommandResult(pi, `已切换模型到 \\`${formatModelReference(match.match)}\\`.`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (match.ambiguous) {\n\t\t\t\t\tsendCommandResult(\n\t\t\t\t\t\tpi,\n\t\t\t\t\t\t`未切换模型:\\`${args.trim()}\\` 匹配到多个模型。请改用精确的 \\`provider/modelId\\` 形式。\n\nAvailable models:\n${available}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\t`未找到模型 \\`${args.trim()}\\`。请使用精确的 \\`provider/modelId\\` 或唯一的 \\`modelId\\`。\n\nAvailable models:\n${available}`,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tpi.registerCommand(\"new\", {\n\t\t\tdescription: \"Start a new session\",\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tconst result = await ctx.newSession();\n\t\t\t\tif (!result.cancelled) {\n\t\t\t\t\tawait options.refreshSessionResources();\n\t\t\t\t}\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\tresult.cancelled\n\t\t\t\t\t\t? \"新会话已取消。\"\n\t\t\t\t\t\t: `已开启新会话。\\n\\nSession ID: \\`${ctx.sessionManager.getSessionId()}\\``,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tpi.registerCommand(\"compact\", {\n\t\t\tdescription: \"Manually compact the current session context\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tconst customInstructions = args.trim() || undefined;\n\t\t\t\tconst result = await runCompact(ctx, customInstructions);\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\t`已压缩当前会话上下文。\n\n- Tokens before compaction: \\`${result.tokensBefore}\\`\n- Summary:\n\n\\`\\`\\`text\n${result.summary}\n\\`\\`\\``,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|