@oyasmi/pipiclaw 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/dist/agent/channel-runner.d.ts +46 -0
  2. package/dist/agent/channel-runner.d.ts.map +1 -0
  3. package/dist/agent/channel-runner.js +434 -0
  4. package/dist/agent/channel-runner.js.map +1 -0
  5. package/dist/agent/index.d.ts +4 -0
  6. package/dist/agent/index.d.ts.map +1 -0
  7. package/dist/agent/index.js +3 -0
  8. package/dist/agent/index.js.map +1 -0
  9. package/dist/agent/progress-formatter.d.ts +5 -0
  10. package/dist/agent/progress-formatter.d.ts.map +1 -0
  11. package/dist/agent/progress-formatter.js +53 -0
  12. package/dist/agent/progress-formatter.js.map +1 -0
  13. package/dist/agent/run-queue.d.ts +8 -0
  14. package/dist/agent/run-queue.d.ts.map +1 -0
  15. package/dist/agent/run-queue.js +27 -0
  16. package/dist/agent/run-queue.js.map +1 -0
  17. package/dist/agent/runner-factory.d.ts +4 -0
  18. package/dist/agent/runner-factory.d.ts.map +1 -0
  19. package/dist/agent/runner-factory.js +11 -0
  20. package/dist/agent/runner-factory.js.map +1 -0
  21. package/dist/agent/session-events.d.ts +15 -0
  22. package/dist/agent/session-events.d.ts.map +1 -0
  23. package/dist/agent/session-events.js +216 -0
  24. package/dist/agent/session-events.js.map +1 -0
  25. package/dist/agent/type-guards.d.ts +23 -0
  26. package/dist/agent/type-guards.d.ts.map +1 -0
  27. package/dist/agent/type-guards.js +107 -0
  28. package/dist/agent/type-guards.js.map +1 -0
  29. package/dist/agent/types.d.ts +161 -0
  30. package/dist/agent/types.d.ts.map +1 -0
  31. package/dist/agent/types.js +23 -0
  32. package/dist/agent/types.js.map +1 -0
  33. package/dist/agent.d.ts +2 -15
  34. package/dist/agent.d.ts.map +1 -1
  35. package/dist/agent.js +1 -781
  36. package/dist/agent.js.map +1 -1
  37. package/dist/context.d.ts +58 -14
  38. package/dist/context.d.ts.map +1 -1
  39. package/dist/context.js +50 -7
  40. package/dist/context.js.map +1 -1
  41. package/dist/index.d.ts +12 -12
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +12 -12
  44. package/dist/index.js.map +1 -1
  45. package/dist/main.js +5 -404
  46. package/dist/main.js.map +1 -1
  47. package/dist/memory/bootstrap.d.ts +7 -0
  48. package/dist/memory/bootstrap.d.ts.map +1 -0
  49. package/dist/memory/bootstrap.js +47 -0
  50. package/dist/memory/bootstrap.js.map +1 -0
  51. package/dist/{memory-candidates.d.ts → memory/candidates.d.ts} +2 -1
  52. package/dist/memory/candidates.d.ts.map +1 -0
  53. package/dist/{memory-candidates.js → memory/candidates.js} +34 -21
  54. package/dist/memory/candidates.js.map +1 -0
  55. package/dist/memory/chinese-words.d.ts +2 -0
  56. package/dist/memory/chinese-words.d.ts.map +1 -0
  57. package/dist/memory/chinese-words.js +210 -0
  58. package/dist/memory/chinese-words.js.map +1 -0
  59. package/dist/{memory-consolidation.d.ts → memory/consolidation.d.ts} +1 -1
  60. package/dist/memory/consolidation.d.ts.map +1 -0
  61. package/dist/{memory-consolidation.js → memory/consolidation.js} +27 -35
  62. package/dist/memory/consolidation.js.map +1 -0
  63. package/dist/{memory-files.d.ts → memory/files.d.ts} +1 -6
  64. package/dist/memory/files.d.ts.map +1 -0
  65. package/dist/{memory-files.js → memory/files.js} +12 -36
  66. package/dist/memory/files.js.map +1 -0
  67. package/dist/{memory-lifecycle.d.ts → memory/lifecycle.d.ts} +24 -6
  68. package/dist/memory/lifecycle.d.ts.map +1 -0
  69. package/dist/memory/lifecycle.js +247 -0
  70. package/dist/memory/lifecycle.js.map +1 -0
  71. package/dist/{memory-recall.d.ts → memory/recall.d.ts} +2 -2
  72. package/dist/memory/recall.d.ts.map +1 -0
  73. package/dist/memory/recall.js +435 -0
  74. package/dist/memory/recall.js.map +1 -0
  75. package/dist/{session-memory.d.ts → memory/session.d.ts} +2 -1
  76. package/dist/memory/session.d.ts.map +1 -0
  77. package/dist/{session-memory.js → memory/session.js} +32 -62
  78. package/dist/memory/session.js.map +1 -0
  79. package/dist/runtime/bootstrap.d.ts +48 -0
  80. package/dist/runtime/bootstrap.d.ts.map +1 -0
  81. package/dist/runtime/bootstrap.js +451 -0
  82. package/dist/runtime/bootstrap.js.map +1 -0
  83. package/dist/runtime/delivery.d.ts.map +1 -0
  84. package/dist/{delivery.js → runtime/delivery.js} +1 -1
  85. package/dist/runtime/delivery.js.map +1 -0
  86. package/dist/{dingtalk.d.ts → runtime/dingtalk.d.ts} +10 -0
  87. package/dist/runtime/dingtalk.d.ts.map +1 -0
  88. package/dist/{dingtalk.js → runtime/dingtalk.js} +87 -27
  89. package/dist/runtime/dingtalk.js.map +1 -0
  90. package/dist/runtime/events.d.ts.map +1 -0
  91. package/dist/{events.js → runtime/events.js} +1 -1
  92. package/dist/runtime/events.js.map +1 -0
  93. package/dist/{store.d.ts → runtime/store.d.ts} +5 -0
  94. package/dist/runtime/store.d.ts.map +1 -0
  95. package/dist/{store.js → runtime/store.js} +60 -19
  96. package/dist/runtime/store.js.map +1 -0
  97. package/dist/shared/markdown-sections.d.ts +7 -0
  98. package/dist/shared/markdown-sections.d.ts.map +1 -0
  99. package/dist/{markdown-sections.js → shared/markdown-sections.js} +10 -3
  100. package/dist/shared/markdown-sections.js.map +1 -0
  101. package/dist/shared/text-utils.d.ts +10 -0
  102. package/dist/shared/text-utils.d.ts.map +1 -0
  103. package/dist/shared/text-utils.js +37 -0
  104. package/dist/shared/text-utils.js.map +1 -0
  105. package/dist/shared/type-guards.d.ts +6 -0
  106. package/dist/shared/type-guards.d.ts.map +1 -0
  107. package/dist/shared/type-guards.js +13 -0
  108. package/dist/shared/type-guards.js.map +1 -0
  109. package/dist/shared/types.d.ts +15 -0
  110. package/dist/shared/types.d.ts.map +1 -0
  111. package/dist/shared/types.js +2 -0
  112. package/dist/shared/types.js.map +1 -0
  113. package/dist/sidecar-worker.d.ts.map +1 -1
  114. package/dist/sidecar-worker.js +1 -7
  115. package/dist/sidecar-worker.js.map +1 -1
  116. package/dist/{sub-agents.d.ts → subagents/discovery.d.ts} +1 -1
  117. package/dist/subagents/discovery.d.ts.map +1 -0
  118. package/dist/{sub-agents.js → subagents/discovery.js} +3 -3
  119. package/dist/subagents/discovery.js.map +1 -0
  120. package/dist/{tools/subagent.d.ts → subagents/tool.d.ts} +3 -16
  121. package/dist/{tools/subagent.d.ts.map → subagents/tool.d.ts.map} +1 -1
  122. package/dist/{tools/subagent.js → subagents/tool.js} +17 -38
  123. package/dist/subagents/tool.js.map +1 -0
  124. package/dist/tools/index.d.ts +1 -1
  125. package/dist/tools/index.d.ts.map +1 -1
  126. package/dist/tools/index.js +1 -1
  127. package/dist/tools/index.js.map +1 -1
  128. package/docs/memory-audit.md +330 -0
  129. package/docs/memory-optimization-round2.md +319 -0
  130. package/package.json +1 -1
  131. package/dist/delivery.d.ts.map +0 -1
  132. package/dist/delivery.js.map +0 -1
  133. package/dist/dingtalk.d.ts.map +0 -1
  134. package/dist/dingtalk.js.map +0 -1
  135. package/dist/events.d.ts.map +0 -1
  136. package/dist/events.js.map +0 -1
  137. package/dist/markdown-sections.d.ts +0 -6
  138. package/dist/markdown-sections.d.ts.map +0 -1
  139. package/dist/markdown-sections.js.map +0 -1
  140. package/dist/memory-candidates.d.ts.map +0 -1
  141. package/dist/memory-candidates.js.map +0 -1
  142. package/dist/memory-consolidation.d.ts.map +0 -1
  143. package/dist/memory-consolidation.js.map +0 -1
  144. package/dist/memory-files.d.ts.map +0 -1
  145. package/dist/memory-files.js.map +0 -1
  146. package/dist/memory-lifecycle.d.ts.map +0 -1
  147. package/dist/memory-lifecycle.js +0 -150
  148. package/dist/memory-lifecycle.js.map +0 -1
  149. package/dist/memory-recall.d.ts.map +0 -1
  150. package/dist/memory-recall.js +0 -218
  151. package/dist/memory-recall.js.map +0 -1
  152. package/dist/session-memory-files.d.ts +0 -2
  153. package/dist/session-memory-files.d.ts.map +0 -1
  154. package/dist/session-memory-files.js +0 -2
  155. package/dist/session-memory-files.js.map +0 -1
  156. package/dist/session-memory.d.ts.map +0 -1
  157. package/dist/session-memory.js.map +0 -1
  158. package/dist/store.d.ts.map +0 -1
  159. package/dist/store.js.map +0 -1
  160. package/dist/sub-agents.d.ts.map +0 -1
  161. package/dist/sub-agents.js.map +0 -1
  162. package/dist/tools/subagent.js.map +0 -1
  163. package/docs/proj-review.md +0 -188
  164. package/docs/test-supplementation-plan.md +0 -553
  165. /package/dist/{delivery.d.ts → runtime/delivery.d.ts} +0 -0
  166. /package/dist/{events.d.ts → runtime/events.d.ts} +0 -0
  167. /package/docs/{memory-rfc.md → specs/001-implement-memory/memory-rfc.md} +0 -0
  168. /package/docs/{subagent → specs/002-subagent}/pi-subagent-analyse.txt +0 -0
  169. /package/docs/{subagent → specs/002-subagent}/pi-subagent-design.txt +0 -0
  170. /package/docs/{subagent → specs/002-subagent}/pi-subagent-phase1-plan.txt +0 -0
  171. /package/docs/{improve-memory → specs/003-improve-memory}/design.md +0 -0
  172. /package/docs/{improve-memory → specs/003-improve-memory}/interfaces-and-tests.md +0 -0
  173. /package/docs/{improve-memory → specs/003-improve-memory}/spec.md +0 -0
