@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.
- package/dist/agent/channel-runner.d.ts +46 -0
- package/dist/agent/channel-runner.d.ts.map +1 -0
- package/dist/agent/channel-runner.js +434 -0
- package/dist/agent/channel-runner.js.map +1 -0
- package/dist/agent/index.d.ts +4 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +3 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/progress-formatter.d.ts +5 -0
- package/dist/agent/progress-formatter.d.ts.map +1 -0
- package/dist/agent/progress-formatter.js +53 -0
- package/dist/agent/progress-formatter.js.map +1 -0
- package/dist/agent/run-queue.d.ts +8 -0
- package/dist/agent/run-queue.d.ts.map +1 -0
- package/dist/agent/run-queue.js +27 -0
- package/dist/agent/run-queue.js.map +1 -0
- package/dist/agent/runner-factory.d.ts +4 -0
- package/dist/agent/runner-factory.d.ts.map +1 -0
- package/dist/agent/runner-factory.js +11 -0
- package/dist/agent/runner-factory.js.map +1 -0
- package/dist/agent/session-events.d.ts +15 -0
- package/dist/agent/session-events.d.ts.map +1 -0
- package/dist/agent/session-events.js +216 -0
- package/dist/agent/session-events.js.map +1 -0
- package/dist/agent/type-guards.d.ts +23 -0
- package/dist/agent/type-guards.d.ts.map +1 -0
- package/dist/agent/type-guards.js +107 -0
- package/dist/agent/type-guards.js.map +1 -0
- package/dist/agent/types.d.ts +161 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +23 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent.d.ts +2 -15
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +1 -781
- package/dist/agent.js.map +1 -1
- package/dist/context.d.ts +58 -14
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +50 -7
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts +12 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/main.js +5 -404
- package/dist/main.js.map +1 -1
- package/dist/memory/bootstrap.d.ts +7 -0
- package/dist/memory/bootstrap.d.ts.map +1 -0
- package/dist/memory/bootstrap.js +47 -0
- package/dist/memory/bootstrap.js.map +1 -0
- package/dist/{memory-candidates.d.ts → memory/candidates.d.ts} +2 -1
- package/dist/memory/candidates.d.ts.map +1 -0
- package/dist/{memory-candidates.js → memory/candidates.js} +34 -21
- package/dist/memory/candidates.js.map +1 -0
- package/dist/memory/chinese-words.d.ts +2 -0
- package/dist/memory/chinese-words.d.ts.map +1 -0
- package/dist/memory/chinese-words.js +210 -0
- package/dist/memory/chinese-words.js.map +1 -0
- package/dist/{memory-consolidation.d.ts → memory/consolidation.d.ts} +1 -1
- package/dist/memory/consolidation.d.ts.map +1 -0
- package/dist/{memory-consolidation.js → memory/consolidation.js} +27 -35
- package/dist/memory/consolidation.js.map +1 -0
- package/dist/{memory-files.d.ts → memory/files.d.ts} +1 -6
- package/dist/memory/files.d.ts.map +1 -0
- package/dist/{memory-files.js → memory/files.js} +12 -36
- package/dist/memory/files.js.map +1 -0
- package/dist/{memory-lifecycle.d.ts → memory/lifecycle.d.ts} +24 -6
- package/dist/memory/lifecycle.d.ts.map +1 -0
- package/dist/memory/lifecycle.js +247 -0
- package/dist/memory/lifecycle.js.map +1 -0
- package/dist/{memory-recall.d.ts → memory/recall.d.ts} +2 -2
- package/dist/memory/recall.d.ts.map +1 -0
- package/dist/memory/recall.js +435 -0
- package/dist/memory/recall.js.map +1 -0
- package/dist/{session-memory.d.ts → memory/session.d.ts} +2 -1
- package/dist/memory/session.d.ts.map +1 -0
- package/dist/{session-memory.js → memory/session.js} +32 -62
- package/dist/memory/session.js.map +1 -0
- package/dist/runtime/bootstrap.d.ts +48 -0
- package/dist/runtime/bootstrap.d.ts.map +1 -0
- package/dist/runtime/bootstrap.js +451 -0
- package/dist/runtime/bootstrap.js.map +1 -0
- package/dist/runtime/delivery.d.ts.map +1 -0
- package/dist/{delivery.js → runtime/delivery.js} +1 -1
- package/dist/runtime/delivery.js.map +1 -0
- package/dist/{dingtalk.d.ts → runtime/dingtalk.d.ts} +10 -0
- package/dist/runtime/dingtalk.d.ts.map +1 -0
- package/dist/{dingtalk.js → runtime/dingtalk.js} +87 -27
- package/dist/runtime/dingtalk.js.map +1 -0
- package/dist/runtime/events.d.ts.map +1 -0
- package/dist/{events.js → runtime/events.js} +1 -1
- package/dist/runtime/events.js.map +1 -0
- package/dist/{store.d.ts → runtime/store.d.ts} +5 -0
- package/dist/runtime/store.d.ts.map +1 -0
- package/dist/{store.js → runtime/store.js} +60 -19
- package/dist/runtime/store.js.map +1 -0
- package/dist/shared/markdown-sections.d.ts +7 -0
- package/dist/shared/markdown-sections.d.ts.map +1 -0
- package/dist/{markdown-sections.js → shared/markdown-sections.js} +10 -3
- package/dist/shared/markdown-sections.js.map +1 -0
- package/dist/shared/text-utils.d.ts +10 -0
- package/dist/shared/text-utils.d.ts.map +1 -0
- package/dist/shared/text-utils.js +37 -0
- package/dist/shared/text-utils.js.map +1 -0
- package/dist/shared/type-guards.d.ts +6 -0
- package/dist/shared/type-guards.d.ts.map +1 -0
- package/dist/shared/type-guards.js +13 -0
- package/dist/shared/type-guards.js.map +1 -0
- package/dist/shared/types.d.ts +15 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/sidecar-worker.d.ts.map +1 -1
- package/dist/sidecar-worker.js +1 -7
- package/dist/sidecar-worker.js.map +1 -1
- package/dist/{sub-agents.d.ts → subagents/discovery.d.ts} +1 -1
- package/dist/subagents/discovery.d.ts.map +1 -0
- package/dist/{sub-agents.js → subagents/discovery.js} +3 -3
- package/dist/subagents/discovery.js.map +1 -0
- package/dist/{tools/subagent.d.ts → subagents/tool.d.ts} +3 -16
- package/dist/{tools/subagent.d.ts.map → subagents/tool.d.ts.map} +1 -1
- package/dist/{tools/subagent.js → subagents/tool.js} +17 -38
- package/dist/subagents/tool.js.map +1 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/docs/memory-audit.md +330 -0
- package/docs/memory-optimization-round2.md +319 -0
- package/package.json +1 -1
- package/dist/delivery.d.ts.map +0 -1
- package/dist/delivery.js.map +0 -1
- package/dist/dingtalk.d.ts.map +0 -1
- package/dist/dingtalk.js.map +0 -1
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js.map +0 -1
- package/dist/markdown-sections.d.ts +0 -6
- package/dist/markdown-sections.d.ts.map +0 -1
- package/dist/markdown-sections.js.map +0 -1
- package/dist/memory-candidates.d.ts.map +0 -1
- package/dist/memory-candidates.js.map +0 -1
- package/dist/memory-consolidation.d.ts.map +0 -1
- package/dist/memory-consolidation.js.map +0 -1
- package/dist/memory-files.d.ts.map +0 -1
- package/dist/memory-files.js.map +0 -1
- package/dist/memory-lifecycle.d.ts.map +0 -1
- package/dist/memory-lifecycle.js +0 -150
- package/dist/memory-lifecycle.js.map +0 -1
- package/dist/memory-recall.d.ts.map +0 -1
- package/dist/memory-recall.js +0 -218
- package/dist/memory-recall.js.map +0 -1
- package/dist/session-memory-files.d.ts +0 -2
- package/dist/session-memory-files.d.ts.map +0 -1
- package/dist/session-memory-files.js +0 -2
- package/dist/session-memory-files.js.map +0 -1
- package/dist/session-memory.d.ts.map +0 -1
- package/dist/session-memory.js.map +0 -1
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js.map +0 -1
- package/dist/sub-agents.d.ts.map +0 -1
- package/dist/sub-agents.js.map +0 -1
- package/dist/tools/subagent.js.map +0 -1
- package/docs/proj-review.md +0 -188
- package/docs/test-supplementation-plan.md +0 -553
- /package/dist/{delivery.d.ts → runtime/delivery.d.ts} +0 -0
- /package/dist/{events.d.ts → runtime/events.d.ts} +0 -0
- /package/docs/{memory-rfc.md → specs/001-implement-memory/memory-rfc.md} +0 -0
- /package/docs/{subagent → specs/002-subagent}/pi-subagent-analyse.txt +0 -0
- /package/docs/{subagent → specs/002-subagent}/pi-subagent-design.txt +0 -0
- /package/docs/{subagent → specs/002-subagent}/pi-subagent-phase1-plan.txt +0 -0
- /package/docs/{improve-memory → specs/003-improve-memory}/design.md +0 -0
- /package/docs/{improve-memory → specs/003-improve-memory}/interfaces-and-tests.md +0 -0
- /package/docs/{improve-memory → specs/003-improve-memory}/spec.md +0 -0
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { serializeConversation } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { writeFile } from "fs/promises";
|
|
3
3
|
import { join } from "path";
|
|
4
|
-
import { parseJsonObject } from "
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { runSidecarTask, SidecarParseError } from "
|
|
4
|
+
import { parseJsonObject } from "../llm-json.js";
|
|
5
|
+
import { splitH1Sections } from "../shared/markdown-sections.js";
|
|
6
|
+
import { clipText } from "../shared/text-utils.js";
|
|
7
|
+
import { buildStandardMessages, isRecord } from "../shared/type-guards.js";
|
|
8
|
+
import { runSidecarTask, SidecarParseError } from "../sidecar-worker.js";
|
|
9
|
+
import { readChannelMemory, readChannelSession, rewriteChannelSession } from "./files.js";
|
|
9
10
|
const SESSION_TRANSCRIPT_MAX_CHARS = 20_000;
|
|
10
11
|
const SESSION_MEMORY_MAX_CHARS = 4_000;
|
|
11
12
|
const SESSION_ITEM_LIMIT = 12;
|
|
12
13
|
const SESSION_ITEM_MAX_CHARS = 300;
|
|
13
|
-
const
|
|
14
|
+
const DEFAULT_SESSION_MEMORY_TIMEOUT_MS = 30_000;
|
|
14
15
|
const SESSION_MEMORY_SYSTEM_PROMPT = `You maintain a Pipiclaw SESSION.md file.
|
|
15
16
|
|
|
16
17
|
Return strict JSON only. Do not use Markdown fences.
|
|
@@ -37,15 +38,6 @@ Rules:
|
|
|
37
38
|
- "nextSteps" should reflect the most likely immediate follow-up actions.
|
|
38
39
|
- "worklog" must stay terse and recent.
|
|
39
40
|
- If a field has nothing useful, return an empty string or empty array.`;
|
|
40
|
-
function clipText(text, maxChars) {
|
|
41
|
-
const normalized = text.replace(/\r/g, "").trim();
|
|
42
|
-
if (normalized.length <= maxChars) {
|
|
43
|
-
return normalized;
|
|
44
|
-
}
|
|
45
|
-
const headChars = Math.floor(maxChars * 0.45);
|
|
46
|
-
const tailChars = maxChars - headChars;
|
|
47
|
-
return `${normalized.slice(0, headChars)}\n\n[... omitted middle section ...]\n\n${normalized.slice(-tailChars)}`;
|
|
48
|
-
}
|
|
49
41
|
function normalizeItem(value) {
|
|
50
42
|
if (typeof value !== "string") {
|
|
51
43
|
return null;
|
|
@@ -70,33 +62,22 @@ function normalizeItems(value) {
|
|
|
70
62
|
function normalizeTitle(value) {
|
|
71
63
|
return typeof value === "string" ? value.trim().slice(0, 120) : "";
|
|
72
64
|
}
|
|
73
|
-
function isRecord(value) {
|
|
74
|
-
return typeof value === "object" && value !== null;
|
|
75
|
-
}
|
|
76
65
|
function parseStateUpdate(text) {
|
|
77
66
|
const parsed = parseJsonObject(text);
|
|
78
67
|
if (!isRecord(parsed)) {
|
|
79
68
|
throw new Error("Session memory response was not a JSON object");
|
|
80
69
|
}
|
|
81
|
-
const next = {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if ("constraints" in parsed)
|
|
93
|
-
next.constraints = normalizeItems(parsed.constraints);
|
|
94
|
-
if ("errorsAndCorrections" in parsed)
|
|
95
|
-
next.errorsAndCorrections = normalizeItems(parsed.errorsAndCorrections);
|
|
96
|
-
if ("nextSteps" in parsed)
|
|
97
|
-
next.nextSteps = normalizeItems(parsed.nextSteps);
|
|
98
|
-
if ("worklog" in parsed)
|
|
99
|
-
next.worklog = normalizeItems(parsed.worklog);
|
|
70
|
+
const next = {
|
|
71
|
+
title: normalizeTitle(parsed.title),
|
|
72
|
+
currentState: normalizeItems(parsed.currentState),
|
|
73
|
+
userIntent: normalizeItems(parsed.userIntent),
|
|
74
|
+
activeFiles: normalizeItems(parsed.activeFiles),
|
|
75
|
+
decisions: normalizeItems(parsed.decisions),
|
|
76
|
+
constraints: normalizeItems(parsed.constraints),
|
|
77
|
+
errorsAndCorrections: normalizeItems(parsed.errorsAndCorrections),
|
|
78
|
+
nextSteps: normalizeItems(parsed.nextSteps),
|
|
79
|
+
worklog: normalizeItems(parsed.worklog),
|
|
80
|
+
};
|
|
100
81
|
return next;
|
|
101
82
|
}
|
|
102
83
|
function createEmptySessionMemoryState() {
|
|
@@ -138,7 +119,7 @@ function parseSectionItems(content) {
|
|
|
138
119
|
}
|
|
139
120
|
function parseRenderedSessionMemory(markdown) {
|
|
140
121
|
const state = createEmptySessionMemoryState();
|
|
141
|
-
for (const section of
|
|
122
|
+
for (const section of splitH1Sections(markdown)) {
|
|
142
123
|
switch (section.heading.toLowerCase()) {
|
|
143
124
|
case "session title":
|
|
144
125
|
state.title = stripHtmlComments(section.content).split("\n")[0]?.trim().slice(0, 120) || "";
|
|
@@ -171,19 +152,17 @@ function parseRenderedSessionMemory(markdown) {
|
|
|
171
152
|
}
|
|
172
153
|
return state;
|
|
173
154
|
}
|
|
174
|
-
function mergeSessionMemoryState(
|
|
155
|
+
function mergeSessionMemoryState(_current, update) {
|
|
175
156
|
return {
|
|
176
|
-
title: typeof update.title === "string" ? update.title :
|
|
177
|
-
currentState: Array.isArray(update.currentState) ? update.currentState :
|
|
178
|
-
userIntent: Array.isArray(update.userIntent) ? update.userIntent :
|
|
179
|
-
activeFiles: Array.isArray(update.activeFiles) ? update.activeFiles :
|
|
180
|
-
decisions: Array.isArray(update.decisions) ? update.decisions :
|
|
181
|
-
constraints: Array.isArray(update.constraints) ? update.constraints :
|
|
182
|
-
errorsAndCorrections: Array.isArray(update.errorsAndCorrections)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
nextSteps: Array.isArray(update.nextSteps) ? update.nextSteps : current.nextSteps,
|
|
186
|
-
worklog: Array.isArray(update.worklog) ? update.worklog : current.worklog,
|
|
157
|
+
title: typeof update.title === "string" ? update.title : "",
|
|
158
|
+
currentState: Array.isArray(update.currentState) ? update.currentState : [],
|
|
159
|
+
userIntent: Array.isArray(update.userIntent) ? update.userIntent : [],
|
|
160
|
+
activeFiles: Array.isArray(update.activeFiles) ? update.activeFiles : [],
|
|
161
|
+
decisions: Array.isArray(update.decisions) ? update.decisions : [],
|
|
162
|
+
constraints: Array.isArray(update.constraints) ? update.constraints : [],
|
|
163
|
+
errorsAndCorrections: Array.isArray(update.errorsAndCorrections) ? update.errorsAndCorrections : [],
|
|
164
|
+
nextSteps: Array.isArray(update.nextSteps) ? update.nextSteps : [],
|
|
165
|
+
worklog: Array.isArray(update.worklog) ? update.worklog : [],
|
|
187
166
|
};
|
|
188
167
|
}
|
|
189
168
|
async function writeSessionMemoryDebugFile(channelDir, error, rawText) {
|
|
@@ -200,15 +179,6 @@ async function writeSessionMemoryDebugFile(channelDir, error, rawText) {
|
|
|
200
179
|
function renderSection(heading, items) {
|
|
201
180
|
return [`# ${heading}`, "", ...items.map((item) => `- ${item}`)].join("\n");
|
|
202
181
|
}
|
|
203
|
-
function isStandardAgentMessage(message) {
|
|
204
|
-
return (typeof message === "object" &&
|
|
205
|
-
message !== null &&
|
|
206
|
-
"role" in message &&
|
|
207
|
-
(message.role === "user" || message.role === "assistant" || message.role === "toolResult"));
|
|
208
|
-
}
|
|
209
|
-
function buildMessagesForSessionMemory(messages) {
|
|
210
|
-
return messages.filter(isStandardAgentMessage);
|
|
211
|
-
}
|
|
212
182
|
export function renderSessionMemory(state) {
|
|
213
183
|
const sections = [];
|
|
214
184
|
if (state.title.trim()) {
|
|
@@ -246,7 +216,7 @@ ${transcript || "(empty)"}`;
|
|
|
246
216
|
export async function updateChannelSessionMemory(options) {
|
|
247
217
|
const currentSession = await readChannelSession(options.channelDir);
|
|
248
218
|
const currentMemory = await readChannelMemory(options.channelDir);
|
|
249
|
-
const messages =
|
|
219
|
+
const messages = buildStandardMessages(options.messages);
|
|
250
220
|
const currentState = parseRenderedSessionMemory(currentSession);
|
|
251
221
|
let update;
|
|
252
222
|
try {
|
|
@@ -257,7 +227,7 @@ export async function updateChannelSessionMemory(options) {
|
|
|
257
227
|
systemPrompt: SESSION_MEMORY_SYSTEM_PROMPT,
|
|
258
228
|
prompt: buildSessionPrompt(currentSession, currentMemory, messages),
|
|
259
229
|
parse: parseStateUpdate,
|
|
260
|
-
timeoutMs:
|
|
230
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_SESSION_MEMORY_TIMEOUT_MS,
|
|
261
231
|
});
|
|
262
232
|
update = result.output;
|
|
263
233
|
}
|
|
@@ -271,4 +241,4 @@ export async function updateChannelSessionMemory(options) {
|
|
|
271
241
|
await rewriteChannelSession(options.channelDir, rendered);
|
|
272
242
|
return parseRenderedSessionMemory(rendered);
|
|
273
243
|
}
|
|
274
|
-
//# sourceMappingURL=session
|
|
244
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/memory/session.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Message, Model } from \"@mariozechner/pi-ai\";\nimport { serializeConversation } from \"@mariozechner/pi-coding-agent\";\nimport { writeFile } from \"fs/promises\";\nimport { join } from \"path\";\nimport { parseJsonObject } from \"../llm-json.js\";\nimport { splitH1Sections } from \"../shared/markdown-sections.js\";\nimport { clipText } from \"../shared/text-utils.js\";\nimport { buildStandardMessages, isRecord } from \"../shared/type-guards.js\";\nimport { runSidecarTask, SidecarParseError } from \"../sidecar-worker.js\";\nimport { readChannelMemory, readChannelSession, rewriteChannelSession } from \"./files.js\";\n\nconst SESSION_TRANSCRIPT_MAX_CHARS = 20_000;\nconst SESSION_MEMORY_MAX_CHARS = 4_000;\nconst SESSION_ITEM_LIMIT = 12;\nconst SESSION_ITEM_MAX_CHARS = 300;\nconst DEFAULT_SESSION_MEMORY_TIMEOUT_MS = 30_000;\n\nconst SESSION_MEMORY_SYSTEM_PROMPT = `You maintain a Pipiclaw SESSION.md file.\n\nReturn strict JSON only. Do not use Markdown fences.\n\nOutput schema:\n{\n \"title\": \"string\",\n \"currentState\": [\"string\"],\n \"userIntent\": [\"string\"],\n \"activeFiles\": [\"string\"],\n \"decisions\": [\"string\"],\n \"constraints\": [\"string\"],\n \"errorsAndCorrections\": [\"string\"],\n \"nextSteps\": [\"string\"],\n \"worklog\": [\"string\"]\n}\n\nRules:\n- Prefer short, information-dense bullet-sized items.\n- Capture only the current active work state, not the full conversation history.\n- Keep durable facts out unless they are directly relevant to the current work.\n- \"activeFiles\" should list only files, directories, or work areas currently in focus.\n- \"errorsAndCorrections\" should record recent failures, fixes, or things to avoid repeating.\n- \"nextSteps\" should reflect the most likely immediate follow-up actions.\n- \"worklog\" must stay terse and recent.\n- If a field has nothing useful, return an empty string or empty array.`;\n\nexport interface SessionMemoryState {\n\ttitle: string;\n\tcurrentState: string[];\n\tuserIntent: string[];\n\tactiveFiles: string[];\n\tdecisions: string[];\n\tconstraints: string[];\n\terrorsAndCorrections: string[];\n\tnextSteps: string[];\n\tworklog: string[];\n}\n\nexport interface SessionMemoryUpdateOptions {\n\tchannelDir: string;\n\tmessages: AgentMessage[];\n\tmodel: Model<Api>;\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n\ttimeoutMs?: number;\n}\n\ntype SessionMemoryStateUpdate = Partial<Record<keyof SessionMemoryState, string[] | string>>;\n\nfunction normalizeItem(value: unknown): string | null {\n\tif (typeof value !== \"string\") {\n\t\treturn null;\n\t}\n\tconst normalized = value.replace(/\\s+/g, \" \").trim();\n\tif (!normalized) {\n\t\treturn null;\n\t}\n\treturn normalized.length > SESSION_ITEM_MAX_CHARS\n\t\t? `${normalized.slice(0, SESSION_ITEM_MAX_CHARS - 3)}...`\n\t\t: normalized;\n}\n\nfunction normalizeItems(value: unknown): string[] {\n\tif (!Array.isArray(value)) {\n\t\treturn [];\n\t}\n\treturn value\n\t\t.map(normalizeItem)\n\t\t.filter((item): item is string => !!item)\n\t\t.slice(0, SESSION_ITEM_LIMIT);\n}\n\nfunction normalizeTitle(value: unknown): string {\n\treturn typeof value === \"string\" ? value.trim().slice(0, 120) : \"\";\n}\n\nfunction parseStateUpdate(text: string): SessionMemoryStateUpdate {\n\tconst parsed = parseJsonObject(text);\n\tif (!isRecord(parsed)) {\n\t\tthrow new Error(\"Session memory response was not a JSON object\");\n\t}\n\n\tconst next: SessionMemoryStateUpdate = {\n\t\ttitle: normalizeTitle(parsed.title),\n\t\tcurrentState: normalizeItems(parsed.currentState),\n\t\tuserIntent: normalizeItems(parsed.userIntent),\n\t\tactiveFiles: normalizeItems(parsed.activeFiles),\n\t\tdecisions: normalizeItems(parsed.decisions),\n\t\tconstraints: normalizeItems(parsed.constraints),\n\t\terrorsAndCorrections: normalizeItems(parsed.errorsAndCorrections),\n\t\tnextSteps: normalizeItems(parsed.nextSteps),\n\t\tworklog: normalizeItems(parsed.worklog),\n\t};\n\treturn next;\n}\n\nfunction createEmptySessionMemoryState(): SessionMemoryState {\n\treturn {\n\t\ttitle: \"\",\n\t\tcurrentState: [],\n\t\tuserIntent: [],\n\t\tactiveFiles: [],\n\t\tdecisions: [],\n\t\tconstraints: [],\n\t\terrorsAndCorrections: [],\n\t\tnextSteps: [],\n\t\tworklog: [],\n\t};\n}\n\nfunction stripHtmlComments(text: string): string {\n\treturn text.replace(/<!--[\\s\\S]*?-->/g, \"\").trim();\n}\n\nfunction parseSectionItems(content: string): string[] {\n\tconst normalized = stripHtmlComments(content);\n\tif (!normalized) {\n\t\treturn [];\n\t}\n\n\tconst lines = normalized\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim())\n\t\t.filter(Boolean);\n\tconst bulletItems = lines\n\t\t.filter((line) => line.startsWith(\"- \"))\n\t\t.map((line) => normalizeItem(line.slice(2)))\n\t\t.filter((item): item is string => !!item);\n\tif (bulletItems.length > 0) {\n\t\treturn bulletItems.slice(0, SESSION_ITEM_LIMIT);\n\t}\n\treturn lines\n\t\t.map(normalizeItem)\n\t\t.filter((item): item is string => !!item)\n\t\t.slice(0, SESSION_ITEM_LIMIT);\n}\n\nfunction parseRenderedSessionMemory(markdown: string): SessionMemoryState {\n\tconst state = createEmptySessionMemoryState();\n\tfor (const section of splitH1Sections(markdown)) {\n\t\tswitch (section.heading.toLowerCase()) {\n\t\t\tcase \"session title\":\n\t\t\t\tstate.title = stripHtmlComments(section.content).split(\"\\n\")[0]?.trim().slice(0, 120) || \"\";\n\t\t\t\tbreak;\n\t\t\tcase \"current state\":\n\t\t\t\tstate.currentState = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"user intent\":\n\t\t\t\tstate.userIntent = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"active files\":\n\t\t\t\tstate.activeFiles = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"decisions\":\n\t\t\t\tstate.decisions = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"constraints\":\n\t\t\t\tstate.constraints = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"errors & corrections\":\n\t\t\t\tstate.errorsAndCorrections = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"next steps\":\n\t\t\t\tstate.nextSteps = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t\tcase \"worklog\":\n\t\t\t\tstate.worklog = parseSectionItems(section.content);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\treturn state;\n}\n\nfunction mergeSessionMemoryState(_current: SessionMemoryState, update: SessionMemoryStateUpdate): SessionMemoryState {\n\treturn {\n\t\ttitle: typeof update.title === \"string\" ? update.title : \"\",\n\t\tcurrentState: Array.isArray(update.currentState) ? update.currentState : [],\n\t\tuserIntent: Array.isArray(update.userIntent) ? update.userIntent : [],\n\t\tactiveFiles: Array.isArray(update.activeFiles) ? update.activeFiles : [],\n\t\tdecisions: Array.isArray(update.decisions) ? update.decisions : [],\n\t\tconstraints: Array.isArray(update.constraints) ? update.constraints : [],\n\t\terrorsAndCorrections: Array.isArray(update.errorsAndCorrections) ? update.errorsAndCorrections : [],\n\t\tnextSteps: Array.isArray(update.nextSteps) ? update.nextSteps : [],\n\t\tworklog: Array.isArray(update.worklog) ? update.worklog : [],\n\t};\n}\n\nasync function writeSessionMemoryDebugFile(channelDir: string, error: unknown, rawText: string): Promise<void> {\n\tconst debugPath = join(channelDir, \"SESSION.invalid-response.txt\");\n\tconst header = [\n\t\t`timestamp: ${new Date().toISOString()}`,\n\t\t`error: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\"\",\n\t\t\"raw response:\",\n\t\t\"\",\n\t].join(\"\\n\");\n\tawait writeFile(debugPath, `${header}${rawText}\\n`, \"utf-8\");\n}\n\nfunction renderSection(heading: string, items: string[]): string {\n\treturn [`# ${heading}`, \"\", ...items.map((item) => `- ${item}`)].join(\"\\n\");\n}\n\nexport function renderSessionMemory(state: SessionMemoryState): string {\n\tconst sections: string[] = [];\n\tif (state.title.trim()) {\n\t\tsections.push(\"# Session Title\", \"\", state.title.trim());\n\t}\n\n\tconst orderedSections: Array<[string, string[]]> = [\n\t\t[\"Current State\", state.currentState],\n\t\t[\"User Intent\", state.userIntent],\n\t\t[\"Active Files\", state.activeFiles],\n\t\t[\"Decisions\", state.decisions],\n\t\t[\"Constraints\", state.constraints],\n\t\t[\"Errors & Corrections\", state.errorsAndCorrections],\n\t\t[\"Next Steps\", state.nextSteps],\n\t\t[\"Worklog\", state.worklog],\n\t];\n\n\tfor (const [heading, items] of orderedSections) {\n\t\tif (items.length === 0 && heading === \"Worklog\") {\n\t\t\tcontinue;\n\t\t}\n\t\tsections.push(renderSection(heading, items));\n\t}\n\n\treturn `${sections.join(\"\\n\\n\").trim()}\\n`;\n}\n\nfunction buildSessionPrompt(currentSession: string, currentMemory: string, messages: Message[]): string {\n\tconst transcript = clipText(serializeConversation(messages), SESSION_TRANSCRIPT_MAX_CHARS);\n\treturn `Current SESSION.md:\n${currentSession || \"(empty)\"}\n\nCurrent channel MEMORY.md:\n${clipText(currentMemory, SESSION_MEMORY_MAX_CHARS) || \"(empty)\"}\n\nRecent conversation:\n${transcript || \"(empty)\"}`;\n}\n\nexport async function updateChannelSessionMemory(options: SessionMemoryUpdateOptions): Promise<SessionMemoryState> {\n\tconst currentSession = await readChannelSession(options.channelDir);\n\tconst currentMemory = await readChannelMemory(options.channelDir);\n\tconst messages = buildStandardMessages(options.messages);\n\tconst currentState = parseRenderedSessionMemory(currentSession);\n\n\tlet update: SessionMemoryStateUpdate;\n\ttry {\n\t\tconst result = await runSidecarTask({\n\t\t\tname: \"session-memory-update\",\n\t\t\tmodel: options.model,\n\t\t\tresolveApiKey: options.resolveApiKey,\n\t\t\tsystemPrompt: SESSION_MEMORY_SYSTEM_PROMPT,\n\t\t\tprompt: buildSessionPrompt(currentSession, currentMemory, messages),\n\t\t\tparse: parseStateUpdate,\n\t\t\ttimeoutMs: options.timeoutMs ?? DEFAULT_SESSION_MEMORY_TIMEOUT_MS,\n\t\t});\n\t\tupdate = result.output;\n\t} catch (error) {\n\t\tif (error instanceof SidecarParseError) {\n\t\t\tawait writeSessionMemoryDebugFile(options.channelDir, error.cause ?? error, error.rawText);\n\t\t}\n\t\tthrow error;\n\t}\n\n\tconst rendered = renderSessionMemory(mergeSessionMemoryState(currentState, update));\n\tawait rewriteChannelSession(options.channelDir, rendered);\n\treturn parseRenderedSessionMemory(rendered);\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type SandboxConfig } from "../sandbox.js";
|
|
2
|
+
import { DingTalkBot, type DingTalkConfig } from "./dingtalk.js";
|
|
3
|
+
import { ChannelStore } from "./store.js";
|
|
4
|
+
export interface BootstrapPaths {
|
|
5
|
+
appName: string;
|
|
6
|
+
appHomeDir: string;
|
|
7
|
+
workspaceDir: string;
|
|
8
|
+
authConfigPath: string;
|
|
9
|
+
channelConfigPath: string;
|
|
10
|
+
modelsConfigPath: string;
|
|
11
|
+
settingsConfigPath: string;
|
|
12
|
+
}
|
|
13
|
+
export interface BootstrapIO {
|
|
14
|
+
log: (...args: unknown[]) => void;
|
|
15
|
+
error: (...args: unknown[]) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface BootstrapOptions {
|
|
18
|
+
env?: NodeJS.ProcessEnv;
|
|
19
|
+
io?: BootstrapIO;
|
|
20
|
+
paths?: BootstrapPaths;
|
|
21
|
+
registerSignalHandlers?: boolean;
|
|
22
|
+
startServices?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface ParsedArgs {
|
|
25
|
+
sandbox: SandboxConfig;
|
|
26
|
+
}
|
|
27
|
+
export interface BootstrapResult {
|
|
28
|
+
created: string[];
|
|
29
|
+
channelTemplateCreated: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface AppContext {
|
|
32
|
+
bot: DingTalkBot;
|
|
33
|
+
store: ChannelStore;
|
|
34
|
+
shutdown: () => Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
export declare const DEFAULT_BOOTSTRAP_PATHS: BootstrapPaths;
|
|
37
|
+
export declare class BootstrapExitError extends Error {
|
|
38
|
+
readonly code: number;
|
|
39
|
+
constructor(code: number, message?: string);
|
|
40
|
+
}
|
|
41
|
+
export declare function isBootstrapExitError(error: unknown): error is BootstrapExitError;
|
|
42
|
+
export declare function sanitizeProxyEnv(env: NodeJS.ProcessEnv): void;
|
|
43
|
+
export declare function bootstrapAppHome(paths?: BootstrapPaths): BootstrapResult;
|
|
44
|
+
export declare function printBootstrapSummary(result: BootstrapResult, io?: BootstrapIO, paths?: BootstrapPaths): void;
|
|
45
|
+
export declare function loadConfig(paths?: BootstrapPaths, io?: BootstrapIO): DingTalkConfig;
|
|
46
|
+
export declare function parseArgs(argv: string[], paths?: BootstrapPaths, io?: BootstrapIO): ParsedArgs;
|
|
47
|
+
export declare function bootstrap(argv: string[], options?: BootstrapOptions): Promise<AppContext>;
|
|
48
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"AAeA,OAAO,EAAmB,KAAK,aAAa,EAAmB,MAAM,eAAe,CAAC;AAErF,OAAO,EAEN,WAAW,EACX,KAAK,cAAc,EAGnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sBAAsB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAmFD,eAAO,MAAM,uBAAuB,EAAE,cAQrC,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAK1C;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEhF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAS7D;AAeD,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,cAAwC,GAAG,eAAe,CAmCjG;AAsCD,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,eAAe,EACvB,EAAE,GAAE,WAAqB,EACzB,KAAK,GAAE,cAAwC,GAC7C,IAAI,CAUN;AAED,wBAAgB,UAAU,CAAC,KAAK,GAAE,cAAwC,EAAE,EAAE,GAAE,WAAqB,GAAG,cAAc,CA6BrH;AAED,wBAAgB,SAAS,CACxB,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,GAAE,cAAwC,EAC/C,EAAE,GAAE,WAAqB,GACvB,UAAU,CAyBZ;AAeD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CAgPnG"}
|