0xkobold 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +59 -5
  2. package/dist/package.json +7 -5
  3. package/dist/src/cli/commands/setup.js +144 -0
  4. package/dist/src/cli/commands/setup.js.map +1 -0
  5. package/dist/src/cli/program.js +3 -0
  6. package/dist/src/cli/program.js.map +1 -1
  7. package/dist/src/extensions/core/auto-compact-on-error-extension.js +244 -0
  8. package/dist/src/extensions/core/auto-compact-on-error-extension.js.map +1 -0
  9. package/dist/src/extensions/core/diagnostics-extension.js +215 -0
  10. package/dist/src/extensions/core/diagnostics-extension.js.map +1 -0
  11. package/dist/src/extensions/core/extension-scaffold-extension.js +449 -0
  12. package/dist/src/extensions/core/extension-scaffold-extension.js.map +1 -0
  13. package/dist/src/extensions/core/git-commit-extension.js +527 -0
  14. package/dist/src/extensions/core/git-commit-extension.js.map +1 -0
  15. package/dist/src/extensions/core/heartbeat-extension.js +43 -0
  16. package/dist/src/extensions/core/heartbeat-extension.js.map +1 -1
  17. package/dist/src/extensions/core/memory-extension.js +120 -0
  18. package/dist/src/extensions/core/memory-extension.js.map +1 -0
  19. package/dist/src/extensions/core/memory-synthesis-extension.js +137 -0
  20. package/dist/src/extensions/core/memory-synthesis-extension.js.map +1 -0
  21. package/dist/src/extensions/core/mode-manager-extension.js +19 -0
  22. package/dist/src/extensions/core/mode-manager-extension.js.map +1 -1
  23. package/dist/src/extensions/core/ollama-cloud-extension.js +132 -0
  24. package/dist/src/extensions/core/ollama-cloud-extension.js.map +1 -0
  25. package/dist/src/extensions/core/ollama-router-extension.js +100 -0
  26. package/dist/src/extensions/core/ollama-router-extension.js.map +1 -0
  27. package/dist/src/extensions/core/perennial-memory-extension.js +449 -0
  28. package/dist/src/extensions/core/perennial-memory-extension.js.map +1 -0
  29. package/dist/src/index.js +7 -0
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/llm/ollama.js +80 -9
  32. package/dist/src/llm/ollama.js.map +1 -1
  33. package/package.json +7 -5
  34. package/scripts/postinstall.js +71 -0
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Diagnostics Extension - Telemetry and Health Monitoring
3
+ *
4
+ * Provides:
5
+ * - Token usage tracking per provider
6
+ * - Cost estimation
7
+ * - Health check aggregation
8
+ * - Prometheus metrics endpoint
9
+ * - /diagnostics dashboard
10
+ *
11
+ * Inspiration: OpenClaw's diagnostics-otel (simplified)
12
+ */
13
+ import { Database } from "bun:sqlite";
14
+ import { Type } from "@sinclair/typebox";
15
+ import * as fs from "node:fs/promises";
16
+ import * as path from "node:path";
17
+ import { homedir } from "node:os";
18
+ const DIAGNOSTICS_DIR = path.join(homedir(), ".0xkobold", "diagnostics");
19
+ const DB_PATH = path.join(DIAGNOSTICS_DIR, "metrics.db");
20
+ async function initDb() {
21
+ await fs.mkdir(DIAGNOSTICS_DIR, { recursive: true });
22
+ const db = new Database(DB_PATH);
23
+ db.exec("PRAGMA journal_mode = WAL;");
24
+ db.exec(`
25
+ CREATE TABLE IF NOT EXISTS token_metrics (
26
+ id TEXT PRIMARY KEY,
27
+ timestamp TEXT NOT NULL,
28
+ provider TEXT NOT NULL,
29
+ model TEXT,
30
+ tokens_sent INTEGER DEFAULT 0,
31
+ tokens_received INTEGER DEFAULT 0,
32
+ duration_ms INTEGER DEFAULT 0,
33
+ cost REAL DEFAULT 0,
34
+ session_id TEXT
35
+ );
36
+
37
+ CREATE INDEX IF NOT EXISTS idx_metrics_time ON token_metrics(timestamp);
38
+ CREATE INDEX IF NOT EXISTS idx_metrics_provider ON token_metrics(provider);
39
+ CREATE INDEX IF NOT EXISTS idx_metrics_session ON token_metrics(session_id);
40
+
41
+ CREATE TABLE IF NOT EXISTS health_checks (
42
+ id TEXT PRIMARY KEY,
43
+ timestamp TEXT NOT NULL,
44
+ name TEXT NOT NULL,
45
+ status TEXT NOT NULL,
46
+ message TEXT,
47
+ latency_ms INTEGER
48
+ );
49
+
50
+ CREATE INDEX IF NOT EXISTS idx_health_time ON health_checks(timestamp);
51
+ `);
52
+ return db;
53
+ }
54
+ export default function diagnosticsExtension(pi) {
55
+ console.log("[Diagnostics] Loading...");
56
+ let db;
57
+ initDb().then((d) => { db = d; console.log("[Diagnostics] Ready"); });
58
+ // Track metrics on turn_end
59
+ pi.on("turn_end", async (event, ctx) => {
60
+ if (!db)
61
+ return;
62
+ const config = ctx.config || {};
63
+ const provider = config.llm?.provider || "unknown";
64
+ const model = config.llm?.model || "unknown";
65
+ const tokensSent = event.tokenUsage?.sent || 0;
66
+ const tokensReceived = event.tokenUsage?.received || 0;
67
+ // Cost estimation (simplified)
68
+ let cost = 0;
69
+ if (provider === "ollama-cloud") {
70
+ cost = ((tokensSent + tokensReceived) / 1000) * 0.001; // $0.001 per 1K tokens
71
+ }
72
+ db.query(`
73
+ INSERT INTO token_metrics (id, timestamp, provider, model, tokens_sent, tokens_received, duration_ms, cost, session_id)
74
+ VALUES (?, datetime('now'), ?, ?, ?, ?, 0, ?, ?)
75
+ `).run("metric-" + Date.now(), provider, model, tokensSent, tokensReceived, cost, ctx.sessionManager?.getSessionId?.());
76
+ });
77
+ // TOOL: Get metrics
78
+ pi.registerTool({
79
+ name: "diagnostics_metrics",
80
+ label: "Get Metrics",
81
+ description: "Get token usage and cost metrics for a time period",
82
+ parameters: Type.Object({
83
+ since: Type.Optional(Type.String({ description: "Period: 1h, 1d, 7d, 30d" })),
84
+ provider: Type.Optional(Type.String({ description: "Filter by provider" })),
85
+ }),
86
+ async execute(_id, params) {
87
+ if (!db)
88
+ throw new Error("Diagnostics DB not ready");
89
+ const since = (params.since || "1d");
90
+ let sinceSql = "1 day";
91
+ if (since === "1h")
92
+ sinceSql = "1 hour";
93
+ else if (since === "7d")
94
+ sinceSql = "7 days";
95
+ else if (since === "30d")
96
+ sinceSql = "30 days";
97
+ const provider = params.provider;
98
+ const query = db.query(`
99
+ SELECT
100
+ provider,
101
+ COUNT(*) as requests,
102
+ SUM(tokens_sent) as tokens_sent,
103
+ SUM(tokens_received) as tokens_received,
104
+ SUM(cost) as total_cost
105
+ FROM token_metrics
106
+ WHERE timestamp > datetime('now', '-${sinceSql}')
107
+ ${provider ? "AND provider = ?" : ""}
108
+ GROUP BY provider
109
+ `);
110
+ const rows = (provider ? query.all(provider) : query.all());
111
+ const totalTokens = rows.reduce((sum, r) => sum + r.tokens_sent + r.tokens_received, 0);
112
+ const totalCost = rows.reduce((sum, r) => sum + r.total_cost, 0);
113
+ const totalRequests = rows.reduce((sum, r) => sum + r.requests, 0);
114
+ const formatted = rows.map(r => `${r.provider}: ${r.requests} req, ${r.tokens_sent + r.tokens_received} tokens, $${r.total_cost.toFixed(4)}`).join("\n");
115
+ return {
116
+ content: [{
117
+ type: "text",
118
+ text: `📊 Metrics (last ${since}):\n${formatted}\n\nTotal: ${totalRequests} req, ${totalTokens} tokens, $${totalCost.toFixed(4)}`,
119
+ }],
120
+ details: { period: since, providers: rows, totalTokens, totalCost },
121
+ };
122
+ },
123
+ });
124
+ // TOOL: Health check
125
+ pi.registerTool({
126
+ name: "diagnostics_health",
127
+ label: "Health Check",
128
+ description: "Check health of all 0xKobold systems",
129
+ parameters: Type.Object({}),
130
+ async execute() {
131
+ const checks = [];
132
+ // Check database
133
+ try {
134
+ db.query("SELECT 1").get();
135
+ checks.push({ ts: new Date().toISOString(), name: "diagnostics_db", status: "healthy", latency: 1 });
136
+ }
137
+ catch (e) {
138
+ checks.push({ ts: new Date().toISOString(), name: "diagnostics_db", status: "error", message: String(e) });
139
+ }
140
+ // Check memory system
141
+ try {
142
+ const memDb = path.join(homedir(), ".0xkobold", "memory", "perennial", "knowledge.db");
143
+ await fs.access(memDb);
144
+ checks.push({ ts: new Date().toISOString(), name: "memory_system", status: "healthy" });
145
+ }
146
+ catch {
147
+ checks.push({ ts: new Date().toISOString(), name: "memory_system", status: "warning", message: "No memories yet" });
148
+ }
149
+ const unhealthy = checks.filter(c => c.status === "error").length;
150
+ const status = unhealthy === 0 ? "✅ All systems healthy" : `❌ ${unhealthy} systems unhealthy`;
151
+ const formatted = checks.map(c => `${c.status === "healthy" ? "✅" : c.status === "warning" ? "⚠️" : "❌"} ${c.name}: ${c.status}`).join("\n");
152
+ return {
153
+ content: [{ type: "text", text: `${status}\n\n${formatted}` }],
154
+ details: { checks, healthy: unhealthy === 0 },
155
+ };
156
+ },
157
+ });
158
+ // COMMAND: /diagnostics
159
+ pi.registerCommand("diagnostics", {
160
+ description: "Show health dashboard: /diagnostics",
161
+ handler: async (_args, ctx) => {
162
+ // Quick health check
163
+ const checks = [];
164
+ try {
165
+ if (db) {
166
+ db.query("SELECT 1").get();
167
+ checks.push("✅ Diagnostics DB: OK");
168
+ }
169
+ }
170
+ catch {
171
+ checks.push("❌ Diagnostics DB: Error");
172
+ }
173
+ try {
174
+ const memDb = path.join(homedir(), ".0xkobold", "memory", "perennial", "knowledge.db");
175
+ await fs.access(memDb);
176
+ checks.push("✅ Memory System: OK");
177
+ }
178
+ catch {
179
+ checks.push("⚠️ Memory System: Not initialized");
180
+ }
181
+ // Get today's metrics
182
+ let metrics = "No metrics yet";
183
+ if (db) {
184
+ const row = db.query(`
185
+ SELECT SUM(tokens_sent + tokens_received) as tokens, SUM(cost) as cost
186
+ FROM token_metrics
187
+ WHERE timestamp > datetime('now', 'start of day')
188
+ `).get();
189
+ if (row && row.tokens) {
190
+ metrics = `Today: ${row.tokens} tokens, $${(row.cost || 0).toFixed(4)}`;
191
+ }
192
+ }
193
+ ctx.ui.notify([
194
+ "📊 0xKobold Diagnostics",
195
+ "",
196
+ ...checks,
197
+ "",
198
+ metrics,
199
+ "",
200
+ "Commands:",
201
+ " /metrics 1h|1d|7d - Show token usage",
202
+ " /export-metrics - Export to CSV",
203
+ ].join("\n"), "info");
204
+ },
205
+ });
206
+ // COMMAND: /metrics
207
+ pi.registerCommand("metrics", {
208
+ description: "Show token metrics: /metrics 1d",
209
+ handler: async (args, ctx) => {
210
+ const period = args.trim() || "1d";
211
+ ctx.ui.notify(`📊 Showing metrics for ${period}...\nUse /diagnostics for health check.`, "info");
212
+ },
213
+ });
214
+ }
215
+ //# sourceMappingURL=diagnostics-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/diagnostics-extension.ts"],"names":[],"mappings":"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"}