@oyasmi/pipiclaw 0.3.4 → 0.4.0
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 +3 -0
- package/LICENSE +184 -0
- package/README.md +230 -231
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +2 -19
- package/dist/agent.js.map +1 -1
- package/dist/command-extension.d.ts.map +1 -1
- package/dist/command-extension.js.map +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js.map +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +0 -2
- package/dist/context.js.map +1 -1
- package/dist/delivery.d.ts.map +1 -1
- package/dist/delivery.js +11 -14
- package/dist/delivery.js.map +1 -1
- package/dist/dingtalk.d.ts.map +1 -1
- package/dist/dingtalk.js +26 -26
- package/dist/dingtalk.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +5 -8
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js.map +1 -1
- package/dist/memory-consolidation.d.ts.map +1 -1
- package/dist/memory-consolidation.js.map +1 -1
- package/dist/memory-files.d.ts.map +1 -1
- package/dist/memory-files.js.map +1 -1
- package/dist/memory-lifecycle.d.ts.map +1 -1
- package/dist/memory-lifecycle.js +1 -2
- package/dist/memory-lifecycle.js.map +1 -1
- package/dist/model-utils.d.ts.map +1 -1
- package/dist/model-utils.js.map +1 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/prompt-builder.d.ts.map +1 -1
- package/dist/prompt-builder.js.map +1 -1
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +0 -1
- package/dist/sandbox.js.map +1 -1
- package/dist/shell-escape.d.ts.map +1 -1
- package/dist/shell-escape.js.map +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +2 -3
- package/dist/store.js.map +1 -1
- package/dist/sub-agents.d.ts.map +1 -1
- package/dist/sub-agents.js +42 -10
- package/dist/sub-agents.js.map +1 -1
- package/dist/tools/attach.d.ts.map +1 -1
- package/dist/tools/attach.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/truncate.d.ts.map +1 -1
- package/dist/tools/truncate.js.map +1 -1
- package/dist/tools/write-content.d.ts.map +1 -1
- package/dist/tools/write-content.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js.map +1 -1
- package/docs/memory-rfc.md +291 -0
- package/docs/subagent/pi-subagent-analyse.txt +190 -0
- package/docs/subagent/pi-subagent-design.txt +266 -0
- package/docs/subagent/pi-subagent-phase1-plan.txt +529 -0
- package/package.json +69 -53
package/dist/log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from \"chalk\";\n\nexport interface LogContext {\n\tchannelId: string;\n\tuserName?: string;\n\tchannelName?: string;\n}\n\nfunction timestamp(): string {\n\tconst now = new Date();\n\tconst hh = String(now.getHours()).padStart(2, \"0\");\n\tconst mm = String(now.getMinutes()).padStart(2, \"0\");\n\tconst ss = String(now.getSeconds()).padStart(2, \"0\");\n\treturn `[${hh}:${mm}:${ss}]`;\n}\n\nfunction formatContext(ctx: LogContext): string {\n\t// DMs: [DM:username]\n\t// Groups: [group:channelId:username]\n\tif (ctx.channelId.startsWith(\"dm_\")) {\n\t\treturn `[DM:${ctx.userName || ctx.channelId}]`;\n\t}\n\tconst channel = ctx.channelName || ctx.channelId;\n\tconst user = ctx.userName || \"unknown\";\n\treturn `[${channel}:${user}]`;\n}\n\nfunction truncate(text: string, maxLen: number): string {\n\tif (text.length <= maxLen) return text;\n\treturn `${text.substring(0, maxLen)}\\n(truncated at ${maxLen} chars)`;\n}\n\nfunction formatToolArgs(args: Record<string, unknown>): string {\n\tconst lines: string[] = [];\n\n\tfor (const [key, value] of Object.entries(args)) {\n\t\tif (key === \"label\") continue;\n\n\t\tif (key === \"path\" && typeof value === \"string\") {\n\t\t\tconst offset = args.offset as number | undefined;\n\t\t\tconst limit = args.limit as number | undefined;\n\t\t\tif (offset !== undefined && limit !== undefined) {\n\t\t\t\tlines.push(`${value}:${offset}-${offset + limit}`);\n\t\t\t} else {\n\t\t\t\tlines.push(value);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (key === \"offset\" || key === \"limit\") continue;\n\n\t\tif (typeof value === \"string\") {\n\t\t\tlines.push(value);\n\t\t} else {\n\t\t\tlines.push(JSON.stringify(value));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n// User messages\nexport function logUserMessage(ctx: LogContext, text: string): void {\n\tconsole.log(chalk.green(`${timestamp()} ${formatContext(ctx)} ${text}`));\n}\n\n// Tool execution\nexport function logToolStart(ctx: LogContext, toolName: string, label: string, args: Record<string, unknown>): void {\n\tconst formattedArgs = formatToolArgs(args);\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ↳ ${toolName}: ${label}`));\n\tif (formattedArgs) {\n\t\tconst indented = formattedArgs\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => ` ${line}`)\n\t\t\t.join(\"\\n\");\n\t\tconsole.log(chalk.dim(indented));\n\t}\n}\n\nexport function logToolSuccess(ctx: LogContext, toolName: string, durationMs: number, result: string): void {\n\tconst duration = (durationMs / 1000).toFixed(1);\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ✓ ${toolName} (${duration}s)`));\n\n\tconst truncated = truncate(result, 1000);\n\tif (truncated) {\n\t\tconst indented = truncated\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => ` ${line}`)\n\t\t\t.join(\"\\n\");\n\t\tconsole.log(chalk.dim(indented));\n\t}\n}\n\nexport function logToolError(ctx: LogContext, toolName: string, durationMs: number, error: string): void {\n\tconst duration = (durationMs / 1000).toFixed(1);\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ✗ ${toolName} (${duration}s)`));\n\n\tconst truncated = truncate(error, 1000);\n\tconst indented = truncated\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\n// Response streaming\nexport function logResponseStart(ctx: LogContext): void {\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} → Streaming response...`));\n}\n\nexport function logThinking(ctx: LogContext, thinking: string): void {\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} 💭 Thinking`));\n\tconst truncated = truncate(thinking, 1000);\n\tconst indented = truncated\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\nexport function logResponse(ctx: LogContext, text: string): void {\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} 💬 Response`));\n\tconst truncated = truncate(text, 1000);\n\tconst indented = truncated\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\n// Control\nexport function logStopRequest(ctx: LogContext): void {\n\tconsole.log(chalk.green(`${timestamp()} ${formatContext(ctx)} stop`));\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ⊗ Stop requested - aborting`));\n}\n\n// System\nexport function logInfo(message: string): void {\n\tconsole.log(chalk.blue(`${timestamp()} [system] ${message}`));\n}\n\nexport function logWarning(message: string, details?: string): void {\n\tconsole.log(chalk.yellow(`${timestamp()} [system] ⚠ ${message}`));\n\tif (details) {\n\t\tconst indented = details\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => ` ${line}`)\n\t\t\t.join(\"\\n\");\n\t\tconsole.log(chalk.dim(indented));\n\t}\n}\n\nexport function logAgentError(ctx: LogContext | \"system\", error: string): void {\n\tconst context = ctx === \"system\" ? \"[system]\" : formatContext(ctx);\n\tconsole.log(chalk.yellow(`${timestamp()} ${context} ✗ Agent error`));\n\tconst indented = error\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\n// Usage summary\nexport function logUsageSummary(\n\tctx: LogContext,\n\tusage: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n\t},\n\tcontextTokens?: number,\n\tcontextWindow?: number,\n): string {\n\tconst formatTokens = (count: number): string => {\n\t\tif (count < 1000) return count.toString();\n\t\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\t\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\t\treturn `${(count / 1000000).toFixed(1)}M`;\n\t};\n\n\tconst lines: string[] = [];\n\tlines.push(\"**Usage Summary**\");\n\tlines.push(`Tokens: ${usage.input.toLocaleString()} in, ${usage.output.toLocaleString()} out`);\n\tif (usage.cacheRead > 0 || usage.cacheWrite > 0) {\n\t\tlines.push(`Cache: ${usage.cacheRead.toLocaleString()} read, ${usage.cacheWrite.toLocaleString()} write`);\n\t}\n\tif (contextTokens && contextWindow) {\n\t\tconst contextPercent = ((contextTokens / contextWindow) * 100).toFixed(1);\n\t\tlines.push(`Context: ${formatTokens(contextTokens)} / ${formatTokens(contextWindow)} (${contextPercent}%)`);\n\t}\n\tlines.push(\n\t\t`Cost: $${usage.cost.input.toFixed(4)} in, $${usage.cost.output.toFixed(4)} out` +\n\t\t\t(usage.cacheRead > 0 || usage.cacheWrite > 0\n\t\t\t\t? `, $${usage.cost.cacheRead.toFixed(4)} cache read, $${usage.cost.cacheWrite.toFixed(4)} cache write`\n\t\t\t\t: \"\"),\n\t);\n\tlines.push(`**Total: $${usage.cost.total.toFixed(4)}**`);\n\n\tconst summary = lines.join(\"\\n\");\n\n\t// Log to console\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} 💰 Usage`));\n\tconsole.log(\n\t\tchalk.dim(\n\t\t\t` ${usage.input.toLocaleString()} in + ${usage.output.toLocaleString()} out` +\n\t\t\t\t(usage.cacheRead > 0 || usage.cacheWrite > 0\n\t\t\t\t\t? ` (${usage.cacheRead.toLocaleString()} cache read, ${usage.cacheWrite.toLocaleString()} cache write)`\n\t\t\t\t\t: \"\") +\n\t\t\t\t` = $${usage.cost.total.toFixed(4)}`,\n\t\t),\n\t);\n\n\treturn summary;\n}\n\n// Startup\nexport function logStartup(workingDir: string, sandbox: string): void {\n\tconsole.log(\"Starting pipiclaw...\");\n\tconsole.log(` Working directory: ${workingDir}`);\n\tconsole.log(` Sandbox: ${sandbox}`);\n}\n\nexport function logConnected(): void {\n\tconsole.log(\"⚡️ pipiclaw connected and listening!\");\n\tconsole.log(\"\");\n}\n\nexport function logDisconnected(): void {\n\tconsole.log(\"pipiclaw disconnected.\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from \"chalk\";\n\nexport interface LogContext {\n\tchannelId: string;\n\tuserName?: string;\n\tchannelName?: string;\n}\n\nfunction timestamp(): string {\n\tconst now = new Date();\n\tconst hh = String(now.getHours()).padStart(2, \"0\");\n\tconst mm = String(now.getMinutes()).padStart(2, \"0\");\n\tconst ss = String(now.getSeconds()).padStart(2, \"0\");\n\treturn `[${hh}:${mm}:${ss}]`;\n}\n\nfunction formatContext(ctx: LogContext): string {\n\t// DMs: [DM:username]\n\t// Groups: [group:channelId:username]\n\tif (ctx.channelId.startsWith(\"dm_\")) {\n\t\treturn `[DM:${ctx.userName || ctx.channelId}]`;\n\t}\n\tconst channel = ctx.channelName || ctx.channelId;\n\tconst user = ctx.userName || \"unknown\";\n\treturn `[${channel}:${user}]`;\n}\n\nfunction truncate(text: string, maxLen: number): string {\n\tif (text.length <= maxLen) return text;\n\treturn `${text.substring(0, maxLen)}\\n(truncated at ${maxLen} chars)`;\n}\n\nfunction formatToolArgs(args: Record<string, unknown>): string {\n\tconst lines: string[] = [];\n\n\tfor (const [key, value] of Object.entries(args)) {\n\t\tif (key === \"label\") continue;\n\n\t\tif (key === \"path\" && typeof value === \"string\") {\n\t\t\tconst offset = args.offset as number | undefined;\n\t\t\tconst limit = args.limit as number | undefined;\n\t\t\tif (offset !== undefined && limit !== undefined) {\n\t\t\t\tlines.push(`${value}:${offset}-${offset + limit}`);\n\t\t\t} else {\n\t\t\t\tlines.push(value);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (key === \"offset\" || key === \"limit\") continue;\n\n\t\tif (typeof value === \"string\") {\n\t\t\tlines.push(value);\n\t\t} else {\n\t\t\tlines.push(JSON.stringify(value));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n// User messages\nexport function logUserMessage(ctx: LogContext, text: string): void {\n\tconsole.log(chalk.green(`${timestamp()} ${formatContext(ctx)} ${text}`));\n}\n\n// Tool execution\nexport function logToolStart(ctx: LogContext, toolName: string, label: string, args: Record<string, unknown>): void {\n\tconst formattedArgs = formatToolArgs(args);\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ↳ ${toolName}: ${label}`));\n\tif (formattedArgs) {\n\t\tconst indented = formattedArgs\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => ` ${line}`)\n\t\t\t.join(\"\\n\");\n\t\tconsole.log(chalk.dim(indented));\n\t}\n}\n\nexport function logToolSuccess(ctx: LogContext, toolName: string, durationMs: number, result: string): void {\n\tconst duration = (durationMs / 1000).toFixed(1);\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ✓ ${toolName} (${duration}s)`));\n\n\tconst truncated = truncate(result, 1000);\n\tif (truncated) {\n\t\tconst indented = truncated\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => ` ${line}`)\n\t\t\t.join(\"\\n\");\n\t\tconsole.log(chalk.dim(indented));\n\t}\n}\n\nexport function logToolError(ctx: LogContext, toolName: string, durationMs: number, error: string): void {\n\tconst duration = (durationMs / 1000).toFixed(1);\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ✗ ${toolName} (${duration}s)`));\n\n\tconst truncated = truncate(error, 1000);\n\tconst indented = truncated\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\n// Response streaming\nexport function logResponseStart(ctx: LogContext): void {\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} → Streaming response...`));\n}\n\nexport function logThinking(ctx: LogContext, thinking: string): void {\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} 💭 Thinking`));\n\tconst truncated = truncate(thinking, 1000);\n\tconst indented = truncated\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\nexport function logResponse(ctx: LogContext, text: string): void {\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} 💬 Response`));\n\tconst truncated = truncate(text, 1000);\n\tconst indented = truncated\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\n// Control\nexport function logStopRequest(ctx: LogContext): void {\n\tconsole.log(chalk.green(`${timestamp()} ${formatContext(ctx)} stop`));\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} ⊗ Stop requested - aborting`));\n}\n\n// System\nexport function logInfo(message: string): void {\n\tconsole.log(chalk.blue(`${timestamp()} [system] ${message}`));\n}\n\nexport function logWarning(message: string, details?: string): void {\n\tconsole.log(chalk.yellow(`${timestamp()} [system] ⚠ ${message}`));\n\tif (details) {\n\t\tconst indented = details\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => ` ${line}`)\n\t\t\t.join(\"\\n\");\n\t\tconsole.log(chalk.dim(indented));\n\t}\n}\n\nexport function logAgentError(ctx: LogContext | \"system\", error: string): void {\n\tconst context = ctx === \"system\" ? \"[system]\" : formatContext(ctx);\n\tconsole.log(chalk.yellow(`${timestamp()} ${context} ✗ Agent error`));\n\tconst indented = error\n\t\t.split(\"\\n\")\n\t\t.map((line) => ` ${line}`)\n\t\t.join(\"\\n\");\n\tconsole.log(chalk.dim(indented));\n}\n\n// Usage summary\nexport function logUsageSummary(\n\tctx: LogContext,\n\tusage: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n\t},\n\tcontextTokens?: number,\n\tcontextWindow?: number,\n): string {\n\tconst formatTokens = (count: number): string => {\n\t\tif (count < 1000) return count.toString();\n\t\tif (count < 10000) return `${(count / 1000).toFixed(1)}k`;\n\t\tif (count < 1000000) return `${Math.round(count / 1000)}k`;\n\t\treturn `${(count / 1000000).toFixed(1)}M`;\n\t};\n\n\tconst lines: string[] = [];\n\tlines.push(\"**Usage Summary**\");\n\tlines.push(`Tokens: ${usage.input.toLocaleString()} in, ${usage.output.toLocaleString()} out`);\n\tif (usage.cacheRead > 0 || usage.cacheWrite > 0) {\n\t\tlines.push(`Cache: ${usage.cacheRead.toLocaleString()} read, ${usage.cacheWrite.toLocaleString()} write`);\n\t}\n\tif (contextTokens && contextWindow) {\n\t\tconst contextPercent = ((contextTokens / contextWindow) * 100).toFixed(1);\n\t\tlines.push(`Context: ${formatTokens(contextTokens)} / ${formatTokens(contextWindow)} (${contextPercent}%)`);\n\t}\n\tlines.push(\n\t\t`Cost: $${usage.cost.input.toFixed(4)} in, $${usage.cost.output.toFixed(4)} out` +\n\t\t\t(usage.cacheRead > 0 || usage.cacheWrite > 0\n\t\t\t\t? `, $${usage.cost.cacheRead.toFixed(4)} cache read, $${usage.cost.cacheWrite.toFixed(4)} cache write`\n\t\t\t\t: \"\"),\n\t);\n\tlines.push(`**Total: $${usage.cost.total.toFixed(4)}**`);\n\n\tconst summary = lines.join(\"\\n\");\n\n\t// Log to console\n\tconsole.log(chalk.yellow(`${timestamp()} ${formatContext(ctx)} 💰 Usage`));\n\tconsole.log(\n\t\tchalk.dim(\n\t\t\t` ${usage.input.toLocaleString()} in + ${usage.output.toLocaleString()} out` +\n\t\t\t\t(usage.cacheRead > 0 || usage.cacheWrite > 0\n\t\t\t\t\t? ` (${usage.cacheRead.toLocaleString()} cache read, ${usage.cacheWrite.toLocaleString()} cache write)`\n\t\t\t\t\t: \"\") +\n\t\t\t\t` = $${usage.cost.total.toFixed(4)}`,\n\t\t),\n\t);\n\n\treturn summary;\n}\n\n// Startup\nexport function logStartup(workingDir: string, sandbox: string): void {\n\tconsole.log(\"Starting pipiclaw...\");\n\tconsole.log(` Working directory: ${workingDir}`);\n\tconsole.log(` Sandbox: ${sandbox}`);\n}\n\nexport function logConnected(): void {\n\tconsole.log(\"⚡️ pipiclaw connected and listening!\");\n\tconsole.log(\"\");\n}\n\nexport function logDisconnected(): void {\n\tconsole.log(\"pipiclaw disconnected.\");\n}\n"]}
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { type AgentRunner, getOrCreateRunner } from \"./agent.js\";\nimport { parseBuiltInCommand } from \"./commands.js\";\nimport { createDingTalkContext } from \"./delivery.js\";\nimport {\n\ttype BusyMessageMode,\n\tDingTalkBot,\n\ttype DingTalkConfig,\n\ttype DingTalkEvent,\n\ttype DingTalkHandler,\n} from \"./dingtalk.js\";\nimport { createEventsWatcher } from \"./events.js\";\nimport * as log from \"./log.js\";\nimport { ensureChannelMemoryFilesSync } from \"./memory-files.js\";\nimport {\n\tAPP_HOME_DIR,\n\tAPP_NAME,\n\tAUTH_CONFIG_PATH,\n\tCHANNEL_CONFIG_PATH,\n\tMODELS_CONFIG_PATH,\n\tSETTINGS_CONFIG_PATH,\n\tWORKSPACE_DIR,\n} from \"./paths.js\";\nimport { parseSandboxArg, type SandboxConfig, validateSandbox } from \"./sandbox.js\";\nimport { ChannelStore } from \"./store.js\";\n\nif (process.env.DINGTALK_FORCE_PROXY !== \"true\") {\n\tdelete process.env.http_proxy;\n\tdelete process.env.https_proxy;\n\tdelete process.env.all_proxy;\n\tdelete process.env.HTTP_PROXY;\n\tdelete process.env.HTTPS_PROXY;\n\tdelete process.env.ALL_PROXY;\n}\n\ninterface ParsedArgs {\n\tsandbox: SandboxConfig;\n}\n\ninterface BootstrapResult {\n\tcreated: string[];\n\tchannelTemplateCreated: boolean;\n}\n\nconst DEFAULT_SOUL = `# SOUL.md\n\nConfigure Pipiclaw's identity, voice, and communication style here.\n\nSuggested sections:\n\n- Who the assistant is\n- Default language\n- Tone and personality\n- Reply style\n- Formatting preferences\n\nExample topics you may want to define:\n\n- \"Answer in Chinese by default.\"\n- \"Be concise and direct.\"\n- \"Prefer Markdown.\"\n- \"Act as an engineering assistant for our team.\"\n\nReplace this template with your actual identity prompt.\n`;\n\nconst DEFAULT_AGENT = `# AGENTS.md\n\nConfigure Pipiclaw's operating rules here.\n\nThis file should define behavior and workflow. Identity, tone, and personality belong in \\`SOUL.md\\`.\n\nSuggested sections:\n\n- Tool usage policy\n- Security constraints\n- Scheduling/reminder policy\n- Project-specific workflows\n- Things the assistant must always or never do\n\nReplace this template with your actual operating instructions.\n`;\n\nconst DEFAULT_MEMORY = `# Workspace Memory\n\nThis file stores stable workspace-level memory.\n\n- It is intended to be managed by a human administrator.\n- It is not automatically rewritten by normal runtime consolidation.\n- Store durable shared background here when it should apply across channels.\n- Keep this file focused on stable facts, policies, and shared context, not transient conversation history.\n\n## Shared Context\n\n<!-- Put team-wide or workspace-wide background here. -->\n\n## Tooling And Environment\n\n<!-- Put durable tool usage rules, environment assumptions, or shared operational conventions here. -->\n\n## Project Notes\n\n<!-- Put long-lived project facts here. -->\n`;\n\nconst CHANNEL_CONFIG_TEMPLATE = {\n\tclientId: \"your-dingtalk-client-id\",\n\tclientSecret: \"your-dingtalk-client-secret\",\n\trobotCode: \"your-robot-code\",\n\tcardTemplateId: \"your-card-template-id\",\n\tcardTemplateKey: \"content\",\n\tallowFrom: [\"your-staff-id\"],\n} satisfies DingTalkConfig;\n\nconst MODELS_CONFIG_TEMPLATE = { providers: {} };\n\nfunction writeTextFileIfMissing(path: string, content: string, label: string, created: string[]): boolean {\n\tif (existsSync(path)) {\n\t\treturn false;\n\t}\n\twriteFileSync(path, content, \"utf-8\");\n\tcreated.push(label);\n\treturn true;\n}\n\nfunction writeJsonFileIfMissing(path: string, value: unknown, label: string, created: string[]): boolean {\n\treturn writeTextFileIfMissing(path, `${JSON.stringify(value, null, 2)}\\n`, label, created);\n}\n\nfunction bootstrapAppHome(): BootstrapResult {\n\tconst created: string[] = [];\n\n\tif (!existsSync(APP_HOME_DIR)) {\n\t\tmkdirSync(APP_HOME_DIR, { recursive: true });\n\t\tcreated.push(\"app home\");\n\t}\n\tif (!existsSync(WORKSPACE_DIR)) {\n\t\tmkdirSync(WORKSPACE_DIR, { recursive: true });\n\t\tcreated.push(\"workspace/\");\n\t}\n\n\tfor (const dir of [\"skills\", \"events\", \"sub-agents\"]) {\n\t\tconst dirPath = join(WORKSPACE_DIR, dir);\n\t\tif (!existsSync(dirPath)) {\n\t\t\tmkdirSync(dirPath, { recursive: true });\n\t\t\tcreated.push(`workspace/${dir}/`);\n\t\t}\n\t}\n\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"SOUL.md\"), DEFAULT_SOUL, \"workspace/SOUL.md\", created);\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"AGENTS.md\"), DEFAULT_AGENT, \"workspace/AGENTS.md\", created);\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"MEMORY.md\"), DEFAULT_MEMORY, \"workspace/MEMORY.md\", created);\n\n\tconst channelTemplateCreated = writeJsonFileIfMissing(\n\t\tCHANNEL_CONFIG_PATH,\n\t\tCHANNEL_CONFIG_TEMPLATE,\n\t\t\"channel.json\",\n\t\tcreated,\n\t);\n\twriteJsonFileIfMissing(AUTH_CONFIG_PATH, {}, \"auth.json\", created);\n\twriteJsonFileIfMissing(MODELS_CONFIG_PATH, MODELS_CONFIG_TEMPLATE, \"models.json\", created);\n\twriteJsonFileIfMissing(SETTINGS_CONFIG_PATH, {}, \"settings.json\", created);\n\n\treturn { created, channelTemplateCreated };\n}\n\nfunction isPlaceholderString(value: string): boolean {\n\treturn value.trim().startsWith(\"your-\");\n}\n\nfunction listChannelConfigIssues(config: Partial<DingTalkConfig>): string[] {\n\tconst issues: string[] = [];\n\n\tif (!config.clientId) {\n\t\tissues.push(\"Missing required field `clientId`.\");\n\t} else if (isPlaceholderString(config.clientId)) {\n\t\tissues.push(\"Replace placeholder value for `clientId`.\");\n\t}\n\n\tif (!config.clientSecret) {\n\t\tissues.push(\"Missing required field `clientSecret`.\");\n\t} else if (isPlaceholderString(config.clientSecret)) {\n\t\tissues.push(\"Replace placeholder value for `clientSecret`.\");\n\t}\n\n\tif (config.robotCode && isPlaceholderString(config.robotCode)) {\n\t\tissues.push(\"Replace placeholder value for `robotCode`, or set it to an empty string to reuse `clientId`.\");\n\t}\n\n\tif (config.cardTemplateId && isPlaceholderString(config.cardTemplateId)) {\n\t\tissues.push(\n\t\t\t\"Replace placeholder value for `cardTemplateId`, or set it to an empty string to disable AI Card streaming.\",\n\t\t);\n\t}\n\n\tif (Array.isArray(config.allowFrom) && config.allowFrom.some((value) => isPlaceholderString(value))) {\n\t\tissues.push(\"Replace placeholder values in `allowFrom`, or set it to an empty array to allow all users.\");\n\t}\n\n\treturn issues;\n}\n\nfunction printBootstrapSummary(result: BootstrapResult): void {\n\tif (result.created.length === 0) {\n\t\treturn;\n\t}\n\n\tconsole.log(`Initialized ${APP_NAME} under ${APP_HOME_DIR}:`);\n\tfor (const item of result.created) {\n\t\tconsole.log(` - ${item}`);\n\t}\n\tconsole.log(\"\");\n}\n\nfunction loadConfig(): DingTalkConfig {\n\tlet parsed: DingTalkConfig;\n\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(CHANNEL_CONFIG_PATH, \"utf-8\")) as DingTalkConfig;\n\t} catch (err) {\n\t\tconsole.error(`Failed to parse configuration: ${CHANNEL_CONFIG_PATH}`);\n\t\tconsole.error(err instanceof Error ? err.message : String(err));\n\t\tprocess.exit(1);\n\t}\n\n\tconst issues = listChannelConfigIssues(parsed);\n\tif (issues.length > 0) {\n\t\tconsole.error(`Configuration is not ready: ${CHANNEL_CONFIG_PATH}`);\n\t\tfor (const issue of issues) {\n\t\t\tconsole.error(` - ${issue}`);\n\t\t}\n\t\tconsole.error(\"\");\n\t\tconsole.error(`Fill in ${CHANNEL_CONFIG_PATH} and run \\`${APP_NAME}\\` again.`);\n\t\tprocess.exit(1);\n\t}\n\n\tparsed.cardTemplateKey = parsed.cardTemplateKey || \"content\";\n\tparsed.robotCode = parsed.robotCode?.trim() ? parsed.robotCode : parsed.clientId;\n\tif (Array.isArray(parsed.allowFrom)) {\n\t\tparsed.allowFrom = parsed.allowFrom.filter((value) => value.trim().length > 0);\n\t}\n\n\treturn parsed;\n}\n\nfunction parseArgs(): ParsedArgs {\n\tconst args = process.argv.slice(2);\n\tlet sandbox: SandboxConfig = { type: \"host\" };\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\t\tif (arg.startsWith(\"--sandbox=\")) {\n\t\t\tsandbox = parseSandboxArg(arg.slice(\"--sandbox=\".length));\n\t\t} else if (arg === \"--sandbox\") {\n\t\t\tsandbox = parseSandboxArg(args[++i] || \"\");\n\t\t} else if (arg === \"--help\" || arg === \"-h\") {\n\t\t\tconsole.log(`Usage: ${APP_NAME} [options]`);\n\t\t\tconsole.log(\"\");\n\t\t\tconsole.log(\"Options:\");\n\t\t\tconsole.log(\" --sandbox=host Run tools on host (default)\");\n\t\t\tconsole.log(\" --sandbox=docker:<name> Run tools in Docker container\");\n\t\t\tconsole.log(\"\");\n\t\t\tconsole.log(`Config: ${CHANNEL_CONFIG_PATH}`);\n\t\t\tconsole.log(`Workspace: ${WORKSPACE_DIR}`);\n\t\t\tprocess.exit(0);\n\t\t}\n\t}\n\n\treturn { sandbox };\n}\n\nconst parsedArgs = parseArgs();\nconst sandbox = parsedArgs.sandbox;\nconst bootstrapResult = bootstrapAppHome();\nprintBootstrapSummary(bootstrapResult);\n\nif (bootstrapResult.channelTemplateCreated) {\n\tconsole.error(`Fill in ${CHANNEL_CONFIG_PATH} and run \\`${APP_NAME}\\` again.`);\n\tprocess.exit(1);\n}\n\nconst dingtalkConfig = loadConfig();\ndingtalkConfig.stateDir = WORKSPACE_DIR;\n\nawait validateSandbox(sandbox);\n\ninterface ChannelState {\n\trunning: boolean;\n\trunner: AgentRunner;\n\tstore: ChannelStore;\n\tstopRequested: boolean;\n}\n\nconst channelStates = new Map<string, ChannelState>();\nconst activeTasks = new Set<Promise<void>>();\nconst SHUTDOWN_WAIT_MS = 15000;\nconst SHUTDOWN_ABORT_WAIT_MS = 5000;\nlet shuttingDown = false;\nlet shutdownPromise: Promise<void> | null = null;\n\nfunction getState(channelId: string): ChannelState {\n\tlet state = channelStates.get(channelId);\n\tif (!state) {\n\t\tconst channelDir = join(WORKSPACE_DIR, channelId);\n\t\tensureChannelMemoryFilesSync(channelDir);\n\t\tstate = {\n\t\t\trunning: false,\n\t\t\trunner: getOrCreateRunner(sandbox, channelId, channelDir),\n\t\t\tstore: new ChannelStore({ workingDir: WORKSPACE_DIR }),\n\t\t\tstopRequested: false,\n\t\t};\n\t\tchannelStates.set(channelId, state);\n\t}\n\treturn state;\n}\n\nconst handler: DingTalkHandler = {\n\tisRunning(channelId: string): boolean {\n\t\tconst state = channelStates.get(channelId);\n\t\treturn state?.running ?? false;\n\t},\n\n\tasync handleStop(channelId: string, _bot: DingTalkBot): Promise<void> {\n\t\tconst state = channelStates.get(channelId);\n\t\tif (state?.running) {\n\t\t\tstate.stopRequested = true;\n\t\t\tvoid state.runner.abort().catch((err) => {\n\t\t\t\tlog.logWarning(`[${channelId}] Failed to abort run`, err instanceof Error ? err.message : String(err));\n\t\t\t});\n\t\t\tlog.logInfo(`[${channelId}] Stop requested`);\n\t\t}\n\t},\n\n\tasync handleBusyMessage(\n\t\tevent: DingTalkEvent,\n\t\tbot: DingTalkBot,\n\t\tmode: BusyMessageMode,\n\t\tqueueText: string,\n\t): Promise<void> {\n\t\tif (shuttingDown) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = getState(event.channelId);\n\t\tconst trimmedQueueText = queueText.trim();\n\n\t\tawait state.store.logMessage(event.channelId, {\n\t\t\tdate: new Date().toISOString(),\n\t\t\tts: event.ts,\n\t\t\tuser: event.user,\n\t\t\tuserName: event.userName,\n\t\t\ttext: event.text,\n\t\t\tisBot: false,\n\t\t\tdeliveryMode: mode,\n\t\t\tskipContextSync: true,\n\t\t});\n\n\t\ttry {\n\t\t\tif (mode === \"followUp\") {\n\t\t\t\tawait state.runner.queueFollowUp(trimmedQueueText, event.userName);\n\t\t\t} else {\n\t\t\t\tawait state.runner.queueSteer(trimmedQueueText, event.userName);\n\t\t\t}\n\n\t\t\tconst confirmation =\n\t\t\t\tmode === \"followUp\"\n\t\t\t\t\t? \"Queued as follow-up. I’ll handle it after the current task completes.\"\n\t\t\t\t\t: event.text.trim().startsWith(\"/\")\n\t\t\t\t\t\t? \"Queued as steer. I’ll apply it after the current tool step finishes.\"\n\t\t\t\t\t\t: \"Queued as steer. I’ll apply this after the current tool step finishes. Use `/followup <message>` to queue it after completion.\";\n\t\t\tawait bot.sendPlain(event.channelId, confirmation);\n\t\t\tlog.logInfo(`[${event.channelId}] Queued ${mode}: ${trimmedQueueText.substring(0, 80)}`);\n\t\t} catch (err) {\n\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${event.channelId}] Failed to queue ${mode}`, errMsg);\n\t\t\tawait bot.sendPlain(event.channelId, `Could not queue this message: ${errMsg}`);\n\t\t}\n\t},\n\n\tasync handleEvent(event: DingTalkEvent, bot: DingTalkBot, _isEvent?: boolean): Promise<void> {\n\t\tif (shuttingDown) {\n\t\t\tlog.logInfo(`[${event.channelId}] Ignoring event during shutdown`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = getState(event.channelId);\n\t\tconst task = (async () => {\n\t\t\tstate.running = true;\n\t\t\tstate.stopRequested = false;\n\n\t\t\tawait state.store.logMessage(event.channelId, {\n\t\t\t\tdate: new Date().toISOString(),\n\t\t\t\tts: event.ts,\n\t\t\t\tuser: event.user,\n\t\t\t\tuserName: event.userName,\n\t\t\t\ttext: event.text,\n\t\t\t\tisBot: false,\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst ctx = createDingTalkContext(event, bot, state.store);\n\t\t\t\tconst builtInCommand = parseBuiltInCommand(event.text);\n\n\t\t\t\tif (builtInCommand) {\n\t\t\t\t\tlog.logInfo(`[${event.channelId}] Executing command: ${builtInCommand.rawText}`);\n\t\t\t\t\tawait state.runner.handleBuiltinCommand(ctx, builtInCommand);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlog.logInfo(`[${event.channelId}] Starting run: ${event.text.substring(0, 50)}`);\n\t\t\t\tconst result = await state.runner.run(ctx, state.store);\n\n\t\t\t\tif (result.stopReason === \"aborted\" && state.stopRequested) {\n\t\t\t\t\tlog.logInfo(`[${event.channelId}] Stopped`);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tlog.logWarning(`[${event.channelId}] Run error`, err instanceof Error ? err.message : String(err));\n\t\t\t} finally {\n\t\t\t\tstate.running = false;\n\t\t\t}\n\t\t})();\n\n\t\tactiveTasks.add(task);\n\t\ttry {\n\t\t\tawait task;\n\t\t} finally {\n\t\t\tactiveTasks.delete(task);\n\t\t}\n\t},\n};\n\nlog.logStartup(WORKSPACE_DIR, sandbox.type === \"host\" ? \"host\" : `docker:${sandbox.container}`);\n\nconst bot = new DingTalkBot(handler, dingtalkConfig);\nconst eventsWatcher = createEventsWatcher(WORKSPACE_DIR, bot);\neventsWatcher.start();\n\nfunction waitForTasks(tasks: Promise<void>[], timeoutMs: number): Promise<boolean> {\n\tif (tasks.length === 0) {\n\t\treturn Promise.resolve(true);\n\t}\n\n\treturn Promise.race([\n\t\tPromise.allSettled(tasks).then(() => true),\n\t\tnew Promise<boolean>((resolve) => {\n\t\t\tsetTimeout(() => resolve(false), timeoutMs);\n\t\t}),\n\t]);\n}\n\nasync function shutdown(signal: NodeJS.Signals): Promise<void> {\n\tif (shutdownPromise) {\n\t\treturn shutdownPromise;\n\t}\n\n\tshutdownPromise = (async () => {\n\t\tshuttingDown = true;\n\t\tlog.logInfo(`Shutting down (${signal})...`);\n\n\t\teventsWatcher.stop();\n\t\tawait bot.stop();\n\n\t\tconst runningTasks = Array.from(activeTasks);\n\t\tif (runningTasks.length > 0) {\n\t\t\tlog.logInfo(`Waiting for ${runningTasks.length} active task(s) to finish`);\n\t\t\tconst completed = await waitForTasks(runningTasks, SHUTDOWN_WAIT_MS);\n\n\t\t\tif (!completed) {\n\t\t\t\tlog.logWarning(`Shutdown grace period exceeded ${SHUTDOWN_WAIT_MS}ms, aborting active runs`);\n\t\t\t\tconst aborts: Promise<void>[] = [];\n\t\t\t\tfor (const [channelId, state] of channelStates) {\n\t\t\t\t\tif (!state.running) continue;\n\t\t\t\t\tstate.stopRequested = true;\n\t\t\t\t\tlog.logInfo(`[${channelId}] Aborting active run for shutdown`);\n\t\t\t\t\taborts.push(\n\t\t\t\t\t\tstate.runner.abort().catch((err) => {\n\t\t\t\t\t\t\tlog.logWarning(\n\t\t\t\t\t\t\t\t`[${channelId}] Failed to abort run during shutdown`,\n\t\t\t\t\t\t\t\terr instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait Promise.allSettled(aborts);\n\n\t\t\t\tconst remainingTasks = Array.from(activeTasks);\n\t\t\t\tif (remainingTasks.length > 0) {\n\t\t\t\t\tconst abortedCompleted = await waitForTasks(remainingTasks, SHUTDOWN_ABORT_WAIT_MS);\n\t\t\t\t\tif (!abortedCompleted) {\n\t\t\t\t\t\tlog.logWarning(`Shutdown forced exit with ${remainingTasks.length} task(s) still active`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})().finally(() => {\n\t\tprocess.exit(0);\n\t});\n\n\treturn shutdownPromise;\n}\n\nprocess.once(\"SIGINT\", () => {\n\tvoid shutdown(\"SIGINT\");\n});\n\nprocess.once(\"SIGTERM\", () => {\n\tvoid shutdown(\"SIGTERM\");\n});\n\nvoid bot.start();\n"]}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { type AgentRunner, getOrCreateRunner } from \"./agent.js\";\nimport { parseBuiltInCommand } from \"./commands.js\";\nimport { createDingTalkContext } from \"./delivery.js\";\nimport {\n\ttype BusyMessageMode,\n\tDingTalkBot,\n\ttype DingTalkConfig,\n\ttype DingTalkEvent,\n\ttype DingTalkHandler,\n} from \"./dingtalk.js\";\nimport { createEventsWatcher } from \"./events.js\";\nimport * as log from \"./log.js\";\nimport { ensureChannelMemoryFilesSync } from \"./memory-files.js\";\nimport {\n\tAPP_HOME_DIR,\n\tAPP_NAME,\n\tAUTH_CONFIG_PATH,\n\tCHANNEL_CONFIG_PATH,\n\tMODELS_CONFIG_PATH,\n\tSETTINGS_CONFIG_PATH,\n\tWORKSPACE_DIR,\n} from \"./paths.js\";\nimport { parseSandboxArg, type SandboxConfig, validateSandbox } from \"./sandbox.js\";\nimport { ChannelStore } from \"./store.js\";\n\nif (process.env.DINGTALK_FORCE_PROXY !== \"true\") {\n\tdelete process.env.http_proxy;\n\tdelete process.env.https_proxy;\n\tdelete process.env.all_proxy;\n\tdelete process.env.HTTP_PROXY;\n\tdelete process.env.HTTPS_PROXY;\n\tdelete process.env.ALL_PROXY;\n}\n\ninterface ParsedArgs {\n\tsandbox: SandboxConfig;\n}\n\ninterface BootstrapResult {\n\tcreated: string[];\n\tchannelTemplateCreated: boolean;\n}\n\nconst DEFAULT_SOUL = `# SOUL.md\n\nConfigure Pipiclaw's identity, voice, and communication style here.\n\nSuggested sections:\n\n- Who the assistant is\n- Default language\n- Tone and personality\n- Reply style\n- Formatting preferences\n\nExample topics you may want to define:\n\n- \"Answer in Chinese by default.\"\n- \"Be concise and direct.\"\n- \"Prefer Markdown.\"\n- \"Act as an engineering assistant for our team.\"\n\nReplace this template with your actual identity prompt.\n`;\n\nconst DEFAULT_AGENT = `# AGENTS.md\n\nConfigure Pipiclaw's operating rules here.\n\nThis file should define behavior and workflow. Identity, tone, and personality belong in \\`SOUL.md\\`.\n\nSuggested sections:\n\n- Tool usage policy\n- Security constraints\n- Scheduling/reminder policy\n- Project-specific workflows\n- Things the assistant must always or never do\n\nReplace this template with your actual operating instructions.\n`;\n\nconst DEFAULT_MEMORY = `# Workspace Memory\n\nThis file stores stable workspace-level memory.\n\n- It is intended to be managed by a human administrator.\n- It is not automatically rewritten by normal runtime consolidation.\n- Store durable shared background here when it should apply across channels.\n- Keep this file focused on stable facts, policies, and shared context, not transient conversation history.\n\n## Shared Context\n\n<!-- Put team-wide or workspace-wide background here. -->\n\n## Tooling And Environment\n\n<!-- Put durable tool usage rules, environment assumptions, or shared operational conventions here. -->\n\n## Project Notes\n\n<!-- Put long-lived project facts here. -->\n`;\n\nconst CHANNEL_CONFIG_TEMPLATE = {\n\tclientId: \"your-dingtalk-client-id\",\n\tclientSecret: \"your-dingtalk-client-secret\",\n\trobotCode: \"your-robot-code\",\n\tcardTemplateId: \"your-card-template-id\",\n\tcardTemplateKey: \"content\",\n\tallowFrom: [\"your-staff-id\"],\n} satisfies DingTalkConfig;\n\nconst MODELS_CONFIG_TEMPLATE = { providers: {} };\n\nfunction writeTextFileIfMissing(path: string, content: string, label: string, created: string[]): boolean {\n\tif (existsSync(path)) {\n\t\treturn false;\n\t}\n\twriteFileSync(path, content, \"utf-8\");\n\tcreated.push(label);\n\treturn true;\n}\n\nfunction writeJsonFileIfMissing(path: string, value: unknown, label: string, created: string[]): boolean {\n\treturn writeTextFileIfMissing(path, `${JSON.stringify(value, null, 2)}\\n`, label, created);\n}\n\nfunction bootstrapAppHome(): BootstrapResult {\n\tconst created: string[] = [];\n\n\tif (!existsSync(APP_HOME_DIR)) {\n\t\tmkdirSync(APP_HOME_DIR, { recursive: true });\n\t\tcreated.push(\"app home\");\n\t}\n\tif (!existsSync(WORKSPACE_DIR)) {\n\t\tmkdirSync(WORKSPACE_DIR, { recursive: true });\n\t\tcreated.push(\"workspace/\");\n\t}\n\n\tfor (const dir of [\"skills\", \"events\", \"sub-agents\"]) {\n\t\tconst dirPath = join(WORKSPACE_DIR, dir);\n\t\tif (!existsSync(dirPath)) {\n\t\t\tmkdirSync(dirPath, { recursive: true });\n\t\t\tcreated.push(`workspace/${dir}/`);\n\t\t}\n\t}\n\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"SOUL.md\"), DEFAULT_SOUL, \"workspace/SOUL.md\", created);\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"AGENTS.md\"), DEFAULT_AGENT, \"workspace/AGENTS.md\", created);\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"MEMORY.md\"), DEFAULT_MEMORY, \"workspace/MEMORY.md\", created);\n\n\tconst channelTemplateCreated = writeJsonFileIfMissing(\n\t\tCHANNEL_CONFIG_PATH,\n\t\tCHANNEL_CONFIG_TEMPLATE,\n\t\t\"channel.json\",\n\t\tcreated,\n\t);\n\twriteJsonFileIfMissing(AUTH_CONFIG_PATH, {}, \"auth.json\", created);\n\twriteJsonFileIfMissing(MODELS_CONFIG_PATH, MODELS_CONFIG_TEMPLATE, \"models.json\", created);\n\twriteJsonFileIfMissing(SETTINGS_CONFIG_PATH, {}, \"settings.json\", created);\n\n\treturn { created, channelTemplateCreated };\n}\n\nfunction isPlaceholderString(value: string): boolean {\n\treturn value.trim().startsWith(\"your-\");\n}\n\nfunction listChannelConfigIssues(config: Partial<DingTalkConfig>): string[] {\n\tconst issues: string[] = [];\n\n\tif (!config.clientId) {\n\t\tissues.push(\"Missing required field `clientId`.\");\n\t} else if (isPlaceholderString(config.clientId)) {\n\t\tissues.push(\"Replace placeholder value for `clientId`.\");\n\t}\n\n\tif (!config.clientSecret) {\n\t\tissues.push(\"Missing required field `clientSecret`.\");\n\t} else if (isPlaceholderString(config.clientSecret)) {\n\t\tissues.push(\"Replace placeholder value for `clientSecret`.\");\n\t}\n\n\tif (config.robotCode && isPlaceholderString(config.robotCode)) {\n\t\tissues.push(\"Replace placeholder value for `robotCode`, or set it to an empty string to reuse `clientId`.\");\n\t}\n\n\tif (config.cardTemplateId && isPlaceholderString(config.cardTemplateId)) {\n\t\tissues.push(\n\t\t\t\"Replace placeholder value for `cardTemplateId`, or set it to an empty string to disable AI Card streaming.\",\n\t\t);\n\t}\n\n\tif (Array.isArray(config.allowFrom) && config.allowFrom.some((value) => isPlaceholderString(value))) {\n\t\tissues.push(\"Replace placeholder values in `allowFrom`, or set it to an empty array to allow all users.\");\n\t}\n\n\treturn issues;\n}\n\nfunction printBootstrapSummary(result: BootstrapResult): void {\n\tif (result.created.length === 0) {\n\t\treturn;\n\t}\n\n\tconsole.log(`Initialized ${APP_NAME} under ${APP_HOME_DIR}:`);\n\tfor (const item of result.created) {\n\t\tconsole.log(` - ${item}`);\n\t}\n\tconsole.log(\"\");\n}\n\nfunction loadConfig(): DingTalkConfig {\n\tlet parsed: DingTalkConfig;\n\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(CHANNEL_CONFIG_PATH, \"utf-8\")) as DingTalkConfig;\n\t} catch (err) {\n\t\tconsole.error(`Failed to parse configuration: ${CHANNEL_CONFIG_PATH}`);\n\t\tconsole.error(err instanceof Error ? err.message : String(err));\n\t\tprocess.exit(1);\n\t}\n\n\tconst issues = listChannelConfigIssues(parsed);\n\tif (issues.length > 0) {\n\t\tconsole.error(`Configuration is not ready: ${CHANNEL_CONFIG_PATH}`);\n\t\tfor (const issue of issues) {\n\t\t\tconsole.error(` - ${issue}`);\n\t\t}\n\t\tconsole.error(\"\");\n\t\tconsole.error(`Fill in ${CHANNEL_CONFIG_PATH} and run \\`${APP_NAME}\\` again.`);\n\t\tprocess.exit(1);\n\t}\n\n\tparsed.cardTemplateKey = parsed.cardTemplateKey || \"content\";\n\tparsed.robotCode = parsed.robotCode?.trim() ? parsed.robotCode : parsed.clientId;\n\tif (Array.isArray(parsed.allowFrom)) {\n\t\tparsed.allowFrom = parsed.allowFrom.filter((value) => value.trim().length > 0);\n\t}\n\n\treturn parsed;\n}\n\nfunction parseArgs(): ParsedArgs {\n\tconst args = process.argv.slice(2);\n\tlet sandbox: SandboxConfig = { type: \"host\" };\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\t\tif (arg.startsWith(\"--sandbox=\")) {\n\t\t\tsandbox = parseSandboxArg(arg.slice(\"--sandbox=\".length));\n\t\t} else if (arg === \"--sandbox\") {\n\t\t\tsandbox = parseSandboxArg(args[++i] || \"\");\n\t\t} else if (arg === \"--help\" || arg === \"-h\") {\n\t\t\tconsole.log(`Usage: ${APP_NAME} [options]`);\n\t\t\tconsole.log(\"\");\n\t\t\tconsole.log(\"Options:\");\n\t\t\tconsole.log(\" --sandbox=host Run tools on host (default)\");\n\t\t\tconsole.log(\" --sandbox=docker:<name> Run tools in Docker container\");\n\t\t\tconsole.log(\"\");\n\t\t\tconsole.log(`Config: ${CHANNEL_CONFIG_PATH}`);\n\t\t\tconsole.log(`Workspace: ${WORKSPACE_DIR}`);\n\t\t\tprocess.exit(0);\n\t\t}\n\t}\n\n\treturn { sandbox };\n}\n\nconst parsedArgs = parseArgs();\nconst sandbox = parsedArgs.sandbox;\nconst bootstrapResult = bootstrapAppHome();\nprintBootstrapSummary(bootstrapResult);\n\nif (bootstrapResult.channelTemplateCreated) {\n\tconsole.error(`Fill in ${CHANNEL_CONFIG_PATH} and run \\`${APP_NAME}\\` again.`);\n\tprocess.exit(1);\n}\n\nconst dingtalkConfig = loadConfig();\ndingtalkConfig.stateDir = WORKSPACE_DIR;\n\nawait validateSandbox(sandbox);\n\ninterface ChannelState {\n\trunning: boolean;\n\trunner: AgentRunner;\n\tstore: ChannelStore;\n\tstopRequested: boolean;\n}\n\nconst channelStates = new Map<string, ChannelState>();\nconst activeTasks = new Set<Promise<void>>();\nconst SHUTDOWN_WAIT_MS = 15000;\nconst SHUTDOWN_ABORT_WAIT_MS = 5000;\nlet shuttingDown = false;\nlet shutdownPromise: Promise<void> | null = null;\n\nfunction getState(channelId: string): ChannelState {\n\tlet state = channelStates.get(channelId);\n\tif (!state) {\n\t\tconst channelDir = join(WORKSPACE_DIR, channelId);\n\t\tensureChannelMemoryFilesSync(channelDir);\n\t\tstate = {\n\t\t\trunning: false,\n\t\t\trunner: getOrCreateRunner(sandbox, channelId, channelDir),\n\t\t\tstore: new ChannelStore({ workingDir: WORKSPACE_DIR }),\n\t\t\tstopRequested: false,\n\t\t};\n\t\tchannelStates.set(channelId, state);\n\t}\n\treturn state;\n}\n\nconst handler: DingTalkHandler = {\n\tisRunning(channelId: string): boolean {\n\t\tconst state = channelStates.get(channelId);\n\t\treturn state?.running ?? false;\n\t},\n\n\tasync handleStop(channelId: string, _bot: DingTalkBot): Promise<void> {\n\t\tconst state = channelStates.get(channelId);\n\t\tif (state?.running) {\n\t\t\tstate.stopRequested = true;\n\t\t\tvoid state.runner.abort().catch((err) => {\n\t\t\t\tlog.logWarning(`[${channelId}] Failed to abort run`, err instanceof Error ? err.message : String(err));\n\t\t\t});\n\t\t\tlog.logInfo(`[${channelId}] Stop requested`);\n\t\t}\n\t},\n\n\tasync handleBusyMessage(\n\t\tevent: DingTalkEvent,\n\t\tbot: DingTalkBot,\n\t\tmode: BusyMessageMode,\n\t\tqueueText: string,\n\t): Promise<void> {\n\t\tif (shuttingDown) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = getState(event.channelId);\n\t\tconst trimmedQueueText = queueText.trim();\n\n\t\tawait state.store.logMessage(event.channelId, {\n\t\t\tdate: new Date().toISOString(),\n\t\t\tts: event.ts,\n\t\t\tuser: event.user,\n\t\t\tuserName: event.userName,\n\t\t\ttext: event.text,\n\t\t\tisBot: false,\n\t\t\tdeliveryMode: mode,\n\t\t\tskipContextSync: true,\n\t\t});\n\n\t\ttry {\n\t\t\tif (mode === \"followUp\") {\n\t\t\t\tawait state.runner.queueFollowUp(trimmedQueueText, event.userName);\n\t\t\t} else {\n\t\t\t\tawait state.runner.queueSteer(trimmedQueueText, event.userName);\n\t\t\t}\n\n\t\t\tconst confirmation =\n\t\t\t\tmode === \"followUp\"\n\t\t\t\t\t? \"Queued as follow-up. I’ll handle it after the current task completes.\"\n\t\t\t\t\t: event.text.trim().startsWith(\"/\")\n\t\t\t\t\t\t? \"Queued as steer. I’ll apply it after the current tool step finishes.\"\n\t\t\t\t\t\t: \"Queued as steer. I’ll apply this after the current tool step finishes. Use `/followup <message>` to queue it after completion.\";\n\t\t\tawait bot.sendPlain(event.channelId, confirmation);\n\t\t\tlog.logInfo(`[${event.channelId}] Queued ${mode}: ${trimmedQueueText.substring(0, 80)}`);\n\t\t} catch (err) {\n\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${event.channelId}] Failed to queue ${mode}`, errMsg);\n\t\t\tawait bot.sendPlain(event.channelId, `Could not queue this message: ${errMsg}`);\n\t\t}\n\t},\n\n\tasync handleEvent(event: DingTalkEvent, bot: DingTalkBot, _isEvent?: boolean): Promise<void> {\n\t\tif (shuttingDown) {\n\t\t\tlog.logInfo(`[${event.channelId}] Ignoring event during shutdown`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = getState(event.channelId);\n\t\tconst task = (async () => {\n\t\t\tstate.running = true;\n\t\t\tstate.stopRequested = false;\n\n\t\t\tawait state.store.logMessage(event.channelId, {\n\t\t\t\tdate: new Date().toISOString(),\n\t\t\t\tts: event.ts,\n\t\t\t\tuser: event.user,\n\t\t\t\tuserName: event.userName,\n\t\t\t\ttext: event.text,\n\t\t\t\tisBot: false,\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst ctx = createDingTalkContext(event, bot, state.store);\n\t\t\t\tconst builtInCommand = parseBuiltInCommand(event.text);\n\n\t\t\t\tif (builtInCommand) {\n\t\t\t\t\tlog.logInfo(`[${event.channelId}] Executing command: ${builtInCommand.rawText}`);\n\t\t\t\t\tawait state.runner.handleBuiltinCommand(ctx, builtInCommand);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlog.logInfo(`[${event.channelId}] Starting run: ${event.text.substring(0, 50)}`);\n\t\t\t\tconst result = await state.runner.run(ctx, state.store);\n\n\t\t\t\tif (result.stopReason === \"aborted\" && state.stopRequested) {\n\t\t\t\t\tlog.logInfo(`[${event.channelId}] Stopped`);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tlog.logWarning(`[${event.channelId}] Run error`, err instanceof Error ? err.message : String(err));\n\t\t\t} finally {\n\t\t\t\tstate.running = false;\n\t\t\t}\n\t\t})();\n\n\t\tactiveTasks.add(task);\n\t\ttry {\n\t\t\tawait task;\n\t\t} finally {\n\t\t\tactiveTasks.delete(task);\n\t\t}\n\t},\n};\n\nlog.logStartup(WORKSPACE_DIR, sandbox.type === \"host\" ? \"host\" : `docker:${sandbox.container}`);\n\nconst bot = new DingTalkBot(handler, dingtalkConfig);\nconst eventsWatcher = createEventsWatcher(WORKSPACE_DIR, bot);\neventsWatcher.start();\n\nfunction waitForTasks(tasks: Promise<void>[], timeoutMs: number): Promise<boolean> {\n\tif (tasks.length === 0) {\n\t\treturn Promise.resolve(true);\n\t}\n\n\treturn Promise.race([\n\t\tPromise.allSettled(tasks).then(() => true),\n\t\tnew Promise<boolean>((resolve) => {\n\t\t\tsetTimeout(() => resolve(false), timeoutMs);\n\t\t}),\n\t]);\n}\n\nasync function shutdown(signal: NodeJS.Signals): Promise<void> {\n\tif (shutdownPromise) {\n\t\treturn shutdownPromise;\n\t}\n\n\tshutdownPromise = (async () => {\n\t\tshuttingDown = true;\n\t\tlog.logInfo(`Shutting down (${signal})...`);\n\n\t\teventsWatcher.stop();\n\t\tawait bot.stop();\n\n\t\tconst runningTasks = Array.from(activeTasks);\n\t\tif (runningTasks.length > 0) {\n\t\t\tlog.logInfo(`Waiting for ${runningTasks.length} active task(s) to finish`);\n\t\t\tconst completed = await waitForTasks(runningTasks, SHUTDOWN_WAIT_MS);\n\n\t\t\tif (!completed) {\n\t\t\t\tlog.logWarning(`Shutdown grace period exceeded ${SHUTDOWN_WAIT_MS}ms, aborting active runs`);\n\t\t\t\tconst aborts: Promise<void>[] = [];\n\t\t\t\tfor (const [channelId, state] of channelStates) {\n\t\t\t\t\tif (!state.running) continue;\n\t\t\t\t\tstate.stopRequested = true;\n\t\t\t\t\tlog.logInfo(`[${channelId}] Aborting active run for shutdown`);\n\t\t\t\t\taborts.push(\n\t\t\t\t\t\tstate.runner.abort().catch((err) => {\n\t\t\t\t\t\t\tlog.logWarning(\n\t\t\t\t\t\t\t\t`[${channelId}] Failed to abort run during shutdown`,\n\t\t\t\t\t\t\t\terr instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait Promise.allSettled(aborts);\n\n\t\t\t\tconst remainingTasks = Array.from(activeTasks);\n\t\t\t\tif (remainingTasks.length > 0) {\n\t\t\t\t\tconst abortedCompleted = await waitForTasks(remainingTasks, SHUTDOWN_ABORT_WAIT_MS);\n\t\t\t\t\tif (!abortedCompleted) {\n\t\t\t\t\t\tlog.logWarning(`Shutdown forced exit with ${remainingTasks.length} task(s) still active`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})().finally(() => {\n\t\tprocess.exit(0);\n\t});\n\n\treturn shutdownPromise;\n}\n\nprocess.once(\"SIGINT\", () => {\n\tvoid shutdown(\"SIGINT\");\n});\n\nprocess.once(\"SIGTERM\", () => {\n\tvoid shutdown(\"SIGTERM\");\n});\n\nvoid bot.start();\n"]}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { type AgentRunner, getOrCreateRunner } from \"./agent.js\";\nimport { parseBuiltInCommand } from \"./commands.js\";\nimport { createDingTalkContext } from \"./delivery.js\";\nimport {\n\ttype BusyMessageMode,\n\tDingTalkBot,\n\ttype DingTalkConfig,\n\ttype DingTalkEvent,\n\ttype DingTalkHandler,\n} from \"./dingtalk.js\";\nimport { createEventsWatcher } from \"./events.js\";\nimport * as log from \"./log.js\";\nimport { ensureChannelMemoryFilesSync } from \"./memory-files.js\";\nimport {\n\tAPP_HOME_DIR,\n\tAPP_NAME,\n\tAUTH_CONFIG_PATH,\n\tCHANNEL_CONFIG_PATH,\n\tMODELS_CONFIG_PATH,\n\tSETTINGS_CONFIG_PATH,\n\tWORKSPACE_DIR,\n} from \"./paths.js\";\nimport { parseSandboxArg, type SandboxConfig, validateSandbox } from \"./sandbox.js\";\nimport { ChannelStore } from \"./store.js\";\n\nif (process.env.DINGTALK_FORCE_PROXY !== \"true\") {\n\tdelete process.env.http_proxy;\n\tdelete process.env.https_proxy;\n\tdelete process.env.all_proxy;\n\tdelete process.env.HTTP_PROXY;\n\tdelete process.env.HTTPS_PROXY;\n\tdelete process.env.ALL_PROXY;\n}\n\ninterface ParsedArgs {\n\tsandbox: SandboxConfig;\n}\n\ninterface BootstrapResult {\n\tcreated: string[];\n\tchannelTemplateCreated: boolean;\n}\n\nconst DEFAULT_SOUL = `# SOUL.md\n\nConfigure Pipiclaw's identity, voice, and communication style here.\n\nSuggested sections:\n\n- Who the assistant is\n- Default language\n- Tone and personality\n- Reply style\n- Formatting preferences\n\nExample topics you may want to define:\n\n- \"Answer in Chinese by default.\"\n- \"Be concise and direct.\"\n- \"Prefer Markdown.\"\n- \"Act as an engineering assistant for our team.\"\n\nReplace this template with your actual identity prompt.\n`;\n\nconst DEFAULT_AGENT = `# AGENTS.md\n\nConfigure Pipiclaw's operating rules here.\n\nThis file should define behavior and workflow. Identity, tone, and personality belong in \\`SOUL.md\\`.\n\nSuggested sections:\n\n- Tool usage policy\n- Security constraints\n- Scheduling/reminder policy\n- Project-specific workflows\n- Things the assistant must always or never do\n\nReplace this template with your actual operating instructions.\n`;\n\nconst DEFAULT_MEMORY = `# Workspace Memory\n\nThis file stores stable workspace-level memory.\n\n- It is intended to be managed by a human administrator.\n- It is not automatically rewritten by normal runtime consolidation.\n- Store durable shared background here when it should apply across channels.\n- Keep this file focused on stable facts, policies, and shared context, not transient conversation history.\n\n## Shared Context\n\n<!-- Put team-wide or workspace-wide background here. -->\n\n## Tooling And Environment\n\n<!-- Put durable tool usage rules, environment assumptions, or shared operational conventions here. -->\n\n## Project Notes\n\n<!-- Put long-lived project facts here. -->\n`;\n\nconst CHANNEL_CONFIG_TEMPLATE = {\n\tclientId: \"your-dingtalk-client-id\",\n\tclientSecret: \"your-dingtalk-client-secret\",\n\trobotCode: \"your-robot-code\",\n\tcardTemplateId: \"your-card-template-id\",\n\tcardTemplateKey: \"content\",\n\tallowFrom: [\"your-staff-id\"],\n} satisfies DingTalkConfig;\n\nconst MODELS_CONFIG_TEMPLATE = { providers: {} };\n\nfunction writeTextFileIfMissing(path: string, content: string, label: string, created: string[]): boolean {\n\tif (existsSync(path)) {\n\t\treturn false;\n\t}\n\twriteFileSync(path, content, \"utf-8\");\n\tcreated.push(label);\n\treturn true;\n}\n\nfunction writeJsonFileIfMissing(path: string, value: unknown, label: string, created: string[]): boolean {\n\treturn writeTextFileIfMissing(path, `${JSON.stringify(value, null, 2)}\\n`, label, created);\n}\n\nfunction bootstrapAppHome(): BootstrapResult {\n\tconst created: string[] = [];\n\n\tif (!existsSync(APP_HOME_DIR)) {\n\t\tmkdirSync(APP_HOME_DIR, { recursive: true });\n\t\tcreated.push(\"app home\");\n\t}\n\tif (!existsSync(WORKSPACE_DIR)) {\n\t\tmkdirSync(WORKSPACE_DIR, { recursive: true });\n\t\tcreated.push(\"workspace/\");\n\t}\n\n\tfor (const dir of [\"skills\", \"events\", \"sub-agents\"]) {\n\t\tconst dirPath = join(WORKSPACE_DIR, dir);\n\t\tif (!existsSync(dirPath)) {\n\t\t\tmkdirSync(dirPath, { recursive: true });\n\t\t\tcreated.push(`workspace/${dir}/`);\n\t\t}\n\t}\n\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"SOUL.md\"), DEFAULT_SOUL, \"workspace/SOUL.md\", created);\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"AGENTS.md\"), DEFAULT_AGENT, \"workspace/AGENTS.md\", created);\n\twriteTextFileIfMissing(join(WORKSPACE_DIR, \"MEMORY.md\"), DEFAULT_MEMORY, \"workspace/MEMORY.md\", created);\n\n\tconst channelTemplateCreated = writeJsonFileIfMissing(\n\t\tCHANNEL_CONFIG_PATH,\n\t\tCHANNEL_CONFIG_TEMPLATE,\n\t\t\"channel.json\",\n\t\tcreated,\n\t);\n\twriteJsonFileIfMissing(AUTH_CONFIG_PATH, {}, \"auth.json\", created);\n\twriteJsonFileIfMissing(MODELS_CONFIG_PATH, MODELS_CONFIG_TEMPLATE, \"models.json\", created);\n\twriteJsonFileIfMissing(SETTINGS_CONFIG_PATH, {}, \"settings.json\", created);\n\n\treturn { created, channelTemplateCreated };\n}\n\nfunction isPlaceholderString(value: string): boolean {\n\treturn value.trim().startsWith(\"your-\");\n}\n\nfunction listChannelConfigIssues(config: Partial<DingTalkConfig>): string[] {\n\tconst issues: string[] = [];\n\n\tif (!config.clientId) {\n\t\tissues.push(\"Missing required field `clientId`.\");\n\t} else if (isPlaceholderString(config.clientId)) {\n\t\tissues.push(\"Replace placeholder value for `clientId`.\");\n\t}\n\n\tif (!config.clientSecret) {\n\t\tissues.push(\"Missing required field `clientSecret`.\");\n\t} else if (isPlaceholderString(config.clientSecret)) {\n\t\tissues.push(\"Replace placeholder value for `clientSecret`.\");\n\t}\n\n\tif (config.robotCode && isPlaceholderString(config.robotCode)) {\n\t\tissues.push(\"Replace placeholder value for `robotCode`, or set it to an empty string to reuse `clientId`.\");\n\t}\n\n\tif (config.cardTemplateId && isPlaceholderString(config.cardTemplateId)) {\n\t\tissues.push(\n\t\t\t\"Replace placeholder value for `cardTemplateId`, or set it to an empty string to disable AI Card streaming.\",\n\t\t);\n\t}\n\n\tif (Array.isArray(config.allowFrom) && config.allowFrom.some((value) => isPlaceholderString(value))) {\n\t\tissues.push(\"Replace placeholder values in `allowFrom`, or set it to an empty array to allow all users.\");\n\t}\n\n\treturn issues;\n}\n\nfunction printBootstrapSummary(result: BootstrapResult): void {\n\tif (result.created.length === 0) {\n\t\treturn;\n\t}\n\n\tconsole.log(`Initialized ${APP_NAME} under ${APP_HOME_DIR}:`);\n\tfor (const item of result.created) {\n\t\tconsole.log(` - ${item}`);\n\t}\n\tconsole.log(\"\");\n}\n\nfunction loadConfig(): DingTalkConfig {\n\tlet parsed: DingTalkConfig;\n\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(CHANNEL_CONFIG_PATH, \"utf-8\")) as DingTalkConfig;\n\t} catch (err) {\n\t\tconsole.error(`Failed to parse configuration: ${CHANNEL_CONFIG_PATH}`);\n\t\tconsole.error(err instanceof Error ? err.message : String(err));\n\t\tprocess.exit(1);\n\t}\n\n\tconst issues = listChannelConfigIssues(parsed);\n\tif (issues.length > 0) {\n\t\tconsole.error(`Configuration is not ready: ${CHANNEL_CONFIG_PATH}`);\n\t\tfor (const issue of issues) {\n\t\t\tconsole.error(` - ${issue}`);\n\t\t}\n\t\tconsole.error(\"\");\n\t\tconsole.error(`Fill in ${CHANNEL_CONFIG_PATH} and run \\`${APP_NAME}\\` again.`);\n\t\tprocess.exit(1);\n\t}\n\n\tparsed.cardTemplateKey = parsed.cardTemplateKey || \"content\";\n\tparsed.robotCode = parsed.robotCode?.trim() ? parsed.robotCode : parsed.clientId;\n\tif (Array.isArray(parsed.allowFrom)) {\n\t\tparsed.allowFrom = parsed.allowFrom.filter((value) => value.trim().length > 0);\n\t}\n\n\treturn parsed;\n}\n\nfunction parseArgs(): ParsedArgs {\n\tconst args = process.argv.slice(2);\n\tlet sandbox: SandboxConfig = { type: \"host\" };\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\t\tif (arg.startsWith(\"--sandbox=\")) {\n\t\t\tsandbox = parseSandboxArg(arg.slice(\"--sandbox=\".length));\n\t\t} else if (arg === \"--sandbox\") {\n\t\t\tsandbox = parseSandboxArg(args[++i] || \"\");\n\t\t} else if (arg === \"--help\" || arg === \"-h\") {\n\t\t\tconsole.log(`Usage: ${APP_NAME} [options]`);\n\t\t\tconsole.log(\"\");\n\t\t\tconsole.log(\"Options:\");\n\t\t\tconsole.log(\" --sandbox=host Run tools on host (default)\");\n\t\t\tconsole.log(\" --sandbox=docker:<name> Run tools in Docker container\");\n\t\t\tconsole.log(\"\");\n\t\t\tconsole.log(`Config: ${CHANNEL_CONFIG_PATH}`);\n\t\t\tconsole.log(`Workspace: ${WORKSPACE_DIR}`);\n\t\t\tprocess.exit(0);\n\t\t}\n\t}\n\n\treturn { sandbox };\n}\n\nconst parsedArgs = parseArgs();\nconst sandbox = parsedArgs.sandbox;\nconst bootstrapResult = bootstrapAppHome();\nprintBootstrapSummary(bootstrapResult);\n\nif (bootstrapResult.channelTemplateCreated) {\n\tconsole.error(`Fill in ${CHANNEL_CONFIG_PATH} and run \\`${APP_NAME}\\` again.`);\n\tprocess.exit(1);\n}\n\nconst dingtalkConfig = loadConfig();\ndingtalkConfig.stateDir = WORKSPACE_DIR;\n\nawait validateSandbox(sandbox);\n\ninterface ChannelState {\n\trunning: boolean;\n\trunner: AgentRunner;\n\tstore: ChannelStore;\n\tstopRequested: boolean;\n}\n\nconst channelStates = new Map<string, ChannelState>();\nconst activeTasks = new Set<Promise<void>>();\nconst SHUTDOWN_WAIT_MS = 15000;\nconst SHUTDOWN_ABORT_WAIT_MS = 5000;\nlet shuttingDown = false;\nlet shutdownPromise: Promise<void> | null = null;\n\nfunction getState(channelId: string): ChannelState {\n\tlet state = channelStates.get(channelId);\n\tif (!state) {\n\t\tconst channelDir = join(WORKSPACE_DIR, channelId);\n\t\tensureChannelMemoryFilesSync(channelDir);\n\t\tstate = {\n\t\t\trunning: false,\n\t\t\trunner: getOrCreateRunner(sandbox, channelId, channelDir),\n\t\t\tstore: new ChannelStore({ workingDir: WORKSPACE_DIR }),\n\t\t\tstopRequested: false,\n\t\t};\n\t\tchannelStates.set(channelId, state);\n\t}\n\treturn state;\n}\n\nconst handler: DingTalkHandler = {\n\tisRunning(channelId: string): boolean {\n\t\tconst state = channelStates.get(channelId);\n\t\treturn state?.running ?? false;\n\t},\n\n\tasync handleStop(channelId: string, _bot: DingTalkBot): Promise<void> {\n\t\tconst state = channelStates.get(channelId);\n\t\tif (state?.running) {\n\t\t\tstate.stopRequested = true;\n\t\t\tvoid state.runner.abort().catch((err) => {\n\t\t\t\tlog.logWarning(`[${channelId}] Failed to abort run`, err instanceof Error ? err.message : String(err));\n\t\t\t});\n\t\t\tlog.logInfo(`[${channelId}] Stop requested`);\n\t\t}\n\t},\n\n\tasync handleBusyMessage(\n\t\tevent: DingTalkEvent,\n\t\tbot: DingTalkBot,\n\t\tmode: BusyMessageMode,\n\t\tqueueText: string,\n\t): Promise<void> {\n\t\tif (shuttingDown) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = getState(event.channelId);\n\t\tconst trimmedQueueText = queueText.trim();\n\n\t\tawait state.store.logMessage(event.channelId, {\n\t\t\tdate: new Date().toISOString(),\n\t\t\tts: event.ts,\n\t\t\tuser: event.user,\n\t\t\tuserName: event.userName,\n\t\t\ttext: event.text,\n\t\t\tisBot: false,\n\t\t\tdeliveryMode: mode,\n\t\t\tskipContextSync: true,\n\t\t});\n\n\t\ttry {\n\t\t\tif (mode === \"followUp\") {\n\t\t\t\tawait state.runner.queueFollowUp(trimmedQueueText, event.userName);\n\t\t\t} else {\n\t\t\t\tawait state.runner.queueSteer(trimmedQueueText, event.userName);\n\t\t\t}\n\n\t\t\tconst confirmation =\n\t\t\t\tmode === \"followUp\"\n\t\t\t\t\t? \"Queued as follow-up. I’ll handle it after the current task completes.\"\n\t\t\t\t\t: event.text.trim().startsWith(\"/\")\n\t\t\t\t\t\t? \"Queued as steer. I’ll apply it after the current tool step finishes.\"\n\t\t\t\t\t\t: \"Queued as steer. I’ll apply this after the current tool step finishes. Use `/followup <message>` to queue it after completion.\";\n\t\t\tawait bot.sendPlain(event.channelId, confirmation);\n\t\t\tlog.logInfo(`[${event.channelId}] Queued ${mode}: ${trimmedQueueText.substring(0, 80)}`);\n\t\t} catch (err) {\n\t\t\tconst errMsg = err instanceof Error ? err.message : String(err);\n\t\t\tlog.logWarning(`[${event.channelId}] Failed to queue ${mode}`, errMsg);\n\t\t\tawait bot.sendPlain(event.channelId, `Could not queue this message: ${errMsg}`);\n\t\t}\n\t},\n\n\tasync handleEvent(event: DingTalkEvent, bot: DingTalkBot, _isEvent?: boolean): Promise<void> {\n\t\tif (shuttingDown) {\n\t\t\tlog.logInfo(`[${event.channelId}] Ignoring event during shutdown`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = getState(event.channelId);\n\t\tconst task = (async () => {\n\t\t\tstate.running = true;\n\t\t\tstate.stopRequested = false;\n\n\t\t\tawait state.store.logMessage(event.channelId, {\n\t\t\t\tdate: new Date().toISOString(),\n\t\t\t\tts: event.ts,\n\t\t\t\tuser: event.user,\n\t\t\t\tuserName: event.userName,\n\t\t\t\ttext: event.text,\n\t\t\t\tisBot: false,\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\tconst ctx = createDingTalkContext(event, bot, state.store);\n\t\t\t\tconst builtInCommand = parseBuiltInCommand(event.text);\n\n\t\t\t\tif (builtInCommand) {\n\t\t\t\t\tlog.logInfo(`[${event.channelId}] Executing command: ${builtInCommand.rawText}`);\n\t\t\t\t\tawait state.runner.handleBuiltinCommand(ctx, builtInCommand);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlog.logInfo(`[${event.channelId}] Starting run: ${event.text.substring(0, 50)}`);\n\t\t\t\tconst result = await state.runner.run(ctx, state.store);\n\n\t\t\t\tif (result.stopReason === \"aborted\" && state.stopRequested) {\n\t\t\t\t\tlog.logInfo(`[${event.channelId}] Stopped`);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tlog.logWarning(`[${event.channelId}] Run error`, err instanceof Error ? err.message : String(err));\n\t\t\t} finally {\n\t\t\t\tstate.running = false;\n\t\t\t}\n\t\t})();\n\n\t\tactiveTasks.add(task);\n\t\ttry {\n\t\t\tawait task;\n\t\t} finally {\n\t\t\tactiveTasks.delete(task);\n\t\t}\n\t},\n};\n\nlog.logStartup(WORKSPACE_DIR, sandbox.type === \"host\" ? \"host\" : `docker:${sandbox.container}`);\n\nconst bot = new DingTalkBot(handler, dingtalkConfig);\nconst eventsWatcher = createEventsWatcher(WORKSPACE_DIR, bot);\neventsWatcher.start();\n\nfunction waitForTasks(tasks: Promise<void>[], timeoutMs: number): Promise<boolean> {\n\tif (tasks.length === 0) {\n\t\treturn Promise.resolve(true);\n\t}\n\n\treturn Promise.race([\n\t\tPromise.allSettled(tasks).then(() => true),\n\t\tnew Promise<boolean>((resolve) => {\n\t\t\tsetTimeout(() => resolve(false), timeoutMs);\n\t\t}),\n\t]);\n}\n\nasync function shutdown(signal: NodeJS.Signals): Promise<void> {\n\tif (shutdownPromise) {\n\t\treturn shutdownPromise;\n\t}\n\n\tshutdownPromise = (async () => {\n\t\tshuttingDown = true;\n\t\tlog.logInfo(`Shutting down (${signal})...`);\n\n\t\teventsWatcher.stop();\n\t\tawait bot.stop();\n\n\t\tconst runningTasks = Array.from(activeTasks);\n\t\tif (runningTasks.length > 0) {\n\t\t\tlog.logInfo(`Waiting for ${runningTasks.length} active task(s) to finish`);\n\t\t\tconst completed = await waitForTasks(runningTasks, SHUTDOWN_WAIT_MS);\n\n\t\t\tif (!completed) {\n\t\t\t\tlog.logWarning(`Shutdown grace period exceeded ${SHUTDOWN_WAIT_MS}ms, aborting active runs`);\n\t\t\t\tconst aborts: Promise<void>[] = [];\n\t\t\t\tfor (const [channelId, state] of channelStates) {\n\t\t\t\t\tif (!state.running) continue;\n\t\t\t\t\tstate.stopRequested = true;\n\t\t\t\t\tlog.logInfo(`[${channelId}] Aborting active run for shutdown`);\n\t\t\t\t\taborts.push(\n\t\t\t\t\t\tstate.runner.abort().catch((err) => {\n\t\t\t\t\t\t\tlog.logWarning(\n\t\t\t\t\t\t\t\t`[${channelId}] Failed to abort run during shutdown`,\n\t\t\t\t\t\t\t\terr instanceof Error ? err.message : String(err),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait Promise.allSettled(aborts);\n\n\t\t\t\tconst remainingTasks = Array.from(activeTasks);\n\t\t\t\tif (remainingTasks.length > 0) {\n\t\t\t\t\tconst abortedCompleted = await waitForTasks(remainingTasks, SHUTDOWN_ABORT_WAIT_MS);\n\t\t\t\t\tif (!abortedCompleted) {\n\t\t\t\t\t\tlog.logWarning(`Shutdown forced exit with ${remainingTasks.length} task(s) still active`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})().finally(() => {\n\t\tprocess.exit(0);\n\t});\n\n\treturn shutdownPromise;\n}\n\nprocess.once(\"SIGINT\", () => {\n\tvoid shutdown(\"SIGINT\");\n});\n\nprocess.once(\"SIGTERM\", () => {\n\tvoid shutdown(\"SIGTERM\");\n});\n\nvoid bot.start();\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-consolidation.d.ts","sourceRoot":"","sources":["../src/memory-consolidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,GAAG,EAA6B,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAGN,KAAK,YAAY,EAGjB,MAAM,+BAA+B,CAAC;AAmEvC,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACvB;AAiLD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAkCjH;AAqDD,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAQrH","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Api, AssistantMessage, Message, Model } from \"@mariozechner/pi-ai\";\nimport {\n\tconvertToLlm,\n\tgetLatestCompactionEntry,\n\ttype SessionEntry,\n\ttype SessionMessageEntry,\n\tserializeConversation,\n} from \"@mariozechner/pi-coding-agent\";\nimport {\n\tappendChannelHistoryBlock,\n\tappendChannelMemoryUpdate,\n\treadChannelHistory,\n\treadChannelMemory,\n\trewriteChannelHistory,\n\trewriteChannelMemory,\n\tsplitMarkdownSections,\n} from \"./memory-files.js\";\n\nconst INLINE_TRANSCRIPT_MAX_CHARS = 28_000;\nconst MEMORY_CLEANUP_LENGTH_THRESHOLD = 8_000;\nconst MEMORY_UPDATE_BLOCK_THRESHOLD = 6;\nconst HISTORY_LENGTH_THRESHOLD = 16_000;\nconst HISTORY_BLOCK_THRESHOLD = 8;\nconst HISTORY_RECENT_BLOCKS_TO_KEEP = 4;\n\nconst INLINE_CONSOLIDATION_SYSTEM_PROMPT = `You are a runtime memory consolidation worker for Pipiclaw.\n\nReturn strict JSON only. Do not wrap in Markdown fences.\n\nOutput schema:\n{\n \"memoryEntries\": [\"string\"],\n \"historyBlock\": \"string\"\n}\n\nRules:\n- memoryEntries: concise durable facts, decisions, preferences, constraints, current work state, or open loops that should survive compaction.\n- Each memoryEntries item must be a standalone sentence fragment suitable for a Markdown bullet without the bullet prefix.\n- Do not include raw transcript quotes unless essential.\n- Do not include ephemeral chatter, obvious one-shot acknowledgements, or formatting instructions.\n- historyBlock: concise Markdown summarizing the conversation chunk for later recovery.\n- Prefer short bullets and short paragraphs.\n- If there is nothing worth storing, return empty values.`;\n\nconst MEMORY_CLEANUP_SYSTEM_PROMPT = `You are rewriting a Pipiclaw channel MEMORY.md file.\n\nReturn Markdown only. Do not use code fences.\n\nGoals:\n- Keep only durable and useful channel memory.\n- Remove outdated entries, duplicates, and verbose phrasing.\n- Organize the result with stable sections where relevant.\n- Prefer concise bullets over prose.\n\nSuggested sections:\n- ## Identity / Participants\n- ## Preferences\n- ## Ongoing Work\n- ## Constraints\n- ## Decisions\n- ## Open Loops\n\nOmit empty sections.`;\n\nconst HISTORY_FOLDING_SYSTEM_PROMPT = `You are folding older HISTORY.md blocks for Pipiclaw.\n\nReturn Markdown only. Do not use code fences.\n\nGoals:\n- Compress older history blocks into one concise summary block.\n- Keep important decisions, milestones, and unresolved outcomes.\n- Remove redundancy and transcript-like detail.\n- Preserve a chronological narrative at a high level.`;\n\nexport interface ConsolidationRunOptions {\n\tchannelDir: string;\n\tmodel: Model<Api>;\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n\tmessages: AgentMessage[];\n\tsessionEntries?: SessionEntry[];\n}\n\nexport interface InlineConsolidationResult {\n\tskipped: boolean;\n\tappendedMemoryEntries: number;\n\tappendedHistoryBlock: boolean;\n}\n\nexport interface BackgroundMaintenanceResult {\n\tcleanedMemory: boolean;\n\tfoldedHistory: boolean;\n}\n\ninterface ConsolidationResponse {\n\tmemoryEntries: string[];\n\thistoryBlock: string;\n}\n\nfunction normalizeText(text: string): string {\n\treturn text.replace(/\\r/g, \"\").trim();\n}\n\nfunction clipTranscript(text: string, maxChars: number): string {\n\tconst normalized = normalizeText(text);\n\tif (normalized.length <= maxChars) {\n\t\treturn normalized;\n\t}\n\n\tconst headChars = Math.floor(maxChars * 0.35);\n\tconst tailChars = maxChars - headChars;\n\treturn `${normalized.slice(0, headChars)}\\n\\n[... omitted middle section ...]\\n\\n${normalized.slice(-tailChars)}`;\n}\n\nfunction extractJsonObject(text: string): string {\n\tconst trimmed = text.trim();\n\tif (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n\t\treturn trimmed;\n\t}\n\n\tconst fenceMatch = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n\tif (fenceMatch?.[1]) {\n\t\treturn fenceMatch[1].trim();\n\t}\n\n\tconst firstBrace = trimmed.indexOf(\"{\");\n\tconst lastBrace = trimmed.lastIndexOf(\"}\");\n\tif (firstBrace >= 0 && lastBrace > firstBrace) {\n\t\treturn trimmed.slice(firstBrace, lastBrace + 1);\n\t}\n\n\treturn trimmed;\n}\n\nfunction parseConsolidationResponse(text: string): ConsolidationResponse {\n\tconst parsed = JSON.parse(extractJsonObject(text)) as Partial<ConsolidationResponse>;\n\treturn {\n\t\tmemoryEntries: Array.isArray(parsed.memoryEntries)\n\t\t\t? parsed.memoryEntries\n\t\t\t\t\t.map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n\t\t\t\t\t.filter((entry) => entry.length > 0)\n\t\t\t: [],\n\t\thistoryBlock: typeof parsed.historyBlock === \"string\" ? parsed.historyBlock.trim() : \"\",\n\t};\n}\n\nfunction getLatestCompactionBoundary(entries: SessionEntry[]): number {\n\tconst latestCompaction = getLatestCompactionEntry(entries);\n\tif (!latestCompaction) {\n\t\treturn 0;\n\t}\n\n\tconst boundaryIndex = entries.findIndex((entry) => entry.id === latestCompaction.firstKeptEntryId);\n\treturn boundaryIndex >= 0 ? boundaryIndex : 0;\n}\n\nfunction isMessage(entry: SessionEntry): entry is SessionMessageEntry {\n\treturn entry.type === \"message\";\n}\n\nfunction isStandardAgentMessage(message: AgentMessage): message is Message {\n\treturn (\n\t\ttypeof message === \"object\" &&\n\t\tmessage !== null &&\n\t\t\"role\" in message &&\n\t\t(message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\")\n\t);\n}\n\nfunction buildMessagesForConsolidation(messages: AgentMessage[]): Message[] {\n\treturn messages.filter(isStandardAgentMessage);\n}\n\nfunction extractMessagesFromSessionEntries(entries: SessionEntry[]): AgentMessage[] {\n\treturn entries.filter(isMessage).map((entry) => entry.message);\n}\n\nfunction hasMeaningfulMessages(messages: Message[]): boolean {\n\tlet meaningfulCount = 0;\n\tfor (const message of messages) {\n\t\tif (message.role === \"user\") {\n\t\t\tconst text =\n\t\t\t\ttypeof message.content === \"string\"\n\t\t\t\t\t? message.content\n\t\t\t\t\t: message.content.map((part) => (part.type === \"text\" ? part.text : \"[image]\")).join(\"\\n\");\n\t\t\tif (text.trim()) meaningfulCount++;\n\t\t} else if (message.role === \"assistant\") {\n\t\t\tconst text = message.content\n\t\t\t\t.filter(\n\t\t\t\t\t(part): part is Extract<AssistantMessage[\"content\"][number], { type: \"text\" }> => part.type === \"text\",\n\t\t\t\t)\n\t\t\t\t.map((part) => part.text)\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (text.trim()) meaningfulCount++;\n\t\t}\n\t\tif (meaningfulCount >= 2) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction countMatchingSectionHeadings(content: string, prefix: string): number {\n\treturn splitMarkdownSections(content).filter((section) => section.heading.startsWith(prefix)).length;\n}\n\nasync function runWorkerPrompt(\n\tmodel: Model<Api>,\n\tresolveApiKey: (model: Model<Api>) => Promise<string>,\n\tsystemPrompt: string,\n\tprompt: string,\n): Promise<string> {\n\tconst apiKey = await resolveApiKey(model);\n\tconst worker = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt,\n\t\t\tmodel,\n\t\t\tthinkingLevel: \"off\",\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm,\n\t\tgetApiKey: async () => apiKey,\n\t});\n\n\tawait worker.prompt(prompt);\n\tawait worker.waitForIdle();\n\n\tconst lastMessage = worker.state.messages[worker.state.messages.length - 1];\n\tif (!lastMessage || lastMessage.role !== \"assistant\") {\n\t\tthrow new Error(\"Consolidation worker returned no assistant message\");\n\t}\n\n\tif (lastMessage.stopReason === \"error\" || lastMessage.stopReason === \"aborted\") {\n\t\tthrow new Error(lastMessage.errorMessage || \"Consolidation worker failed\");\n\t}\n\n\treturn lastMessage.content\n\t\t.filter((part): part is Extract<AssistantMessage[\"content\"][number], { type: \"text\" }> => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nasync function buildInlineConsolidationResponse(\n\toptions: ConsolidationRunOptions,\n\tmessages: Message[],\n): Promise<ConsolidationResponse> {\n\tconst transcript = clipTranscript(serializeConversation(messages), INLINE_TRANSCRIPT_MAX_CHARS);\n\tconst currentMemory = clipTranscript(await readChannelMemory(options.channelDir), 8_000);\n\tconst currentHistory = clipTranscript(await readChannelHistory(options.channelDir), 8_000);\n\n\tconst prompt = `Channel memory file:\n${currentMemory || \"(empty)\"}\n\nChannel history file:\n${currentHistory || \"(empty)\"}\n\nConversation chunk to persist:\n${transcript || \"(empty)\"}`;\n\n\tconst rawResponse = await runWorkerPrompt(\n\t\toptions.model,\n\t\toptions.resolveApiKey,\n\t\tINLINE_CONSOLIDATION_SYSTEM_PROMPT,\n\t\tprompt,\n\t);\n\treturn parseConsolidationResponse(rawResponse);\n}\n\nexport async function runInlineConsolidation(options: ConsolidationRunOptions): Promise<InlineConsolidationResult> {\n\tconst sourceEntries = options.sessionEntries ?? [];\n\tconst relevantEntries =\n\t\tsourceEntries.length > 0 ? sourceEntries.slice(getLatestCompactionBoundary(sourceEntries)) : sourceEntries;\n\tconst relevantMessages = buildMessagesForConsolidation(\n\t\trelevantEntries.length > 0 ? extractMessagesFromSessionEntries(relevantEntries) : options.messages,\n\t);\n\n\tif (!hasMeaningfulMessages(relevantMessages)) {\n\t\treturn { skipped: true, appendedMemoryEntries: 0, appendedHistoryBlock: false };\n\t}\n\n\tconst response = await buildInlineConsolidationResponse(options, relevantMessages);\n\tconst timestamp = new Date().toISOString();\n\n\tif (response.memoryEntries.length > 0) {\n\t\tawait appendChannelMemoryUpdate(options.channelDir, {\n\t\t\ttimestamp,\n\t\t\tentries: response.memoryEntries,\n\t\t});\n\t}\n\n\tif (response.historyBlock.trim()) {\n\t\tawait appendChannelHistoryBlock(options.channelDir, {\n\t\t\ttimestamp,\n\t\t\tcontent: response.historyBlock,\n\t\t});\n\t}\n\n\treturn {\n\t\tskipped: false,\n\t\tappendedMemoryEntries: response.memoryEntries.length,\n\t\tappendedHistoryBlock: response.historyBlock.trim().length > 0,\n\t};\n}\n\nasync function cleanupChannelMemory(options: ConsolidationRunOptions, currentMemory: string): Promise<boolean> {\n\tif (\n\t\tcurrentMemory.length < MEMORY_CLEANUP_LENGTH_THRESHOLD &&\n\t\tcountMatchingSectionHeadings(currentMemory, \"Update \") < MEMORY_UPDATE_BLOCK_THRESHOLD\n\t) {\n\t\treturn false;\n\t}\n\n\tconst prompt = `Current MEMORY.md:\n${currentMemory}`;\n\tconst nextMemory = await runWorkerPrompt(options.model, options.resolveApiKey, MEMORY_CLEANUP_SYSTEM_PROMPT, prompt);\n\tawait rewriteChannelMemory(options.channelDir, nextMemory);\n\treturn true;\n}\n\nasync function foldChannelHistory(options: ConsolidationRunOptions, currentHistory: string): Promise<boolean> {\n\tconst sections = splitMarkdownSections(currentHistory);\n\tif (currentHistory.length < HISTORY_LENGTH_THRESHOLD && sections.length < HISTORY_BLOCK_THRESHOLD) {\n\t\treturn false;\n\t}\n\n\tif (sections.length <= HISTORY_RECENT_BLOCKS_TO_KEEP) {\n\t\treturn false;\n\t}\n\n\tconst olderSections = sections.slice(0, -HISTORY_RECENT_BLOCKS_TO_KEEP);\n\tconst recentSections = sections.slice(-HISTORY_RECENT_BLOCKS_TO_KEEP);\n\tconst prompt = `Older history blocks to fold:\n${olderSections.map((section) => `## ${section.heading}\\n\\n${section.content}`).join(\"\\n\\n\")}`;\n\tconst foldedSummary = await runWorkerPrompt(\n\t\toptions.model,\n\t\toptions.resolveApiKey,\n\t\tHISTORY_FOLDING_SYSTEM_PROMPT,\n\t\tprompt,\n\t);\n\n\tconst foldedHeading = `## Folded History Through ${olderSections[olderSections.length - 1]?.heading ?? new Date().toISOString()}`;\n\tconst rebuiltHistory = [\n\t\t\"# Channel History\",\n\t\t\"\",\n\t\tfoldedHeading,\n\t\t\"\",\n\t\tnormalizeText(foldedSummary),\n\t\t\"\",\n\t\t...recentSections.flatMap((section) => [`## ${section.heading}`, \"\", normalizeText(section.content), \"\"]),\n\t].join(\"\\n\");\n\n\tawait rewriteChannelHistory(options.channelDir, rebuiltHistory);\n\treturn true;\n}\n\nexport async function runBackgroundMaintenance(options: ConsolidationRunOptions): Promise<BackgroundMaintenanceResult> {\n\tconst currentMemory = await readChannelMemory(options.channelDir);\n\tconst currentHistory = await readChannelHistory(options.channelDir);\n\n\tconst cleanedMemory = await cleanupChannelMemory(options, currentMemory);\n\tconst foldedHistory = await foldChannelHistory(options, currentHistory);\n\n\treturn { cleanedMemory, foldedHistory };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"memory-consolidation.d.ts","sourceRoot":"","sources":["../src/memory-consolidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,GAAG,EAA6B,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAGN,KAAK,YAAY,EAGjB,MAAM,+BAA+B,CAAC;AAmEvC,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACvB;AAiLD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAkCjH;AAqDD,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAQrH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-consolidation.js","sourceRoot":"","sources":["../src/memory-consolidation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Api, AssistantMessage, Message, Model } from \"@mariozechner/pi-ai\";\nimport {\n\tconvertToLlm,\n\tgetLatestCompactionEntry,\n\ttype SessionEntry,\n\ttype SessionMessageEntry,\n\tserializeConversation,\n} from \"@mariozechner/pi-coding-agent\";\nimport {\n\tappendChannelHistoryBlock,\n\tappendChannelMemoryUpdate,\n\treadChannelHistory,\n\treadChannelMemory,\n\trewriteChannelHistory,\n\trewriteChannelMemory,\n\tsplitMarkdownSections,\n} from \"./memory-files.js\";\n\nconst INLINE_TRANSCRIPT_MAX_CHARS = 28_000;\nconst MEMORY_CLEANUP_LENGTH_THRESHOLD = 8_000;\nconst MEMORY_UPDATE_BLOCK_THRESHOLD = 6;\nconst HISTORY_LENGTH_THRESHOLD = 16_000;\nconst HISTORY_BLOCK_THRESHOLD = 8;\nconst HISTORY_RECENT_BLOCKS_TO_KEEP = 4;\n\nconst INLINE_CONSOLIDATION_SYSTEM_PROMPT = `You are a runtime memory consolidation worker for Pipiclaw.\n\nReturn strict JSON only. Do not wrap in Markdown fences.\n\nOutput schema:\n{\n \"memoryEntries\": [\"string\"],\n \"historyBlock\": \"string\"\n}\n\nRules:\n- memoryEntries: concise durable facts, decisions, preferences, constraints, current work state, or open loops that should survive compaction.\n- Each memoryEntries item must be a standalone sentence fragment suitable for a Markdown bullet without the bullet prefix.\n- Do not include raw transcript quotes unless essential.\n- Do not include ephemeral chatter, obvious one-shot acknowledgements, or formatting instructions.\n- historyBlock: concise Markdown summarizing the conversation chunk for later recovery.\n- Prefer short bullets and short paragraphs.\n- If there is nothing worth storing, return empty values.`;\n\nconst MEMORY_CLEANUP_SYSTEM_PROMPT = `You are rewriting a Pipiclaw channel MEMORY.md file.\n\nReturn Markdown only. Do not use code fences.\n\nGoals:\n- Keep only durable and useful channel memory.\n- Remove outdated entries, duplicates, and verbose phrasing.\n- Organize the result with stable sections where relevant.\n- Prefer concise bullets over prose.\n\nSuggested sections:\n- ## Identity / Participants\n- ## Preferences\n- ## Ongoing Work\n- ## Constraints\n- ## Decisions\n- ## Open Loops\n\nOmit empty sections.`;\n\nconst HISTORY_FOLDING_SYSTEM_PROMPT = `You are folding older HISTORY.md blocks for Pipiclaw.\n\nReturn Markdown only. Do not use code fences.\n\nGoals:\n- Compress older history blocks into one concise summary block.\n- Keep important decisions, milestones, and unresolved outcomes.\n- Remove redundancy and transcript-like detail.\n- Preserve a chronological narrative at a high level.`;\n\nexport interface ConsolidationRunOptions {\n\tchannelDir: string;\n\tmodel: Model<Api>;\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n\tmessages: AgentMessage[];\n\tsessionEntries?: SessionEntry[];\n}\n\nexport interface InlineConsolidationResult {\n\tskipped: boolean;\n\tappendedMemoryEntries: number;\n\tappendedHistoryBlock: boolean;\n}\n\nexport interface BackgroundMaintenanceResult {\n\tcleanedMemory: boolean;\n\tfoldedHistory: boolean;\n}\n\ninterface ConsolidationResponse {\n\tmemoryEntries: string[];\n\thistoryBlock: string;\n}\n\nfunction normalizeText(text: string): string {\n\treturn text.replace(/\\r/g, \"\").trim();\n}\n\nfunction clipTranscript(text: string, maxChars: number): string {\n\tconst normalized = normalizeText(text);\n\tif (normalized.length <= maxChars) {\n\t\treturn normalized;\n\t}\n\n\tconst headChars = Math.floor(maxChars * 0.35);\n\tconst tailChars = maxChars - headChars;\n\treturn `${normalized.slice(0, headChars)}\\n\\n[... omitted middle section ...]\\n\\n${normalized.slice(-tailChars)}`;\n}\n\nfunction extractJsonObject(text: string): string {\n\tconst trimmed = text.trim();\n\tif (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n\t\treturn trimmed;\n\t}\n\n\tconst fenceMatch = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n\tif (fenceMatch?.[1]) {\n\t\treturn fenceMatch[1].trim();\n\t}\n\n\tconst firstBrace = trimmed.indexOf(\"{\");\n\tconst lastBrace = trimmed.lastIndexOf(\"}\");\n\tif (firstBrace >= 0 && lastBrace > firstBrace) {\n\t\treturn trimmed.slice(firstBrace, lastBrace + 1);\n\t}\n\n\treturn trimmed;\n}\n\nfunction parseConsolidationResponse(text: string): ConsolidationResponse {\n\tconst parsed = JSON.parse(extractJsonObject(text)) as Partial<ConsolidationResponse>;\n\treturn {\n\t\tmemoryEntries: Array.isArray(parsed.memoryEntries)\n\t\t\t? parsed.memoryEntries\n\t\t\t\t\t.map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n\t\t\t\t\t.filter((entry) => entry.length > 0)\n\t\t\t: [],\n\t\thistoryBlock: typeof parsed.historyBlock === \"string\" ? parsed.historyBlock.trim() : \"\",\n\t};\n}\n\nfunction getLatestCompactionBoundary(entries: SessionEntry[]): number {\n\tconst latestCompaction = getLatestCompactionEntry(entries);\n\tif (!latestCompaction) {\n\t\treturn 0;\n\t}\n\n\tconst boundaryIndex = entries.findIndex((entry) => entry.id === latestCompaction.firstKeptEntryId);\n\treturn boundaryIndex >= 0 ? boundaryIndex : 0;\n}\n\nfunction isMessage(entry: SessionEntry): entry is SessionMessageEntry {\n\treturn entry.type === \"message\";\n}\n\nfunction isStandardAgentMessage(message: AgentMessage): message is Message {\n\treturn (\n\t\ttypeof message === \"object\" &&\n\t\tmessage !== null &&\n\t\t\"role\" in message &&\n\t\t(message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\")\n\t);\n}\n\nfunction buildMessagesForConsolidation(messages: AgentMessage[]): Message[] {\n\treturn messages.filter(isStandardAgentMessage);\n}\n\nfunction extractMessagesFromSessionEntries(entries: SessionEntry[]): AgentMessage[] {\n\treturn entries.filter(isMessage).map((entry) => entry.message);\n}\n\nfunction hasMeaningfulMessages(messages: Message[]): boolean {\n\tlet meaningfulCount = 0;\n\tfor (const message of messages) {\n\t\tif (message.role === \"user\") {\n\t\t\tconst text =\n\t\t\t\ttypeof message.content === \"string\"\n\t\t\t\t\t? message.content\n\t\t\t\t\t: message.content.map((part) => (part.type === \"text\" ? part.text : \"[image]\")).join(\"\\n\");\n\t\t\tif (text.trim()) meaningfulCount++;\n\t\t} else if (message.role === \"assistant\") {\n\t\t\tconst text = message.content\n\t\t\t\t.filter(\n\t\t\t\t\t(part): part is Extract<AssistantMessage[\"content\"][number], { type: \"text\" }> => part.type === \"text\",\n\t\t\t\t)\n\t\t\t\t.map((part) => part.text)\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (text.trim()) meaningfulCount++;\n\t\t}\n\t\tif (meaningfulCount >= 2) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction countMatchingSectionHeadings(content: string, prefix: string): number {\n\treturn splitMarkdownSections(content).filter((section) => section.heading.startsWith(prefix)).length;\n}\n\nasync function runWorkerPrompt(\n\tmodel: Model<Api>,\n\tresolveApiKey: (model: Model<Api>) => Promise<string>,\n\tsystemPrompt: string,\n\tprompt: string,\n): Promise<string> {\n\tconst apiKey = await resolveApiKey(model);\n\tconst worker = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt,\n\t\t\tmodel,\n\t\t\tthinkingLevel: \"off\",\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm,\n\t\tgetApiKey: async () => apiKey,\n\t});\n\n\tawait worker.prompt(prompt);\n\tawait worker.waitForIdle();\n\n\tconst lastMessage = worker.state.messages[worker.state.messages.length - 1];\n\tif (!lastMessage || lastMessage.role !== \"assistant\") {\n\t\tthrow new Error(\"Consolidation worker returned no assistant message\");\n\t}\n\n\tif (lastMessage.stopReason === \"error\" || lastMessage.stopReason === \"aborted\") {\n\t\tthrow new Error(lastMessage.errorMessage || \"Consolidation worker failed\");\n\t}\n\n\treturn lastMessage.content\n\t\t.filter((part): part is Extract<AssistantMessage[\"content\"][number], { type: \"text\" }> => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nasync function buildInlineConsolidationResponse(\n\toptions: ConsolidationRunOptions,\n\tmessages: Message[],\n): Promise<ConsolidationResponse> {\n\tconst transcript = clipTranscript(serializeConversation(messages), INLINE_TRANSCRIPT_MAX_CHARS);\n\tconst currentMemory = clipTranscript(await readChannelMemory(options.channelDir), 8_000);\n\tconst currentHistory = clipTranscript(await readChannelHistory(options.channelDir), 8_000);\n\n\tconst prompt = `Channel memory file:\n${currentMemory || \"(empty)\"}\n\nChannel history file:\n${currentHistory || \"(empty)\"}\n\nConversation chunk to persist:\n${transcript || \"(empty)\"}`;\n\n\tconst rawResponse = await runWorkerPrompt(\n\t\toptions.model,\n\t\toptions.resolveApiKey,\n\t\tINLINE_CONSOLIDATION_SYSTEM_PROMPT,\n\t\tprompt,\n\t);\n\treturn parseConsolidationResponse(rawResponse);\n}\n\nexport async function runInlineConsolidation(options: ConsolidationRunOptions): Promise<InlineConsolidationResult> {\n\tconst sourceEntries = options.sessionEntries ?? [];\n\tconst relevantEntries =\n\t\tsourceEntries.length > 0 ? sourceEntries.slice(getLatestCompactionBoundary(sourceEntries)) : sourceEntries;\n\tconst relevantMessages = buildMessagesForConsolidation(\n\t\trelevantEntries.length > 0 ? extractMessagesFromSessionEntries(relevantEntries) : options.messages,\n\t);\n\n\tif (!hasMeaningfulMessages(relevantMessages)) {\n\t\treturn { skipped: true, appendedMemoryEntries: 0, appendedHistoryBlock: false };\n\t}\n\n\tconst response = await buildInlineConsolidationResponse(options, relevantMessages);\n\tconst timestamp = new Date().toISOString();\n\n\tif (response.memoryEntries.length > 0) {\n\t\tawait appendChannelMemoryUpdate(options.channelDir, {\n\t\t\ttimestamp,\n\t\t\tentries: response.memoryEntries,\n\t\t});\n\t}\n\n\tif (response.historyBlock.trim()) {\n\t\tawait appendChannelHistoryBlock(options.channelDir, {\n\t\t\ttimestamp,\n\t\t\tcontent: response.historyBlock,\n\t\t});\n\t}\n\n\treturn {\n\t\tskipped: false,\n\t\tappendedMemoryEntries: response.memoryEntries.length,\n\t\tappendedHistoryBlock: response.historyBlock.trim().length > 0,\n\t};\n}\n\nasync function cleanupChannelMemory(options: ConsolidationRunOptions, currentMemory: string): Promise<boolean> {\n\tif (\n\t\tcurrentMemory.length < MEMORY_CLEANUP_LENGTH_THRESHOLD &&\n\t\tcountMatchingSectionHeadings(currentMemory, \"Update \") < MEMORY_UPDATE_BLOCK_THRESHOLD\n\t) {\n\t\treturn false;\n\t}\n\n\tconst prompt = `Current MEMORY.md:\n${currentMemory}`;\n\tconst nextMemory = await runWorkerPrompt(options.model, options.resolveApiKey, MEMORY_CLEANUP_SYSTEM_PROMPT, prompt);\n\tawait rewriteChannelMemory(options.channelDir, nextMemory);\n\treturn true;\n}\n\nasync function foldChannelHistory(options: ConsolidationRunOptions, currentHistory: string): Promise<boolean> {\n\tconst sections = splitMarkdownSections(currentHistory);\n\tif (currentHistory.length < HISTORY_LENGTH_THRESHOLD && sections.length < HISTORY_BLOCK_THRESHOLD) {\n\t\treturn false;\n\t}\n\n\tif (sections.length <= HISTORY_RECENT_BLOCKS_TO_KEEP) {\n\t\treturn false;\n\t}\n\n\tconst olderSections = sections.slice(0, -HISTORY_RECENT_BLOCKS_TO_KEEP);\n\tconst recentSections = sections.slice(-HISTORY_RECENT_BLOCKS_TO_KEEP);\n\tconst prompt = `Older history blocks to fold:\n${olderSections.map((section) => `## ${section.heading}\\n\\n${section.content}`).join(\"\\n\\n\")}`;\n\tconst foldedSummary = await runWorkerPrompt(\n\t\toptions.model,\n\t\toptions.resolveApiKey,\n\t\tHISTORY_FOLDING_SYSTEM_PROMPT,\n\t\tprompt,\n\t);\n\n\tconst foldedHeading = `## Folded History Through ${olderSections[olderSections.length - 1]?.heading ?? new Date().toISOString()}`;\n\tconst rebuiltHistory = [\n\t\t\"# Channel History\",\n\t\t\"\",\n\t\tfoldedHeading,\n\t\t\"\",\n\t\tnormalizeText(foldedSummary),\n\t\t\"\",\n\t\t...recentSections.flatMap((section) => [`## ${section.heading}`, \"\", normalizeText(section.content), \"\"]),\n\t].join(\"\\n\");\n\n\tawait rewriteChannelHistory(options.channelDir, rebuiltHistory);\n\treturn true;\n}\n\nexport async function runBackgroundMaintenance(options: ConsolidationRunOptions): Promise<BackgroundMaintenanceResult> {\n\tconst currentMemory = await readChannelMemory(options.channelDir);\n\tconst currentHistory = await readChannelHistory(options.channelDir);\n\n\tconst cleanedMemory = await cleanupChannelMemory(options, currentMemory);\n\tconst foldedHistory = await foldChannelHistory(options, currentHistory);\n\n\treturn { cleanedMemory, foldedHistory };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"memory-consolidation.js","sourceRoot":"","sources":["../src/memory-consolidation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEpD,OAAO,EACN,YAAY,EACZ,wBAAwB,EAGxB,qBAAqB,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,GACrB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAC3C,MAAM,+BAA+B,GAAG,KAAK,CAAC;AAC9C,MAAM,6BAA6B,GAAG,CAAC,CAAC;AACxC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AACxC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAClC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAExC,MAAM,kCAAkC,GAAG;;;;;;;;;;;;;;;;;0DAiBe,CAAC;AAE3D,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;;;qBAkBhB,CAAC;AAEtB,MAAM,6BAA6B,GAAG;;;;;;;;sDAQgB,CAAC;AA0BvD,SAAS,aAAa,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,QAAgB;IACrD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,UAAU,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QACnC,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACvC,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,2CAA2C,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;AACnH,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClE,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,UAAU,IAAI,CAAC,IAAI,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/C,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAmC,CAAC;IACrF,OAAO;QACN,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;YACjD,CAAC,CAAC,MAAM,CAAC,aAAa;iBACnB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;iBAC/D,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACtC,CAAC,CAAC,EAAE;QACL,YAAY,EAAE,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;KACvF,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,OAAuB;IAC3D,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvB,OAAO,CAAC,CAAC;IACV,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACnG,OAAO,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,SAAS,CAAC,KAAmB;IACrC,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAqB;IACpD,OAAO,CACN,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,KAAK,IAAI;QAChB,MAAM,IAAI,OAAO;QACjB,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC,CAC1F,CAAC;AACH,CAAC;AAED,SAAS,6BAA6B,CAAC,QAAwB;IAC9D,OAAO,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,iCAAiC,CAAC,OAAuB;IACjE,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAmB;IACjD,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,MAAM,IAAI,GACT,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;gBAClC,CAAC,CAAC,OAAO,CAAC,OAAO;gBACjB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7F,IAAI,IAAI,CAAC,IAAI,EAAE;gBAAE,eAAe,EAAE,CAAC;QACpC,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO;iBAC1B,MAAM,CACN,CAAC,IAAI,EAA0E,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CACtG;iBACA,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;iBACxB,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,IAAI,IAAI,CAAC,IAAI,EAAE;gBAAE,eAAe,EAAE,CAAC;QACpC,CAAC;QACD,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,4BAA4B,CAAC,OAAe,EAAE,MAAc;IACpE,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AACtG,CAAC;AAED,KAAK,UAAU,eAAe,CAC7B,KAAiB,EACjB,aAAqD,EACrD,YAAoB,EACpB,MAAc;IAEd,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC;QACxB,YAAY,EAAE;YACb,YAAY;YACZ,KAAK;YACL,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,EAAE;SACT;QACD,YAAY;QACZ,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM;KAC7B,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;IAE3B,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,WAAW,CAAC,UAAU,KAAK,OAAO,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAChF,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,IAAI,6BAA6B,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,WAAW,CAAC,OAAO;SACxB,MAAM,CAAC,CAAC,IAAI,EAA0E,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;SAC9G,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAC;AACV,CAAC;AAED,KAAK,UAAU,gCAAgC,CAC9C,OAAgC,EAChC,QAAmB;IAEnB,MAAM,UAAU,GAAG,cAAc,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAChG,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;IACzF,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;IAE3F,MAAM,MAAM,GAAG;EACd,aAAa,IAAI,SAAS;;;EAG1B,cAAc,IAAI,SAAS;;;EAG3B,UAAU,IAAI,SAAS,EAAE,CAAC;IAE3B,MAAM,WAAW,GAAG,MAAM,eAAe,CACxC,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,aAAa,EACrB,kCAAkC,EAClC,MAAM,CACN,CAAC;IACF,OAAO,0BAA0B,CAAC,WAAW,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAAgC;IAC5E,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;IACnD,MAAM,eAAe,GACpB,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,2BAA2B,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAC5G,MAAM,gBAAgB,GAAG,6BAA6B,CACrD,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iCAAiC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAClG,CAAC;IAEF,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC;IACjF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,gCAAgC,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACnF,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE3C,IAAI,QAAQ,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,yBAAyB,CAAC,OAAO,CAAC,UAAU,EAAE;YACnD,SAAS;YACT,OAAO,EAAE,QAAQ,CAAC,aAAa;SAC/B,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,MAAM,yBAAyB,CAAC,OAAO,CAAC,UAAU,EAAE;YACnD,SAAS;YACT,OAAO,EAAE,QAAQ,CAAC,YAAY;SAC9B,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACN,OAAO,EAAE,KAAK;QACd,qBAAqB,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM;QACpD,oBAAoB,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;KAC7D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,OAAgC,EAAE,aAAqB;IAC1F,IACC,aAAa,CAAC,MAAM,GAAG,+BAA+B;QACtD,4BAA4B,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG,6BAA6B,EACrF,CAAC;QACF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG;EACd,aAAa,EAAE,CAAC;IACjB,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE,4BAA4B,EAAE,MAAM,CAAC,CAAC;IACrH,MAAM,oBAAoB,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,OAAgC,EAAE,cAAsB;IACzF,MAAM,QAAQ,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACvD,IAAI,cAAc,CAAC,MAAM,GAAG,wBAAwB,IAAI,QAAQ,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QACnG,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,IAAI,6BAA6B,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,6BAA6B,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG;EACd,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,OAAO,CAAC,OAAO,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IAC9F,MAAM,aAAa,GAAG,MAAM,eAAe,CAC1C,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,aAAa,EACrB,6BAA6B,EAC7B,MAAM,CACN,CAAC;IAEF,MAAM,aAAa,GAAG,6BAA6B,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAClI,MAAM,cAAc,GAAG;QACtB,mBAAmB;QACnB,EAAE;QACF,aAAa;QACb,EAAE;QACF,aAAa,CAAC,aAAa,CAAC;QAC5B,EAAE;QACF,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;KACzG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,qBAAqB,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAAgC;IAC9E,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAEpE,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACzE,MAAM,aAAa,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAExE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AACzC,CAAC","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport { Agent } from \"@mariozechner/pi-agent-core\";\nimport type { Api, AssistantMessage, Message, Model } from \"@mariozechner/pi-ai\";\nimport {\n\tconvertToLlm,\n\tgetLatestCompactionEntry,\n\ttype SessionEntry,\n\ttype SessionMessageEntry,\n\tserializeConversation,\n} from \"@mariozechner/pi-coding-agent\";\nimport {\n\tappendChannelHistoryBlock,\n\tappendChannelMemoryUpdate,\n\treadChannelHistory,\n\treadChannelMemory,\n\trewriteChannelHistory,\n\trewriteChannelMemory,\n\tsplitMarkdownSections,\n} from \"./memory-files.js\";\n\nconst INLINE_TRANSCRIPT_MAX_CHARS = 28_000;\nconst MEMORY_CLEANUP_LENGTH_THRESHOLD = 8_000;\nconst MEMORY_UPDATE_BLOCK_THRESHOLD = 6;\nconst HISTORY_LENGTH_THRESHOLD = 16_000;\nconst HISTORY_BLOCK_THRESHOLD = 8;\nconst HISTORY_RECENT_BLOCKS_TO_KEEP = 4;\n\nconst INLINE_CONSOLIDATION_SYSTEM_PROMPT = `You are a runtime memory consolidation worker for Pipiclaw.\n\nReturn strict JSON only. Do not wrap in Markdown fences.\n\nOutput schema:\n{\n \"memoryEntries\": [\"string\"],\n \"historyBlock\": \"string\"\n}\n\nRules:\n- memoryEntries: concise durable facts, decisions, preferences, constraints, current work state, or open loops that should survive compaction.\n- Each memoryEntries item must be a standalone sentence fragment suitable for a Markdown bullet without the bullet prefix.\n- Do not include raw transcript quotes unless essential.\n- Do not include ephemeral chatter, obvious one-shot acknowledgements, or formatting instructions.\n- historyBlock: concise Markdown summarizing the conversation chunk for later recovery.\n- Prefer short bullets and short paragraphs.\n- If there is nothing worth storing, return empty values.`;\n\nconst MEMORY_CLEANUP_SYSTEM_PROMPT = `You are rewriting a Pipiclaw channel MEMORY.md file.\n\nReturn Markdown only. Do not use code fences.\n\nGoals:\n- Keep only durable and useful channel memory.\n- Remove outdated entries, duplicates, and verbose phrasing.\n- Organize the result with stable sections where relevant.\n- Prefer concise bullets over prose.\n\nSuggested sections:\n- ## Identity / Participants\n- ## Preferences\n- ## Ongoing Work\n- ## Constraints\n- ## Decisions\n- ## Open Loops\n\nOmit empty sections.`;\n\nconst HISTORY_FOLDING_SYSTEM_PROMPT = `You are folding older HISTORY.md blocks for Pipiclaw.\n\nReturn Markdown only. Do not use code fences.\n\nGoals:\n- Compress older history blocks into one concise summary block.\n- Keep important decisions, milestones, and unresolved outcomes.\n- Remove redundancy and transcript-like detail.\n- Preserve a chronological narrative at a high level.`;\n\nexport interface ConsolidationRunOptions {\n\tchannelDir: string;\n\tmodel: Model<Api>;\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n\tmessages: AgentMessage[];\n\tsessionEntries?: SessionEntry[];\n}\n\nexport interface InlineConsolidationResult {\n\tskipped: boolean;\n\tappendedMemoryEntries: number;\n\tappendedHistoryBlock: boolean;\n}\n\nexport interface BackgroundMaintenanceResult {\n\tcleanedMemory: boolean;\n\tfoldedHistory: boolean;\n}\n\ninterface ConsolidationResponse {\n\tmemoryEntries: string[];\n\thistoryBlock: string;\n}\n\nfunction normalizeText(text: string): string {\n\treturn text.replace(/\\r/g, \"\").trim();\n}\n\nfunction clipTranscript(text: string, maxChars: number): string {\n\tconst normalized = normalizeText(text);\n\tif (normalized.length <= maxChars) {\n\t\treturn normalized;\n\t}\n\n\tconst headChars = Math.floor(maxChars * 0.35);\n\tconst tailChars = maxChars - headChars;\n\treturn `${normalized.slice(0, headChars)}\\n\\n[... omitted middle section ...]\\n\\n${normalized.slice(-tailChars)}`;\n}\n\nfunction extractJsonObject(text: string): string {\n\tconst trimmed = text.trim();\n\tif (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n\t\treturn trimmed;\n\t}\n\n\tconst fenceMatch = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n\tif (fenceMatch?.[1]) {\n\t\treturn fenceMatch[1].trim();\n\t}\n\n\tconst firstBrace = trimmed.indexOf(\"{\");\n\tconst lastBrace = trimmed.lastIndexOf(\"}\");\n\tif (firstBrace >= 0 && lastBrace > firstBrace) {\n\t\treturn trimmed.slice(firstBrace, lastBrace + 1);\n\t}\n\n\treturn trimmed;\n}\n\nfunction parseConsolidationResponse(text: string): ConsolidationResponse {\n\tconst parsed = JSON.parse(extractJsonObject(text)) as Partial<ConsolidationResponse>;\n\treturn {\n\t\tmemoryEntries: Array.isArray(parsed.memoryEntries)\n\t\t\t? parsed.memoryEntries\n\t\t\t\t\t.map((entry) => (typeof entry === \"string\" ? entry.trim() : \"\"))\n\t\t\t\t\t.filter((entry) => entry.length > 0)\n\t\t\t: [],\n\t\thistoryBlock: typeof parsed.historyBlock === \"string\" ? parsed.historyBlock.trim() : \"\",\n\t};\n}\n\nfunction getLatestCompactionBoundary(entries: SessionEntry[]): number {\n\tconst latestCompaction = getLatestCompactionEntry(entries);\n\tif (!latestCompaction) {\n\t\treturn 0;\n\t}\n\n\tconst boundaryIndex = entries.findIndex((entry) => entry.id === latestCompaction.firstKeptEntryId);\n\treturn boundaryIndex >= 0 ? boundaryIndex : 0;\n}\n\nfunction isMessage(entry: SessionEntry): entry is SessionMessageEntry {\n\treturn entry.type === \"message\";\n}\n\nfunction isStandardAgentMessage(message: AgentMessage): message is Message {\n\treturn (\n\t\ttypeof message === \"object\" &&\n\t\tmessage !== null &&\n\t\t\"role\" in message &&\n\t\t(message.role === \"user\" || message.role === \"assistant\" || message.role === \"toolResult\")\n\t);\n}\n\nfunction buildMessagesForConsolidation(messages: AgentMessage[]): Message[] {\n\treturn messages.filter(isStandardAgentMessage);\n}\n\nfunction extractMessagesFromSessionEntries(entries: SessionEntry[]): AgentMessage[] {\n\treturn entries.filter(isMessage).map((entry) => entry.message);\n}\n\nfunction hasMeaningfulMessages(messages: Message[]): boolean {\n\tlet meaningfulCount = 0;\n\tfor (const message of messages) {\n\t\tif (message.role === \"user\") {\n\t\t\tconst text =\n\t\t\t\ttypeof message.content === \"string\"\n\t\t\t\t\t? message.content\n\t\t\t\t\t: message.content.map((part) => (part.type === \"text\" ? part.text : \"[image]\")).join(\"\\n\");\n\t\t\tif (text.trim()) meaningfulCount++;\n\t\t} else if (message.role === \"assistant\") {\n\t\t\tconst text = message.content\n\t\t\t\t.filter(\n\t\t\t\t\t(part): part is Extract<AssistantMessage[\"content\"][number], { type: \"text\" }> => part.type === \"text\",\n\t\t\t\t)\n\t\t\t\t.map((part) => part.text)\n\t\t\t\t.join(\"\\n\");\n\t\t\tif (text.trim()) meaningfulCount++;\n\t\t}\n\t\tif (meaningfulCount >= 2) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction countMatchingSectionHeadings(content: string, prefix: string): number {\n\treturn splitMarkdownSections(content).filter((section) => section.heading.startsWith(prefix)).length;\n}\n\nasync function runWorkerPrompt(\n\tmodel: Model<Api>,\n\tresolveApiKey: (model: Model<Api>) => Promise<string>,\n\tsystemPrompt: string,\n\tprompt: string,\n): Promise<string> {\n\tconst apiKey = await resolveApiKey(model);\n\tconst worker = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt,\n\t\t\tmodel,\n\t\t\tthinkingLevel: \"off\",\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm,\n\t\tgetApiKey: async () => apiKey,\n\t});\n\n\tawait worker.prompt(prompt);\n\tawait worker.waitForIdle();\n\n\tconst lastMessage = worker.state.messages[worker.state.messages.length - 1];\n\tif (!lastMessage || lastMessage.role !== \"assistant\") {\n\t\tthrow new Error(\"Consolidation worker returned no assistant message\");\n\t}\n\n\tif (lastMessage.stopReason === \"error\" || lastMessage.stopReason === \"aborted\") {\n\t\tthrow new Error(lastMessage.errorMessage || \"Consolidation worker failed\");\n\t}\n\n\treturn lastMessage.content\n\t\t.filter((part): part is Extract<AssistantMessage[\"content\"][number], { type: \"text\" }> => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nasync function buildInlineConsolidationResponse(\n\toptions: ConsolidationRunOptions,\n\tmessages: Message[],\n): Promise<ConsolidationResponse> {\n\tconst transcript = clipTranscript(serializeConversation(messages), INLINE_TRANSCRIPT_MAX_CHARS);\n\tconst currentMemory = clipTranscript(await readChannelMemory(options.channelDir), 8_000);\n\tconst currentHistory = clipTranscript(await readChannelHistory(options.channelDir), 8_000);\n\n\tconst prompt = `Channel memory file:\n${currentMemory || \"(empty)\"}\n\nChannel history file:\n${currentHistory || \"(empty)\"}\n\nConversation chunk to persist:\n${transcript || \"(empty)\"}`;\n\n\tconst rawResponse = await runWorkerPrompt(\n\t\toptions.model,\n\t\toptions.resolveApiKey,\n\t\tINLINE_CONSOLIDATION_SYSTEM_PROMPT,\n\t\tprompt,\n\t);\n\treturn parseConsolidationResponse(rawResponse);\n}\n\nexport async function runInlineConsolidation(options: ConsolidationRunOptions): Promise<InlineConsolidationResult> {\n\tconst sourceEntries = options.sessionEntries ?? [];\n\tconst relevantEntries =\n\t\tsourceEntries.length > 0 ? sourceEntries.slice(getLatestCompactionBoundary(sourceEntries)) : sourceEntries;\n\tconst relevantMessages = buildMessagesForConsolidation(\n\t\trelevantEntries.length > 0 ? extractMessagesFromSessionEntries(relevantEntries) : options.messages,\n\t);\n\n\tif (!hasMeaningfulMessages(relevantMessages)) {\n\t\treturn { skipped: true, appendedMemoryEntries: 0, appendedHistoryBlock: false };\n\t}\n\n\tconst response = await buildInlineConsolidationResponse(options, relevantMessages);\n\tconst timestamp = new Date().toISOString();\n\n\tif (response.memoryEntries.length > 0) {\n\t\tawait appendChannelMemoryUpdate(options.channelDir, {\n\t\t\ttimestamp,\n\t\t\tentries: response.memoryEntries,\n\t\t});\n\t}\n\n\tif (response.historyBlock.trim()) {\n\t\tawait appendChannelHistoryBlock(options.channelDir, {\n\t\t\ttimestamp,\n\t\t\tcontent: response.historyBlock,\n\t\t});\n\t}\n\n\treturn {\n\t\tskipped: false,\n\t\tappendedMemoryEntries: response.memoryEntries.length,\n\t\tappendedHistoryBlock: response.historyBlock.trim().length > 0,\n\t};\n}\n\nasync function cleanupChannelMemory(options: ConsolidationRunOptions, currentMemory: string): Promise<boolean> {\n\tif (\n\t\tcurrentMemory.length < MEMORY_CLEANUP_LENGTH_THRESHOLD &&\n\t\tcountMatchingSectionHeadings(currentMemory, \"Update \") < MEMORY_UPDATE_BLOCK_THRESHOLD\n\t) {\n\t\treturn false;\n\t}\n\n\tconst prompt = `Current MEMORY.md:\n${currentMemory}`;\n\tconst nextMemory = await runWorkerPrompt(options.model, options.resolveApiKey, MEMORY_CLEANUP_SYSTEM_PROMPT, prompt);\n\tawait rewriteChannelMemory(options.channelDir, nextMemory);\n\treturn true;\n}\n\nasync function foldChannelHistory(options: ConsolidationRunOptions, currentHistory: string): Promise<boolean> {\n\tconst sections = splitMarkdownSections(currentHistory);\n\tif (currentHistory.length < HISTORY_LENGTH_THRESHOLD && sections.length < HISTORY_BLOCK_THRESHOLD) {\n\t\treturn false;\n\t}\n\n\tif (sections.length <= HISTORY_RECENT_BLOCKS_TO_KEEP) {\n\t\treturn false;\n\t}\n\n\tconst olderSections = sections.slice(0, -HISTORY_RECENT_BLOCKS_TO_KEEP);\n\tconst recentSections = sections.slice(-HISTORY_RECENT_BLOCKS_TO_KEEP);\n\tconst prompt = `Older history blocks to fold:\n${olderSections.map((section) => `## ${section.heading}\\n\\n${section.content}`).join(\"\\n\\n\")}`;\n\tconst foldedSummary = await runWorkerPrompt(\n\t\toptions.model,\n\t\toptions.resolveApiKey,\n\t\tHISTORY_FOLDING_SYSTEM_PROMPT,\n\t\tprompt,\n\t);\n\n\tconst foldedHeading = `## Folded History Through ${olderSections[olderSections.length - 1]?.heading ?? new Date().toISOString()}`;\n\tconst rebuiltHistory = [\n\t\t\"# Channel History\",\n\t\t\"\",\n\t\tfoldedHeading,\n\t\t\"\",\n\t\tnormalizeText(foldedSummary),\n\t\t\"\",\n\t\t...recentSections.flatMap((section) => [`## ${section.heading}`, \"\", normalizeText(section.content), \"\"]),\n\t].join(\"\\n\");\n\n\tawait rewriteChannelHistory(options.channelDir, rebuiltHistory);\n\treturn true;\n}\n\nexport async function runBackgroundMaintenance(options: ConsolidationRunOptions): Promise<BackgroundMaintenanceResult> {\n\tconst currentMemory = await readChannelMemory(options.channelDir);\n\tconst currentHistory = await readChannelHistory(options.channelDir);\n\n\tconst cleanedMemory = await cleanupChannelMemory(options, currentMemory);\n\tconst foldedHistory = await foldChannelHistory(options, currentHistory);\n\n\treturn { cleanedMemory, foldedHistory };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-files.d.ts","sourceRoot":"","sources":["../src/memory-files.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAiBD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAsB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAYrE;AASD,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3E;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7F;AAED,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9F;AAED,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3G;AAED,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAWtG;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAmCxE"
|
|
1
|
+
{"version":3,"file":"memory-files.d.ts","sourceRoot":"","sources":["../src/memory-files.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAiBD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED,wBAAsB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAYrE;AASD,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3E;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7F;AAED,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9F;AAED,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3G;AAED,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAWtG;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAmCxE"}
|
package/dist/memory-files.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-files.js","sourceRoot":"","sources":["../src/memory-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,sBAAsB,GAAG;;;;;;;;;;;CAW9B,CAAC;AAEF,MAAM,uBAAuB,GAAG;;;;;;;CAO/B,CAAC;AAYF,SAAS,gBAAgB,CAAC,OAAe
|
|
1
|
+
{"version":3,"file":"memory-files.js","sourceRoot":"","sources":["../src/memory-files.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from \"fs\";\nimport { mkdir, readFile, rename, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\n\nconst DEFAULT_CHANNEL_MEMORY = `# Channel Memory\n\nThis file stores durable channel-specific memory.\n\n- It is not preloaded into session context.\n- Read it on demand when prior decisions, preferences, or long-running work matter.\n- The runtime may append updates here during consolidation.\n\n## Durable Facts\n\n<!-- Stable facts, preferences, and ongoing commitments can accumulate here. -->\n`;\n\nconst DEFAULT_CHANNEL_HISTORY = `# Channel History\n\nThis file stores summarized older channel history.\n\n- It is not preloaded into session context.\n- Read it on demand when older context matters.\n- The runtime may append and fold history blocks here during consolidation.\n`;\n\nexport interface MemoryUpdateBlock {\n\ttimestamp: string;\n\tentries: string[];\n}\n\nexport interface HistoryBlock {\n\ttimestamp: string;\n\tcontent: string;\n}\n\nfunction normalizeContent(content: string): string {\n\treturn content.trim().length > 0 ? `${content.trim()}\\n` : \"\";\n}\n\nasync function writeAtomically(path: string, content: string): Promise<void> {\n\tawait mkdir(dirname(path), { recursive: true });\n\tconst tempPath = `${path}.tmp`;\n\tawait writeFile(tempPath, content, \"utf-8\");\n\tawait rename(tempPath, path);\n}\n\nfunction ensureTrailingNewlines(content: string): string {\n\treturn content.trimEnd().length > 0 ? `${content.trimEnd()}\\n\\n` : \"\";\n}\n\nexport function getChannelMemoryPath(channelDir: string): string {\n\treturn join(channelDir, \"MEMORY.md\");\n}\n\nexport function getChannelHistoryPath(channelDir: string): string {\n\treturn join(channelDir, \"HISTORY.md\");\n}\n\nexport async function ensureChannelMemoryFiles(channelDir: string): Promise<void> {\n\tensureChannelMemoryFilesSync(channelDir);\n}\n\nexport function ensureChannelMemoryFilesSync(channelDir: string): void {\n\tconst memoryPath = getChannelMemoryPath(channelDir);\n\tconst historyPath = getChannelHistoryPath(channelDir);\n\n\tmkdirSync(channelDir, { recursive: true });\n\n\tif (!existsSync(memoryPath)) {\n\t\twriteFileSync(memoryPath, DEFAULT_CHANNEL_MEMORY, \"utf-8\");\n\t}\n\tif (!existsSync(historyPath)) {\n\t\twriteFileSync(historyPath, DEFAULT_CHANNEL_HISTORY, \"utf-8\");\n\t}\n}\n\nasync function readTextFile(path: string): Promise<string> {\n\tif (!existsSync(path)) {\n\t\treturn \"\";\n\t}\n\treturn readFile(path, \"utf-8\");\n}\n\nexport async function readChannelMemory(channelDir: string): Promise<string> {\n\treturn readTextFile(getChannelMemoryPath(channelDir));\n}\n\nexport async function readChannelHistory(channelDir: string): Promise<string> {\n\treturn readTextFile(getChannelHistoryPath(channelDir));\n}\n\nexport async function rewriteChannelMemory(channelDir: string, content: string): Promise<void> {\n\tawait ensureChannelMemoryFiles(channelDir);\n\tconst nextContent = normalizeContent(content) || DEFAULT_CHANNEL_MEMORY;\n\tawait writeAtomically(getChannelMemoryPath(channelDir), nextContent);\n}\n\nexport async function rewriteChannelHistory(channelDir: string, content: string): Promise<void> {\n\tawait ensureChannelMemoryFiles(channelDir);\n\tconst nextContent = normalizeContent(content) || DEFAULT_CHANNEL_HISTORY;\n\tawait writeAtomically(getChannelHistoryPath(channelDir), nextContent);\n}\n\nexport async function appendChannelMemoryUpdate(channelDir: string, block: MemoryUpdateBlock): Promise<void> {\n\tif (block.entries.length === 0) {\n\t\treturn;\n\t}\n\n\tawait ensureChannelMemoryFiles(channelDir);\n\tconst path = getChannelMemoryPath(channelDir);\n\tconst existing = await readTextFile(path);\n\tconst renderedBlock = [`## Update ${block.timestamp}`, ...block.entries.map((entry) => `- ${entry.trim()}`)].join(\n\t\t\"\\n\",\n\t);\n\tawait writeAtomically(path, `${ensureTrailingNewlines(existing)}${renderedBlock}\\n`);\n}\n\nexport async function appendChannelHistoryBlock(channelDir: string, block: HistoryBlock): Promise<void> {\n\tconst trimmedContent = block.content.trim();\n\tif (!trimmedContent) {\n\t\treturn;\n\t}\n\n\tawait ensureChannelMemoryFiles(channelDir);\n\tconst path = getChannelHistoryPath(channelDir);\n\tconst existing = await readTextFile(path);\n\tconst renderedBlock = [`## ${block.timestamp}`, trimmedContent].join(\"\\n\\n\");\n\tawait writeAtomically(path, `${ensureTrailingNewlines(existing)}${renderedBlock}\\n`);\n}\n\nexport interface MarkdownSection {\n\theading: string;\n\tcontent: string;\n}\n\nexport function splitMarkdownSections(content: string): MarkdownSection[] {\n\tconst normalized = content.replace(/\\r/g, \"\").trim();\n\tif (!normalized) {\n\t\treturn [];\n\t}\n\n\tconst lines = normalized.split(\"\\n\");\n\tconst sections: MarkdownSection[] = [];\n\tlet currentHeading = \"\";\n\tlet currentLines: string[] = [];\n\n\tconst flush = (): void => {\n\t\tif (!currentHeading) {\n\t\t\treturn;\n\t\t}\n\t\tsections.push({\n\t\t\theading: currentHeading,\n\t\t\tcontent: currentLines.join(\"\\n\").trim(),\n\t\t});\n\t};\n\n\tfor (const line of lines) {\n\t\tif (line.startsWith(\"## \")) {\n\t\t\tflush();\n\t\t\tcurrentHeading = line.slice(3).trim();\n\t\t\tcurrentLines = [];\n\t\t\tcontinue;\n\t\t}\n\t\tif (currentHeading) {\n\t\t\tcurrentLines.push(line);\n\t\t}\n\t}\n\n\tflush();\n\treturn sections;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-lifecycle.d.ts","sourceRoot":"","sources":["../src/memory-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EACX,gBAAgB,EAIhB,YAAY,EAEZ,MAAM,+BAA+B,CAAC;AASvC,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,aAAa,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,YAAY,EAAE,CAAC;IAClC,iBAAiB,EAAE,MAAM,YAAY,EAAE,CAAC;IACxC,QAAQ,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAED,qBAAa,eAAe;IAGf,OAAO,CAAC,OAAO;IAF3B,OAAO,CAAC,eAAe,CAAoC;
|
|
1
|
+
{"version":3,"file":"memory-lifecycle.d.ts","sourceRoot":"","sources":["../src/memory-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EACX,gBAAgB,EAIhB,YAAY,EAEZ,MAAM,+BAA+B,CAAC;AASvC,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,aAAa,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,YAAY,EAAE,CAAC;IAClC,iBAAiB,EAAE,MAAM,YAAY,EAAE,CAAC;IACxC,QAAQ,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAED,qBAAa,eAAe;IAGf,OAAO,CAAC,OAAO;IAF3B,OAAO,CAAC,eAAe,CAAoC;gBAEvC,OAAO,EAAE,sBAAsB;IAEnD,OAAO,CAAC,eAAe;IAUvB,sBAAsB,IAAI,gBAAgB;YAiB5B,4BAA4B;YAiB5B,0BAA0B;IAIxC,OAAO,CAAC,oBAAoB;YAId,yBAAyB;IAQvC,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,4BAA4B;IAYpC,OAAO,CAAC,mBAAmB;CAW3B"}
|
package/dist/memory-lifecycle.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as log from "./log.js";
|
|
2
2
|
import { runBackgroundMaintenance, runInlineConsolidation, } from "./memory-consolidation.js";
|
|
3
3
|
export class MemoryLifecycle {
|
|
4
|
-
options;
|
|
5
|
-
backgroundQueue = Promise.resolve();
|
|
6
4
|
constructor(options) {
|
|
7
5
|
this.options = options;
|
|
6
|
+
this.backgroundQueue = Promise.resolve();
|
|
8
7
|
}
|
|
9
8
|
buildRunOptions(messages, sessionEntries) {
|
|
10
9
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-lifecycle.js","sourceRoot":"","sources":["../src/memory-lifecycle.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAGN,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,2BAA2B,CAAC;AAanC,MAAM,OAAO,eAAe;
|
|
1
|
+
{"version":3,"file":"memory-lifecycle.js","sourceRoot":"","sources":["../src/memory-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport type {\n\tExtensionFactory,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeSwitchEvent,\n\tSessionCompactEvent,\n\tSessionEntry,\n\tSessionSwitchEvent,\n} from \"@mariozechner/pi-coding-agent\";\nimport * as log from \"./log.js\";\nimport {\n\ttype BackgroundMaintenanceResult,\n\ttype ConsolidationRunOptions,\n\trunBackgroundMaintenance,\n\trunInlineConsolidation,\n} from \"./memory-consolidation.js\";\n\nexport type ConsolidationReason = \"compaction\" | \"new-session\";\n\nexport interface MemoryLifecycleOptions {\n\tchannelId: string;\n\tchannelDir: string;\n\tgetMessages: () => AgentMessage[];\n\tgetSessionEntries: () => SessionEntry[];\n\tgetModel: () => Model<Api>;\n\tresolveApiKey: (model: Model<Api>) => Promise<string>;\n}\n\nexport class MemoryLifecycle {\n\tprivate backgroundQueue: Promise<void> = Promise.resolve();\n\n\tconstructor(private options: MemoryLifecycleOptions) {}\n\n\tprivate buildRunOptions(messages?: AgentMessage[], sessionEntries?: SessionEntry[]): ConsolidationRunOptions {\n\t\treturn {\n\t\t\tchannelDir: this.options.channelDir,\n\t\t\tmodel: this.options.getModel(),\n\t\t\tresolveApiKey: this.options.resolveApiKey,\n\t\t\tmessages: messages ?? this.options.getMessages(),\n\t\t\tsessionEntries: sessionEntries ?? this.options.getSessionEntries(),\n\t\t};\n\t}\n\n\tcreateExtensionFactory(): ExtensionFactory {\n\t\treturn (pi) => {\n\t\t\tpi.on(\"session_before_compact\", async (event: SessionBeforeCompactEvent) => {\n\t\t\t\tawait this.handleSessionBeforeCompact(event);\n\t\t\t});\n\t\t\tpi.on(\"session_compact\", async (event: SessionCompactEvent) => {\n\t\t\t\tthis.handleSessionCompact(event);\n\t\t\t});\n\t\t\tpi.on(\"session_before_switch\", async (event: SessionBeforeSwitchEvent) => {\n\t\t\t\tawait this.handleSessionBeforeSwitch(event);\n\t\t\t});\n\t\t\tpi.on(\"session_switch\", async (event: SessionSwitchEvent) => {\n\t\t\t\tthis.handleSessionSwitch(event);\n\t\t\t});\n\t\t};\n\t}\n\n\tprivate async consolidateBeforeContextDrop(\n\t\treason: ConsolidationReason,\n\t\tmessages?: AgentMessage[],\n\t\tsessionEntries?: SessionEntry[],\n\t): Promise<void> {\n\t\tlog.logInfo(`[${this.options.channelId}] Memory consolidation starting (${reason})`);\n\t\ttry {\n\t\t\tconst result = await runInlineConsolidation(this.buildRunOptions(messages, sessionEntries));\n\t\t\tlog.logInfo(\n\t\t\t\t`[${this.options.channelId}] Memory consolidation finished (${reason}): memory entries=${result.appendedMemoryEntries}, history=${result.appendedHistoryBlock ? \"yes\" : \"no\"}`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tlog.logWarning(`[${this.options.channelId}] Memory consolidation failed (${reason})`, message);\n\t\t}\n\t}\n\n\tprivate async handleSessionBeforeCompact(event: SessionBeforeCompactEvent): Promise<void> {\n\t\tawait this.consolidateBeforeContextDrop(\"compaction\", event.preparation.messagesToSummarize);\n\t}\n\n\tprivate handleSessionCompact(_event: SessionCompactEvent): void {\n\t\tthis.enqueueBackgroundMaintenance();\n\t}\n\n\tprivate async handleSessionBeforeSwitch(event: SessionBeforeSwitchEvent): Promise<void> {\n\t\tif (event.reason !== \"new\") {\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.consolidateBeforeContextDrop(\"new-session\");\n\t}\n\n\tprivate handleSessionSwitch(event: SessionSwitchEvent): void {\n\t\tif (event.reason !== \"new\") {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.enqueueBackgroundMaintenance();\n\t}\n\n\tprivate enqueueBackgroundMaintenance(): void {\n\t\tthis.backgroundQueue = this.backgroundQueue\n\t\t\t.then(async () => {\n\t\t\t\tconst result = await runBackgroundMaintenance(this.buildRunOptions([], []));\n\t\t\t\tthis.logBackgroundResult(result);\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tlog.logWarning(`[${this.options.channelId}] Background memory maintenance failed`, message);\n\t\t\t});\n\t}\n\n\tprivate logBackgroundResult(result: BackgroundMaintenanceResult): void {\n\t\tif (!result.cleanedMemory && !result.foldedHistory) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst details = [\n\t\t\t`memory cleanup=${result.cleanedMemory ? \"yes\" : \"no\"}`,\n\t\t\t`history fold=${result.foldedHistory ? \"yes\" : \"no\"}`,\n\t\t].join(\", \");\n\t\tlog.logInfo(`[${this.options.channelId}] Background memory maintenance complete: ${details}`);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-utils.d.ts","sourceRoot":"","sources":["../src/model-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAY,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAK5D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAE9D;AAED,wBAAgB,4BAA4B,CAC3C,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAC3B;IAAE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CA2C5C;AAED,wBAAgB,eAAe,CAC9B,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EACpB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,EACpC,KAAK,GAAE,MAAW,GAChB,MAAM,CAkBR;AAED,wBAAgB,mBAAmB,CAClC,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,uBAAuB,GACtC,KAAK,CAAC,GAAG,CAAC,CAmBZ"
|
|
1
|
+
{"version":3,"file":"model-utils.d.ts","sourceRoot":"","sources":["../src/model-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAY,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAK5D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAE9D;AAED,wBAAgB,4BAA4B,CAC3C,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAC3B;IAAE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CA2C5C;AAED,wBAAgB,eAAe,CAC9B,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EACpB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,EACpC,KAAK,GAAE,MAAW,GAChB,MAAM,CAkBR;AAED,wBAAgB,mBAAmB,CAClC,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,uBAAuB,GACtC,KAAK,CAAC,GAAG,CAAC,CAmBZ"}
|