@nexagent-cli/cli 0.3.1 → 0.5.0
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/README.md +117 -9
- package/dist/agent/loop.d.ts +2 -0
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +59 -27
- package/dist/agent/loop.js.map +1 -1
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +3 -1
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/completion.d.ts +2 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +287 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +221 -12
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +1 -0
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/server.js +1 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/session.d.ts +1 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +72 -1
- package/dist/commands/session.js.map +1 -1
- package/dist/config/loader.js +2 -2
- package/dist/config/loader.js.map +1 -1
- package/dist/db/database.js +96 -79
- package/dist/db/database.js.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/llm/providers/anthropic.d.ts +1 -1
- package/dist/llm/providers/anthropic.d.ts.map +1 -1
- package/dist/llm/providers/anthropic.js.map +1 -1
- package/dist/llm/providers/google.d.ts +1 -0
- package/dist/llm/providers/google.d.ts.map +1 -1
- package/dist/llm/providers/google.js +3 -0
- package/dist/llm/providers/google.js.map +1 -1
- package/dist/llm/providers/ollama.d.ts +1 -0
- package/dist/llm/providers/ollama.d.ts.map +1 -1
- package/dist/llm/providers/ollama.js +3 -0
- package/dist/llm/providers/ollama.js.map +1 -1
- package/dist/llm/providers/openai.d.ts +1 -1
- package/dist/llm/providers/openai.d.ts.map +1 -1
- package/dist/llm/providers/openai.js.map +1 -1
- package/dist/llm/router.d.ts +1 -0
- package/dist/llm/router.d.ts.map +1 -1
- package/dist/llm/router.js +6 -0
- package/dist/llm/router.js.map +1 -1
- package/dist/mcp/catalog.js +5 -5
- package/dist/mcp/catalog.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/installer.d.ts.map +1 -1
- package/dist/mcp/installer.js +13 -1
- package/dist/mcp/installer.js.map +1 -1
- package/dist/mcp/registry.d.ts +1 -1
- package/dist/mcp/registry.d.ts.map +1 -1
- package/dist/mcp/registry.js +8 -3
- package/dist/mcp/registry.js.map +1 -1
- package/dist/mcp/templates.d.ts +6 -0
- package/dist/mcp/templates.d.ts.map +1 -0
- package/dist/mcp/templates.js +185 -0
- package/dist/mcp/templates.js.map +1 -0
- package/dist/memory/manager.d.ts +5 -1
- package/dist/memory/manager.d.ts.map +1 -1
- package/dist/memory/manager.js +50 -7
- package/dist/memory/manager.js.map +1 -1
- package/dist/tools/custom-loader.d.ts +3 -0
- package/dist/tools/custom-loader.d.ts.map +1 -0
- package/dist/tools/custom-loader.js +119 -0
- package/dist/tools/custom-loader.js.map +1 -0
- package/dist/tools/file-write.d.ts +1 -0
- package/dist/tools/file-write.d.ts.map +1 -1
- package/dist/tools/file-write.js +1 -0
- package/dist/tools/file-write.js.map +1 -1
- package/dist/tools/registry.d.ts +8 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +40 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/shell-exec.d.ts +1 -0
- package/dist/tools/shell-exec.d.ts.map +1 -1
- package/dist/tools/shell-exec.js +28 -1
- package/dist/tools/shell-exec.js.map +1 -1
- package/dist/ui/ChatApp.d.ts +1 -0
- package/dist/ui/ChatApp.d.ts.map +1 -1
- package/dist/ui/ChatApp.js +34 -10
- package/dist/ui/ChatApp.js.map +1 -1
- package/dist/ui/InputBar.d.ts +2 -1
- package/dist/ui/InputBar.d.ts.map +1 -1
- package/dist/ui/InputBar.js +71 -11
- package/dist/ui/InputBar.js.map +1 -1
- package/dist/ui/StatusBar.d.ts +2 -1
- package/dist/ui/StatusBar.d.ts.map +1 -1
- package/dist/ui/StatusBar.js +3 -3
- package/dist/ui/StatusBar.js.map +1 -1
- package/dist/ui/SubagentPanel.d.ts +21 -0
- package/dist/ui/SubagentPanel.d.ts.map +1 -0
- package/dist/ui/SubagentPanel.js +21 -0
- package/dist/ui/SubagentPanel.js.map +1 -0
- package/package.json +77 -76
package/dist/memory/manager.js
CHANGED
|
@@ -58,19 +58,19 @@ export class MemoryManager {
|
|
|
58
58
|
if (blockId) {
|
|
59
59
|
const existing = this.getBlock(blockId);
|
|
60
60
|
if (existing) {
|
|
61
|
-
this.db.prepare(`
|
|
62
|
-
UPDATE memory_blocks
|
|
63
|
-
SET content = ?, version = version + 1, token_estimate = ?, updated_at = ?
|
|
64
|
-
WHERE id = ?
|
|
61
|
+
this.db.prepare(`
|
|
62
|
+
UPDATE memory_blocks
|
|
63
|
+
SET content = ?, version = version + 1, token_estimate = ?, updated_at = ?
|
|
64
|
+
WHERE id = ?
|
|
65
65
|
`).run(content, tokenEstimate, now, blockId);
|
|
66
66
|
return { ...existing, content, version: existing.version + 1, tokenEstimate, updatedAt: now };
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
// Create new block
|
|
70
70
|
const id = blockId ?? generateId();
|
|
71
|
-
this.db.prepare(`
|
|
72
|
-
INSERT INTO memory_blocks (id, agent_name, block_type, content, version, token_estimate, updated_at, pinned, archived, tags)
|
|
73
|
-
VALUES (?, ?, ?, ?, 1, ?, ?, 0, 0, '[]')
|
|
71
|
+
this.db.prepare(`
|
|
72
|
+
INSERT INTO memory_blocks (id, agent_name, block_type, content, version, token_estimate, updated_at, pinned, archived, tags)
|
|
73
|
+
VALUES (?, ?, ?, ?, 1, ?, ?, 0, 0, '[]')
|
|
74
74
|
`).run(id, this.agentName, blockType, content, tokenEstimate, now);
|
|
75
75
|
return {
|
|
76
76
|
id, blockType, content, version: 1,
|
|
@@ -97,6 +97,49 @@ export class MemoryManager {
|
|
|
97
97
|
const rows = this.db.prepare(q).all(this.agentName);
|
|
98
98
|
return rows.map(this.rowToBlock);
|
|
99
99
|
}
|
|
100
|
+
/** Simple keyword search across all memory blocks for this agent */
|
|
101
|
+
search(query) {
|
|
102
|
+
const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 0);
|
|
103
|
+
if (words.length === 0)
|
|
104
|
+
return [];
|
|
105
|
+
const rows = this.db.prepare('SELECT * FROM memory_blocks WHERE agent_name = ? AND archived = 0 ORDER BY updated_at DESC').all(this.agentName);
|
|
106
|
+
const scored = rows.map(row => {
|
|
107
|
+
const block = this.rowToBlock(row);
|
|
108
|
+
const contentLower = block.content.toLowerCase();
|
|
109
|
+
const score = words.reduce((s, w) => s + (contentLower.includes(w) ? 1 : 0), 0);
|
|
110
|
+
return { block, score };
|
|
111
|
+
});
|
|
112
|
+
return scored
|
|
113
|
+
.filter(({ score }) => score > 0)
|
|
114
|
+
.sort((a, b) => {
|
|
115
|
+
if (b.score !== a.score)
|
|
116
|
+
return b.score - a.score;
|
|
117
|
+
return b.block.updatedAt - a.block.updatedAt;
|
|
118
|
+
})
|
|
119
|
+
.slice(0, 20)
|
|
120
|
+
.map(({ block }) => block);
|
|
121
|
+
}
|
|
122
|
+
/** Summarize old memory blocks using an LLM and return the summary */
|
|
123
|
+
async compact(llm, model) {
|
|
124
|
+
const blocks = this.listAll(false);
|
|
125
|
+
if (blocks.length === 0)
|
|
126
|
+
return 'No memory blocks to compact.';
|
|
127
|
+
const context = blocks.map(b => `[${b.blockType}] ${b.content}`).join('\n\n---\n\n');
|
|
128
|
+
const res = await llm.complete({
|
|
129
|
+
model,
|
|
130
|
+
messages: [
|
|
131
|
+
{ role: 'system', content: 'Summarize the following agent memory blocks into a concise recap. Include key facts, learned preferences, and open tasks. Be brief but complete.' },
|
|
132
|
+
{ role: 'user', content: context },
|
|
133
|
+
],
|
|
134
|
+
temperature: 0.3,
|
|
135
|
+
maxTokens: 1024,
|
|
136
|
+
});
|
|
137
|
+
const summary = res.content;
|
|
138
|
+
// Replace old blocks with a single conversation_summary block
|
|
139
|
+
this.db.prepare('DELETE FROM memory_blocks WHERE agent_name = ? AND archived = 0').run(this.agentName);
|
|
140
|
+
this.upsertBlock('conversation_summary', summary);
|
|
141
|
+
return summary;
|
|
142
|
+
}
|
|
100
143
|
rowToBlock(row) {
|
|
101
144
|
return {
|
|
102
145
|
id: row.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/memory/manager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/memory/manager.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sDAAsD;AACtD,mEAAmE;AACnE,+DAA+D;AAI/D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAQlD,MAAM,OAAO,aAAa;IAEd;IACA;IAFV,YACU,EAA4B,EAC5B,SAAiB;QADjB,OAAE,GAAF,EAAE,CAA0B;QAC5B,cAAS,GAAT,SAAS,CAAQ;IACxB,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,OAA0B,EAAE;QACrC,MAAM,EACJ,aAAa,EACb,eAAe,GAAG,KAAK,EACvB,KAAK,GAAa,EAAE,EACpB,WAAW,EACX,QAAQ,GAAU,IAAI,GACvB,GAAG,IAAI,CAAC;QAET,IAAI,KAAK,GAAI,kDAAkD,CAAC;QAChE,MAAM,MAAM,GAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,KAAK,IAAI,mBAAmB,CAAC;QAC/B,CAAC;QAED,KAAK,IAAI,wCAAwC,CAAC;QAElD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAgB,CAAC;QAClE,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEvC,wDAAwD;QACxD,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpF,MAAM,GAAG,MAAM;iBACZ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACT,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACzF,CAAC,CAAC;iBACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACb,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM;oBAAE,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;YAC3B,CAAC,CAAC;iBACD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,qBAAqB;QACrB,IAAI,cAAc,GAAkB,EAAE,CAAC;QACvC,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,cAAc,CAAC,MAAM,IAAI,KAAK;gBAAE,MAAM;YAC1C,IAAI,WAAW,IAAI,UAAU,GAAG,KAAK,CAAC,aAAa,GAAG,WAAW;gBAAE,SAAS;YAC5E,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,UAAU,IAAI,KAAK,CAAC,aAAa,CAAC;QACpC,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,QAAQ,CAAC,OAAe;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACzB,6DAA6D,CAC9D,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAA0B,CAAC;QACxD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAED,WAAW,CAAC,SAA0B,EAAE,OAAe,EAAE,OAAgB;QACvE,MAAM,GAAG,GAAY,IAAI,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEpD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;SAIf,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC7C,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;YAChG,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,MAAM,EAAE,GAAW,OAAO,IAAI,UAAU,EAAE,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;KAGf,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAEnE,OAAO;YACL,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;YAClC,aAAa,EAAE,SAAS,EAAE,GAAG;YAC7B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;SACzC,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC;aACzE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC;aACrF,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,OAAe,EAAE,MAAe;QACvC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,qEAAqE,CAAC;aACnF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,CAAC,eAAe,GAAG,KAAK;QAC7B,MAAM,CAAC,GAAG,eAAe;YACvB,CAAC,CAAC,wFAAwF;YAC1F,CAAC,CAAC,yGAAyG,CAAC;QAC9G,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;QACnE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAED,oEAAoE;IACpE,MAAM,CAAC,KAAa;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAElC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC1B,4FAA4F,CAC7F,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;QAErC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM;aACV,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC;aAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;gBAAE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;YAClD,OAAO,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;QAC/C,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;aACZ,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,OAAO,CAAC,GAAgB,EAAE,KAAa;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,8BAA8B,CAAC;QAE/D,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrF,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC;YAC7B,KAAK;YACL,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,kJAAkJ,EAAE;gBAC/K,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;aACnC;YACD,WAAW,EAAE,GAAG;YAChB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC5B,8DAA8D;QAC9D,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvG,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;QAElD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,UAAU,CAAC,GAAc;QAC/B,OAAO;YACL,EAAE,EAAc,GAAG,CAAC,EAAE;YACtB,SAAS,EAAO,GAAG,CAAC,UAA6B;YACjD,OAAO,EAAS,GAAG,CAAC,OAAO;YAC3B,OAAO,EAAS,GAAG,CAAC,OAAO;YAC3B,aAAa,EAAG,GAAG,CAAC,cAAc;YAClC,SAAS,EAAO,GAAG,CAAC,UAAU;YAC9B,MAAM,EAAU,GAAG,CAAC,MAAM,KAAK,CAAC;YAChC,QAAQ,EAAQ,GAAG,CAAC,QAAQ,KAAK,CAAC;YAClC,IAAI,EAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAa;SACjD,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-loader.d.ts","sourceRoot":"","sources":["../../src/tools/custom-loader.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAyD,MAAM,sBAAsB,CAAC;AAiGxG,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CA6B3E"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Custom Tool Loader — load user-defined tools from .nxagent/tools
|
|
3
|
+
// ============================================================
|
|
4
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
5
|
+
import { join, resolve } from 'node:path';
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { parse as parseYaml } from 'yaml';
|
|
9
|
+
import { generateId } from '@nexagent-cli/shared';
|
|
10
|
+
const CustomToolSchema = z.object({
|
|
11
|
+
id: z.string(),
|
|
12
|
+
name: z.string(),
|
|
13
|
+
description: z.string(),
|
|
14
|
+
version: z.string(),
|
|
15
|
+
parameters: z.custom((val) => typeof val === 'object' && val !== null && 'type' in val && val.type === 'object'),
|
|
16
|
+
permissions: z.array(z.string()),
|
|
17
|
+
riskLevel: z.enum(['low', 'medium', 'high', 'critical']),
|
|
18
|
+
scriptPath: z.string(),
|
|
19
|
+
enabled: z.boolean(),
|
|
20
|
+
});
|
|
21
|
+
class CustomTool {
|
|
22
|
+
name;
|
|
23
|
+
version;
|
|
24
|
+
description;
|
|
25
|
+
parameters;
|
|
26
|
+
permissions;
|
|
27
|
+
riskLevel;
|
|
28
|
+
enabled;
|
|
29
|
+
cacheable = true;
|
|
30
|
+
scriptPath;
|
|
31
|
+
workspaceDir;
|
|
32
|
+
constructor(def, workspaceDir) {
|
|
33
|
+
this.name = def.name;
|
|
34
|
+
this.version = def.version;
|
|
35
|
+
this.description = def.description;
|
|
36
|
+
this.parameters = def.parameters;
|
|
37
|
+
this.permissions = def.permissions;
|
|
38
|
+
this.riskLevel = def.riskLevel;
|
|
39
|
+
this.enabled = def.enabled;
|
|
40
|
+
this.scriptPath = resolve(workspaceDir, def.scriptPath);
|
|
41
|
+
this.workspaceDir = workspaceDir;
|
|
42
|
+
}
|
|
43
|
+
async execute(args, _ctx) {
|
|
44
|
+
const executionId = generateId();
|
|
45
|
+
const start = Date.now();
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const child = spawn(process.execPath, [this.scriptPath], {
|
|
48
|
+
cwd: this.workspaceDir,
|
|
49
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
50
|
+
});
|
|
51
|
+
let stdout = '';
|
|
52
|
+
let stderr = '';
|
|
53
|
+
child.stdout?.on('data', (d) => { stdout += d.toString(); });
|
|
54
|
+
child.stderr?.on('data', (d) => { stderr += d.toString(); });
|
|
55
|
+
child.stdin?.write(JSON.stringify(args));
|
|
56
|
+
child.stdin?.end();
|
|
57
|
+
child.on('close', (code) => {
|
|
58
|
+
const durationMs = Date.now() - start;
|
|
59
|
+
if (code !== 0) {
|
|
60
|
+
resolve({
|
|
61
|
+
success: false,
|
|
62
|
+
output: `Custom tool exited with code ${code}: ${stderr || stdout}`,
|
|
63
|
+
executionId,
|
|
64
|
+
durationMs,
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(stdout);
|
|
70
|
+
resolve({
|
|
71
|
+
success: parsed.success ?? true,
|
|
72
|
+
output: parsed.output ?? stdout,
|
|
73
|
+
data: parsed.data,
|
|
74
|
+
executionId,
|
|
75
|
+
durationMs,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
resolve({
|
|
80
|
+
success: true,
|
|
81
|
+
output: stdout.trim(),
|
|
82
|
+
executionId,
|
|
83
|
+
durationMs,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
child.on('error', (err) => {
|
|
88
|
+
reject(new Error(`Failed to spawn custom tool: ${err.message}`));
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export async function loadCustomTools(workspaceDir) {
|
|
94
|
+
const toolsDir = join(workspaceDir, '.nxagent', 'tools');
|
|
95
|
+
const tools = [];
|
|
96
|
+
try {
|
|
97
|
+
const entries = await readdir(toolsDir, { withFileTypes: true });
|
|
98
|
+
const files = entries.filter(e => e.isFile() && (e.name.endsWith('.json') || e.name.endsWith('.yaml') || e.name.endsWith('.yml')));
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
const raw = await readFile(join(toolsDir, file.name), 'utf-8');
|
|
101
|
+
const parsed = file.name.endsWith('.json') ? JSON.parse(raw) : parseYaml(raw);
|
|
102
|
+
const validated = CustomToolSchema.safeParse(parsed);
|
|
103
|
+
if (!validated.success) {
|
|
104
|
+
console.warn(`[custom-loader] Skipping invalid tool definition ${file.name}:`, validated.error.format());
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
tools.push(new CustomTool(validated.data, workspaceDir));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
if (err.code === 'ENOENT') {
|
|
112
|
+
// No custom tools directory — that's fine
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
return tools;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=custom-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-loader.js","sourceRoot":"","sources":["../../src/tools/custom-loader.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,mEAAmE;AACnE,+DAA+D;AAE/D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,UAAU,EAAE,CAAC,CAAC,MAAM,CAAmB,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,IAAK,GAAW,CAAC,IAAI,KAAK,QAAQ,CAAC;IAC3I,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAChC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACxD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;CACrB,CAAC,CAAC;AAEH,MAAM,UAAU;IACd,IAAI,CAAS;IACb,OAAO,CAAS;IAChB,WAAW,CAAS;IACpB,UAAU,CAAmB;IAC7B,WAAW,CAAwB;IACnC,SAAS,CAAyC;IAClD,OAAO,CAAU;IACjB,SAAS,GAAG,IAAI,CAAC;IAET,UAAU,CAAS;IACnB,YAAY,CAAS;IAE7B,YAAY,GAAqC,EAAE,YAAoB;QACrE,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,WAA2B,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAa,EAAE,IAAiB;QAC5C,MAAM,WAAW,GAAG,UAAU,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,OAAO,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACjD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBACvD,GAAG,EAAE,IAAI,CAAC,YAAY;gBACtB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAChC,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAEhB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACrE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAErE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;YAEnB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;gBACtC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,OAAO,CAAC;wBACN,OAAO,EAAE,KAAK;wBACd,MAAM,EAAE,gCAAgC,IAAI,KAAK,MAAM,IAAI,MAAM,EAAE;wBACnE,WAAW;wBACX,UAAU;qBACX,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAA2D,CAAC;oBAC5F,OAAO,CAAC;wBACN,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;wBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM;wBAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,WAAW;wBACX,UAAU;qBACX,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,CAAC;wBACN,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;wBACrB,WAAW;wBACX,UAAU;qBACX,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,YAAoB;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IACzD,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAEnI,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAC9E,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAErD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,oDAAoD,IAAI,CAAC,IAAI,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzG,SAAS;YACX,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,0CAA0C;YAC1C,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-write.d.ts","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA0G;IACrH,OAAO,UAAY;IACnB,SAAS,EAAK,QAAQ,CAAU;IAChC,WAAW,wBAAyB;IAEpC,UAAU,EAAE,gBAAgB,CAkB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAwC7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CAQpB"}
|
|
1
|
+
{"version":3,"file":"file-write.d.ts","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA0G;IACrH,OAAO,UAAY;IACnB,SAAS,UAAW;IACpB,SAAS,EAAK,QAAQ,CAAU;IAChC,WAAW,wBAAyB;IAEpC,UAAU,EAAE,gBAAgB,CAkB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAwC7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CAQpB"}
|
package/dist/tools/file-write.js
CHANGED
|
@@ -12,6 +12,7 @@ export class FileWriteTool {
|
|
|
12
12
|
version = '1.0.0';
|
|
13
13
|
description = 'Write content to a file atomically. Creates parent directories as needed. Overwrites existing files.';
|
|
14
14
|
enabled = true;
|
|
15
|
+
cacheable = false;
|
|
15
16
|
riskLevel = 'medium';
|
|
16
17
|
permissions = ['fs:write'];
|
|
17
18
|
parameters = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-write.js","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-write.js","sourceRoot":"","sources":["../../src/tools/file-write.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import type { Tool, LLMToolDefinition } from '@nexagent-cli/shared';
|
|
1
|
+
import type { Tool, LLMToolDefinition, ToolContext, ToolResult } from '@nexagent-cli/shared';
|
|
2
2
|
export declare class ToolRegistry {
|
|
3
3
|
private tools;
|
|
4
|
+
private cache;
|
|
4
5
|
register(tool: Tool): void;
|
|
5
6
|
get(name: string): Tool | undefined;
|
|
6
7
|
list(): Tool[];
|
|
7
8
|
/** Convert registered tools to LLM function-call format */
|
|
8
9
|
toToolDefinitions(allowList: string[], blockList: string[]): LLMToolDefinition[];
|
|
10
|
+
/** Execute a tool with result caching */
|
|
11
|
+
executeWithCache(toolName: string, args: unknown, context: ToolContext): Promise<ToolResult>;
|
|
12
|
+
/** Clear the entire tool result cache */
|
|
13
|
+
clearCache(): void;
|
|
14
|
+
/** Invalidate cached results for a specific tool */
|
|
15
|
+
invalidateCache(toolName: string): void;
|
|
9
16
|
}
|
|
10
17
|
/** Create a pre-loaded registry with all default tools */
|
|
11
18
|
export declare function createDefaultRegistry(): Promise<ToolRegistry>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAkB,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAK7G,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAInC,IAAI,IAAI,IAAI,EAAE;IAId,2DAA2D;IAC3D,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE;IAkBhF,yCAAyC;IACnC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IA8BlG,yCAAyC;IACzC,UAAU,IAAI,IAAI;IAIlB,oDAAoD;IACpD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAOxC;AAED,0DAA0D;AAC1D,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,YAAY,CAAC,CAyCnE"}
|
package/dist/tools/registry.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// ============================================================
|
|
2
2
|
// Tool Registry — central registration and lookup
|
|
3
3
|
// ============================================================
|
|
4
|
+
const DEFAULT_CACHE_TTL_MS = 60_000;
|
|
5
|
+
const NEVER_CACHE_TOOLS = new Set(['shell_exec', 'file_write']);
|
|
4
6
|
export class ToolRegistry {
|
|
5
7
|
tools = new Map();
|
|
8
|
+
cache = new Map();
|
|
6
9
|
register(tool) {
|
|
7
10
|
this.tools.set(tool.name, tool);
|
|
8
11
|
}
|
|
@@ -33,6 +36,43 @@ export class ToolRegistry {
|
|
|
33
36
|
},
|
|
34
37
|
}));
|
|
35
38
|
}
|
|
39
|
+
/** Execute a tool with result caching */
|
|
40
|
+
async executeWithCache(toolName, args, context) {
|
|
41
|
+
const tool = this.tools.get(toolName);
|
|
42
|
+
if (!tool) {
|
|
43
|
+
throw new Error(`Unknown tool: "${toolName}"`);
|
|
44
|
+
}
|
|
45
|
+
const cacheable = tool.cacheable !== false && !NEVER_CACHE_TOOLS.has(toolName);
|
|
46
|
+
const cacheKey = `${toolName}::${JSON.stringify(args)}`;
|
|
47
|
+
if (cacheable) {
|
|
48
|
+
const cached = this.cache.get(cacheKey);
|
|
49
|
+
if (cached && Date.now() - cached.cachedAt < cached.ttlMs) {
|
|
50
|
+
return cached.result;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const result = await tool.execute(args, context);
|
|
54
|
+
if (cacheable) {
|
|
55
|
+
this.cache.set(cacheKey, {
|
|
56
|
+
key: cacheKey,
|
|
57
|
+
result,
|
|
58
|
+
cachedAt: Date.now(),
|
|
59
|
+
ttlMs: DEFAULT_CACHE_TTL_MS,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/** Clear the entire tool result cache */
|
|
65
|
+
clearCache() {
|
|
66
|
+
this.cache.clear();
|
|
67
|
+
}
|
|
68
|
+
/** Invalidate cached results for a specific tool */
|
|
69
|
+
invalidateCache(toolName) {
|
|
70
|
+
for (const [key, entry] of this.cache) {
|
|
71
|
+
if (entry.key.startsWith(`${toolName}::`)) {
|
|
72
|
+
this.cache.delete(key);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
36
76
|
}
|
|
37
77
|
/** Create a pre-loaded registry with all default tools */
|
|
38
78
|
export async function createDefaultRegistry() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,kDAAkD;AAClD,+DAA+D;AAI/D,MAAM,OAAO,YAAY;IACf,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-exec.d.ts","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"shell-exec.d.ts","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAsB5F,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAuB;IAC3B,OAAO,SAAe;IACtB,WAAW,SAA4L;IACvM,OAAO,UAAY;IACnB,SAAS,UAAW;IACpB,SAAS,EAAK,MAAM,CAAU;IAC9B,WAAW,0BAA2B;IAEtC,UAAU,EAAE,gBAAgB,CAqB1B;IAEI,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAgG7D,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/D,OAAO,CAAC,WAAW;CASpB"}
|
package/dist/tools/shell-exec.js
CHANGED
|
@@ -5,11 +5,24 @@
|
|
|
5
5
|
import { spawn } from 'node:child_process';
|
|
6
6
|
import { resolve } from 'node:path';
|
|
7
7
|
import { generateId, GLOBAL_SHELL_BLOCKLIST } from '@nexagent-cli/shared';
|
|
8
|
+
/** Write an audit log entry for shell execution */
|
|
9
|
+
function writeAuditLog(db, sessionId, action, details, status) {
|
|
10
|
+
if (!db)
|
|
11
|
+
return;
|
|
12
|
+
try {
|
|
13
|
+
const stmt = db.prepare('INSERT INTO audit_log (id, session_id, tool_name, action, details, status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)');
|
|
14
|
+
stmt.run(generateId(), sessionId, 'shell_exec', action, JSON.stringify(details), status, Date.now());
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Audit logging is best-effort; never fail the tool execution
|
|
18
|
+
}
|
|
19
|
+
}
|
|
8
20
|
export class ShellExecTool {
|
|
9
21
|
name = 'shell_exec';
|
|
10
22
|
version = '1.0.0';
|
|
11
23
|
description = 'Execute a shell command in the workspace directory. Output is captured and returned. Long-running commands time out after timeout_ms. Dangerous commands are blocked by safety checks.';
|
|
12
24
|
enabled = true;
|
|
25
|
+
cacheable = false;
|
|
13
26
|
riskLevel = 'high';
|
|
14
27
|
permissions = ['shell:exec'];
|
|
15
28
|
parameters = {
|
|
@@ -77,12 +90,21 @@ export class ShellExecTool {
|
|
|
77
90
|
const truncated = combined.length > 20_000
|
|
78
91
|
? combined.slice(0, 20_000) + '\n[...output truncated at 20k chars...]'
|
|
79
92
|
: combined;
|
|
93
|
+
const success = code === 0;
|
|
94
|
+
const status = success ? 'success' : 'failed';
|
|
95
|
+
writeAuditLog(ctx.db, ctx.sessionId, 'execute', {
|
|
96
|
+
command: command.slice(0, 2000), // cap detail size
|
|
97
|
+
cwd: absCwd,
|
|
98
|
+
exitCode: code,
|
|
99
|
+
durationMs,
|
|
100
|
+
outputLength: combined.length,
|
|
101
|
+
}, status);
|
|
80
102
|
if (code !== 0 && !stderr) {
|
|
81
103
|
reject(new Error(`Command exited with code ${code}: ${truncated}`));
|
|
82
104
|
return;
|
|
83
105
|
}
|
|
84
106
|
resolve_p({
|
|
85
|
-
success
|
|
107
|
+
success,
|
|
86
108
|
output: truncated || `(no output, exit code ${code})`,
|
|
87
109
|
data: { exitCode: code, stdout, stderr, command, durationMs },
|
|
88
110
|
executionId,
|
|
@@ -91,6 +113,11 @@ export class ShellExecTool {
|
|
|
91
113
|
});
|
|
92
114
|
proc.on('error', (err) => {
|
|
93
115
|
clearTimeout(timer);
|
|
116
|
+
writeAuditLog(ctx.db, ctx.sessionId, 'spawn_error', {
|
|
117
|
+
command: command.slice(0, 2000),
|
|
118
|
+
cwd: absCwd,
|
|
119
|
+
error: err.message,
|
|
120
|
+
}, 'error');
|
|
94
121
|
reject(new Error(`Failed to spawn process: ${err.message}`));
|
|
95
122
|
});
|
|
96
123
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-exec.js","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"shell-exec.js","sourceRoot":"","sources":["../../src/tools/shell-exec.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/ChatApp.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ interface ChatAppProps {
|
|
|
22
22
|
contextWindow: number;
|
|
23
23
|
};
|
|
24
24
|
countTokens(t: string, m: string): number;
|
|
25
|
+
estimateCost?(model: string, promptTokens: number, completionTokens: number): number;
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
export declare function ChatApp({ agentName, model, sessionId, events, onUserInput, onQuickCommand, onExit, theme, llm, }: ChatAppProps): React.ReactElement;
|
package/dist/ui/ChatApp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatApp.d.ts","sourceRoot":"","sources":["../../src/ui/ChatApp.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatApp.d.ts","sourceRoot":"","sources":["../../src/ui/ChatApp.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAW1D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAS,MAAM,CAAC;IAClB,IAAI,EAAO,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,OAAO,EAAI,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AA8BD,UAAU,YAAY;IACpB,SAAS,EAAO,MAAM,CAAC;IACvB,KAAK,EAAW,MAAM,CAAC;IACvB,SAAS,EAAO,MAAM,CAAC;IACvB,MAAM,EAAU,iBAAiB,CAAC;IAClC,WAAW,EAAK,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,EAAU,MAAM,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAU,MAAM,GAAG,OAAO,CAAC;IACjC,GAAG,CAAC,EAAY;QAAE,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,YAAY,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC5M;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,KAAc,EAAE,GAAG,GAC9F,EAAE,YAAY,GAAG,KAAK,CAAC,YAAY,CAoOnC"}
|
package/dist/ui/ChatApp.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// ============================================================
|
|
3
|
-
// ChatApp
|
|
3
|
+
// ChatApp -- Root Ink TUI component for interactive chat
|
|
4
4
|
// ============================================================
|
|
5
5
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
6
6
|
import { Box, Text, useInput, useApp } from 'ink';
|
|
@@ -10,6 +10,7 @@ import { InputBar } from './InputBar.js';
|
|
|
10
10
|
import { StatusBar } from './StatusBar.js';
|
|
11
11
|
import { ToolPanel } from './ToolPanel.js';
|
|
12
12
|
import { ConfirmDialog } from './ConfirmDialog.js';
|
|
13
|
+
import { SubagentPanel } from './SubagentPanel.js';
|
|
13
14
|
function estimateContextTokens(messages, latestText, llm, model) {
|
|
14
15
|
let total = 0;
|
|
15
16
|
for (const m of messages) {
|
|
@@ -28,13 +29,16 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
|
|
|
28
29
|
const [confirmReq, setConfirmReq] = useState(null);
|
|
29
30
|
const [sessionCost, setCost] = useState(0);
|
|
30
31
|
const [contextTokens, setContextTokens] = useState(0);
|
|
32
|
+
const [subagentJobs, setSubagentJobs] = useState([]);
|
|
33
|
+
const [inputCostHint, setInputCostHint] = useState('');
|
|
34
|
+
const [currentInput, setCurrentInput] = useState('');
|
|
31
35
|
const msgIdCounter = useRef(0);
|
|
32
36
|
const isStreaming = agentStatus === 'streaming';
|
|
33
37
|
const contextWindow = llm?.getCapabilities(model).contextWindow ?? 128_000;
|
|
34
38
|
const contextPercent = Math.min(100, (contextTokens / contextWindow) * 100);
|
|
35
39
|
const compactHint = contextPercent > 85;
|
|
36
40
|
const nextId = () => `msg-${++msgIdCounter.current}`;
|
|
37
|
-
//
|
|
41
|
+
// -- Subscribe to agent events --
|
|
38
42
|
useEffect(() => {
|
|
39
43
|
const addMsg = (msg) => setMessages(prev => [...prev, { ...msg, id: nextId(), timestamp: Date.now() }]);
|
|
40
44
|
events.on('status:change', ({ status }) => setStatus(status));
|
|
@@ -75,16 +79,18 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
|
|
|
75
79
|
setStatus('error');
|
|
76
80
|
});
|
|
77
81
|
events.on('confirmation:request', ({ prompt, toolName, riskLevel }) => {
|
|
78
|
-
// surfaced as a dialog
|
|
82
|
+
// surfaced as a dialog -- resolved by user keypress
|
|
79
83
|
// The promise resolve is wired via the confirmFn below
|
|
80
84
|
});
|
|
81
85
|
events.on('subagent:spawn', ({ jobId, task }) => {
|
|
82
|
-
addMsg({ role: 'system', content:
|
|
86
|
+
addMsg({ role: 'system', content: `Subagent [${String(jobId).slice(0, 8)}] spawned: ${task}` });
|
|
87
|
+
setSubagentJobs(prev => [...prev, { jobId, task, status: 'running', startTime: Date.now() }]);
|
|
83
88
|
});
|
|
84
89
|
events.on('subagent:progress', ({ jobId, chunk }) => {
|
|
85
90
|
if (chunk) {
|
|
86
91
|
setStreamBuf(prev => prev + chunk);
|
|
87
92
|
}
|
|
93
|
+
setSubagentJobs(prev => prev.map(j => j.jobId === jobId ? { ...j, chunk: (j.chunk ?? '') + (chunk ?? '') } : j));
|
|
88
94
|
});
|
|
89
95
|
events.on('subagent:done', ({ jobId, status, output, artifacts, costUsd, durationMs }) => {
|
|
90
96
|
setStreamBuf('');
|
|
@@ -93,21 +99,39 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
|
|
|
93
99
|
: '';
|
|
94
100
|
addMsg({
|
|
95
101
|
role: 'system',
|
|
96
|
-
content:
|
|
102
|
+
content: `Subagent [${String(jobId).slice(0, 8)}] ${status} in ${(durationMs / 1000).toFixed(1)}s | $${costUsd.toFixed(5)}${artifactList}\n\n${output.slice(0, 800)}${output.length > 800 ? '...' : ''}`,
|
|
97
103
|
});
|
|
104
|
+
setSubagentJobs(prev => prev.filter(j => j.jobId !== jobId));
|
|
98
105
|
});
|
|
99
106
|
events.on('subagent:error', ({ jobId, error }) => {
|
|
100
107
|
addMsg({ role: 'system', content: `${SYM.ERROR} Subagent [${String(jobId).slice(0, 8)}] failed: ${error}` });
|
|
108
|
+
setSubagentJobs(prev => prev.filter(j => j.jobId !== jobId));
|
|
101
109
|
});
|
|
102
110
|
return () => { events.removeAllListeners(); };
|
|
103
111
|
}, [events]);
|
|
104
|
-
//
|
|
112
|
+
// -- Cost hint derived from current input --
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (!currentInput.trim() || !llm) {
|
|
115
|
+
setInputCostHint('');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const tokens = llm.countTokens(currentInput, model);
|
|
119
|
+
let hint = `~${tokens} tokens`;
|
|
120
|
+
if (llm.estimateCost) {
|
|
121
|
+
const cost = llm.estimateCost(model, tokens, 0);
|
|
122
|
+
if (cost > 0) {
|
|
123
|
+
hint += ` · ~$${cost.toFixed(4)}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
setInputCostHint(hint);
|
|
127
|
+
}, [currentInput, llm, model]);
|
|
128
|
+
// -- Confirmation function passed to agent loop --
|
|
105
129
|
const confirmFn = useCallback((prompt) => {
|
|
106
130
|
return new Promise(resolve => {
|
|
107
131
|
setConfirmReq({ prompt, toolName: '', riskLevel: 'high', resolve });
|
|
108
132
|
});
|
|
109
133
|
}, []);
|
|
110
|
-
//
|
|
134
|
+
// -- Handle user text submission --
|
|
111
135
|
const handleSubmit = useCallback(async (text) => {
|
|
112
136
|
if (!text.trim())
|
|
113
137
|
return;
|
|
@@ -136,16 +160,16 @@ export function ChatApp({ agentName, model, sessionId, events, onUserInput, onQu
|
|
|
136
160
|
}]);
|
|
137
161
|
await onUserInput(text, confirmFn);
|
|
138
162
|
}, [onUserInput, onQuickCommand, confirmFn]);
|
|
139
|
-
//
|
|
163
|
+
// -- Keyboard shortcuts --
|
|
140
164
|
useInput((input, key) => {
|
|
141
165
|
if (key.ctrl && input === 'c') {
|
|
142
166
|
onExit();
|
|
143
167
|
exit();
|
|
144
168
|
}
|
|
145
169
|
});
|
|
146
|
-
return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsxs(Box, { borderStyle: "round", borderColor: colors.primary, paddingX: 1, marginBottom: 0, children: [_jsxs(Text, { color: colors.primary, bold: true, children: [SYM.AGENT, " NexAgent"] }), _jsxs(Text, { color: colors.muted, children: [" ", agentName] }), _jsxs(Text, { color: colors.muted, children: ["
|
|
170
|
+
return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsxs(Box, { borderStyle: "round", borderColor: colors.primary, paddingX: 1, marginBottom: 0, children: [_jsxs(Text, { color: colors.primary, bold: true, children: [SYM.AGENT, " NexAgent"] }), _jsxs(Text, { color: colors.muted, children: [" ", agentName] }), _jsxs(Text, { color: colors.muted, children: [" \u26A1 ", model] }), _jsxs(Text, { color: colors.muted, children: [" \uD83D\uDD11 ", sessionId.slice(0, 8)] })] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, overflowY: "hidden", children: [_jsx(MessageList, { messages: messages, colors: colors }), isStreaming && streamBuffer && (_jsxs(Box, { paddingLeft: 2, children: [_jsx(Text, { color: colors.text, children: streamBuffer }), _jsx(Text, { color: colors.primary, children: SYM.SPIN[0] })] }))] }), toolActivity.length > 0 && (_jsx(ToolPanel, { activities: toolActivity, colors: colors })), subagentJobs.length > 0 && (_jsx(SubagentPanel, { jobs: subagentJobs, colors: colors })), confirmReq && (_jsx(ConfirmDialog, { prompt: confirmReq.prompt, riskLevel: confirmReq.riskLevel, colors: colors, onConfirm: (approved) => {
|
|
147
171
|
confirmReq.resolve(approved);
|
|
148
172
|
setConfirmReq(null);
|
|
149
|
-
} })), _jsx(StatusBar, { status: agentStatus, cost: sessionCost, colors: colors, contextPercent: contextPercent, compactHint: compactHint }), agentStatus === 'idle' || agentStatus === 'done' ? (_jsx(InputBar, { onSubmit: handleSubmit, colors: colors })) : null] }));
|
|
173
|
+
} })), _jsx(StatusBar, { status: agentStatus, cost: sessionCost, colors: colors, contextPercent: contextPercent, compactHint: compactHint, costHint: inputCostHint }), agentStatus === 'idle' || agentStatus === 'done' ? (_jsx(InputBar, { onSubmit: handleSubmit, onChange: setCurrentInput, colors: colors })) : null] }));
|
|
150
174
|
}
|
|
151
175
|
//# sourceMappingURL=ChatApp.js.map
|