0xkobold 0.0.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/.agents/skills/nextjs-best-practices/SKILL.md +208 -0
- package/.agents/skills/sql-optimization-patterns/SKILL.md +509 -0
- package/HEARTBEAT.md +45 -0
- package/README.md +197 -0
- package/USAGE.md +191 -0
- package/dist/package.json +77 -0
- package/dist/src/agent/pi-adapter.js +307 -0
- package/dist/src/agent/pi-adapter.js.map +1 -0
- package/dist/src/agent/tool-adapter.js +86 -0
- package/dist/src/agent/tool-adapter.js.map +1 -0
- package/dist/src/approval/queue.js +114 -0
- package/dist/src/approval/queue.js.map +1 -0
- package/dist/src/ascii-kobold.js +76 -0
- package/dist/src/ascii-kobold.js.map +1 -0
- package/dist/src/cli/client.js +217 -0
- package/dist/src/cli/client.js.map +1 -0
- package/dist/src/cli/commands/agent.js +272 -0
- package/dist/src/cli/commands/agent.js.map +1 -0
- package/dist/src/cli/commands/chat.js +234 -0
- package/dist/src/cli/commands/chat.js.map +1 -0
- package/dist/src/cli/commands/config.js +202 -0
- package/dist/src/cli/commands/config.js.map +1 -0
- package/dist/src/cli/commands/daemon.js +203 -0
- package/dist/src/cli/commands/daemon.js.map +1 -0
- package/dist/src/cli/commands/gateway.js +184 -0
- package/dist/src/cli/commands/gateway.js.map +1 -0
- package/dist/src/cli/commands/init.js +175 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/kobold.js +21 -0
- package/dist/src/cli/commands/kobold.js.map +1 -0
- package/dist/src/cli/commands/logs.js +27 -0
- package/dist/src/cli/commands/logs.js.map +1 -0
- package/dist/src/cli/commands/mode.js +121 -0
- package/dist/src/cli/commands/mode.js.map +1 -0
- package/dist/src/cli/commands/persona.js +261 -0
- package/dist/src/cli/commands/persona.js.map +1 -0
- package/dist/src/cli/commands/start.js +66 -0
- package/dist/src/cli/commands/start.js.map +1 -0
- package/dist/src/cli/commands/status.js +117 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/commands/stop.js +27 -0
- package/dist/src/cli/commands/stop.js.map +1 -0
- package/dist/src/cli/commands/system.js +128 -0
- package/dist/src/cli/commands/system.js.map +1 -0
- package/dist/src/cli/commands/tui.js +103 -0
- package/dist/src/cli/commands/tui.js.map +1 -0
- package/dist/src/cli/commands/update.js +133 -0
- package/dist/src/cli/commands/update.js.map +1 -0
- package/dist/src/cli/extensions/discord.js +113 -0
- package/dist/src/cli/extensions/discord.js.map +1 -0
- package/dist/src/cli/extensions/env.js +91 -0
- package/dist/src/cli/extensions/env.js.map +1 -0
- package/dist/src/cli/extensions/heartbeat.js +78 -0
- package/dist/src/cli/extensions/heartbeat.js.map +1 -0
- package/dist/src/cli/index.js +24 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/program.js +70 -0
- package/dist/src/cli/program.js.map +1 -0
- package/dist/src/cli/repl.js +184 -0
- package/dist/src/cli/repl.js.map +1 -0
- package/dist/src/cli/shared/discord-service.js +102 -0
- package/dist/src/cli/shared/discord-service.js.map +1 -0
- package/dist/src/config/index.js +10 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/loader.js +401 -0
- package/dist/src/config/loader.js.map +1 -0
- package/dist/src/config/paths.js +84 -0
- package/dist/src/config/paths.js.map +1 -0
- package/dist/src/config/types.js +8 -0
- package/dist/src/config/types.js.map +1 -0
- package/dist/src/context-detector.js +60 -0
- package/dist/src/context-detector.js.map +1 -0
- package/dist/src/discord/index.js +376 -0
- package/dist/src/discord/index.js.map +1 -0
- package/dist/src/event-bus/index.js +97 -0
- package/dist/src/event-bus/index.js.map +1 -0
- package/dist/src/extensions/command-args.js +68 -0
- package/dist/src/extensions/command-args.js.map +1 -0
- package/dist/src/extensions/core/agent-registry-extension.js +541 -0
- package/dist/src/extensions/core/agent-registry-extension.js.map +1 -0
- package/dist/src/extensions/core/agent-worker.js +148 -0
- package/dist/src/extensions/core/agent-worker.js.map +1 -0
- package/dist/src/extensions/core/compaction-safeguard.js +154 -0
- package/dist/src/extensions/core/compaction-safeguard.js.map +1 -0
- package/dist/src/extensions/core/confirm-destructive.js +43 -0
- package/dist/src/extensions/core/confirm-destructive.js.map +1 -0
- package/dist/src/extensions/core/context-aware-extension.js +124 -0
- package/dist/src/extensions/core/context-aware-extension.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/extension.js +124 -0
- package/dist/src/extensions/core/context-pruning/extension.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/pruner.js +312 -0
- package/dist/src/extensions/core/context-pruning/pruner.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/runtime.js +48 -0
- package/dist/src/extensions/core/context-pruning/runtime.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/settings.js +105 -0
- package/dist/src/extensions/core/context-pruning/settings.js.map +1 -0
- package/dist/src/extensions/core/dirty-repo-guard.js +42 -0
- package/dist/src/extensions/core/dirty-repo-guard.js.map +1 -0
- package/dist/src/extensions/core/discord-channel-extension.js +205 -0
- package/dist/src/extensions/core/discord-channel-extension.js.map +1 -0
- package/dist/src/extensions/core/discord-extension.js +142 -0
- package/dist/src/extensions/core/discord-extension.js.map +1 -0
- package/dist/src/extensions/core/env-loader-extension.js +157 -0
- package/dist/src/extensions/core/env-loader-extension.js.map +1 -0
- package/dist/src/extensions/core/fileops-extension.js +699 -0
- package/dist/src/extensions/core/fileops-extension.js.map +1 -0
- package/dist/src/extensions/core/gateway-extension.js +730 -0
- package/dist/src/extensions/core/gateway-extension.js.map +1 -0
- package/dist/src/extensions/core/git-checkpoint.js +46 -0
- package/dist/src/extensions/core/git-checkpoint.js.map +1 -0
- package/dist/src/extensions/core/handoff-extension.js +206 -0
- package/dist/src/extensions/core/handoff-extension.js.map +1 -0
- package/dist/src/extensions/core/heartbeat-extension.js +373 -0
- package/dist/src/extensions/core/heartbeat-extension.js.map +1 -0
- package/dist/src/extensions/core/mcp-extension.js +413 -0
- package/dist/src/extensions/core/mcp-extension.js.map +1 -0
- package/dist/src/extensions/core/mode-manager-extension.js +562 -0
- package/dist/src/extensions/core/mode-manager-extension.js.map +1 -0
- package/dist/src/extensions/core/multi-channel-extension.js +435 -0
- package/dist/src/extensions/core/multi-channel-extension.js.map +1 -0
- package/dist/src/extensions/core/ollama-provider-extension.js +66 -0
- package/dist/src/extensions/core/ollama-provider-extension.js.map +1 -0
- package/dist/src/extensions/core/onboarding-extension.js +122 -0
- package/dist/src/extensions/core/onboarding-extension.js.map +1 -0
- package/dist/src/extensions/core/persona-loader-extension.js +139 -0
- package/dist/src/extensions/core/persona-loader-extension.js.map +1 -0
- package/dist/src/extensions/core/pi-notify-extension.js +70 -0
- package/dist/src/extensions/core/pi-notify-extension.js.map +1 -0
- package/dist/src/extensions/core/protected-paths.js +24 -0
- package/dist/src/extensions/core/protected-paths.js.map +1 -0
- package/dist/src/extensions/core/questionnaire-extension.js +242 -0
- package/dist/src/extensions/core/questionnaire-extension.js.map +1 -0
- package/dist/src/extensions/core/self-update-extension.js +181 -0
- package/dist/src/extensions/core/self-update-extension.js.map +1 -0
- package/dist/src/extensions/core/session-bridge-extension.js +78 -0
- package/dist/src/extensions/core/session-bridge-extension.js.map +1 -0
- package/dist/src/extensions/core/session-manager-extension.js +319 -0
- package/dist/src/extensions/core/session-manager-extension.js.map +1 -0
- package/dist/src/extensions/core/session-name-extension.js +88 -0
- package/dist/src/extensions/core/session-name-extension.js.map +1 -0
- package/dist/src/extensions/core/session-pruning-extension.js +480 -0
- package/dist/src/extensions/core/session-pruning-extension.js.map +1 -0
- package/dist/src/extensions/core/task-manager-extension.js +661 -0
- package/dist/src/extensions/core/task-manager-extension.js.map +1 -0
- package/dist/src/extensions/core/update-extension.js +438 -0
- package/dist/src/extensions/core/update-extension.js.map +1 -0
- package/dist/src/extensions/core/websearch-extension.js +463 -0
- package/dist/src/extensions/core/websearch-extension.js.map +1 -0
- package/dist/src/extensions/index.js +5 -0
- package/dist/src/extensions/index.js.map +1 -0
- package/dist/src/extensions/loader.js +80 -0
- package/dist/src/extensions/loader.js.map +1 -0
- package/dist/src/gateway/index.js +353 -0
- package/dist/src/gateway/index.js.map +1 -0
- package/dist/src/index.js +150 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm/anthropic.js +86 -0
- package/dist/src/llm/anthropic.js.map +1 -0
- package/dist/src/llm/index.js +9 -0
- package/dist/src/llm/index.js.map +1 -0
- package/dist/src/llm/ollama.js +113 -0
- package/dist/src/llm/ollama.js.map +1 -0
- package/dist/src/llm/router.js +145 -0
- package/dist/src/llm/router.js.map +1 -0
- package/dist/src/llm/types.js +7 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/memory/index.js +5 -0
- package/dist/src/memory/index.js.map +1 -0
- package/dist/src/memory/store.js +91 -0
- package/dist/src/memory/store.js.map +1 -0
- package/dist/src/pi-config.js +80 -0
- package/dist/src/pi-config.js.map +1 -0
- package/dist/src/skills/builtin/file.js +184 -0
- package/dist/src/skills/builtin/file.js.map +1 -0
- package/dist/src/skills/builtin/shell.js +100 -0
- package/dist/src/skills/builtin/shell.js.map +1 -0
- package/dist/src/skills/builtin/subagent.js +62 -0
- package/dist/src/skills/builtin/subagent.js.map +1 -0
- package/dist/src/skills/hello.js +42 -0
- package/dist/src/skills/hello.js.map +1 -0
- package/dist/src/skills/index.js +11 -0
- package/dist/src/skills/index.js.map +1 -0
- package/dist/src/skills/loader.js +382 -0
- package/dist/src/skills/loader.js.map +1 -0
- package/dist/src/skills/types.js +8 -0
- package/dist/src/skills/types.js.map +1 -0
- package/dist/src/utils/working-dir.js +71 -0
- package/dist/src/utils/working-dir.js.map +1 -0
- package/package.json +77 -0
- package/skills/1password/SKILL.md +70 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/apple-notes/SKILL.md +77 -0
- package/skills/apple-reminders/SKILL.md +118 -0
- package/skills/bear-notes/SKILL.md +107 -0
- package/skills/blogwatcher/SKILL.md +69 -0
- package/skills/blucli/SKILL.md +47 -0
- package/skills/bluebubbles/SKILL.md +131 -0
- package/skills/camsnap/SKILL.md +45 -0
- package/skills/canvas/SKILL.md +198 -0
- package/skills/clawhub/SKILL.md +77 -0
- package/skills/coding-agent/SKILL.md +284 -0
- package/skills/discord/SKILL.md +197 -0
- package/skills/eightctl/SKILL.md +50 -0
- package/skills/food-order/SKILL.md +48 -0
- package/skills/gemini/SKILL.md +43 -0
- package/skills/gh-issues/SKILL.md +865 -0
- package/skills/gifgrep/SKILL.md +79 -0
- package/skills/github/SKILL.md +163 -0
- package/skills/gog/SKILL.md +116 -0
- package/skills/goplaces/SKILL.md +52 -0
- package/skills/healthcheck/SKILL.md +245 -0
- package/skills/himalaya/SKILL.md +257 -0
- package/skills/himalaya/references/configuration.md +184 -0
- package/skills/himalaya/references/message-composition.md +199 -0
- package/skills/imsg/SKILL.md +122 -0
- package/skills/mcporter/SKILL.md +61 -0
- package/skills/model-usage/SKILL.md +69 -0
- package/skills/model-usage/references/codexbar-cli.md +33 -0
- package/skills/model-usage/scripts/model_usage.py +310 -0
- package/skills/nano-banana-pro/SKILL.md +58 -0
- package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
- package/skills/nano-pdf/SKILL.md +38 -0
- package/skills/notion/SKILL.md +172 -0
- package/skills/obsidian/SKILL.md +81 -0
- package/skills/openai-image-gen/SKILL.md +89 -0
- package/skills/openai-image-gen/scripts/gen.py +240 -0
- package/skills/openai-whisper/SKILL.md +38 -0
- package/skills/openai-whisper-api/SKILL.md +52 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
- package/skills/openhue/SKILL.md +112 -0
- package/skills/oracle/SKILL.md +125 -0
- package/skills/ordercli/SKILL.md +78 -0
- package/skills/peekaboo/SKILL.md +190 -0
- package/skills/sag/SKILL.md +87 -0
- package/skills/session-logs/SKILL.md +115 -0
- package/skills/sherpa-onnx-tts/SKILL.md +103 -0
- package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
- package/skills/skill-creator/SKILL.md +370 -0
- package/skills/skill-creator/license.txt +202 -0
- package/skills/skill-creator/scripts/init_skill.py +378 -0
- package/skills/skill-creator/scripts/package_skill.py +111 -0
- package/skills/skill-creator/scripts/quick_validate.py +101 -0
- package/skills/slack/SKILL.md +144 -0
- package/skills/songsee/SKILL.md +49 -0
- package/skills/sonoscli/SKILL.md +46 -0
- package/skills/spotify-player/SKILL.md +64 -0
- package/skills/summarize/SKILL.md +87 -0
- package/skills/things-mac/SKILL.md +86 -0
- package/skills/tmux/SKILL.md +153 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +95 -0
- package/skills/video-frames/SKILL.md +46 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/voice-call/SKILL.md +45 -0
- package/skills/wacli/SKILL.md +72 -0
- package/skills/weather/SKILL.md +112 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Agent Worker Process
|
|
4
|
+
*
|
|
5
|
+
* This is spawned as a subprocess by agent-registry-extension.ts
|
|
6
|
+
* Connects to gateway, authenticates, executes task, reports completion.
|
|
7
|
+
*/
|
|
8
|
+
const AGENT_ID = process.env.KOBOLD_AGENT_ID;
|
|
9
|
+
const AGENT_TYPE = process.env.KOBOLD_AGENT_TYPE;
|
|
10
|
+
const AGENT_TASK = process.env.KOBOLD_AGENT_TASK;
|
|
11
|
+
const SESSION_KEY = process.env.KOBOLD_SESSION_KEY;
|
|
12
|
+
const PARENT_ID = process.env.KOBOLD_PARENT_ID || "";
|
|
13
|
+
const WORKSPACE = process.env.KOBOLD_WORKSPACE;
|
|
14
|
+
const GATEWAY_PORT = parseInt(process.env.KOBOLD_GATEWAY_PORT || "18789");
|
|
15
|
+
if (!AGENT_ID || !SESSION_KEY) {
|
|
16
|
+
console.error("[AgentWorker] Missing required environment variables");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
console.log(`[AgentWorker] ${AGENT_ID} starting...`);
|
|
20
|
+
console.log(`[AgentWorker] Type: ${AGENT_TYPE}`);
|
|
21
|
+
console.log(`[AgentWorker] Task: ${AGENT_TASK?.slice(0, 100)}...`);
|
|
22
|
+
console.log(`[AgentWorker] Workspace: ${WORKSPACE}`);
|
|
23
|
+
// Results tracking
|
|
24
|
+
let tokensInput = 0;
|
|
25
|
+
let tokensOutput = 0;
|
|
26
|
+
let result = "";
|
|
27
|
+
let exitCode = 0;
|
|
28
|
+
// Main execution
|
|
29
|
+
async function main() {
|
|
30
|
+
try {
|
|
31
|
+
// Connect to gateway
|
|
32
|
+
await connectToGateway();
|
|
33
|
+
// Execute the task
|
|
34
|
+
await executeTask();
|
|
35
|
+
// Report completion
|
|
36
|
+
await reportCompletion("success");
|
|
37
|
+
console.log("[AgentWorker] Completed successfully");
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error("[AgentWorker] Error:", error);
|
|
42
|
+
await reportCompletion("error", String(error));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function connectToGateway() {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const ws = new WebSocket(`ws://127.0.0.1:${GATEWAY_PORT}`);
|
|
49
|
+
ws.onopen = () => {
|
|
50
|
+
console.log("[AgentWorker] Connected to gateway");
|
|
51
|
+
// Send connect frame with authentication
|
|
52
|
+
const connectFrame = {
|
|
53
|
+
type: "connect",
|
|
54
|
+
id: `conn-${Date.now()}`,
|
|
55
|
+
params: {
|
|
56
|
+
role: "node",
|
|
57
|
+
client: AGENT_ID,
|
|
58
|
+
caps: ["subagent"],
|
|
59
|
+
device: { id: AGENT_ID, platform: "bun-subprocess" },
|
|
60
|
+
sessionKey: SESSION_KEY,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
ws.send(JSON.stringify(connectFrame));
|
|
64
|
+
// Wait for response
|
|
65
|
+
const onMessage = (data) => {
|
|
66
|
+
try {
|
|
67
|
+
const frame = JSON.parse(data.data);
|
|
68
|
+
if (frame.type === "res" && frame.ok) {
|
|
69
|
+
console.log("[AgentWorker] Authenticated with gateway");
|
|
70
|
+
ws.removeEventListener("message", onMessage);
|
|
71
|
+
resolve();
|
|
72
|
+
}
|
|
73
|
+
else if (frame.type === "res" && !frame.ok) {
|
|
74
|
+
reject(new Error(frame.error || "Authentication failed"));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch { }
|
|
78
|
+
};
|
|
79
|
+
ws.addEventListener("message", onMessage);
|
|
80
|
+
};
|
|
81
|
+
ws.onerror = (err) => {
|
|
82
|
+
reject(new Error(`WebSocket error: ${err}`));
|
|
83
|
+
};
|
|
84
|
+
// Timeout after 10 seconds
|
|
85
|
+
setTimeout(() => reject(new Error("Gateway connection timeout")), 10000);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async function executeTask() {
|
|
89
|
+
const task = AGENT_TASK || "";
|
|
90
|
+
// Simulate work - in real implementation, this would:
|
|
91
|
+
// - Initialize the pi-coding-agent framework
|
|
92
|
+
// - Execute the task using available tools
|
|
93
|
+
// - Track token usage
|
|
94
|
+
// - Generate output
|
|
95
|
+
console.log("[AgentWorker] Executing task...");
|
|
96
|
+
// Simulate processing time
|
|
97
|
+
await delay(2000 + Math.random() * 3000);
|
|
98
|
+
// Simulate token counting
|
|
99
|
+
tokensInput = task.length * 2;
|
|
100
|
+
tokensOutput = Math.floor(Math.random() * 500) + 100;
|
|
101
|
+
// Generate result
|
|
102
|
+
result = `Task completed by ${AGENT_ID}\\n` +
|
|
103
|
+
`Type: ${AGENT_TYPE}\\n` +
|
|
104
|
+
`Task: ${task.slice(0, 50)}...\\n` +
|
|
105
|
+
`Output: ${tokensOutput} tokens generated`;
|
|
106
|
+
console.log("[AgentWorker] Task complete");
|
|
107
|
+
console.log(`[AgentWorker] Input tokens: ${tokensInput}`);
|
|
108
|
+
console.log(`[AgentWorker] Output tokens: ${tokensOutput}`);
|
|
109
|
+
}
|
|
110
|
+
async function reportCompletion(status, errorMessage) {
|
|
111
|
+
const ws = new WebSocket(`ws://127.0.0.1:${GATEWAY_PORT}`);
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
ws.onopen = () => {
|
|
114
|
+
const announceFrame = {
|
|
115
|
+
type: "req",
|
|
116
|
+
id: `announce-${Date.now()}`,
|
|
117
|
+
method: "agent.announce",
|
|
118
|
+
params: {
|
|
119
|
+
sessionKey: SESSION_KEY,
|
|
120
|
+
source: "subagent",
|
|
121
|
+
childSessionKey: SESSION_KEY,
|
|
122
|
+
taskLabel: AGENT_TASK?.slice(0, 50),
|
|
123
|
+
status: status === "success" ? "success" : "error",
|
|
124
|
+
result: errorMessage || result,
|
|
125
|
+
tokens: { input: tokensInput, output: tokensOutput },
|
|
126
|
+
runtime: Date.now() - startTime,
|
|
127
|
+
exitCode: status === "success" ? 0 : 1,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
ws.send(JSON.stringify(announceFrame));
|
|
131
|
+
// Close after sending
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
ws.close();
|
|
134
|
+
resolve();
|
|
135
|
+
}, 500);
|
|
136
|
+
};
|
|
137
|
+
ws.onerror = () => {
|
|
138
|
+
console.error("[AgentWorker] Failed to report completion");
|
|
139
|
+
resolve();
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function delay(ms) {
|
|
144
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
145
|
+
}
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
main();
|
|
148
|
+
//# sourceMappingURL=agent-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-worker.js","sourceRoot":"","sources":["../../../../src/extensions/core/agent-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compaction Safeguard Extension
|
|
3
|
+
*
|
|
4
|
+
* Adapted from OpenClaw - protects context during message compaction
|
|
5
|
+
* Features:
|
|
6
|
+
* - Tracks tool failures during compaction
|
|
7
|
+
* - Preserves read/modified file lists
|
|
8
|
+
* - Summarizes dropped messages before they're lost
|
|
9
|
+
* - Adaptive chunk ratios based on message sizes
|
|
10
|
+
* - Workspace context extraction (AGENTS.md rules)
|
|
11
|
+
*/
|
|
12
|
+
const FALLBACK_SUMMARY = "Summary unavailable due to context limits. Older messages were truncated.";
|
|
13
|
+
const TURN_PREFIX_INSTRUCTIONS = "This summary covers the prefix of a split turn. Focus on the original request," +
|
|
14
|
+
" early progress, and any details needed to understand the retained suffix.";
|
|
15
|
+
const MAX_TOOL_FAILURES = 8;
|
|
16
|
+
const MAX_TOOL_FAILURE_CHARS = 240;
|
|
17
|
+
function normalizeFailureText(text) {
|
|
18
|
+
return text.replace(/\s+/g, " ").trim();
|
|
19
|
+
}
|
|
20
|
+
function truncateFailureText(text, maxChars) {
|
|
21
|
+
if (text.length <= maxChars) {
|
|
22
|
+
return text;
|
|
23
|
+
}
|
|
24
|
+
return `${text.slice(0, Math.max(0, maxChars - 3))}...`;
|
|
25
|
+
}
|
|
26
|
+
function formatToolFailureMeta(details) {
|
|
27
|
+
if (!details || typeof details !== "object") {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const record = details;
|
|
31
|
+
const status = typeof record.status === "string" ? record.status : undefined;
|
|
32
|
+
const exitCode = typeof record.exitCode === "number" && Number.isFinite(record.exitCode)
|
|
33
|
+
? record.exitCode
|
|
34
|
+
: undefined;
|
|
35
|
+
const parts = [];
|
|
36
|
+
if (status) {
|
|
37
|
+
parts.push(`status=${status}`);
|
|
38
|
+
}
|
|
39
|
+
if (exitCode !== undefined) {
|
|
40
|
+
parts.push(`exitCode=${exitCode}`);
|
|
41
|
+
}
|
|
42
|
+
return parts.length > 0 ? parts.join(" ") : undefined;
|
|
43
|
+
}
|
|
44
|
+
function extractToolResultText(content) {
|
|
45
|
+
if (!Array.isArray(content)) {
|
|
46
|
+
return "";
|
|
47
|
+
}
|
|
48
|
+
const parts = [];
|
|
49
|
+
for (const block of content) {
|
|
50
|
+
if (!block || typeof block !== "object") {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const rec = block;
|
|
54
|
+
if (rec.type === "text" && typeof rec.text === "string") {
|
|
55
|
+
parts.push(rec.text);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return parts.join("\n");
|
|
59
|
+
}
|
|
60
|
+
function collectToolFailures(messages) {
|
|
61
|
+
const failures = [];
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
for (const message of messages) {
|
|
64
|
+
if (!message || typeof message !== "object") {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const role = message.role;
|
|
68
|
+
if (role !== "toolResult") {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const toolResult = message;
|
|
72
|
+
if (toolResult.isError !== true) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const toolCallId = typeof toolResult.toolCallId === "string" ? toolResult.toolCallId : "";
|
|
76
|
+
if (!toolCallId || seen.has(toolCallId)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
seen.add(toolCallId);
|
|
80
|
+
const toolName = typeof toolResult.toolName === "string" && toolResult.toolName.trim()
|
|
81
|
+
? toolResult.toolName
|
|
82
|
+
: "tool";
|
|
83
|
+
const rawText = extractToolResultText(toolResult.content);
|
|
84
|
+
const meta = formatToolFailureMeta(toolResult.details);
|
|
85
|
+
const normalized = normalizeFailureText(rawText);
|
|
86
|
+
const summary = truncateFailureText(normalized || (meta ? "failed" : "failed (no output)"), MAX_TOOL_FAILURE_CHARS);
|
|
87
|
+
failures.push({ toolCallId, toolName, summary, meta });
|
|
88
|
+
}
|
|
89
|
+
return failures;
|
|
90
|
+
}
|
|
91
|
+
function formatToolFailuresSection(failures) {
|
|
92
|
+
if (failures.length === 0) {
|
|
93
|
+
return "";
|
|
94
|
+
}
|
|
95
|
+
const lines = failures.slice(0, MAX_TOOL_FAILURES).map((failure) => {
|
|
96
|
+
const meta = failure.meta ? ` (${failure.meta})` : "";
|
|
97
|
+
return `- ${failure.toolName}${meta}: ${failure.summary}`;
|
|
98
|
+
});
|
|
99
|
+
if (failures.length > MAX_TOOL_FAILURES) {
|
|
100
|
+
lines.push(`- ...and ${failures.length - MAX_TOOL_FAILURES} more`);
|
|
101
|
+
}
|
|
102
|
+
return `\n\n## Tool Failures\n${lines.join("\n")}`;
|
|
103
|
+
}
|
|
104
|
+
function computeFileLists(fileOps) {
|
|
105
|
+
const modified = new Set([...fileOps.edited, ...fileOps.written]);
|
|
106
|
+
const readFiles = [...fileOps.read].filter((f) => !modified.has(f)).toSorted();
|
|
107
|
+
const modifiedFiles = [...modified].toSorted();
|
|
108
|
+
return { readFiles, modifiedFiles };
|
|
109
|
+
}
|
|
110
|
+
function formatFileOperations(readFiles, modifiedFiles) {
|
|
111
|
+
const sections = [];
|
|
112
|
+
if (readFiles.length > 0) {
|
|
113
|
+
sections.push(`<read-files>\n${readFiles.join("\n")}\n</read-files>`);
|
|
114
|
+
}
|
|
115
|
+
if (modifiedFiles.length > 0) {
|
|
116
|
+
sections.push(`<modified-files>\n${modifiedFiles.join("\n")}\n</modified-files>`);
|
|
117
|
+
}
|
|
118
|
+
if (sections.length === 0) {
|
|
119
|
+
return "";
|
|
120
|
+
}
|
|
121
|
+
return `\n\n${sections.join("\n\n")}`;
|
|
122
|
+
}
|
|
123
|
+
export default function compactionSafeguardExtension(api) {
|
|
124
|
+
console.log("[CompactionSafeguard] Extension loaded");
|
|
125
|
+
api.on("session_before_compact", async (event, ctx) => {
|
|
126
|
+
const { preparation } = event;
|
|
127
|
+
const { readFiles, modifiedFiles } = computeFileLists(preparation.fileOps);
|
|
128
|
+
const fileOpsSummary = formatFileOperations(readFiles, modifiedFiles);
|
|
129
|
+
const toolFailures = collectToolFailures([
|
|
130
|
+
...preparation.messagesToSummarize,
|
|
131
|
+
...preparation.turnPrefixMessages,
|
|
132
|
+
]);
|
|
133
|
+
const toolFailureSection = formatToolFailuresSection(toolFailures);
|
|
134
|
+
const fallbackSummary = `${FALLBACK_SUMMARY}${toolFailureSection}${fileOpsSummary}`;
|
|
135
|
+
// Return enhanced compaction data
|
|
136
|
+
return {
|
|
137
|
+
compaction: {
|
|
138
|
+
summary: fallbackSummary,
|
|
139
|
+
firstKeptEntryId: preparation.firstKeptEntryId,
|
|
140
|
+
tokensBefore: preparation.tokensBefore,
|
|
141
|
+
details: {
|
|
142
|
+
readFiles,
|
|
143
|
+
modifiedFiles,
|
|
144
|
+
toolFailures: toolFailures.length > 0 ? toolFailures : undefined,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
export const __testing = {
|
|
151
|
+
collectToolFailures,
|
|
152
|
+
formatToolFailuresSection,
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=compaction-safeguard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction-safeguard.js","sourceRoot":"","sources":["../../../../src/extensions/core/compaction-safeguard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirm Destructive Actions Extension
|
|
3
|
+
*
|
|
4
|
+
* Prompts for confirmation before destructive session actions (clear, switch, branch).
|
|
5
|
+
* Demonstrates how to cancel session events using the before_* events.
|
|
6
|
+
*/
|
|
7
|
+
export default function (pi) {
|
|
8
|
+
pi.on("session_before_switch", async (event, ctx) => {
|
|
9
|
+
if (!ctx.hasUI)
|
|
10
|
+
return;
|
|
11
|
+
if (event.reason === "new") {
|
|
12
|
+
const confirmed = await ctx.ui.confirm("Clear session?", "This will delete all messages in the current session.");
|
|
13
|
+
if (!confirmed) {
|
|
14
|
+
ctx.ui.notify("Clear cancelled", "info");
|
|
15
|
+
return { cancel: true };
|
|
16
|
+
}
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// reason === "resume" - check if there are unsaved changes (messages since last assistant response)
|
|
20
|
+
const entries = ctx.sessionManager.getEntries();
|
|
21
|
+
const hasUnsavedWork = entries.some((e) => e.type === "message" && e.message.role === "user");
|
|
22
|
+
if (hasUnsavedWork) {
|
|
23
|
+
const confirmed = await ctx.ui.confirm("Switch session?", "You have messages in the current session. Switch anyway?");
|
|
24
|
+
if (!confirmed) {
|
|
25
|
+
ctx.ui.notify("Switch cancelled", "info");
|
|
26
|
+
return { cancel: true };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
pi.on("session_before_fork", async (event, ctx) => {
|
|
31
|
+
if (!ctx.hasUI)
|
|
32
|
+
return;
|
|
33
|
+
const choice = await ctx.ui.select(`Fork from entry ${event.entryId.slice(0, 8)}?`, [
|
|
34
|
+
"Yes, create fork",
|
|
35
|
+
"No, stay in current session",
|
|
36
|
+
]);
|
|
37
|
+
if (choice !== "Yes, create fork") {
|
|
38
|
+
ctx.ui.notify("Fork cancelled", "info");
|
|
39
|
+
return { cancel: true };
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=confirm-destructive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-destructive.js","sourceRoot":"","sources":["../../../../src/extensions/core/confirm-destructive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,OAAO,WAAW,EAAgB;IACxC,EAAE,CAAC,EAAE,CAAC,uBAAuB,EAAE,KAAK,EAAE,KAA+B,EAAE,GAAG,EAAE,EAAE;QAC7E,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO;QAEvB,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CACrC,gBAAgB,EAChB,uDAAuD,CACvD,CAAC;YAEF,IAAI,CAAC,SAAS,EAAE,CAAC;gBAChB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;gBACzC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YACzB,CAAC;YACD,OAAO;QACR,CAAC;QAED,oGAAoG;QACpG,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QAChD,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAClC,CAAC,CAAC,EAA4B,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAClF,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACpB,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,OAAO,CACrC,iBAAiB,EACjB,0DAA0D,CAC1D,CAAC;YAEF,IAAI,CAAC,SAAS,EAAE,CAAC;gBAChB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;gBAC1C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YACzB,CAAC;QACF,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACjD,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO;QAEvB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,mBAAmB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE;YACnF,kBAAkB;YAClB,6BAA6B;SAC7B,CAAC,CAAC;QAEH,IAAI,MAAM,KAAK,kBAAkB,EAAE,CAAC;YACnC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;YACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
import { join, basename } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
const CONTEXT_FILE = join(homedir(), ".0xkobold", ".active-context");
|
|
5
|
+
/**
|
|
6
|
+
* Context-Aware Extension
|
|
7
|
+
*
|
|
8
|
+
* Reads the active context file and updates TUI display
|
|
9
|
+
* to show the actual working directory with --local mode.
|
|
10
|
+
*/
|
|
11
|
+
export default function contextAwareExtension(pi) {
|
|
12
|
+
let activeContext = null;
|
|
13
|
+
/**
|
|
14
|
+
* Load active context from file
|
|
15
|
+
*/
|
|
16
|
+
function loadContext() {
|
|
17
|
+
try {
|
|
18
|
+
if (!existsSync(CONTEXT_FILE)) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const content = readFileSync(CONTEXT_FILE, "utf-8");
|
|
22
|
+
const parsed = JSON.parse(content);
|
|
23
|
+
// Check if context is fresh (within 5 minutes)
|
|
24
|
+
const age = Date.now() - parsed.timestamp;
|
|
25
|
+
if (age > 5 * 60 * 1000) {
|
|
26
|
+
return null; // Too old
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get git branch from a directory
|
|
36
|
+
*/
|
|
37
|
+
function getGitBranch(dir) {
|
|
38
|
+
try {
|
|
39
|
+
const { execSync } = require("child_process");
|
|
40
|
+
const result = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
41
|
+
cwd: dir,
|
|
42
|
+
encoding: "utf-8",
|
|
43
|
+
});
|
|
44
|
+
return result.trim();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Load context on startup
|
|
51
|
+
activeContext = loadContext();
|
|
52
|
+
if (activeContext?.isLocal) {
|
|
53
|
+
console.log(`[Context-Aware] Local mode active: ${activeContext.workingDir}`);
|
|
54
|
+
}
|
|
55
|
+
// Hook into session start
|
|
56
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
57
|
+
activeContext = loadContext();
|
|
58
|
+
// Only apply local context if:
|
|
59
|
+
// 1. Context file says it's local
|
|
60
|
+
// 2. KOBOLD_WORKING_DIR env var is set (confirms --local was used)
|
|
61
|
+
if (!activeContext?.isLocal) {
|
|
62
|
+
return; // Not in local mode
|
|
63
|
+
}
|
|
64
|
+
const envWorkingDir = process.env.KOBOLD_WORKING_DIR;
|
|
65
|
+
if (!envWorkingDir || envWorkingDir === process.cwd()) {
|
|
66
|
+
return; // Not actually in local mode (env var missing or matches cwd)
|
|
67
|
+
}
|
|
68
|
+
;
|
|
69
|
+
const { workingDir } = activeContext;
|
|
70
|
+
const gitBranch = getGitBranch(workingDir);
|
|
71
|
+
const dirName = basename(workingDir);
|
|
72
|
+
// Replace the footer to show actual working directory
|
|
73
|
+
ctx.ui?.setFooter?.((tui, theme, footerData) => ({
|
|
74
|
+
invalidate() { },
|
|
75
|
+
render(width) {
|
|
76
|
+
// Build status line with actual working directory
|
|
77
|
+
const parts = [];
|
|
78
|
+
// Working directory (the key fix!)
|
|
79
|
+
const workingDirDisplay = `${workingDir}`;
|
|
80
|
+
parts.push(theme.fg("dim", workingDirDisplay));
|
|
81
|
+
// Git branch if available
|
|
82
|
+
if (gitBranch) {
|
|
83
|
+
parts.push(theme.fg("accent", `(${gitBranch})`));
|
|
84
|
+
}
|
|
85
|
+
// Mode indicator
|
|
86
|
+
parts.push(theme.fg("dim", "• local mode"));
|
|
87
|
+
// Original footer data
|
|
88
|
+
const extensionStatuses = footerData.getExtensionStatuses?.() || new Map();
|
|
89
|
+
const statusItems = Array.from(extensionStatuses.values()).filter(Boolean);
|
|
90
|
+
if (statusItems.length > 0) {
|
|
91
|
+
parts.push(theme.fg("dim", "• " + statusItems.slice(0, 2).join(" ")));
|
|
92
|
+
}
|
|
93
|
+
// Combine parts and truncate to width
|
|
94
|
+
const line = parts.join(" ");
|
|
95
|
+
if (line.length > width) {
|
|
96
|
+
return [line.slice(0, width - 3) + "..."];
|
|
97
|
+
}
|
|
98
|
+
return [line];
|
|
99
|
+
},
|
|
100
|
+
dispose: footerData.onBranchChange?.(() => tui.requestRender()),
|
|
101
|
+
}));
|
|
102
|
+
// Add a status bar item showing we're in local mode
|
|
103
|
+
ctx.ui?.setStatus?.("workspace", `🗂️ ${dirName}`);
|
|
104
|
+
// Log for debugging
|
|
105
|
+
console.log(`[Context-Aware] Footer updated for: ${workingDir}`);
|
|
106
|
+
});
|
|
107
|
+
// Register a command
|
|
108
|
+
pi.registerCommand("context", {
|
|
109
|
+
description: "Show current workspace context",
|
|
110
|
+
handler: async (_args, ctx) => {
|
|
111
|
+
activeContext = loadContext();
|
|
112
|
+
if (!activeContext) {
|
|
113
|
+
ctx.ui?.notify?.("No active context. Not in local mode.", "info");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
ctx.ui?.notify?.(`🗂️ Current Context:\n` +
|
|
117
|
+
` Working: ${activeContext.workingDir}\n` +
|
|
118
|
+
` Mode: ${activeContext.isLocal ? "local" : "global"}\n` +
|
|
119
|
+
` From: ${new Date(activeContext.timestamp).toLocaleTimeString()}`, "info");
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
console.log("[Context-Aware] Extension loaded");
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=context-aware-extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-aware-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/context-aware-extension.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Pruning Extension
|
|
3
|
+
*
|
|
4
|
+
* Adapted from OpenClaw - intelligent context window management
|
|
5
|
+
* Features:
|
|
6
|
+
* - Soft trimming: keeps head+tail of large tool results
|
|
7
|
+
* - Hard clearing: removes old tool results entirely
|
|
8
|
+
* - Image protection: never prunes results with images
|
|
9
|
+
* - Cache TTL: avoids unnecessary pruning
|
|
10
|
+
*
|
|
11
|
+
* NOTE: This extension uses @ts-ignore for SessionManager methods that exist
|
|
12
|
+
* at runtime but are missing from type definitions:
|
|
13
|
+
* - ExtensionContext.sessionManager.getCurrentSession(): Returns current session
|
|
14
|
+
* - Session.getConfig(key): Gets session-specific config
|
|
15
|
+
* - Session.setConfig(key, value): Sets session-specific config
|
|
16
|
+
* - Session.getExtensionRuntime(key): Gets extension runtime state
|
|
17
|
+
* - Session.setExtensionRuntime(key, value): Sets extension runtime state
|
|
18
|
+
*
|
|
19
|
+
* These are available in pi-coding-agent runtime but types are incomplete.
|
|
20
|
+
* Tracked: Extension API needs ReadonlySessionManager → Session type cast.
|
|
21
|
+
*/
|
|
22
|
+
import { pruneContextMessages } from "./pruner.js";
|
|
23
|
+
import { getContextPruningRuntime, setContextPruningRuntime } from "./runtime.js";
|
|
24
|
+
import { computeEffectiveSettings } from "./settings.js";
|
|
25
|
+
export { pruneContextMessages } from "./pruner.js";
|
|
26
|
+
export { computeEffectiveSettings, DEFAULT_CONTEXT_PRUNING_SETTINGS, } from "./settings.js";
|
|
27
|
+
export default function contextPruningExtension(api) {
|
|
28
|
+
console.log("[ContextPruning] Extension loaded");
|
|
29
|
+
api.on("context", (event, ctx) => {
|
|
30
|
+
// Get or initialize runtime
|
|
31
|
+
// @ts-ignore - sessionManager type mismatch
|
|
32
|
+
let runtime = getContextPruningRuntime(ctx.sessionManager);
|
|
33
|
+
// First time - try to load from session config
|
|
34
|
+
if (!runtime) {
|
|
35
|
+
// @ts-ignore - getCurrentSession doesn't exist on ReadonlySessionManager
|
|
36
|
+
const session = ctx.sessionManager.getCurrentSession?.();
|
|
37
|
+
// @ts-ignore - getConfig doesn't exist
|
|
38
|
+
const rawConfig = session?.getConfig?.("contextPruning") ?? session?.contextPruning;
|
|
39
|
+
const settings = computeEffectiveSettings(rawConfig);
|
|
40
|
+
if (!settings) {
|
|
41
|
+
return undefined; // Pruning disabled
|
|
42
|
+
}
|
|
43
|
+
runtime = { settings };
|
|
44
|
+
// @ts-ignore - sessionManager type mismatch
|
|
45
|
+
setContextPruningRuntime(ctx.sessionManager, runtime);
|
|
46
|
+
}
|
|
47
|
+
// Check TTL cache mode
|
|
48
|
+
if (runtime.settings.mode === "cache-ttl") {
|
|
49
|
+
const ttlMs = runtime.settings.ttlMs;
|
|
50
|
+
const lastTouch = runtime.lastCacheTouchAt ?? null;
|
|
51
|
+
if (!lastTouch || ttlMs <= 0) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
if (ttlMs > 0 && Date.now() - lastTouch < ttlMs) {
|
|
55
|
+
return undefined; // Cache still valid, skip pruning
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Perform pruning
|
|
59
|
+
const next = pruneContextMessages({
|
|
60
|
+
messages: event.messages,
|
|
61
|
+
settings: runtime.settings,
|
|
62
|
+
ctx,
|
|
63
|
+
contextWindowTokensOverride: runtime.contextWindowTokens ?? undefined,
|
|
64
|
+
});
|
|
65
|
+
// No changes needed
|
|
66
|
+
if (next === event.messages) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
// Update cache timestamp
|
|
70
|
+
if (runtime.settings.mode === "cache-ttl") {
|
|
71
|
+
runtime.lastCacheTouchAt = Date.now();
|
|
72
|
+
// @ts-ignore - sessionManager type mismatch
|
|
73
|
+
setContextPruningRuntime(ctx.sessionManager, runtime);
|
|
74
|
+
}
|
|
75
|
+
return { messages: next };
|
|
76
|
+
});
|
|
77
|
+
// Command to configure pruning
|
|
78
|
+
api.registerCommand?.("pruning-config", {
|
|
79
|
+
description: "Configure context pruning settings",
|
|
80
|
+
// @ts-ignore - handler return type
|
|
81
|
+
handler: async (args, ctx) => {
|
|
82
|
+
const parts = args.trim().split(" ");
|
|
83
|
+
const subcommand = parts[0];
|
|
84
|
+
if (subcommand === "status") {
|
|
85
|
+
// @ts-ignore - sessionManager type mismatch
|
|
86
|
+
const runtime = getContextPruningRuntime(ctx.sessionManager);
|
|
87
|
+
if (!runtime) {
|
|
88
|
+
ctx.ui.notify("Context pruning: disabled", "info");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const s = runtime.settings;
|
|
92
|
+
const lines = [
|
|
93
|
+
"Context Pruning Status:",
|
|
94
|
+
` Mode: ${s.mode}`,
|
|
95
|
+
` TTL: ${s.ttlMs / 1000}s`,
|
|
96
|
+
` Keep last assistants: ${s.keepLastAssistants}`,
|
|
97
|
+
` Soft trim ratio: ${(s.softTrimRatio * 100).toFixed(0)}%`,
|
|
98
|
+
` Hard clear ratio: ${(s.hardClearRatio * 100).toFixed(0)}%`,
|
|
99
|
+
];
|
|
100
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (subcommand === "disable") {
|
|
104
|
+
// @ts-ignore - getCurrentSession doesn't exist
|
|
105
|
+
const session = ctx.sessionManager.getCurrentSession?.();
|
|
106
|
+
if (session?.setConfig) {
|
|
107
|
+
session.setConfig("contextPruning", { mode: "off" });
|
|
108
|
+
}
|
|
109
|
+
// @ts-ignore - sessionManager type mismatch
|
|
110
|
+
const runtime = getContextPruningRuntime(ctx.sessionManager);
|
|
111
|
+
if (runtime) {
|
|
112
|
+
// @ts-ignore - sessionManager type mismatch
|
|
113
|
+
setContextPruningRuntime(ctx.sessionManager, {
|
|
114
|
+
settings: { ...runtime.settings, mode: "cache-ttl" }
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
ctx.ui.notify("Context pruning disabled", "info");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
ctx.ui.notify("Usage: /pruning-config [status|disable]", "error");
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../../../src/extensions/core/context-pruning/extension.ts"],"names":[],"mappings":"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"}
|