@nikcli-ai/plugin-context-analysis 0.0.6
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/dist/index.d.ts +15 -0
- package/dist/index.js +88 -0
- package/package.json +31 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Plugin } from "@nikcli-ai/plugin";
|
|
2
|
+
/**
|
|
3
|
+
* Context Analysis
|
|
4
|
+
*
|
|
5
|
+
* Tracks message count, estimated token usage, and per-tool call counts
|
|
6
|
+
* across the current session. Exposes a `context_stats` tool for inspection.
|
|
7
|
+
*
|
|
8
|
+
* Options:
|
|
9
|
+
* warnAt — emit a warning in tool output when estimated tokens exceed this (default: disabled)
|
|
10
|
+
*/
|
|
11
|
+
export declare const ContextAnalysisPlugin: Plugin;
|
|
12
|
+
declare const _default: {
|
|
13
|
+
server: Plugin;
|
|
14
|
+
};
|
|
15
|
+
export default _default;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { tool } from "@nikcli-ai/plugin";
|
|
2
|
+
const stats = {
|
|
3
|
+
messageCount: 0,
|
|
4
|
+
estimatedTokens: 0,
|
|
5
|
+
toolCallCounts: {},
|
|
6
|
+
sessionStart: Date.now(),
|
|
7
|
+
lastUpdated: Date.now(),
|
|
8
|
+
};
|
|
9
|
+
function estimateTokens(text) {
|
|
10
|
+
return Math.ceil(text.length / 4);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Context Analysis
|
|
14
|
+
*
|
|
15
|
+
* Tracks message count, estimated token usage, and per-tool call counts
|
|
16
|
+
* across the current session. Exposes a `context_stats` tool for inspection.
|
|
17
|
+
*
|
|
18
|
+
* Options:
|
|
19
|
+
* warnAt — emit a warning in tool output when estimated tokens exceed this (default: disabled)
|
|
20
|
+
*/
|
|
21
|
+
export const ContextAnalysisPlugin = async (_input, options) => {
|
|
22
|
+
const warnAt = options?.warnAt;
|
|
23
|
+
return {
|
|
24
|
+
"experimental.chat.messages.transform": async (_input, output) => {
|
|
25
|
+
const { messages } = output;
|
|
26
|
+
stats.messageCount = messages.length;
|
|
27
|
+
stats.lastUpdated = Date.now();
|
|
28
|
+
let totalChars = 0;
|
|
29
|
+
const toolCounts = {};
|
|
30
|
+
for (const msg of messages) {
|
|
31
|
+
for (const part of msg.parts) {
|
|
32
|
+
const p = part;
|
|
33
|
+
if (p.type === "text" && typeof p.text === "string") {
|
|
34
|
+
totalChars += p.text.length;
|
|
35
|
+
}
|
|
36
|
+
if (p.type === "tool") {
|
|
37
|
+
const toolName = p.tool;
|
|
38
|
+
if (toolName) {
|
|
39
|
+
toolCounts[toolName] = (toolCounts[toolName] ?? 0) + 1;
|
|
40
|
+
}
|
|
41
|
+
const state = p.state;
|
|
42
|
+
if (state?.status === "completed" && typeof state.output === "string") {
|
|
43
|
+
totalChars += state.output.length;
|
|
44
|
+
}
|
|
45
|
+
if (state?.input) {
|
|
46
|
+
totalChars += JSON.stringify(state.input).length;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (p.type === "reasoning" && typeof p.text === "string") {
|
|
50
|
+
totalChars += p.text.length;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
stats.estimatedTokens = estimateTokens(String(totalChars));
|
|
55
|
+
stats.toolCallCounts = toolCounts;
|
|
56
|
+
},
|
|
57
|
+
tool: {
|
|
58
|
+
context_stats: tool({
|
|
59
|
+
description: "Show current context usage statistics: message count, estimated tokens, and tool call breakdown.",
|
|
60
|
+
args: {},
|
|
61
|
+
async execute() {
|
|
62
|
+
const elapsed = Math.floor((Date.now() - stats.sessionStart) / 1000);
|
|
63
|
+
const topTools = Object.entries(stats.toolCallCounts)
|
|
64
|
+
.sort(([, a], [, b]) => b - a)
|
|
65
|
+
.slice(0, 10)
|
|
66
|
+
.map(([name, count]) => ` ${name}: ${count}`);
|
|
67
|
+
const lines = [
|
|
68
|
+
`Context Analysis`,
|
|
69
|
+
` Messages: ${stats.messageCount}`,
|
|
70
|
+
` Estimated tokens: ~${stats.estimatedTokens.toLocaleString()}`,
|
|
71
|
+
` Session age: ${elapsed}s`,
|
|
72
|
+
];
|
|
73
|
+
if (topTools.length > 0) {
|
|
74
|
+
lines.push(` Top tool calls:`);
|
|
75
|
+
lines.push(...topTools);
|
|
76
|
+
}
|
|
77
|
+
if (warnAt && stats.estimatedTokens > warnAt) {
|
|
78
|
+
lines.push(``);
|
|
79
|
+
lines.push(` ⚠ Token estimate (${stats.estimatedTokens.toLocaleString()}) exceeds warning threshold (${warnAt.toLocaleString()})`);
|
|
80
|
+
lines.push(` Consider using dynamic-context-pruning or starting a new session.`);
|
|
81
|
+
}
|
|
82
|
+
return lines.join("\n");
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
export default { server: ContextAnalysisPlugin };
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "@nikcli-ai/plugin-context-analysis",
|
|
4
|
+
"version": "0.0.6",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"description": "Token usage analytics and context size tracking",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"exports": {
|
|
16
|
+
".": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc --project tsconfig.json"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@tsconfig/node22": "22.0.2",
|
|
27
|
+
"@types/node": "22.13.9",
|
|
28
|
+
"typescript": "5.8.2",
|
|
29
|
+
"@nikcli-ai/plugin": "0.0.6"
|
|
30
|
+
}
|
|
31
|
+
}
|