@@ -0,0 +1,46 @@
1
+ import { type BuiltInCommand } from "../commands.js";
2
+ import type { DingTalkContext } from "../runtime/dingtalk.js";
3
+ import type { ChannelStore } from "../runtime/store.js";
4
+ import { type SandboxConfig } from "../sandbox.js";
5
+ import { type AgentRunner } from "./types.js";
6
+ export declare class ChannelRunner implements AgentRunner {
7
+ private readonly sandboxConfig;
8
+ private readonly channelId;
9
+ private readonly channelDir;
10
+ private readonly workspacePath;
11
+ private readonly workspaceDir;
12
+ private readonly session;
13
+ private readonly agent;
14
+ private readonly sessionManager;
15
+ private readonly settingsManager;
16
+ private readonly modelRegistry;
17
+ private readonly memoryLifecycle;
18
+ private readonly sessionReady;
19
+ private subAgentDiscovery;
20
+ private activeModel;
21
+ private currentSkills;
22
+ private firstTurnMemoryBootstrapPending;
23
+ private runState;
24
+ constructor(sandboxConfig: SandboxConfig, channelId: string, channelDir: string);
25
+ run(ctx: DingTalkContext, store: ChannelStore): Promise<{
26
+ stopReason: string;
27
+ errorMessage?: string;
28
+ }>;
29
+ handleBuiltinCommand(ctx: DingTalkContext, command: BuiltInCommand): Promise<void>;
30
+ queueSteer(text: string, userName?: string): Promise<void>;
31
+ queueFollowUp(text: string, userName?: string): Promise<void>;
32
+ abort(): Promise<void>;
33
+ private sendCommandReply;
34
+ private requireQueuedMessage;
35
+ private shouldPreserveRawInput;
36
+ private formatUserMessage;
37
+ private queueBusyMessage;
38
+ private resetRunState;
39
+ private refreshSessionResources;
40
+ private initializeSession;
41
+ private ensureSessionReady;
42
+ private refreshSubAgentDiscovery;
43
+ private subscribeToSessionEvents;
44
+ private buildFirstTurnMemoryBootstrap;
45
+ }
46
+ //# sourceMappingURL=channel-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-runner.d.ts","sourceRoot":"","sources":["../../src/agent/channel-runner.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,gBAAgB,CAAC;AAYxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AASnE,OAAO,EACN,KAAK,WAAW,EAKhB,MAAM,YAAY,CAAC;AA6BpB,qBAAa,aAAc,YAAW,WAAW;IAEhD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,iBAAiB,CAA0B;IAGnD,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,+BAA+B,CAAQ;IAG/C,OAAO,CAAC,QAAQ,CAAmC;gBAEvC,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAoIzE,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsItG,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BlF,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAMd,gBAAgB;IAQ9B,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,iBAAiB;YAUX,gBAAgB;IAe9B,OAAO,CAAC,aAAa;YAWP,uBAAuB;YAQvB,iBAAiB;YAQjB,kBAAkB;IAIhC,OAAO,CAAC,wBAAwB;IAWhC,OAAO,CAAC,wBAAwB;YAkBlB,6BAA6B;CAmB3C"}
@@ -0,0 +1,434 @@
1
+ import { Agent } from "@mariozechner/pi-agent-core";
2
+ import { AgentSession, AuthStorage, convertToLlm, DefaultResourceLoader, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
3
+ import { mkdir, readFile, writeFile } from "fs/promises";
4
+ import { dirname, join, resolve } from "path";
5
+ import { createCommandExtension } from "../command-extension.js";
6
+ import { renderBuiltInHelp } from "../commands.js";
7
+ import { getAgentConfig, getApiKeyForModel, getSoul, loadPipiclawSkills } from "../config-loader.js";
8
+ import { PipiclawSettingsManager } from "../context.js";
9
+ import * as log from "../log.js";
10
+ import { buildFirstTurnMemoryBootstrap as renderFirstTurnMemoryBootstrap } from "../memory/bootstrap.js";
11
+ import { createMemoryCandidateCache } from "../memory/candidates.js";
12
+ import { getChannelMemoryPath } from "../memory/files.js";
13
+ import { MemoryLifecycle } from "../memory/lifecycle.js";
14
+ import { recallRelevantMemory } from "../memory/recall.js";
15
+ import { resolveInitialModel } from "../model-utils.js";
16
+ import { APP_HOME_DIR, AUTH_CONFIG_PATH, MODELS_CONFIG_PATH } from "../paths.js";
17
+ import { buildAppendSystemPrompt } from "../prompt-builder.js";
18
+ import { createExecutor } from "../sandbox.js";
19
+ import { HAN_REGEX } from "../shared/text-utils.js";
20
+ import { isRecord } from "../shared/type-guards.js";
21
+ import { discoverSubAgents, formatSubAgentList } from "../subagents/discovery.js";
22
+ import { createPipiclawTools } from "../tools/index.js";
23
+ import { clipUserInput } from "./progress-formatter.js";
24
+ import { createRunQueue } from "./run-queue.js";
25
+ import { handleSessionEvent } from "./session-events.js";
26
+ import { getLastAssistantUsage } from "./type-guards.js";
27
+ import { createEmptyRunState, MAX_USER_MESSAGE_CHARS, } from "./types.js";
28
+ function isSilentOutcome(outcome) {
29
+ return outcome.kind === "silent";
30
+ }
31
+ function isFinalOutcome(outcome) {
32
+ return outcome.kind === "final";
33
+ }
34
+ function getFinalOutcomeText(outcome) {
35
+ return isFinalOutcome(outcome) ? outcome.text : null;
36
+ }
37
+ function createModelRegistry(authStorage, modelsJsonPath) {
38
+ const registryClass = ModelRegistry;
39
+ return typeof registryClass.create === "function"
40
+ ? registryClass.create(authStorage, modelsJsonPath)
41
+ : new registryClass(authStorage, modelsJsonPath);
42
+ }
43
+ function asSdkSettingsManager(manager) {
44
+ return manager;
45
+ }
46
+ export class ChannelRunner {
47
+ constructor(sandboxConfig, channelId, channelDir) {
48
+ this.firstTurnMemoryBootstrapPending = true;
49
+ // --- Per run ---
50
+ this.runState = createEmptyRunState();
51
+ this.sandboxConfig = sandboxConfig;
52
+ this.channelId = channelId;
53
+ this.channelDir = channelDir;
54
+ const executor = createExecutor(sandboxConfig);
55
+ this.workspaceDir = resolve(dirname(channelDir));
56
+ this.workspacePath = executor.getWorkspacePath(this.workspaceDir);
57
+ // Initial skill summaries
58
+ const initialSkills = loadPipiclawSkills(channelDir, this.workspacePath);
59
+ this.currentSkills = initialSkills;
60
+ // Create session manager
61
+ const contextFile = join(channelDir, "context.jsonl");
62
+ this.sessionManager = SessionManager.open(contextFile, channelDir);
63
+ this.settingsManager = new PipiclawSettingsManager(APP_HOME_DIR);
64
+ // Create AuthStorage and ModelRegistry
65
+ const authStorage = AuthStorage.create(AUTH_CONFIG_PATH);
66
+ this.modelRegistry = createModelRegistry(authStorage, MODELS_CONFIG_PATH);
67
+ // Resolve model: prefer saved global default, fall back to first available model
68
+ this.activeModel = resolveInitialModel(this.modelRegistry, this.settingsManager);
69
+ log.logInfo(`Using model: ${this.activeModel.provider}/${this.activeModel.id} (${this.activeModel.name})`);
70
+ this.subAgentDiscovery = this.refreshSubAgentDiscovery();
71
+ // Create tools
72
+ const tools = createPipiclawTools({
73
+ executor,
74
+ getCurrentModel: () => this.activeModel,
75
+ getAvailableModels: () => this.modelRegistry.getAvailable(),
76
+ resolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),
77
+ workspaceDir: this.workspaceDir,
78
+ channelDir: this.channelDir,
79
+ workspacePath: this.workspacePath,
80
+ channelId: this.channelId,
81
+ sandboxConfig: this.sandboxConfig,
82
+ getSubAgentDiscovery: () => this.subAgentDiscovery,
83
+ getMemoryRecallSettings: () => this.settingsManager.getMemoryRecallSettings(),
84
+ });
85
+ // Create agent
86
+ this.agent = new Agent({
87
+ initialState: {
88
+ systemPrompt: "",
89
+ model: this.activeModel,
90
+ thinkingLevel: "off",
91
+ tools,
92
+ },
93
+ convertToLlm,
94
+ getApiKey: async () => getApiKeyForModel(this.modelRegistry, this.activeModel),
95
+ });
96
+ this.memoryLifecycle = new MemoryLifecycle({
97
+ channelId: this.channelId,
98
+ channelDir: this.channelDir,
99
+ getMessages: () => this.session.messages,
100
+ getSessionEntries: () => this.sessionManager.getBranch(),
101
+ getModel: () => this.session.model ?? this.activeModel,
102
+ resolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),
103
+ getSessionMemorySettings: () => this.settingsManager.getSessionMemorySettings(),
104
+ });
105
+ const resourceLoader = new DefaultResourceLoader({
106
+ cwd: process.cwd(),
107
+ agentDir: APP_HOME_DIR,
108
+ settingsManager: asSdkSettingsManager(this.settingsManager),
109
+ extensionFactories: [
110
+ this.memoryLifecycle.createExtensionFactory(),
111
+ createCommandExtension({
112
+ getCurrentModel: () => this.session.model ?? this.activeModel,
113
+ getAvailableModels: async () => {
114
+ this.modelRegistry.refresh();
115
+ return await this.modelRegistry.getAvailable();
116
+ },
117
+ getSessionStats: () => this.session.getSessionStats(),
118
+ getThinkingLevel: () => this.session.thinkingLevel,
119
+ switchModel: async (model) => {
120
+ await this.session.setModel(model);
121
+ this.activeModel = model;
122
+ },
123
+ refreshSessionResources: async () => {
124
+ await this.refreshSessionResources();
125
+ },
126
+ }),
127
+ ],
128
+ appendSystemPromptOverride: (base) => {
129
+ const soul = getSoul(this.workspaceDir);
130
+ const sections = [...base];
131
+ if (soul) {
132
+ sections.unshift(soul);
133
+ }
134
+ sections.push(buildAppendSystemPrompt(this.workspacePath, this.channelId, this.sandboxConfig, {
135
+ subAgentList: formatSubAgentList(this.subAgentDiscovery.agents),
136
+ }));
137
+ return sections;
138
+ },
139
+ agentsFilesOverride: () => {
140
+ const agentConfig = getAgentConfig(this.channelDir);
141
+ return {
142
+ agentsFiles: agentConfig ? [{ path: `${this.workspacePath}/AGENTS.md`, content: agentConfig }] : [],
143
+ };
144
+ },
145
+ skillsOverride: (base) => ({
146
+ skills: [...base.skills, ...this.currentSkills],
147
+ diagnostics: base.diagnostics,
148
+ }),
149
+ });
150
+ const baseToolsOverride = Object.fromEntries(tools.map((tool) => [tool.name, tool]));
151
+ // Create AgentSession
152
+ this.session = new AgentSession({
153
+ agent: this.agent,
154
+ sessionManager: this.sessionManager,
155
+ settingsManager: asSdkSettingsManager(this.settingsManager),
156
+ cwd: process.cwd(),
157
+ modelRegistry: this.modelRegistry,
158
+ resourceLoader,
159
+ baseToolsOverride,
160
+ });
161
+ // Subscribe to session events
162
+ this.subscribeToSessionEvents();
163
+ this.sessionReady = this.initializeSession();
164
+ }
165
+ // === Public API ===
166
+ async run(ctx, store) {
167
+ this.resetRunState(ctx, store);
168
+ const runQueue = createRunQueue(ctx);
169
+ this.runState.queue = runQueue.queue;
170
+ try {
171
+ await this.ensureSessionReady();
172
+ // Ensure channel directory exists
173
+ await mkdir(this.channelDir, { recursive: true });
174
+ const candidateCache = createMemoryCandidateCache();
175
+ const clippedInput = clipUserInput(ctx.message.text, MAX_USER_MESSAGE_CHARS);
176
+ const userMessage = this.formatUserMessage(clippedInput, ctx.message.userName);
177
+ let promptText = this.shouldPreserveRawInput(ctx.message.text) ? clippedInput : userMessage;
178
+ let recalledContextText = "";
179
+ let durableMemoryBootstrapText = "";
180
+ this.memoryLifecycle.noteUserTurnStarted();
181
+ if (!this.shouldPreserveRawInput(ctx.message.text)) {
182
+ const recallSettings = this.settingsManager.getMemoryRecallSettings();
183
+ if (recallSettings.enabled) {
184
+ const recall = await recallRelevantMemory({
185
+ query: clippedInput,
186
+ workspaceDir: this.workspaceDir,
187
+ channelDir: this.channelDir,
188
+ maxCandidates: recallSettings.maxCandidates,
189
+ maxInjected: recallSettings.maxInjected,
190
+ maxChars: recallSettings.maxChars,
191
+ rerankWithModel: recallSettings.rerankWithModel,
192
+ autoRerank: HAN_REGEX.test(clippedInput),
193
+ model: this.session.model ?? this.activeModel,
194
+ resolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),
195
+ candidateCache,
196
+ });
197
+ if (recall.renderedText) {
198
+ recalledContextText = recall.renderedText;
199
+ promptText = `${recall.renderedText}\n\n<user_message>\n${promptText}\n</user_message>`;
200
+ }
201
+ }
202
+ if (this.firstTurnMemoryBootstrapPending) {
203
+ durableMemoryBootstrapText = await this.buildFirstTurnMemoryBootstrap();
204
+ if (durableMemoryBootstrapText) {
205
+ promptText = `${durableMemoryBootstrapText}\n\n${promptText}`;
206
+ }
207
+ this.firstTurnMemoryBootstrapPending = false;
208
+ }
209
+ }
210
+ // Debug: write context to last_prompt.json (only with PIPICLAW_DEBUG=1)
211
+ if (process.env.PIPICLAW_DEBUG) {
212
+ const debugContext = {
213
+ systemPrompt: this.agent.state.systemPrompt,
214
+ messages: this.session.messages,
215
+ durableMemoryBootstrap: durableMemoryBootstrapText || undefined,
216
+ recalledContext: recalledContextText || undefined,
217
+ newUserMessage: promptText,
218
+ };
219
+ await writeFile(join(this.channelDir, "last_prompt.json"), JSON.stringify(debugContext, null, 2));
220
+ }
221
+ await this.session.prompt(promptText);
222
+ }
223
+ catch (err) {
224
+ this.runState.stopReason = "error";
225
+ this.runState.errorMessage = err instanceof Error ? err.message : String(err);
226
+ log.logWarning(`[${this.channelId}] Runner failed`, this.runState.errorMessage);
227
+ }
228
+ finally {
229
+ await runQueue.drain();
230
+ const finalOutcome = this.runState.finalOutcome;
231
+ const finalOutcomeText = getFinalOutcomeText(finalOutcome);
232
+ try {
233
+ if (this.runState.stopReason === "error" &&
234
+ this.runState.errorMessage &&
235
+ !this.runState.finalResponseDelivered) {
236
+ try {
237
+ await ctx.replaceMessage("_Sorry, something went wrong_");
238
+ }
239
+ catch (err) {
240
+ const errMsg = err instanceof Error ? err.message : String(err);
241
+ log.logWarning("Failed to post error message", errMsg);
242
+ }
243
+ }
244
+ else if (isSilentOutcome(finalOutcome)) {
245
+ try {
246
+ await ctx.deleteMessage();
247
+ log.logInfo("Silent response - deleted message");
248
+ }
249
+ catch (err) {
250
+ const errMsg = err instanceof Error ? err.message : String(err);
251
+ log.logWarning("Failed to delete message for silent response", errMsg);
252
+ }
253
+ }
254
+ else if (finalOutcomeText && !this.runState.finalResponseDelivered) {
255
+ try {
256
+ await ctx.replaceMessage(finalOutcomeText);
257
+ }
258
+ catch (err) {
259
+ const errMsg = err instanceof Error ? err.message : String(err);
260
+ log.logWarning("Failed to replace message with final text", errMsg);
261
+ }
262
+ }
263
+ await ctx.flush();
264
+ }
265
+ finally {
266
+ await ctx.close();
267
+ }
268
+ // Log usage summary
269
+ if (this.runState.totalUsage.cost.total > 0) {
270
+ const lastAssistantMessage = getLastAssistantUsage(this.session.messages);
271
+ const contextTokens = lastAssistantMessage
272
+ ? lastAssistantMessage.usage.input +
273
+ lastAssistantMessage.usage.output +
274
+ lastAssistantMessage.usage.cacheRead +
275
+ lastAssistantMessage.usage.cacheWrite
276
+ : 0;
277
+ const currentRunModel = this.session.model ?? this.activeModel;
278
+ const contextWindow = currentRunModel.contextWindow || 200000;
279
+ log.logUsageSummary(this.runState.logCtx, this.runState.totalUsage, contextTokens, contextWindow);
280
+ }
281
+ // Clear run state
282
+ this.runState.ctx = null;
283
+ this.runState.logCtx = null;
284
+ this.runState.queue = null;
285
+ }
286
+ return { stopReason: this.runState.stopReason, errorMessage: this.runState.errorMessage };
287
+ }
288
+ async handleBuiltinCommand(ctx, command) {
289
+ try {
290
+ switch (command.name) {
291
+ case "help":
292
+ await this.sendCommandReply(ctx, renderBuiltInHelp());
293
+ return;
294
+ case "stop":
295
+ await this.sendCommandReply(ctx, "No task is running. Use `/stop` only while a task is running.");
296
+ return;
297
+ case "steer":
298
+ this.requireQueuedMessage(command.args, "steer");
299
+ await this.sendCommandReply(ctx, "No task is running. Send the message directly instead of using `/steer`.");
300
+ return;
301
+ case "followup":
302
+ this.requireQueuedMessage(command.args, "followup");
303
+ await this.sendCommandReply(ctx, "No task is running. Send the message directly now, or use `/followup` while a task is running.");
304
+ return;
305
+ }
306
+ }
307
+ catch (err) {
308
+ const errMsg = err instanceof Error ? err.message : String(err);
309
+ log.logWarning(`[${this.channelId}] Built-in command failed`, errMsg);
310
+ await this.sendCommandReply(ctx, `命令执行失败:${errMsg}`);
311
+ }
312
+ }
313
+ async queueSteer(text, userName) {
314
+ await this.queueBusyMessage("steer", this.requireQueuedMessage(text, "steer"), userName);
315
+ }
316
+ async queueFollowUp(text, userName) {
317
+ await this.queueBusyMessage("followUp", this.requireQueuedMessage(text, "followup"), userName);
318
+ }
319
+ async abort() {
320
+ await this.session.abort();
321
+ }
322
+ // === Private helpers ===
323
+ async sendCommandReply(ctx, text) {
324
+ const delivered = await ctx.respondPlain(text);
325
+ if (!delivered) {
326
+ await ctx.replaceMessage(text);
327
+ await ctx.flush();
328
+ }
329
+ }
330
+ requireQueuedMessage(text, commandName) {
331
+ const trimmedText = text.trim();
332
+ if (!trimmedText) {
333
+ throw new Error(`/${commandName} requires a message.`);
334
+ }
335
+ return trimmedText;
336
+ }
337
+ shouldPreserveRawInput(text) {
338
+ return text.trim().startsWith("/");
339
+ }
340
+ formatUserMessage(text, userName, now = new Date()) {
341
+ const pad = (n) => n.toString().padStart(2, "0");
342
+ const offset = -now.getTimezoneOffset();
343
+ const offsetSign = offset >= 0 ? "+" : "-";
344
+ const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
345
+ const offsetMins = pad(Math.abs(offset) % 60);
346
+ const timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}${offsetSign}${offsetHours}:${offsetMins}`;
347
+ return `[${timestamp}] [${userName || "unknown"}]: ${text}`;
348
+ }
349
+ async queueBusyMessage(delivery, text, userName) {
350
+ if (!this.session.isStreaming) {
351
+ throw new Error("No task is currently running.");
352
+ }
353
+ const clippedText = clipUserInput(text, MAX_USER_MESSAGE_CHARS);
354
+ if (clippedText !== text.trim()) {
355
+ log.logWarning(`[${this.channelId}] Queued message exceeded ${MAX_USER_MESSAGE_CHARS} chars and was clipped`);
356
+ }
357
+ await this.session.prompt(this.formatUserMessage(clippedText, userName), {
358
+ streamingBehavior: delivery,
359
+ });
360
+ }
361
+ resetRunState(ctx, store) {
362
+ this.runState = createEmptyRunState();
363
+ this.runState.ctx = ctx;
364
+ this.runState.logCtx = {
365
+ channelId: ctx.message.channel,
366
+ userName: ctx.message.userName,
367
+ channelName: ctx.channelName,
368
+ };
369
+ this.runState.store = store;
370
+ }
371
+ async refreshSessionResources() {
372
+ await this.ensureSessionReady();
373
+ const skills = loadPipiclawSkills(this.channelDir, this.workspacePath);
374
+ this.currentSkills = skills;
375
+ this.subAgentDiscovery = this.refreshSubAgentDiscovery();
376
+ await this.session.reload();
377
+ }
378
+ async initializeSession() {
379
+ const skills = loadPipiclawSkills(this.channelDir, this.workspacePath);
380
+ this.currentSkills = skills;
381
+ this.subAgentDiscovery = this.refreshSubAgentDiscovery();
382
+ this.firstTurnMemoryBootstrapPending = true;
383
+ await this.session.reload();
384
+ }
385
+ async ensureSessionReady() {
386
+ await this.sessionReady;
387
+ }
388
+ refreshSubAgentDiscovery() {
389
+ this.modelRegistry.refresh();
390
+ const discovery = discoverSubAgents(this.workspaceDir, this.modelRegistry.getAvailable());
391
+ for (const warning of discovery.warnings) {
392
+ log.logWarning(`Sub-agent config warning (${this.channelId})`, warning);
393
+ }
394
+ return discovery;
395
+ }
396
+ // === Session event subscription ===
397
+ subscribeToSessionEvents() {
398
+ this.session.subscribe(async (event) => {
399
+ if (isRecord(event) && "reason" in event && event.reason === "new") {
400
+ this.firstTurnMemoryBootstrapPending = true;
401
+ }
402
+ if (!this.runState.ctx || !this.runState.logCtx || !this.runState.queue)
403
+ return;
404
+ await handleSessionEvent(event, {
405
+ ctx: this.runState.ctx,
406
+ logCtx: this.runState.logCtx,
407
+ queue: this.runState.queue,
408
+ pendingTools: this.runState.pendingTools,
409
+ store: this.runState.store,
410
+ runState: this.runState,
411
+ memoryLifecycle: this.memoryLifecycle,
412
+ });
413
+ });
414
+ }
415
+ async buildFirstTurnMemoryBootstrap() {
416
+ const readOptionalFile = async (path) => {
417
+ try {
418
+ return await readFile(path, "utf-8");
419
+ }
420
+ catch {
421
+ return "";
422
+ }
423
+ };
424
+ const [channelMemory, workspaceMemory] = await Promise.all([
425
+ readOptionalFile(getChannelMemoryPath(this.channelDir)),
426
+ readOptionalFile(join(this.workspaceDir, "MEMORY.md")),
427
+ ]);
428
+ return renderFirstTurnMemoryBootstrap({
429
+ channelMemory,
430
+ workspaceMemory,
431
+ });
432
+ }
433
+ }
434
+ //# sourceMappingURL=channel-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-runner.js","sourceRoot":"","sources":["../../src/agent/channel-runner.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\ttype SettingsManager as SDKSettingsManager,\n\tSessionManager,\n\ttype Skill,\n} from \"@mariozechner/pi-coding-agent\";\nimport { mkdir, readFile, writeFile } from \"fs/promises\";\nimport { dirname, join, resolve } from \"path\";\nimport { 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 * as log from \"../log.js\";\nimport { buildFirstTurnMemoryBootstrap as renderFirstTurnMemoryBootstrap } from \"../memory/bootstrap.js\";\nimport { createMemoryCandidateCache } from \"../memory/candidates.js\";\nimport { getChannelMemoryPath } from \"../memory/files.js\";\nimport { MemoryLifecycle } from \"../memory/lifecycle.js\";\nimport { recallRelevantMemory } from \"../memory/recall.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 type { DingTalkContext } from \"../runtime/dingtalk.js\";\nimport type { ChannelStore } from \"../runtime/store.js\";\nimport { createExecutor, type SandboxConfig } from \"../sandbox.js\";\nimport { HAN_REGEX } from \"../shared/text-utils.js\";\nimport { isRecord } from \"../shared/type-guards.js\";\nimport { discoverSubAgents, formatSubAgentList, type SubAgentDiscoveryResult } from \"../subagents/discovery.js\";\nimport { createPipiclawTools } from \"../tools/index.js\";\nimport { clipUserInput } from \"./progress-formatter.js\";\nimport { createRunQueue } from \"./run-queue.js\";\nimport { handleSessionEvent } from \"./session-events.js\";\nimport { getLastAssistantUsage } from \"./type-guards.js\";\nimport {\n\ttype AgentRunner,\n\tcreateEmptyRunState,\n\ttype FinalOutcome,\n\tMAX_USER_MESSAGE_CHARS,\n\ttype RunState,\n} from \"./types.js\";\n\ntype ModelRegistryClass = {\n\tcreate?: (authStorage: AuthStorage, modelsJsonPath?: string) => ModelRegistry;\n\tnew (authStorage: AuthStorage, modelsJsonPath?: string): ModelRegistry;\n};\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\nfunction createModelRegistry(authStorage: AuthStorage, modelsJsonPath: string): ModelRegistry {\n\tconst registryClass = ModelRegistry as unknown as ModelRegistryClass;\n\treturn typeof registryClass.create === \"function\"\n\t\t? registryClass.create(authStorage, modelsJsonPath)\n\t\t: new registryClass(authStorage, modelsJsonPath);\n}\n\nfunction asSdkSettingsManager(manager: PipiclawSettingsManager): SDKSettingsManager {\n\treturn manager as unknown as SDKSettingsManager;\n}\nexport class 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\tprivate subAgentDiscovery: SubAgentDiscoveryResult;\n\n\t// --- Mutable across runs ---\n\tprivate activeModel: Model<Api>;\n\tprivate currentSkills: Skill[];\n\tprivate firstTurnMemoryBootstrapPending = true;\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.workspaceDir = resolve(dirname(channelDir));\n\t\tthis.workspacePath = executor.getWorkspacePath(this.workspaceDir);\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 = createModelRegistry(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\t\tthis.subAgentDiscovery = this.refreshSubAgentDiscovery();\n\n\t\t// Create tools\n\t\tconst tools = createPipiclawTools({\n\t\t\texecutor,\n\t\t\tgetCurrentModel: () => this.activeModel,\n\t\t\tgetAvailableModels: () => this.modelRegistry.getAvailable(),\n\t\t\tresolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),\n\t\t\tworkspaceDir: this.workspaceDir,\n\t\t\tchannelDir: this.channelDir,\n\t\t\tworkspacePath: this.workspacePath,\n\t\t\tchannelId: this.channelId,\n\t\t\tsandboxConfig: this.sandboxConfig,\n\t\t\tgetSubAgentDiscovery: () => this.subAgentDiscovery,\n\t\t\tgetMemoryRecallSettings: () => this.settingsManager.getMemoryRecallSettings(),\n\t\t});\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\tgetSessionMemorySettings: () => this.settingsManager.getSessionMemorySettings(),\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: asSdkSettingsManager(this.settingsManager),\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(\n\t\t\t\t\tbuildAppendSystemPrompt(this.workspacePath, this.channelId, this.sandboxConfig, {\n\t\t\t\t\t\tsubAgentList: formatSubAgentList(this.subAgentDiscovery.agents),\n\t\t\t\t\t}),\n\t\t\t\t);\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: asSdkSettingsManager(this.settingsManager),\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, store);\n\n\t\tconst runQueue = createRunQueue(ctx);\n\t\tthis.runState.queue = runQueue.queue;\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 candidateCache = createMemoryCandidateCache();\n\t\t\tconst clippedInput = clipUserInput(ctx.message.text, MAX_USER_MESSAGE_CHARS);\n\t\t\tconst userMessage = this.formatUserMessage(clippedInput, ctx.message.userName);\n\t\t\tlet promptText = this.shouldPreserveRawInput(ctx.message.text) ? clippedInput : userMessage;\n\t\t\tlet recalledContextText = \"\";\n\t\t\tlet durableMemoryBootstrapText = \"\";\n\n\t\t\tthis.memoryLifecycle.noteUserTurnStarted();\n\n\t\t\tif (!this.shouldPreserveRawInput(ctx.message.text)) {\n\t\t\t\tconst recallSettings = this.settingsManager.getMemoryRecallSettings();\n\t\t\t\tif (recallSettings.enabled) {\n\t\t\t\t\tconst recall = await recallRelevantMemory({\n\t\t\t\t\t\tquery: clippedInput,\n\t\t\t\t\t\tworkspaceDir: this.workspaceDir,\n\t\t\t\t\t\tchannelDir: this.channelDir,\n\t\t\t\t\t\tmaxCandidates: recallSettings.maxCandidates,\n\t\t\t\t\t\tmaxInjected: recallSettings.maxInjected,\n\t\t\t\t\t\tmaxChars: recallSettings.maxChars,\n\t\t\t\t\t\trerankWithModel: recallSettings.rerankWithModel,\n\t\t\t\t\t\tautoRerank: HAN_REGEX.test(clippedInput),\n\t\t\t\t\t\tmodel: this.session.model ?? this.activeModel,\n\t\t\t\t\t\tresolveApiKey: async (model) => getApiKeyForModel(this.modelRegistry, model),\n\t\t\t\t\t\tcandidateCache,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (recall.renderedText) {\n\t\t\t\t\t\trecalledContextText = recall.renderedText;\n\t\t\t\t\t\tpromptText = `${recall.renderedText}\\n\\n<user_message>\\n${promptText}\\n</user_message>`;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this.firstTurnMemoryBootstrapPending) {\n\t\t\t\t\tdurableMemoryBootstrapText = await this.buildFirstTurnMemoryBootstrap();\n\t\t\t\t\tif (durableMemoryBootstrapText) {\n\t\t\t\t\t\tpromptText = `${durableMemoryBootstrapText}\\n\\n${promptText}`;\n\t\t\t\t\t}\n\t\t\t\t\tthis.firstTurnMemoryBootstrapPending = false;\n\t\t\t\t}\n\t\t\t}\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\tdurableMemoryBootstrap: durableMemoryBootstrapText || undefined,\n\t\t\t\t\trecalledContext: recalledContextText || undefined,\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 runQueue.drain();\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 lastAssistantMessage = getLastAssistantUsage(this.session.messages);\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\tasync abort(): Promise<void> {\n\t\tawait this.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\tconst clippedText = clipUserInput(text, MAX_USER_MESSAGE_CHARS);\n\t\tif (clippedText !== text.trim()) {\n\t\t\tlog.logWarning(`[${this.channelId}] Queued message exceeded ${MAX_USER_MESSAGE_CHARS} chars and was clipped`);\n\t\t}\n\n\t\tawait this.session.prompt(this.formatUserMessage(clippedText, userName), {\n\t\t\tstreamingBehavior: delivery,\n\t\t});\n\t}\n\n\tprivate resetRunState(ctx: DingTalkContext, store: ChannelStore): 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\tthis.runState.store = store;\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\tthis.subAgentDiscovery = this.refreshSubAgentDiscovery();\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\tthis.subAgentDiscovery = this.refreshSubAgentDiscovery();\n\t\tthis.firstTurnMemoryBootstrapPending = true;\n\t\tawait this.session.reload();\n\t}\n\n\tprivate async ensureSessionReady(): Promise<void> {\n\t\tawait this.sessionReady;\n\t}\n\n\tprivate refreshSubAgentDiscovery(): SubAgentDiscoveryResult {\n\t\tthis.modelRegistry.refresh();\n\t\tconst discovery = discoverSubAgents(this.workspaceDir, this.modelRegistry.getAvailable());\n\t\tfor (const warning of discovery.warnings) {\n\t\t\tlog.logWarning(`Sub-agent config warning (${this.channelId})`, warning);\n\t\t}\n\t\treturn discovery;\n\t}\n\n\t// === Session event subscription ===\n\n\tprivate subscribeToSessionEvents(): void {\n\t\tthis.session.subscribe(async (event: unknown) => {\n\t\t\tif (isRecord(event) && \"reason\" in event && event.reason === \"new\") {\n\t\t\t\tthis.firstTurnMemoryBootstrapPending = true;\n\t\t\t}\n\t\t\tif (!this.runState.ctx || !this.runState.logCtx || !this.runState.queue) return;\n\t\t\tawait handleSessionEvent(event, {\n\t\t\t\tctx: this.runState.ctx,\n\t\t\t\tlogCtx: this.runState.logCtx,\n\t\t\t\tqueue: this.runState.queue,\n\t\t\t\tpendingTools: this.runState.pendingTools,\n\t\t\t\tstore: this.runState.store,\n\t\t\t\trunState: this.runState,\n\t\t\t\tmemoryLifecycle: this.memoryLifecycle,\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate async buildFirstTurnMemoryBootstrap(): Promise<string> {\n\t\tconst readOptionalFile = async (path: string): Promise<string> => {\n\t\t\ttry {\n\t\t\t\treturn await readFile(path, \"utf-8\");\n\t\t\t} catch {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t};\n\n\t\tconst [channelMemory, workspaceMemory] = await Promise.all([\n\t\t\treadOptionalFile(getChannelMemoryPath(this.channelDir)),\n\t\t\treadOptionalFile(join(this.workspaceDir, \"MEMORY.md\")),\n\t\t]);\n\n\t\treturn renderFirstTurnMemoryBootstrap({\n\t\t\tchannelMemory,\n\t\t\tworkspaceMemory,\n\t\t});\n\t}\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export { ChannelRunner } from "./channel-runner.js";
2
+ export { getOrCreateRunner } from "./runner-factory.js";
3
+ export type { AgentRunner } from "./types.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ChannelRunner } from "./channel-runner.js";
2
+ export { getOrCreateRunner } from "./runner-factory.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export { ChannelRunner } from \"./channel-runner.js\";\nexport { getOrCreateRunner } from \"./runner-factory.js\";\nexport type { AgentRunner } from \"./types.js\";\n"]}
@@ -0,0 +1,5 @@
1
+ import type { ProgressEntryKind } from "./types.js";
2
+ export declare function clipUserInput(text: string, maxChars: number): string;
3
+ export declare function formatProgressEntry(kind: ProgressEntryKind, text: string): string;
4
+ export declare function extractToolResultText(result: unknown): string;
5
+ //# sourceMappingURL=progress-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-formatter.d.ts","sourceRoot":"","sources":["../../src/agent/progress-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASpE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAejF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAwB7D"}