@oyasmi/pipiclaw 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +48 -16
- package/dist/agent.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +119 -106
- package/dist/agent.js.map +1 -1
- package/dist/command-extension.d.ts +14 -0
- package/dist/command-extension.d.ts.map +1 -0
- package/dist/command-extension.js +112 -0
- package/dist/command-extension.js.map +1 -0
- package/dist/commands.d.ts +1 -1
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +22 -25
- package/dist/commands.js.map +1 -1
- package/dist/config-loader.d.ts +2 -6
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +4 -60
- package/dist/config-loader.js.map +1 -1
- package/dist/context.d.ts +4 -23
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +7 -122
- package/dist/context.js.map +1 -1
- package/dist/dingtalk.d.ts.map +1 -1
- package/dist/dingtalk.js +5 -0
- package/dist/dingtalk.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +27 -15
- package/dist/main.js.map +1 -1
- package/dist/memory-consolidation.d.ts +22 -0
- package/dist/memory-consolidation.d.ts.map +1 -0
- package/dist/memory-consolidation.js +258 -0
- package/dist/memory-consolidation.js.map +1 -0
- package/dist/memory-files.d.ts +24 -0
- package/dist/memory-files.d.ts.map +1 -0
- package/dist/memory-files.js +131 -0
- package/dist/memory-files.js.map +1 -0
- package/dist/memory-lifecycle.d.ts +27 -0
- package/dist/memory-lifecycle.d.ts.map +1 -0
- package/dist/memory-lifecycle.js +85 -0
- package/dist/memory-lifecycle.js.map +1 -0
- package/dist/prompt-builder.d.ts +1 -2
- package/dist/prompt-builder.d.ts.map +1 -1
- package/dist/prompt-builder.js +35 -88
- package/dist/prompt-builder.js.map +1 -1
- package/dist/store.d.ts +2 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +2 -1
- package/dist/store.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { basename } from "path";
|
|
2
|
+
import { findExactModelReferenceMatch, formatModelList, formatModelReference } from "./model-utils.js";
|
|
3
|
+
export const COMMAND_RESULT_CUSTOM_TYPE = "pipiclaw.command_result";
|
|
4
|
+
function buildSessionText(stats, currentModel, thinkingLevel) {
|
|
5
|
+
const modelText = currentModel ? `\`${formatModelReference(currentModel)}\`` : "(none)";
|
|
6
|
+
const sessionFile = stats.sessionFile ? `\`${basename(stats.sessionFile)}\`` : "(none)";
|
|
7
|
+
return `# Session
|
|
8
|
+
|
|
9
|
+
- Session ID: \`${stats.sessionId}\`
|
|
10
|
+
- Session file: ${sessionFile}
|
|
11
|
+
- Model: ${modelText}
|
|
12
|
+
- Thinking level: \`${thinkingLevel}\`
|
|
13
|
+
- User messages: \`${stats.userMessages}\`
|
|
14
|
+
- Assistant messages: \`${stats.assistantMessages}\`
|
|
15
|
+
- Tool calls: \`${stats.toolCalls}\`
|
|
16
|
+
- Tool results: \`${stats.toolResults}\`
|
|
17
|
+
- Total messages: \`${stats.totalMessages}\`
|
|
18
|
+
- Tokens: \`${stats.tokens.total}\` (input \`${stats.tokens.input}\`, output \`${stats.tokens.output}\`, cache read \`${stats.tokens.cacheRead}\`, cache write \`${stats.tokens.cacheWrite}\`)
|
|
19
|
+
- Cost: \`$${stats.cost.toFixed(4)}\``;
|
|
20
|
+
}
|
|
21
|
+
async function runCompact(ctx, customInstructions) {
|
|
22
|
+
return await new Promise((resolve, reject) => {
|
|
23
|
+
ctx.compact({
|
|
24
|
+
customInstructions,
|
|
25
|
+
onComplete: resolve,
|
|
26
|
+
onError: reject,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function sendCommandResult(pi, text) {
|
|
31
|
+
pi.sendMessage({
|
|
32
|
+
customType: COMMAND_RESULT_CUSTOM_TYPE,
|
|
33
|
+
content: text,
|
|
34
|
+
display: true,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function createCommandExtension(options) {
|
|
38
|
+
return (pi) => {
|
|
39
|
+
pi.registerCommand("session", {
|
|
40
|
+
description: "Show current session state, usage, and model info",
|
|
41
|
+
handler: async () => {
|
|
42
|
+
sendCommandResult(pi, buildSessionText(options.getSessionStats(), options.getCurrentModel(), options.getThinkingLevel()));
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
pi.registerCommand("model", {
|
|
46
|
+
description: "Show the current model or switch models using an exact match",
|
|
47
|
+
handler: async (args) => {
|
|
48
|
+
const availableModels = await options.getAvailableModels();
|
|
49
|
+
const currentModel = options.getCurrentModel();
|
|
50
|
+
if (!args.trim()) {
|
|
51
|
+
const current = currentModel ? `\`${formatModelReference(currentModel)}\`` : "(none)";
|
|
52
|
+
const available = availableModels.length > 0 ? formatModelList(availableModels, currentModel) : "- (none)";
|
|
53
|
+
sendCommandResult(pi, `# Model
|
|
54
|
+
|
|
55
|
+
Current model: ${current}
|
|
56
|
+
|
|
57
|
+
Use \`/model <provider/modelId>\` or \`/model <modelId>\` to switch. Bare model IDs must resolve uniquely.
|
|
58
|
+
|
|
59
|
+
Available models:
|
|
60
|
+
${available}`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const match = findExactModelReferenceMatch(args, availableModels);
|
|
64
|
+
const available = availableModels.length > 0 ? formatModelList(availableModels, currentModel, 10) : "- (none)";
|
|
65
|
+
if (match.match) {
|
|
66
|
+
await options.switchModel(match.match);
|
|
67
|
+
sendCommandResult(pi, `已切换模型到 \`${formatModelReference(match.match)}\`.`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (match.ambiguous) {
|
|
71
|
+
sendCommandResult(pi, `未切换模型:\`${args.trim()}\` 匹配到多个模型。请改用精确的 \`provider/modelId\` 形式。
|
|
72
|
+
|
|
73
|
+
Available models:
|
|
74
|
+
${available}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
sendCommandResult(pi, `未找到模型 \`${args.trim()}\`。请使用精确的 \`provider/modelId\` 或唯一的 \`modelId\`。
|
|
78
|
+
|
|
79
|
+
Available models:
|
|
80
|
+
${available}`);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
pi.registerCommand("new", {
|
|
84
|
+
description: "Start a new session",
|
|
85
|
+
handler: async (_args, ctx) => {
|
|
86
|
+
const result = await ctx.newSession();
|
|
87
|
+
if (!result.cancelled) {
|
|
88
|
+
await options.refreshSessionResources();
|
|
89
|
+
}
|
|
90
|
+
sendCommandResult(pi, result.cancelled
|
|
91
|
+
? "新会话已取消。"
|
|
92
|
+
: `已开启新会话。\n\nSession ID: \`${ctx.sessionManager.getSessionId()}\``);
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
pi.registerCommand("compact", {
|
|
96
|
+
description: "Manually compact the current session context",
|
|
97
|
+
handler: async (args, ctx) => {
|
|
98
|
+
const customInstructions = args.trim() || undefined;
|
|
99
|
+
const result = await runCompact(ctx, customInstructions);
|
|
100
|
+
sendCommandResult(pi, `已压缩当前会话上下文。
|
|
101
|
+
|
|
102
|
+
- Tokens before compaction: \`${result.tokensBefore}\`
|
|
103
|
+
- Summary:
|
|
104
|
+
|
|
105
|
+
\`\`\`text
|
|
106
|
+
${result.summary}
|
|
107
|
+
\`\`\``);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=command-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-extension.js","sourceRoot":"","sources":["../src/command-extension.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport type {\n\tCompactionResult,\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionFactory,\n\tSessionStats,\n} from \"@mariozechner/pi-coding-agent\";\nimport { basename } from \"path\";\nimport { findExactModelReferenceMatch, formatModelList, formatModelReference } from \"./model-utils.js\";\n\nexport const COMMAND_RESULT_CUSTOM_TYPE = \"pipiclaw.command_result\";\n\nexport interface PipiclawCommandExtensionOptions {\n\tgetCurrentModel: () => Model<Api> | undefined;\n\tgetAvailableModels: () => Promise<Model<Api>[]>;\n\tgetSessionStats: () => SessionStats;\n\tgetThinkingLevel: () => ThinkingLevel;\n\tswitchModel: (model: Model<Api>) => Promise<void>;\n\trefreshSessionResources: () => Promise<void>;\n}\n\nfunction buildSessionText(\n\tstats: SessionStats,\n\tcurrentModel: Model<Api> | undefined,\n\tthinkingLevel: ThinkingLevel,\n): string {\n\tconst modelText = currentModel ? `\\`${formatModelReference(currentModel)}\\`` : \"(none)\";\n\tconst sessionFile = stats.sessionFile ? `\\`${basename(stats.sessionFile)}\\`` : \"(none)\";\n\treturn `# Session\n\n- Session ID: \\`${stats.sessionId}\\`\n- Session file: ${sessionFile}\n- Model: ${modelText}\n- Thinking level: \\`${thinkingLevel}\\`\n- User messages: \\`${stats.userMessages}\\`\n- Assistant messages: \\`${stats.assistantMessages}\\`\n- Tool calls: \\`${stats.toolCalls}\\`\n- Tool results: \\`${stats.toolResults}\\`\n- Total messages: \\`${stats.totalMessages}\\`\n- Tokens: \\`${stats.tokens.total}\\` (input \\`${stats.tokens.input}\\`, output \\`${stats.tokens.output}\\`, cache read \\`${stats.tokens.cacheRead}\\`, cache write \\`${stats.tokens.cacheWrite}\\`)\n- Cost: \\`$${stats.cost.toFixed(4)}\\``;\n}\n\nasync function runCompact(\n\tctx: ExtensionCommandContext,\n\tcustomInstructions: string | undefined,\n): Promise<CompactionResult> {\n\treturn await new Promise<CompactionResult>((resolve, reject) => {\n\t\tctx.compact({\n\t\t\tcustomInstructions,\n\t\t\tonComplete: resolve,\n\t\t\tonError: reject,\n\t\t});\n\t});\n}\n\nfunction sendCommandResult(pi: Pick<ExtensionAPI, \"sendMessage\">, text: string): void {\n\tpi.sendMessage({\n\t\tcustomType: COMMAND_RESULT_CUSTOM_TYPE,\n\t\tcontent: text,\n\t\tdisplay: true,\n\t});\n}\n\nexport function createCommandExtension(options: PipiclawCommandExtensionOptions): ExtensionFactory {\n\treturn (pi) => {\n\t\tpi.registerCommand(\"session\", {\n\t\t\tdescription: \"Show current session state, usage, and model info\",\n\t\t\thandler: async () => {\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\tbuildSessionText(options.getSessionStats(), options.getCurrentModel(), options.getThinkingLevel()),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tpi.registerCommand(\"model\", {\n\t\t\tdescription: \"Show the current model or switch models using an exact match\",\n\t\t\thandler: async (args) => {\n\t\t\t\tconst availableModels = await options.getAvailableModels();\n\t\t\t\tconst currentModel = options.getCurrentModel();\n\n\t\t\t\tif (!args.trim()) {\n\t\t\t\t\tconst current = currentModel ? `\\`${formatModelReference(currentModel)}\\`` : \"(none)\";\n\t\t\t\t\tconst available =\n\t\t\t\t\t\tavailableModels.length > 0 ? formatModelList(availableModels, currentModel) : \"- (none)\";\n\t\t\t\t\tsendCommandResult(\n\t\t\t\t\t\tpi,\n\t\t\t\t\t\t`# Model\n\nCurrent model: ${current}\n\nUse \\`/model <provider/modelId>\\` or \\`/model <modelId>\\` to switch. Bare model IDs must resolve uniquely.\n\nAvailable models:\n${available}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst match = findExactModelReferenceMatch(args, availableModels);\n\t\t\t\tconst available =\n\t\t\t\t\tavailableModels.length > 0 ? formatModelList(availableModels, currentModel, 10) : \"- (none)\";\n\n\t\t\t\tif (match.match) {\n\t\t\t\t\tawait options.switchModel(match.match);\n\t\t\t\t\tsendCommandResult(pi, `已切换模型到 \\`${formatModelReference(match.match)}\\`.`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (match.ambiguous) {\n\t\t\t\t\tsendCommandResult(\n\t\t\t\t\t\tpi,\n\t\t\t\t\t\t`未切换模型:\\`${args.trim()}\\` 匹配到多个模型。请改用精确的 \\`provider/modelId\\` 形式。\n\nAvailable models:\n${available}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\t`未找到模型 \\`${args.trim()}\\`。请使用精确的 \\`provider/modelId\\` 或唯一的 \\`modelId\\`。\n\nAvailable models:\n${available}`,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tpi.registerCommand(\"new\", {\n\t\t\tdescription: \"Start a new session\",\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tconst result = await ctx.newSession();\n\t\t\t\tif (!result.cancelled) {\n\t\t\t\t\tawait options.refreshSessionResources();\n\t\t\t\t}\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\tresult.cancelled\n\t\t\t\t\t\t? \"新会话已取消。\"\n\t\t\t\t\t\t: `已开启新会话。\\n\\nSession ID: \\`${ctx.sessionManager.getSessionId()}\\``,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\n\t\tpi.registerCommand(\"compact\", {\n\t\t\tdescription: \"Manually compact the current session context\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tconst customInstructions = args.trim() || undefined;\n\t\t\t\tconst result = await runCompact(ctx, customInstructions);\n\t\t\t\tsendCommandResult(\n\t\t\t\t\tpi,\n\t\t\t\t\t`已压缩当前会话上下文。\n\n- Tokens before compaction: \\`${result.tokensBefore}\\`\n- Summary:\n\n\\`\\`\\`text\n${result.summary}\n\\`\\`\\``,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n}\n"]}
|
package/dist/commands.d.ts
CHANGED
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;AAExE,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AA6CD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAmBvE;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C","sourcesContent":["export type BuiltInCommandName = \"help\" | \"steer\" | \"followup\" | \"stop\";\n\nexport interface BuiltInCommand {\n\tname: BuiltInCommandName;\n\targs: string;\n\trawText: string;\n}\n\nconst HELP_TEXT = `# Slash Commands\n\nPipiclaw supports two command groups.\n\n## Transport Commands\n\nThese are handled directly by the DingTalk transport/runtime layer.\n\n- \\`/help\\`\n Show command help\n Example: \\`/help\\`\n- \\`/stop\\`\n Stop the current task\n Example: \\`/stop\\`\n- \\`/steer <message>\\`\n Change the current task after the current tool step finishes\n Example: \\`/steer Use the Shanghai time zone and summarize only the latest updates\\`\n- \\`/followup <message>\\`\n Queue another request to run after the current task completes\n Example: \\`/followup After that, draft a short executive summary\\`\n\nWhile a task is running, a plain message is treated as \\`steer\\` by default.\n\n## Session Commands\n\nThese are handled inside the Pipiclaw session layer:\n\n- \\`/session\\`\n Show current session state, message stats, token usage, and model info\n Example: \\`/session\\`\n- \\`/model [provider/modelId|modelId]\\`\n Show the current model, or switch models using an exact match\n Example: \\`/model\\`\n Example: \\`/model anthropic/claude-opus-4-6\\`\n- \\`/new\\`\n Start a new session\n Example: \\`/new\\`\n- \\`/compact [instructions]\\`\n Manually compact the current session context, with optional custom instructions\n Example: \\`/compact\\`\n Example: \\`/compact Keep the latest TODOs and decisions\\`\n`;\n\nexport function parseBuiltInCommand(text: string): BuiltInCommand | null {\n\tconst rawText = text.trim();\n\tif (!rawText.startsWith(\"/\")) {\n\t\treturn null;\n\t}\n\n\tconst spaceIndex = rawText.indexOf(\" \");\n\tconst rawName = spaceIndex === -1 ? rawText.slice(1) : rawText.slice(1, spaceIndex);\n\tconst args = spaceIndex === -1 ? \"\" : rawText.slice(spaceIndex + 1).trim();\n\n\tswitch (rawName) {\n\t\tcase \"help\":\n\t\tcase \"steer\":\n\t\tcase \"followup\":\n\t\tcase \"stop\":\n\t\t\treturn { name: rawName, args, rawText };\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nexport function renderBuiltInHelp(): string {\n\treturn HELP_TEXT;\n}\n"]}
|
package/dist/commands.js
CHANGED
|
@@ -1,28 +1,10 @@
|
|
|
1
1
|
const HELP_TEXT = `# Slash Commands
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Pipiclaw supports two command groups.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Transport Commands
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
Show command help
|
|
9
|
-
Example: \`/help\`
|
|
10
|
-
- \`/new\`
|
|
11
|
-
Start a new session
|
|
12
|
-
Example: \`/new\`
|
|
13
|
-
- \`/compact [instructions]\`
|
|
14
|
-
Manually compact the current session context, with optional custom instructions
|
|
15
|
-
Example: \`/compact\`
|
|
16
|
-
Example: \`/compact Keep the latest TODOs and decisions\`
|
|
17
|
-
- \`/session\`
|
|
18
|
-
Show current session state, message stats, token usage, and model info
|
|
19
|
-
Example: \`/session\`
|
|
20
|
-
- \`/model [provider/modelId|modelId]\`
|
|
21
|
-
Show the current model, or switch models using an exact match
|
|
22
|
-
Example: \`/model\`
|
|
23
|
-
Example: \`/model anthropic/claude-opus-4-6\`
|
|
24
|
-
|
|
25
|
-
## Available While A Task Is Running
|
|
7
|
+
These are handled directly by the DingTalk transport/runtime layer.
|
|
26
8
|
|
|
27
9
|
- \`/help\`
|
|
28
10
|
Show command help
|
|
@@ -38,6 +20,25 @@ The following slash commands are supported:
|
|
|
38
20
|
Example: \`/followup After that, draft a short executive summary\`
|
|
39
21
|
|
|
40
22
|
While a task is running, a plain message is treated as \`steer\` by default.
|
|
23
|
+
|
|
24
|
+
## Session Commands
|
|
25
|
+
|
|
26
|
+
These are handled inside the Pipiclaw session layer:
|
|
27
|
+
|
|
28
|
+
- \`/session\`
|
|
29
|
+
Show current session state, message stats, token usage, and model info
|
|
30
|
+
Example: \`/session\`
|
|
31
|
+
- \`/model [provider/modelId|modelId]\`
|
|
32
|
+
Show the current model, or switch models using an exact match
|
|
33
|
+
Example: \`/model\`
|
|
34
|
+
Example: \`/model anthropic/claude-opus-4-6\`
|
|
35
|
+
- \`/new\`
|
|
36
|
+
Start a new session
|
|
37
|
+
Example: \`/new\`
|
|
38
|
+
- \`/compact [instructions]\`
|
|
39
|
+
Manually compact the current session context, with optional custom instructions
|
|
40
|
+
Example: \`/compact\`
|
|
41
|
+
Example: \`/compact Keep the latest TODOs and decisions\`
|
|
41
42
|
`;
|
|
42
43
|
export function parseBuiltInCommand(text) {
|
|
43
44
|
const rawText = text.trim();
|
|
@@ -49,10 +50,6 @@ export function parseBuiltInCommand(text) {
|
|
|
49
50
|
const args = spaceIndex === -1 ? "" : rawText.slice(spaceIndex + 1).trim();
|
|
50
51
|
switch (rawName) {
|
|
51
52
|
case "help":
|
|
52
|
-
case "new":
|
|
53
|
-
case "compact":
|
|
54
|
-
case "session":
|
|
55
|
-
case "model":
|
|
56
53
|
case "steer":
|
|
57
54
|
case "followup":
|
|
58
55
|
case "stop":
|
package/dist/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAQA,MAAM,SAAS,GAAG
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAQA,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCjB,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAyB;IACxE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE3E,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO,CAAC;QACb,KAAK,UAAU,CAAC;QAChB,KAAK,MAAM;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACzC;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AAAA,CACD;AAED,MAAM,UAAU,iBAAiB,GAAW;IAC3C,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["export type BuiltInCommandName = \"help\" | \"steer\" | \"followup\" | \"stop\";\n\nexport interface BuiltInCommand {\n\tname: BuiltInCommandName;\n\targs: string;\n\trawText: string;\n}\n\nconst HELP_TEXT = `# Slash Commands\n\nPipiclaw supports two command groups.\n\n## Transport Commands\n\nThese are handled directly by the DingTalk transport/runtime layer.\n\n- \\`/help\\`\n Show command help\n Example: \\`/help\\`\n- \\`/stop\\`\n Stop the current task\n Example: \\`/stop\\`\n- \\`/steer <message>\\`\n Change the current task after the current tool step finishes\n Example: \\`/steer Use the Shanghai time zone and summarize only the latest updates\\`\n- \\`/followup <message>\\`\n Queue another request to run after the current task completes\n Example: \\`/followup After that, draft a short executive summary\\`\n\nWhile a task is running, a plain message is treated as \\`steer\\` by default.\n\n## Session Commands\n\nThese are handled inside the Pipiclaw session layer:\n\n- \\`/session\\`\n Show current session state, message stats, token usage, and model info\n Example: \\`/session\\`\n- \\`/model [provider/modelId|modelId]\\`\n Show the current model, or switch models using an exact match\n Example: \\`/model\\`\n Example: \\`/model anthropic/claude-opus-4-6\\`\n- \\`/new\\`\n Start a new session\n Example: \\`/new\\`\n- \\`/compact [instructions]\\`\n Manually compact the current session context, with optional custom instructions\n Example: \\`/compact\\`\n Example: \\`/compact Keep the latest TODOs and decisions\\`\n`;\n\nexport function parseBuiltInCommand(text: string): BuiltInCommand | null {\n\tconst rawText = text.trim();\n\tif (!rawText.startsWith(\"/\")) {\n\t\treturn null;\n\t}\n\n\tconst spaceIndex = rawText.indexOf(\" \");\n\tconst rawName = spaceIndex === -1 ? rawText.slice(1) : rawText.slice(1, spaceIndex);\n\tconst args = spaceIndex === -1 ? \"\" : rawText.slice(spaceIndex + 1).trim();\n\n\tswitch (rawName) {\n\t\tcase \"help\":\n\t\tcase \"steer\":\n\t\tcase \"followup\":\n\t\tcase \"stop\":\n\t\t\treturn { name: rawName, args, rawText };\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nexport function renderBuiltInHelp(): string {\n\treturn HELP_TEXT;\n}\n"]}
|
package/dist/config-loader.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configuration file loaders for pipiclaw workspace files:
|
|
3
|
-
* SOUL.md, AGENTS.md,
|
|
3
|
+
* SOUL.md, AGENTS.md, skills/, and API key resolution.
|
|
4
4
|
*/
|
|
5
5
|
import type { Api, Model } from "@mariozechner/pi-ai";
|
|
6
6
|
import { type ModelRegistry, type Skill } from "@mariozechner/pi-coding-agent";
|
|
@@ -11,13 +11,9 @@ import { type ModelRegistry, type Skill } from "@mariozechner/pi-coding-agent";
|
|
|
11
11
|
export declare function getSoul(workspaceDir: string): string;
|
|
12
12
|
/**
|
|
13
13
|
* Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.
|
|
14
|
-
*
|
|
14
|
+
* Only loaded from workspace root (global).
|
|
15
15
|
*/
|
|
16
16
|
export declare function getAgentConfig(channelDir: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* Load MEMORY.md — persistent working memory, both global and channel-specific.
|
|
19
|
-
*/
|
|
20
|
-
export declare function getMemory(channelDir: string): string;
|
|
21
17
|
/**
|
|
22
18
|
* Load skills from both workspace-level and channel-level skill directories.
|
|
23
19
|
* Channel-level skills override global skills with the same name.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAqB,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAKlG;;;GAGG;AACH,wBAAgB,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAqB,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAKlG;;;GAGG;AACH,wBAAgB,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,EAAE,CA4BrF;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAUxG","sourcesContent":["/**\n * Configuration file loaders for pipiclaw workspace files:\n * SOUL.md, AGENTS.md, skills/, and API key resolution.\n */\n\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { loadSkillsFromDir, type ModelRegistry, type Skill } from \"@mariozechner/pi-coding-agent\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport * as log from \"./log.js\";\n\n/**\n * Load SOUL.md — defines the agent's identity, personality, and communication style.\n * Only loaded from workspace root (global).\n */\nexport function getSoul(workspaceDir: string): string {\n\tconst soulPath = join(workspaceDir, \"SOUL.md\");\n\tif (existsSync(soulPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(soulPath, \"utf-8\").trim();\n\t\t\tif (content) return content;\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read SOUL.md\", `${soulPath}: ${error}`);\n\t\t}\n\t}\n\treturn \"\";\n}\n\n/**\n * Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.\n * Only loaded from workspace root (global).\n */\nexport function getAgentConfig(channelDir: string): string {\n\tconst workspaceAgentPath = join(channelDir, \"..\", \"AGENTS.md\");\n\tif (existsSync(workspaceAgentPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(workspaceAgentPath, \"utf-8\").trim();\n\t\t\tif (content) {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read workspace AGENTS.md\", `${workspaceAgentPath}: ${error}`);\n\t\t}\n\t}\n\treturn \"\";\n}\n\n/**\n * Load skills from both workspace-level and channel-level skill directories.\n * Channel-level skills override global skills with the same name.\n */\nexport function loadPipiclawSkills(channelDir: string, workspacePath: string): Skill[] {\n\tconst skillMap = new Map<string, Skill>();\n\tconst hostWorkspacePath = join(channelDir, \"..\");\n\n\tconst translatePath = (hostPath: string): string => {\n\t\tif (hostPath.startsWith(hostWorkspacePath)) {\n\t\t\treturn workspacePath + hostPath.slice(hostWorkspacePath.length);\n\t\t}\n\t\treturn hostPath;\n\t};\n\n\t// Load workspace-level skills (global)\n\tconst workspaceSkillsDir = join(hostWorkspacePath, \"skills\");\n\tfor (const skill of loadSkillsFromDir({ dir: workspaceSkillsDir, source: \"workspace\" }).skills) {\n\t\tskill.filePath = translatePath(skill.filePath);\n\t\tskill.baseDir = translatePath(skill.baseDir);\n\t\tskillMap.set(skill.name, skill);\n\t}\n\n\t// Load channel-specific skills\n\tconst channelSkillsDir = join(channelDir, \"skills\");\n\tfor (const skill of loadSkillsFromDir({ dir: channelSkillsDir, source: \"channel\" }).skills) {\n\t\tskill.filePath = translatePath(skill.filePath);\n\t\tskill.baseDir = translatePath(skill.baseDir);\n\t\tskillMap.set(skill.name, skill);\n\t}\n\n\treturn Array.from(skillMap.values());\n}\n\n/**\n * Resolve an API key for the given model's provider.\n * Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY env var.\n */\nexport async function getApiKeyForModel(modelRegistry: ModelRegistry, model: Model<Api>): Promise<string> {\n\tconst key = await modelRegistry.getApiKeyForProvider(model.provider);\n\tif (key) return key;\n\t// Fallback: try anthropic env var\n\tconst envKey = process.env.ANTHROPIC_API_KEY;\n\tif (envKey) return envKey;\n\tthrow new Error(\n\t\t`No API key found for provider: ${model.provider}.\\n\\n` +\n\t\t\t\"Configure API key in ~/.pi/agent/models.json or set ANTHROPIC_API_KEY environment variable.\",\n\t);\n}\n"]}
|
package/dist/config-loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configuration file loaders for pipiclaw workspace files:
|
|
3
|
-
* SOUL.md, AGENTS.md,
|
|
3
|
+
* SOUL.md, AGENTS.md, skills/, and API key resolution.
|
|
4
4
|
*/
|
|
5
5
|
import { loadSkillsFromDir } from "@mariozechner/pi-coding-agent";
|
|
6
6
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -26,78 +26,22 @@ export function getSoul(workspaceDir) {
|
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.
|
|
29
|
-
*
|
|
29
|
+
* Only loaded from workspace root (global).
|
|
30
30
|
*/
|
|
31
31
|
export function getAgentConfig(channelDir) {
|
|
32
|
-
const parts = [];
|
|
33
|
-
// Read workspace-level AGENTS.md (global)
|
|
34
32
|
const workspaceAgentPath = join(channelDir, "..", "AGENTS.md");
|
|
35
33
|
if (existsSync(workspaceAgentPath)) {
|
|
36
34
|
try {
|
|
37
35
|
const content = readFileSync(workspaceAgentPath, "utf-8").trim();
|
|
38
36
|
if (content) {
|
|
39
|
-
|
|
37
|
+
return content;
|
|
40
38
|
}
|
|
41
39
|
}
|
|
42
40
|
catch (error) {
|
|
43
41
|
log.logWarning("Failed to read workspace AGENTS.md", `${workspaceAgentPath}: ${error}`);
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
|
-
|
|
47
|
-
const channelAgentPath = join(channelDir, "AGENTS.md");
|
|
48
|
-
if (existsSync(channelAgentPath)) {
|
|
49
|
-
try {
|
|
50
|
-
const content = readFileSync(channelAgentPath, "utf-8").trim();
|
|
51
|
-
if (content) {
|
|
52
|
-
parts.push(content);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
log.logWarning("Failed to read channel AGENTS.md", `${channelAgentPath}: ${error}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return parts.join("\n\n");
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Load MEMORY.md — persistent working memory, both global and channel-specific.
|
|
63
|
-
*/
|
|
64
|
-
export function getMemory(channelDir) {
|
|
65
|
-
const parts = [];
|
|
66
|
-
// Read workspace-level memory (shared across all channels)
|
|
67
|
-
const workspaceMemoryPath = join(channelDir, "..", "MEMORY.md");
|
|
68
|
-
if (existsSync(workspaceMemoryPath)) {
|
|
69
|
-
try {
|
|
70
|
-
const content = readFileSync(workspaceMemoryPath, "utf-8").trim();
|
|
71
|
-
if (content) {
|
|
72
|
-
parts.push(`### Global Workspace Memory\n${content}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
log.logWarning("Failed to read workspace memory", `${workspaceMemoryPath}: ${error}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Read channel-specific memory
|
|
80
|
-
const channelMemoryPath = join(channelDir, "MEMORY.md");
|
|
81
|
-
if (existsSync(channelMemoryPath)) {
|
|
82
|
-
try {
|
|
83
|
-
const content = readFileSync(channelMemoryPath, "utf-8").trim();
|
|
84
|
-
if (content) {
|
|
85
|
-
parts.push(`### Channel-Specific Memory\n${content}`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
log.logWarning("Failed to read channel memory", `${channelMemoryPath}: ${error}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (parts.length === 0) {
|
|
93
|
-
return "(no working memory yet)";
|
|
94
|
-
}
|
|
95
|
-
const combined = parts.join("\n\n");
|
|
96
|
-
// Warn if memory is getting too large (consumes system prompt token budget)
|
|
97
|
-
if (combined.length > 5000) {
|
|
98
|
-
return `\u26a0\ufe0f Memory is large (${combined.length} chars). Consolidate: remove outdated entries, merge duplicates, tighten descriptions.\n\n${combined}`;
|
|
99
|
-
}
|
|
100
|
-
return combined;
|
|
44
|
+
return "";
|
|
101
45
|
}
|
|
102
46
|
/**
|
|
103
47
|
* Load skills from both workspace-level and channel-level skill directories.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Configuration file loaders for pipiclaw workspace files:\n * SOUL.md, AGENTS.md, MEMORY.md, skills/, and API key resolution.\n */\n\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { loadSkillsFromDir, type ModelRegistry, type Skill } from \"@mariozechner/pi-coding-agent\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport * as log from \"./log.js\";\n\n/**\n * Load SOUL.md — defines the agent's identity, personality, and communication style.\n * Only loaded from workspace root (global).\n */\nexport function getSoul(workspaceDir: string): string {\n\tconst soulPath = join(workspaceDir, \"SOUL.md\");\n\tif (existsSync(soulPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(soulPath, \"utf-8\").trim();\n\t\t\tif (content) return content;\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read SOUL.md\", `${soulPath}: ${error}`);\n\t\t}\n\t}\n\treturn \"\";\n}\n\n/**\n * Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.\n * Supports both global (workspace root) and channel-level override.\n */\nexport function getAgentConfig(channelDir: string): string {\n\tconst parts: string[] = [];\n\n\t// Read workspace-level AGENTS.md (global)\n\tconst workspaceAgentPath = join(channelDir, \"..\", \"AGENTS.md\");\n\tif (existsSync(workspaceAgentPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(workspaceAgentPath, \"utf-8\").trim();\n\t\t\tif (content) {\n\t\t\t\tparts.push(content);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read workspace AGENTS.md\", `${workspaceAgentPath}: ${error}`);\n\t\t}\n\t}\n\n\t// Read channel-specific AGENTS.md (overrides/extends global)\n\tconst channelAgentPath = join(channelDir, \"AGENTS.md\");\n\tif (existsSync(channelAgentPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(channelAgentPath, \"utf-8\").trim();\n\t\t\tif (content) {\n\t\t\t\tparts.push(content);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read channel AGENTS.md\", `${channelAgentPath}: ${error}`);\n\t\t}\n\t}\n\n\treturn parts.join(\"\\n\\n\");\n}\n\n/**\n * Load MEMORY.md — persistent working memory, both global and channel-specific.\n */\nexport function getMemory(channelDir: string): string {\n\tconst parts: string[] = [];\n\n\t// Read workspace-level memory (shared across all channels)\n\tconst workspaceMemoryPath = join(channelDir, \"..\", \"MEMORY.md\");\n\tif (existsSync(workspaceMemoryPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(workspaceMemoryPath, \"utf-8\").trim();\n\t\t\tif (content) {\n\t\t\t\tparts.push(`### Global Workspace Memory\\n${content}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read workspace memory\", `${workspaceMemoryPath}: ${error}`);\n\t\t}\n\t}\n\n\t// Read channel-specific memory\n\tconst channelMemoryPath = join(channelDir, \"MEMORY.md\");\n\tif (existsSync(channelMemoryPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(channelMemoryPath, \"utf-8\").trim();\n\t\t\tif (content) {\n\t\t\t\tparts.push(`### Channel-Specific Memory\\n${content}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read channel memory\", `${channelMemoryPath}: ${error}`);\n\t\t}\n\t}\n\n\tif (parts.length === 0) {\n\t\treturn \"(no working memory yet)\";\n\t}\n\n\tconst combined = parts.join(\"\\n\\n\");\n\n\t// Warn if memory is getting too large (consumes system prompt token budget)\n\tif (combined.length > 5000) {\n\t\treturn `\\u26a0\\ufe0f Memory is large (${combined.length} chars). Consolidate: remove outdated entries, merge duplicates, tighten descriptions.\\n\\n${combined}`;\n\t}\n\n\treturn combined;\n}\n\n/**\n * Load skills from both workspace-level and channel-level skill directories.\n * Channel-level skills override global skills with the same name.\n */\nexport function loadPipiclawSkills(channelDir: string, workspacePath: string): Skill[] {\n\tconst skillMap = new Map<string, Skill>();\n\tconst hostWorkspacePath = join(channelDir, \"..\");\n\n\tconst translatePath = (hostPath: string): string => {\n\t\tif (hostPath.startsWith(hostWorkspacePath)) {\n\t\t\treturn workspacePath + hostPath.slice(hostWorkspacePath.length);\n\t\t}\n\t\treturn hostPath;\n\t};\n\n\t// Load workspace-level skills (global)\n\tconst workspaceSkillsDir = join(hostWorkspacePath, \"skills\");\n\tfor (const skill of loadSkillsFromDir({ dir: workspaceSkillsDir, source: \"workspace\" }).skills) {\n\t\tskill.filePath = translatePath(skill.filePath);\n\t\tskill.baseDir = translatePath(skill.baseDir);\n\t\tskillMap.set(skill.name, skill);\n\t}\n\n\t// Load channel-specific skills\n\tconst channelSkillsDir = join(channelDir, \"skills\");\n\tfor (const skill of loadSkillsFromDir({ dir: channelSkillsDir, source: \"channel\" }).skills) {\n\t\tskill.filePath = translatePath(skill.filePath);\n\t\tskill.baseDir = translatePath(skill.baseDir);\n\t\tskillMap.set(skill.name, skill);\n\t}\n\n\treturn Array.from(skillMap.values());\n}\n\n/**\n * Resolve an API key for the given model's provider.\n * Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY env var.\n */\nexport async function getApiKeyForModel(modelRegistry: ModelRegistry, model: Model<Api>): Promise<string> {\n\tconst key = await modelRegistry.getApiKeyForProvider(model.provider);\n\tif (key) return key;\n\t// Fallback: try anthropic env var\n\tconst envKey = process.env.ANTHROPIC_API_KEY;\n\tif (envKey) return envKey;\n\tthrow new Error(\n\t\t`No API key found for provider: ${model.provider}.\\n\\n` +\n\t\t\t\"Configure API key in ~/.pi/agent/models.json or set ANTHROPIC_API_KEY environment variable.\",\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAkC,MAAM,+BAA+B,CAAC;AAClG,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,YAAoB,EAAU;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,GAAG,CAAC,UAAU,CAAC,wBAAwB,EAAE,GAAG,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IACD,OAAO,EAAE,CAAC;AAAA,CACV;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAU;IAC1D,MAAM,kBAAkB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/D,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,IAAI,OAAO,EAAE,CAAC;gBACb,OAAO,OAAO,CAAC;YAChB,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,GAAG,CAAC,UAAU,CAAC,oCAAoC,EAAE,GAAG,kBAAkB,KAAK,KAAK,EAAE,CAAC,CAAC;QACzF,CAAC;IACF,CAAC;IACD,OAAO,EAAE,CAAC;AAAA,CACV;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,aAAqB,EAAW;IACtF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAEjD,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAU,EAAE,CAAC;QACnD,IAAI,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC5C,OAAO,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,QAAQ,CAAC;IAAA,CAChB,CAAC;IAEF,uCAAuC;IACvC,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAC7D,KAAK,MAAM,KAAK,IAAI,iBAAiB,CAAC,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAChG,KAAK,CAAC,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,iBAAiB,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QAC5F,KAAK,CAAC,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/C,KAAK,CAAC,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAAA,CACrC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,aAA4B,EAAE,KAAiB,EAAmB;IACzG,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,kCAAkC;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC7C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,KAAK,CACd,kCAAkC,KAAK,CAAC,QAAQ,OAAO;QACtD,6FAA6F,CAC9F,CAAC;AAAA,CACF","sourcesContent":["/**\n * Configuration file loaders for pipiclaw workspace files:\n * SOUL.md, AGENTS.md, skills/, and API key resolution.\n */\n\nimport type { Api, Model } from \"@mariozechner/pi-ai\";\nimport { loadSkillsFromDir, type ModelRegistry, type Skill } from \"@mariozechner/pi-coding-agent\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport * as log from \"./log.js\";\n\n/**\n * Load SOUL.md — defines the agent's identity, personality, and communication style.\n * Only loaded from workspace root (global).\n */\nexport function getSoul(workspaceDir: string): string {\n\tconst soulPath = join(workspaceDir, \"SOUL.md\");\n\tif (existsSync(soulPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(soulPath, \"utf-8\").trim();\n\t\t\tif (content) return content;\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read SOUL.md\", `${soulPath}: ${error}`);\n\t\t}\n\t}\n\treturn \"\";\n}\n\n/**\n * Load AGENTS.md — defines the agent's behavior instructions, capabilities, and constraints.\n * Only loaded from workspace root (global).\n */\nexport function getAgentConfig(channelDir: string): string {\n\tconst workspaceAgentPath = join(channelDir, \"..\", \"AGENTS.md\");\n\tif (existsSync(workspaceAgentPath)) {\n\t\ttry {\n\t\t\tconst content = readFileSync(workspaceAgentPath, \"utf-8\").trim();\n\t\t\tif (content) {\n\t\t\t\treturn content;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.logWarning(\"Failed to read workspace AGENTS.md\", `${workspaceAgentPath}: ${error}`);\n\t\t}\n\t}\n\treturn \"\";\n}\n\n/**\n * Load skills from both workspace-level and channel-level skill directories.\n * Channel-level skills override global skills with the same name.\n */\nexport function loadPipiclawSkills(channelDir: string, workspacePath: string): Skill[] {\n\tconst skillMap = new Map<string, Skill>();\n\tconst hostWorkspacePath = join(channelDir, \"..\");\n\n\tconst translatePath = (hostPath: string): string => {\n\t\tif (hostPath.startsWith(hostWorkspacePath)) {\n\t\t\treturn workspacePath + hostPath.slice(hostWorkspacePath.length);\n\t\t}\n\t\treturn hostPath;\n\t};\n\n\t// Load workspace-level skills (global)\n\tconst workspaceSkillsDir = join(hostWorkspacePath, \"skills\");\n\tfor (const skill of loadSkillsFromDir({ dir: workspaceSkillsDir, source: \"workspace\" }).skills) {\n\t\tskill.filePath = translatePath(skill.filePath);\n\t\tskill.baseDir = translatePath(skill.baseDir);\n\t\tskillMap.set(skill.name, skill);\n\t}\n\n\t// Load channel-specific skills\n\tconst channelSkillsDir = join(channelDir, \"skills\");\n\tfor (const skill of loadSkillsFromDir({ dir: channelSkillsDir, source: \"channel\" }).skills) {\n\t\tskill.filePath = translatePath(skill.filePath);\n\t\tskill.baseDir = translatePath(skill.baseDir);\n\t\tskillMap.set(skill.name, skill);\n\t}\n\n\treturn Array.from(skillMap.values());\n}\n\n/**\n * Resolve an API key for the given model's provider.\n * Checks ModelRegistry first, then falls back to ANTHROPIC_API_KEY env var.\n */\nexport async function getApiKeyForModel(modelRegistry: ModelRegistry, model: Model<Api>): Promise<string> {\n\tconst key = await modelRegistry.getApiKeyForProvider(model.provider);\n\tif (key) return key;\n\t// Fallback: try anthropic env var\n\tconst envKey = process.env.ANTHROPIC_API_KEY;\n\tif (envKey) return envKey;\n\tthrow new Error(\n\t\t`No API key found for provider: ${model.provider}.\\n\\n` +\n\t\t\t\"Configure API key in ~/.pi/agent/models.json or set ANTHROPIC_API_KEY environment variable.\",\n\t);\n}\n"]}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,30 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Context management for pipiclaw.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - log.jsonl: Human-readable channel history for grep (no tool results)
|
|
4
|
+
* `log.jsonl` and `context.jsonl` are treated as raw cold storage.
|
|
5
|
+
* They are not proactively scanned or loaded as part of the memory model.
|
|
7
6
|
*
|
|
8
|
-
* This module provides
|
|
9
|
-
* - syncLogToSessionManager: Syncs messages from log.jsonl to SessionManager
|
|
10
|
-
* - PipiclawSettingsManager: Simple settings for pipiclaw (compaction, retry, model preferences)
|
|
7
|
+
* This module currently provides only PipiclawSettingsManager.
|
|
11
8
|
*/
|
|
12
|
-
import type { SessionManager } from "@mariozechner/pi-coding-agent";
|
|
13
|
-
/**
|
|
14
|
-
* Sync user messages from log.jsonl to SessionManager.
|
|
15
|
-
*
|
|
16
|
-
* Uses byte-offset tracking for incremental reads (only processes new content)
|
|
17
|
-
* and timestamp-based dedup for crash safety.
|
|
18
|
-
*
|
|
19
|
-
* This ensures that messages logged while pipiclaw wasn't running (channel chatter,
|
|
20
|
-
* externally appended user messages) are added to the LLM context.
|
|
21
|
-
*
|
|
22
|
-
* @param sessionManager - The SessionManager to sync to
|
|
23
|
-
* @param channelDir - Path to channel directory containing log.jsonl
|
|
24
|
-
* @param excludeTs - Timestamp of current message (will be added via prompt(), not sync)
|
|
25
|
-
* @returns Number of messages synced
|
|
26
|
-
*/
|
|
27
|
-
export declare function syncLogToSessionManager(sessionManager: SessionManager, channelDir: string, excludeTs?: string): number;
|
|
28
9
|
export interface PipiclawCompactionSettings {
|
|
29
10
|
enabled: boolean;
|
|
30
11
|
reserveTokens: number;
|
|
@@ -52,6 +33,7 @@ export declare class PipiclawSettingsManager {
|
|
|
52
33
|
constructor(baseDir: string);
|
|
53
34
|
private load;
|
|
54
35
|
private save;
|
|
36
|
+
reload(): void;
|
|
55
37
|
getCompactionSettings(): PipiclawCompactionSettings;
|
|
56
38
|
getCompactionEnabled(): boolean;
|
|
57
39
|
setCompactionEnabled(enabled: boolean): void;
|
|
@@ -131,7 +113,6 @@ export declare class PipiclawSettingsManager {
|
|
|
131
113
|
setDefaultModel(_modelId: string): void;
|
|
132
114
|
getGlobalSettings(): object;
|
|
133
115
|
getProjectSettings(): object;
|
|
134
|
-
reload(): void;
|
|
135
116
|
applyOverrides(_overrides: Partial<PipiclawSettings>): void;
|
|
136
117
|
flush(): Promise<void>;
|
|
137
118
|
drainErrors(): unknown[];
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Context management for pipiclaw.\n *\n * Uses two files per channel:\n * - context.jsonl: Structured API messages for LLM context (same format as coding-agent sessions)\n * - log.jsonl: Human-readable channel history for grep (no tool results)\n *\n * This module provides:\n * - syncLogToSessionManager: Syncs messages from log.jsonl to SessionManager\n * - PipiclawSettingsManager: Simple settings for pipiclaw (compaction, retry, model preferences)\n */\n\nimport type { UserMessage } from \"@mariozechner/pi-ai\";\nimport type { SessionManager, SessionMessageEntry } from \"@mariozechner/pi-coding-agent\";\nimport { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, statSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n// ============================================================================\n// Sync log.jsonl to SessionManager\n// ============================================================================\n\ninterface LogMessage {\n\tdate?: string;\n\tts?: string;\n\tuser?: string;\n\tuserName?: string;\n\ttext?: string;\n\tisBot?: boolean;\n\tskipContextSync?: boolean;\n}\n\n/**\n * Sync user messages from log.jsonl to SessionManager.\n *\n * Uses byte-offset tracking for incremental reads (only processes new content)\n * and timestamp-based dedup for crash safety.\n *\n * This ensures that messages logged while pipiclaw wasn't running (channel chatter,\n * externally appended user messages) are added to the LLM context.\n *\n * @param sessionManager - The SessionManager to sync to\n * @param channelDir - Path to channel directory containing log.jsonl\n * @param excludeTs - Timestamp of current message (will be added via prompt(), not sync)\n * @returns Number of messages synced\n */\nexport function syncLogToSessionManager(\n\tsessionManager: SessionManager,\n\tchannelDir: string,\n\texcludeTs?: string,\n): number {\n\tconst logFile = join(channelDir, \"log.jsonl\");\n\tconst syncOffsetFile = join(channelDir, \".sync-offset\");\n\n\tif (!existsSync(logFile)) return 0;\n\n\t// Read sync offset (byte position of last processed content)\n\tlet offset = 0;\n\tif (existsSync(syncOffsetFile)) {\n\t\ttry {\n\t\t\toffset = Number(readFileSync(syncOffsetFile, \"utf-8\").trim()) || 0;\n\t\t} catch {\n\t\t\toffset = 0;\n\t\t}\n\t}\n\n\t// Check file size\n\tconst fileStats = statSync(logFile);\n\tif (fileStats.size < offset) {\n\t\t// File was truncated or rotated — reset to beginning\n\t\toffset = 0;\n\t}\n\tif (fileStats.size === offset) {\n\t\treturn 0; // No new content\n\t}\n\n\t// Read only new bytes from log.jsonl\n\tconst bytesToRead = fileStats.size - offset;\n\tconst fd = openSync(logFile, \"r\");\n\tlet newContent: string;\n\ttry {\n\t\tconst buffer = Buffer.alloc(bytesToRead);\n\t\treadSync(fd, buffer, 0, bytesToRead, offset);\n\t\tnewContent = buffer.toString(\"utf-8\");\n\t} finally {\n\t\tcloseSync(fd);\n\t}\n\n\tconst newLines = newContent.trim().split(\"\\n\").filter(Boolean);\n\tif (newLines.length === 0) {\n\t\twriteFileSync(syncOffsetFile, String(fileStats.size));\n\t\treturn 0;\n\t}\n\n\t// Build set of existing user message timestamps for crash-safe dedup.\n\t// This prevents duplicates if the process crashed after appendMessage()\n\t// but before writing the sync offset.\n\tconst existingTimestamps = new Set<number>();\n\tfor (const entry of sessionManager.getEntries()) {\n\t\tif (entry.type === \"message\") {\n\t\t\tconst msgEntry = entry as SessionMessageEntry;\n\t\t\tconst msg = msgEntry.message as { role?: string; timestamp?: number };\n\t\t\tif (msg.role === \"user\" && typeof msg.timestamp === \"number\") {\n\t\t\t\texistingTimestamps.add(msg.timestamp);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Process new log lines\n\tconst newMessages: Array<{ timestamp: number; message: UserMessage }> = [];\n\n\tfor (const line of newLines) {\n\t\ttry {\n\t\t\tconst logMsg: LogMessage = JSON.parse(line);\n\n\t\t\tconst ts = logMsg.ts;\n\t\t\tconst date = logMsg.date;\n\t\t\tif (!ts || !date) continue;\n\n\t\t\t// Skip the current message being processed (will be added via prompt())\n\t\t\tif (excludeTs && ts === excludeTs) continue;\n\n\t\t\t// Skip bot messages and user inputs already delivered directly to AgentSession.\n\t\t\tif (logMsg.isBot || logMsg.skipContextSync) continue;\n\n\t\t\tconst msgTime = new Date(date).getTime() || Date.now();\n\n\t\t\t// Skip if already in context (crash recovery dedup)\n\t\t\tif (existingTimestamps.has(msgTime)) continue;\n\t\t\texistingTimestamps.add(msgTime); // Track within this batch\n\n\t\t\tconst messageText = `[${logMsg.userName || logMsg.user || \"unknown\"}]: ${logMsg.text || \"\"}`;\n\t\t\tnewMessages.push({\n\t\t\t\ttimestamp: msgTime,\n\t\t\t\tmessage: {\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [{ type: \"text\", text: messageText }],\n\t\t\t\t\ttimestamp: msgTime,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch {\n\t\t\t// Skip malformed lines\n\t\t}\n\t}\n\n\tif (newMessages.length > 0) {\n\t\tnewMessages.sort((a, b) => a.timestamp - b.timestamp);\n\t\tfor (const { message } of newMessages) {\n\t\t\tsessionManager.appendMessage(message);\n\t\t}\n\t}\n\n\t// Update sync offset to current file end\n\twriteFileSync(syncOffsetFile, String(fileStats.size));\n\n\treturn newMessages.length;\n}\n\n// ============================================================================\n// PipiclawSettingsManager - Simple settings for pipiclaw\n// ============================================================================\n\nexport interface PipiclawCompactionSettings {\n\tenabled: boolean;\n\treserveTokens: number;\n\tkeepRecentTokens: number;\n}\n\nexport interface PipiclawRetrySettings {\n\tenabled: boolean;\n\tmaxRetries: number;\n\tbaseDelayMs: number;\n}\n\nexport interface PipiclawSettings {\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\";\n\tcompaction?: Partial<PipiclawCompactionSettings>;\n\tretry?: Partial<PipiclawRetrySettings>;\n}\n\nconst DEFAULT_COMPACTION: PipiclawCompactionSettings = {\n\tenabled: true,\n\treserveTokens: 16384,\n\tkeepRecentTokens: 20000,\n};\n\nconst DEFAULT_RETRY: PipiclawRetrySettings = {\n\tenabled: true,\n\tmaxRetries: 3,\n\tbaseDelayMs: 2000,\n};\n\n/**\n * Settings manager for pipiclaw.\n * Stores global settings in the pipiclaw root directory.\n */\nexport class PipiclawSettingsManager {\n\tprivate settingsPath: string;\n\tprivate settings: PipiclawSettings;\n\n\tconstructor(baseDir: string) {\n\t\tthis.settingsPath = join(baseDir, \"settings.json\");\n\t\tthis.settings = this.load();\n\t}\n\n\tprivate load(): PipiclawSettings {\n\t\tif (!existsSync(this.settingsPath)) {\n\t\t\treturn {};\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(this.settingsPath, \"utf-8\");\n\t\t\treturn JSON.parse(content);\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprivate save(): void {\n\t\ttry {\n\t\t\tconst dir = dirname(this.settingsPath);\n\t\t\tif (!existsSync(dir)) {\n\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t}\n\t\t\twriteFileSync(this.settingsPath, JSON.stringify(this.settings, null, 2), \"utf-8\");\n\t\t} catch (error) {\n\t\t\tconsole.error(`Warning: Could not save settings file: ${error}`);\n\t\t}\n\t}\n\n\tgetCompactionSettings(): PipiclawCompactionSettings {\n\t\treturn {\n\t\t\t...DEFAULT_COMPACTION,\n\t\t\t...this.settings.compaction,\n\t\t};\n\t}\n\n\tgetCompactionEnabled(): boolean {\n\t\treturn this.settings.compaction?.enabled ?? DEFAULT_COMPACTION.enabled;\n\t}\n\n\tsetCompactionEnabled(enabled: boolean): void {\n\t\tthis.settings.compaction = { ...this.settings.compaction, enabled };\n\t\tthis.save();\n\t}\n\n\tgetRetrySettings(): PipiclawRetrySettings {\n\t\treturn {\n\t\t\t...DEFAULT_RETRY,\n\t\t\t...this.settings.retry,\n\t\t};\n\t}\n\n\tgetRetryEnabled(): boolean {\n\t\treturn this.settings.retry?.enabled ?? DEFAULT_RETRY.enabled;\n\t}\n\n\tsetRetryEnabled(enabled: boolean): void {\n\t\tthis.settings.retry = { ...this.settings.retry, enabled };\n\t\tthis.save();\n\t}\n\n\tgetDefaultModel(): string | undefined {\n\t\treturn this.settings.defaultModel;\n\t}\n\n\tgetDefaultProvider(): string | undefined {\n\t\treturn this.settings.defaultProvider;\n\t}\n\n\tsetDefaultModelAndProvider(provider: string, modelId: string): void {\n\t\tthis.settings.defaultProvider = provider;\n\t\tthis.settings.defaultModel = modelId;\n\t\tthis.save();\n\t}\n\n\tgetDefaultThinkingLevel(): string {\n\t\treturn this.settings.defaultThinkingLevel || \"off\";\n\t}\n\n\tsetDefaultThinkingLevel(level: string): void {\n\t\tthis.settings.defaultThinkingLevel = level as PipiclawSettings[\"defaultThinkingLevel\"];\n\t\tthis.save();\n\t}\n\n\t// Compatibility methods for AgentSession\n\tgetSteeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn \"one-at-a-time\";\n\t}\n\n\tsetSteeringMode(_mode: \"all\" | \"one-at-a-time\"): void {\n\t\t// No-op\n\t}\n\n\tgetFollowUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn \"one-at-a-time\";\n\t}\n\n\tsetFollowUpMode(_mode: \"all\" | \"one-at-a-time\"): void {\n\t\t// No-op\n\t}\n\n\tgetHookPaths(): string[] {\n\t\treturn [];\n\t}\n\n\tgetHookTimeout(): number {\n\t\treturn 30000;\n\t}\n\n\t// Image settings\n\tgetImageAutoResize(): boolean {\n\t\treturn false;\n\t}\n\n\tsetImageAutoResize(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetBlockImages(): boolean {\n\t\treturn false;\n\t}\n\n\tsetBlockImages(_blocked: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetShowImages(): boolean {\n\t\treturn false;\n\t}\n\n\tsetShowImages(_show: boolean): void {\n\t\t// No-op\n\t}\n\n\t// Compaction details\n\tgetCompactionReserveTokens(): number {\n\t\treturn DEFAULT_COMPACTION.reserveTokens;\n\t}\n\n\tgetCompactionKeepRecentTokens(): number {\n\t\treturn DEFAULT_COMPACTION.keepRecentTokens;\n\t}\n\n\tgetBranchSummarySettings(): { reserveTokens: number } {\n\t\treturn { reserveTokens: 16384 };\n\t}\n\n\t// Thinking\n\tgetHideThinkingBlock(): boolean {\n\t\treturn false;\n\t}\n\n\tsetHideThinkingBlock(_hide: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetThinkingBudgets(): undefined {\n\t\treturn undefined;\n\t}\n\n\t// Shell\n\tgetShellPath(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetShellPath(_path: string | undefined): void {\n\t\t// No-op\n\t}\n\n\tgetShellCommandPrefix(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetShellCommandPrefix(_prefix: string | undefined): void {\n\t\t// No-op\n\t}\n\n\t// Misc settings stubs\n\tgetQuietStartup(): boolean {\n\t\treturn true;\n\t}\n\n\tsetQuietStartup(_quiet: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetCollapseChangelog(): boolean {\n\t\treturn true;\n\t}\n\n\tsetCollapseChangelog(_collapse: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetTransport(): string {\n\t\treturn \"stdio\";\n\t}\n\n\tsetTransport(_transport: string): void {\n\t\t// No-op\n\t}\n\n\tgetTheme(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetTheme(_theme: string): void {\n\t\t// No-op\n\t}\n\n\tgetPackages(): unknown[] {\n\t\treturn [];\n\t}\n\n\tsetPackages(_packages: unknown[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectPackages(_packages: unknown[]): void {\n\t\t// No-op\n\t}\n\n\tgetExtensionPaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetExtensionPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectExtensionPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetSkillPaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetSkillPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectSkillPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetPromptTemplatePaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetPromptTemplatePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectPromptTemplatePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetThemePaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetThemePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectThemePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetEnableSkillCommands(): boolean {\n\t\treturn false;\n\t}\n\n\tsetEnableSkillCommands(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetEnabledModels(): string[] | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetEnabledModels(_patterns: string[] | undefined): void {\n\t\t// No-op\n\t}\n\n\tgetDoubleEscapeAction(): \"none\" {\n\t\treturn \"none\";\n\t}\n\n\tsetDoubleEscapeAction(_action: string): void {\n\t\t// No-op\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn false;\n\t}\n\n\tsetShowHardwareCursor(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetClearOnShrink(): boolean {\n\t\treturn false;\n\t}\n\n\tsetClearOnShrink(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetEditorPaddingX(): number {\n\t\treturn 0;\n\t}\n\n\tsetEditorPaddingX(_padding: number): void {\n\t\t// No-op\n\t}\n\n\tgetAutocompleteMaxVisible(): number {\n\t\treturn 10;\n\t}\n\n\tsetAutocompleteMaxVisible(_maxVisible: number): void {\n\t\t// No-op\n\t}\n\n\tgetCodeBlockIndent(): string {\n\t\treturn \" \";\n\t}\n\n\tgetLastChangelogVersion(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetLastChangelogVersion(_version: string): void {\n\t\t// No-op\n\t}\n\n\tsetDefaultProvider(_provider: string): void {\n\t\t// No-op\n\t}\n\n\tsetDefaultModel(_modelId: string): void {\n\t\t// No-op\n\t}\n\n\tgetGlobalSettings(): object {\n\t\treturn {};\n\t}\n\n\tgetProjectSettings(): object {\n\t\treturn {};\n\t}\n\n\treload(): void {\n\t\tthis.settings = this.load();\n\t}\n\n\tapplyOverrides(_overrides: Partial<PipiclawSettings>): void {\n\t\t// No-op\n\t}\n\n\tflush(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n\n\tdrainErrors(): unknown[] {\n\t\treturn [];\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Context management for pipiclaw.\n *\n * `log.jsonl` and `context.jsonl` are treated as raw cold storage.\n * They are not proactively scanned or loaded as part of the memory model.\n *\n * This module currently provides only PipiclawSettingsManager.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n// ============================================================================\n// PipiclawSettingsManager - Simple settings for pipiclaw\n// ============================================================================\n\nexport interface PipiclawCompactionSettings {\n\tenabled: boolean;\n\treserveTokens: number;\n\tkeepRecentTokens: number;\n}\n\nexport interface PipiclawRetrySettings {\n\tenabled: boolean;\n\tmaxRetries: number;\n\tbaseDelayMs: number;\n}\n\nexport interface PipiclawSettings {\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\";\n\tcompaction?: Partial<PipiclawCompactionSettings>;\n\tretry?: Partial<PipiclawRetrySettings>;\n}\n\nconst DEFAULT_COMPACTION: PipiclawCompactionSettings = {\n\tenabled: true,\n\treserveTokens: 16384,\n\tkeepRecentTokens: 20000,\n};\n\nconst DEFAULT_RETRY: PipiclawRetrySettings = {\n\tenabled: true,\n\tmaxRetries: 3,\n\tbaseDelayMs: 2000,\n};\n\n/**\n * Settings manager for pipiclaw.\n * Stores global settings in the pipiclaw root directory.\n */\nexport class PipiclawSettingsManager {\n\tprivate settingsPath: string;\n\tprivate settings: PipiclawSettings;\n\n\tconstructor(baseDir: string) {\n\t\tthis.settingsPath = join(baseDir, \"settings.json\");\n\t\tthis.settings = this.load();\n\t}\n\n\tprivate load(): PipiclawSettings {\n\t\tif (!existsSync(this.settingsPath)) {\n\t\t\treturn {};\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(this.settingsPath, \"utf-8\");\n\t\t\treturn JSON.parse(content);\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprivate save(): void {\n\t\ttry {\n\t\t\tconst dir = dirname(this.settingsPath);\n\t\t\tif (!existsSync(dir)) {\n\t\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\t}\n\t\t\twriteFileSync(this.settingsPath, JSON.stringify(this.settings, null, 2), \"utf-8\");\n\t\t} catch (error) {\n\t\t\tconsole.error(`Warning: Could not save settings file: ${error}`);\n\t\t}\n\t}\n\n\treload(): void {\n\t\tthis.settings = this.load();\n\t}\n\n\tgetCompactionSettings(): PipiclawCompactionSettings {\n\t\treturn {\n\t\t\t...DEFAULT_COMPACTION,\n\t\t\t...this.settings.compaction,\n\t\t};\n\t}\n\n\tgetCompactionEnabled(): boolean {\n\t\treturn this.settings.compaction?.enabled ?? DEFAULT_COMPACTION.enabled;\n\t}\n\n\tsetCompactionEnabled(enabled: boolean): void {\n\t\tthis.settings.compaction = { ...this.settings.compaction, enabled };\n\t\tthis.save();\n\t}\n\n\tgetRetrySettings(): PipiclawRetrySettings {\n\t\treturn {\n\t\t\t...DEFAULT_RETRY,\n\t\t\t...this.settings.retry,\n\t\t};\n\t}\n\n\tgetRetryEnabled(): boolean {\n\t\treturn this.settings.retry?.enabled ?? DEFAULT_RETRY.enabled;\n\t}\n\n\tsetRetryEnabled(enabled: boolean): void {\n\t\tthis.settings.retry = { ...this.settings.retry, enabled };\n\t\tthis.save();\n\t}\n\n\tgetDefaultModel(): string | undefined {\n\t\treturn this.settings.defaultModel;\n\t}\n\n\tgetDefaultProvider(): string | undefined {\n\t\treturn this.settings.defaultProvider;\n\t}\n\n\tsetDefaultModelAndProvider(provider: string, modelId: string): void {\n\t\tthis.settings.defaultProvider = provider;\n\t\tthis.settings.defaultModel = modelId;\n\t\tthis.save();\n\t}\n\n\tgetDefaultThinkingLevel(): string {\n\t\treturn this.settings.defaultThinkingLevel || \"off\";\n\t}\n\n\tsetDefaultThinkingLevel(level: string): void {\n\t\tthis.settings.defaultThinkingLevel = level as PipiclawSettings[\"defaultThinkingLevel\"];\n\t\tthis.save();\n\t}\n\n\t// Compatibility methods for AgentSession\n\tgetSteeringMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn \"one-at-a-time\";\n\t}\n\n\tsetSteeringMode(_mode: \"all\" | \"one-at-a-time\"): void {\n\t\t// No-op\n\t}\n\n\tgetFollowUpMode(): \"all\" | \"one-at-a-time\" {\n\t\treturn \"one-at-a-time\";\n\t}\n\n\tsetFollowUpMode(_mode: \"all\" | \"one-at-a-time\"): void {\n\t\t// No-op\n\t}\n\n\tgetHookPaths(): string[] {\n\t\treturn [];\n\t}\n\n\tgetHookTimeout(): number {\n\t\treturn 30000;\n\t}\n\n\t// Image settings\n\tgetImageAutoResize(): boolean {\n\t\treturn false;\n\t}\n\n\tsetImageAutoResize(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetBlockImages(): boolean {\n\t\treturn false;\n\t}\n\n\tsetBlockImages(_blocked: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetShowImages(): boolean {\n\t\treturn false;\n\t}\n\n\tsetShowImages(_show: boolean): void {\n\t\t// No-op\n\t}\n\n\t// Compaction details\n\tgetCompactionReserveTokens(): number {\n\t\treturn DEFAULT_COMPACTION.reserveTokens;\n\t}\n\n\tgetCompactionKeepRecentTokens(): number {\n\t\treturn DEFAULT_COMPACTION.keepRecentTokens;\n\t}\n\n\tgetBranchSummarySettings(): { reserveTokens: number } {\n\t\treturn { reserveTokens: 16384 };\n\t}\n\n\t// Thinking\n\tgetHideThinkingBlock(): boolean {\n\t\treturn false;\n\t}\n\n\tsetHideThinkingBlock(_hide: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetThinkingBudgets(): undefined {\n\t\treturn undefined;\n\t}\n\n\t// Shell\n\tgetShellPath(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetShellPath(_path: string | undefined): void {\n\t\t// No-op\n\t}\n\n\tgetShellCommandPrefix(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetShellCommandPrefix(_prefix: string | undefined): void {\n\t\t// No-op\n\t}\n\n\t// Misc settings stubs\n\tgetQuietStartup(): boolean {\n\t\treturn true;\n\t}\n\n\tsetQuietStartup(_quiet: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetCollapseChangelog(): boolean {\n\t\treturn true;\n\t}\n\n\tsetCollapseChangelog(_collapse: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetTransport(): string {\n\t\treturn \"stdio\";\n\t}\n\n\tsetTransport(_transport: string): void {\n\t\t// No-op\n\t}\n\n\tgetTheme(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetTheme(_theme: string): void {\n\t\t// No-op\n\t}\n\n\tgetPackages(): unknown[] {\n\t\treturn [];\n\t}\n\n\tsetPackages(_packages: unknown[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectPackages(_packages: unknown[]): void {\n\t\t// No-op\n\t}\n\n\tgetExtensionPaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetExtensionPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectExtensionPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetSkillPaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetSkillPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectSkillPaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetPromptTemplatePaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetPromptTemplatePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectPromptTemplatePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetThemePaths(): string[] {\n\t\treturn [];\n\t}\n\n\tsetThemePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tsetProjectThemePaths(_paths: string[]): void {\n\t\t// No-op\n\t}\n\n\tgetEnableSkillCommands(): boolean {\n\t\treturn false;\n\t}\n\n\tsetEnableSkillCommands(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetEnabledModels(): string[] | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetEnabledModels(_patterns: string[] | undefined): void {\n\t\t// No-op\n\t}\n\n\tgetDoubleEscapeAction(): \"none\" {\n\t\treturn \"none\";\n\t}\n\n\tsetDoubleEscapeAction(_action: string): void {\n\t\t// No-op\n\t}\n\n\tgetShowHardwareCursor(): boolean {\n\t\treturn false;\n\t}\n\n\tsetShowHardwareCursor(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetClearOnShrink(): boolean {\n\t\treturn false;\n\t}\n\n\tsetClearOnShrink(_enabled: boolean): void {\n\t\t// No-op\n\t}\n\n\tgetEditorPaddingX(): number {\n\t\treturn 0;\n\t}\n\n\tsetEditorPaddingX(_padding: number): void {\n\t\t// No-op\n\t}\n\n\tgetAutocompleteMaxVisible(): number {\n\t\treturn 10;\n\t}\n\n\tsetAutocompleteMaxVisible(_maxVisible: number): void {\n\t\t// No-op\n\t}\n\n\tgetCodeBlockIndent(): string {\n\t\treturn \" \";\n\t}\n\n\tgetLastChangelogVersion(): string | undefined {\n\t\treturn undefined;\n\t}\n\n\tsetLastChangelogVersion(_version: string): void {\n\t\t// No-op\n\t}\n\n\tsetDefaultProvider(_provider: string): void {\n\t\t// No-op\n\t}\n\n\tsetDefaultModel(_modelId: string): void {\n\t\t// No-op\n\t}\n\n\tgetGlobalSettings(): object {\n\t\treturn {};\n\t}\n\n\tgetProjectSettings(): object {\n\t\treturn {};\n\t}\n\n\tapplyOverrides(_overrides: Partial<PipiclawSettings>): void {\n\t\t// No-op\n\t}\n\n\tflush(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n\n\tdrainErrors(): unknown[] {\n\t\treturn [];\n\t}\n}\n"]}
|