clawkit-ai 1.1.1 → 1.1.3
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/package.json +13 -3
- package/src/sync.mjs +60 -25
package/package.json
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawkit-ai",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Transform your OpenClaw agent into a production-ready AI assistant with memory, skills, and a dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"clawkit": "./bin/clawkit.mjs"
|
|
8
8
|
},
|
|
9
|
-
"keywords": [
|
|
9
|
+
"keywords": [
|
|
10
|
+
"openclaw",
|
|
11
|
+
"ai",
|
|
12
|
+
"agent",
|
|
13
|
+
"skills",
|
|
14
|
+
"memory",
|
|
15
|
+
"dashboard",
|
|
16
|
+
"clawkit"
|
|
17
|
+
],
|
|
10
18
|
"author": "ClawKit",
|
|
11
19
|
"license": "MIT",
|
|
12
|
-
"engines": {
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18"
|
|
22
|
+
},
|
|
13
23
|
"dependencies": {}
|
|
14
24
|
}
|
package/src/sync.mjs
CHANGED
|
@@ -149,6 +149,14 @@ function applyPendingChanges(workspace, changes, quiet) {
|
|
|
149
149
|
if (change.type === 'model_switch' && change.model) {
|
|
150
150
|
if (!quiet) log.info(`Model switch requested: ${change.model} (agent should pick this up)`);
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
if (change.type === 'clear_context' || (change.type === 'preferences_update' && change.preferences?.clearContext)) {
|
|
154
|
+
const flagPath = join(workspace, 'logs', 'clear-context.flag');
|
|
155
|
+
const logsDir = join(workspace, 'logs');
|
|
156
|
+
if (!existsSync(logsDir)) mkdirSync(logsDir, { recursive: true });
|
|
157
|
+
writeFileSync(flagPath, JSON.stringify({ requested: change.timestamp || new Date().toISOString(), source: 'dashboard' }));
|
|
158
|
+
if (!quiet) log.ok('Clear context requested — flag written to logs/clear-context.flag');
|
|
159
|
+
}
|
|
152
160
|
}
|
|
153
161
|
|
|
154
162
|
if (toolsChanged) writeFileSync(toolsPath, tools);
|
|
@@ -424,33 +432,60 @@ function gatherState(workspace) {
|
|
|
424
432
|
state.agentActivity = 'Waiting for instructions';
|
|
425
433
|
}
|
|
426
434
|
|
|
427
|
-
// --- Token Usage & Cost ---
|
|
428
|
-
state.usage = { inputTokens: 0, outputTokens: 0, contextUsed: 0, contextMax: 0, costEstimate: '', model: '', compactions: 0 };
|
|
429
|
-
|
|
430
|
-
//
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
435
|
+
// --- Token Usage & Cost + Context Breakdown ---
|
|
436
|
+
state.usage = { inputTokens: 0, outputTokens: 0, contextUsed: 0, contextMax: 0, costEstimate: '', model: '', compactions: 0, breakdown: [] };
|
|
437
|
+
|
|
438
|
+
// Calculate context breakdown from injected workspace files
|
|
439
|
+
const injectedFiles = ['AGENTS.md', 'SOUL.md', 'TOOLS.md', 'IDENTITY.md', 'USER.md', 'HEARTBEAT.md', 'MEMORY.md'];
|
|
440
|
+
let totalFileTokens = 0;
|
|
441
|
+
const breakdown = [];
|
|
442
|
+
|
|
443
|
+
for (const fname of injectedFiles) {
|
|
444
|
+
const fpath = join(workspace, fname);
|
|
445
|
+
if (existsSync(fpath)) {
|
|
446
|
+
const bytes = statSync(fpath).size;
|
|
447
|
+
const tokens = Math.round(bytes / 4); // ~4 chars per token
|
|
448
|
+
totalFileTokens += tokens;
|
|
449
|
+
breakdown.push({ label: fname.replace('.md', ''), tokens });
|
|
437
450
|
}
|
|
438
|
-
}
|
|
451
|
+
}
|
|
439
452
|
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
453
|
+
// Add estimates for system prompt and tools
|
|
454
|
+
breakdown.push({ label: 'System Prompt', tokens: 3000 });
|
|
455
|
+
breakdown.push({ label: 'Tool Definitions', tokens: 2000 });
|
|
456
|
+
breakdown.push({ label: 'Skills List', tokens: 1500 });
|
|
457
|
+
totalFileTokens += 6500;
|
|
458
|
+
|
|
459
|
+
// Sort by size descending
|
|
460
|
+
breakdown.sort((a, b) => b.tokens - a.tokens);
|
|
461
|
+
state.usage.breakdown = breakdown;
|
|
462
|
+
state.usage.systemTokens = totalFileTokens;
|
|
463
|
+
|
|
464
|
+
// Read context stats from logs/context-stats.json (updated by agent)
|
|
465
|
+
const ctxStatsPath = join(workspace, 'logs', 'context-stats.json');
|
|
466
|
+
if (existsSync(ctxStatsPath)) {
|
|
467
|
+
try {
|
|
468
|
+
const cs = JSON.parse(readFileSync(ctxStatsPath, 'utf8'));
|
|
469
|
+
state.usage.model = cs.model || state.usage.model;
|
|
470
|
+
state.usage.inputTokens = cs.inputTokens || 0;
|
|
471
|
+
state.usage.outputTokens = cs.outputTokens || 0;
|
|
472
|
+
state.usage.contextUsed = cs.contextUsed || 0;
|
|
473
|
+
state.usage.contextMax = cs.contextMax || 0;
|
|
474
|
+
state.usage.compactions = cs.compactions || 0;
|
|
475
|
+
} catch {}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Fallback: read model from gateway config
|
|
479
|
+
if (!state.usage.model) {
|
|
480
|
+
try {
|
|
481
|
+
const gwPath = join(process.env.HOME || '', '.openclaw', 'openclaw.json');
|
|
482
|
+
if (existsSync(gwPath)) {
|
|
483
|
+
const gw = JSON.parse(readFileSync(gwPath, 'utf8'));
|
|
484
|
+
const primary = gw.agents?.defaults?.model?.primary;
|
|
485
|
+
if (primary) state.usage.model = primary;
|
|
486
|
+
}
|
|
487
|
+
} catch {}
|
|
488
|
+
}
|
|
454
489
|
|
|
455
490
|
// If we couldn't get from CLI, estimate from daily note sizes
|
|
456
491
|
if (!state.usage.model) {
|