@xandout/libra-harness 0.1.8
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/LICENSE +21 -0
- package/README.md +486 -0
- package/dist/agent.d.ts +174 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +575 -0
- package/dist/agent.js.map +1 -0
- package/dist/ai-sdk-model.d.ts +26 -0
- package/dist/ai-sdk-model.d.ts.map +1 -0
- package/dist/ai-sdk-model.js +260 -0
- package/dist/ai-sdk-model.js.map +1 -0
- package/dist/context.d.ts +75 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/extension.d.ts +63 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +2 -0
- package/dist/extension.js.map +1 -0
- package/dist/extras/extension-loader.d.ts +205 -0
- package/dist/extras/extension-loader.d.ts.map +1 -0
- package/dist/extras/extension-loader.js +315 -0
- package/dist/extras/extension-loader.js.map +1 -0
- package/dist/extras/extensions/auto-steer/extension.d.ts +46 -0
- package/dist/extras/extensions/auto-steer/extension.d.ts.map +1 -0
- package/dist/extras/extensions/auto-steer/extension.js +52 -0
- package/dist/extras/extensions/auto-steer/extension.js.map +1 -0
- package/dist/extras/extensions/auto-steer/extension.json +7 -0
- package/dist/extras/extensions/auto-steer/index.d.ts +3 -0
- package/dist/extras/extensions/auto-steer/index.d.ts.map +1 -0
- package/dist/extras/extensions/auto-steer/index.js +2 -0
- package/dist/extras/extensions/auto-steer/index.js.map +1 -0
- package/dist/extras/extensions/disk-session/extension.d.ts +167 -0
- package/dist/extras/extensions/disk-session/extension.d.ts.map +1 -0
- package/dist/extras/extensions/disk-session/extension.js +492 -0
- package/dist/extras/extensions/disk-session/extension.js.map +1 -0
- package/dist/extras/extensions/disk-session/extension.json +6 -0
- package/dist/extras/extensions/disk-session/extension.test.d.ts +2 -0
- package/dist/extras/extensions/disk-session/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/disk-session/extension.test.js +672 -0
- package/dist/extras/extensions/disk-session/extension.test.js.map +1 -0
- package/dist/extras/extensions/disk-session/index.d.ts +3 -0
- package/dist/extras/extensions/disk-session/index.d.ts.map +1 -0
- package/dist/extras/extensions/disk-session/index.js +2 -0
- package/dist/extras/extensions/disk-session/index.js.map +1 -0
- package/dist/extras/extensions/emoji/extension.d.ts +20 -0
- package/dist/extras/extensions/emoji/extension.d.ts.map +1 -0
- package/dist/extras/extensions/emoji/extension.js +22 -0
- package/dist/extras/extensions/emoji/extension.js.map +1 -0
- package/dist/extras/extensions/emoji/extension.json +7 -0
- package/dist/extras/extensions/emoji/index.d.ts +3 -0
- package/dist/extras/extensions/emoji/index.d.ts.map +1 -0
- package/dist/extras/extensions/emoji/index.js +2 -0
- package/dist/extras/extensions/emoji/index.js.map +1 -0
- package/dist/extras/extensions/filesystem/extension.d.ts +53 -0
- package/dist/extras/extensions/filesystem/extension.d.ts.map +1 -0
- package/dist/extras/extensions/filesystem/extension.js +350 -0
- package/dist/extras/extensions/filesystem/extension.js.map +1 -0
- package/dist/extras/extensions/filesystem/extension.json +6 -0
- package/dist/extras/extensions/filesystem/extension.test.d.ts +2 -0
- package/dist/extras/extensions/filesystem/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/filesystem/extension.test.js +387 -0
- package/dist/extras/extensions/filesystem/extension.test.js.map +1 -0
- package/dist/extras/extensions/filesystem/index.d.ts +2 -0
- package/dist/extras/extensions/filesystem/index.d.ts.map +1 -0
- package/dist/extras/extensions/filesystem/index.js +2 -0
- package/dist/extras/extensions/filesystem/index.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.d.ts +53 -0
- package/dist/extras/extensions/keyword-extractor/extension.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.js +61 -0
- package/dist/extras/extensions/keyword-extractor/extension.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.json +6 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.d.ts +2 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.js +105 -0
- package/dist/extras/extensions/keyword-extractor/extension.test.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/index.d.ts +5 -0
- package/dist/extras/extensions/keyword-extractor/index.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/index.js +3 -0
- package/dist/extras/extensions/keyword-extractor/index.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.d.ts +68 -0
- package/dist/extras/extensions/keyword-extractor/nlp.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.js +156 -0
- package/dist/extras/extensions/keyword-extractor/nlp.js.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.d.ts +2 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.d.ts.map +1 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.js +176 -0
- package/dist/extras/extensions/keyword-extractor/nlp.test.js.map +1 -0
- package/dist/extras/extensions/logger/extension.d.ts +52 -0
- package/dist/extras/extensions/logger/extension.d.ts.map +1 -0
- package/dist/extras/extensions/logger/extension.js +68 -0
- package/dist/extras/extensions/logger/extension.js.map +1 -0
- package/dist/extras/extensions/logger/extension.json +7 -0
- package/dist/extras/extensions/logger/index.d.ts +3 -0
- package/dist/extras/extensions/logger/index.d.ts.map +1 -0
- package/dist/extras/extensions/logger/index.js +2 -0
- package/dist/extras/extensions/logger/index.js.map +1 -0
- package/dist/extras/extensions/mcp/extension.d.ts +63 -0
- package/dist/extras/extensions/mcp/extension.d.ts.map +1 -0
- package/dist/extras/extensions/mcp/extension.js +437 -0
- package/dist/extras/extensions/mcp/extension.js.map +1 -0
- package/dist/extras/extensions/mcp/extension.json +7 -0
- package/dist/extras/extensions/mcp/extension.test.d.ts +2 -0
- package/dist/extras/extensions/mcp/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/mcp/extension.test.js +286 -0
- package/dist/extras/extensions/mcp/extension.test.js.map +1 -0
- package/dist/extras/extensions/mcp/index.d.ts +3 -0
- package/dist/extras/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extras/extensions/mcp/index.js +2 -0
- package/dist/extras/extensions/mcp/index.js.map +1 -0
- package/dist/extras/extensions/mem-session/extension.d.ts +24 -0
- package/dist/extras/extensions/mem-session/extension.d.ts.map +1 -0
- package/dist/extras/extensions/mem-session/extension.js +49 -0
- package/dist/extras/extensions/mem-session/extension.js.map +1 -0
- package/dist/extras/extensions/mem-session/extension.json +6 -0
- package/dist/extras/extensions/mem-session/index.d.ts +2 -0
- package/dist/extras/extensions/mem-session/index.d.ts.map +1 -0
- package/dist/extras/extensions/mem-session/index.js +2 -0
- package/dist/extras/extensions/mem-session/index.js.map +1 -0
- package/dist/extras/extensions/memory/extension.d.ts +54 -0
- package/dist/extras/extensions/memory/extension.d.ts.map +1 -0
- package/dist/extras/extensions/memory/extension.js +143 -0
- package/dist/extras/extensions/memory/extension.js.map +1 -0
- package/dist/extras/extensions/memory/extension.json +7 -0
- package/dist/extras/extensions/memory/index.d.ts +5 -0
- package/dist/extras/extensions/memory/index.d.ts.map +1 -0
- package/dist/extras/extensions/memory/index.js +3 -0
- package/dist/extras/extensions/memory/index.js.map +1 -0
- package/dist/extras/extensions/memory/llm-extractor.d.ts +42 -0
- package/dist/extras/extensions/memory/llm-extractor.d.ts.map +1 -0
- package/dist/extras/extensions/memory/llm-extractor.js +89 -0
- package/dist/extras/extensions/memory/llm-extractor.js.map +1 -0
- package/dist/extras/extensions/memory/types.d.ts +142 -0
- package/dist/extras/extensions/memory/types.d.ts.map +1 -0
- package/dist/extras/extensions/memory/types.js +2 -0
- package/dist/extras/extensions/memory/types.js.map +1 -0
- package/dist/extras/extensions/otel/extension.d.ts +57 -0
- package/dist/extras/extensions/otel/extension.d.ts.map +1 -0
- package/dist/extras/extensions/otel/extension.js +253 -0
- package/dist/extras/extensions/otel/extension.js.map +1 -0
- package/dist/extras/extensions/otel/extension.json +7 -0
- package/dist/extras/extensions/otel/extension.test.d.ts +2 -0
- package/dist/extras/extensions/otel/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/otel/extension.test.js +399 -0
- package/dist/extras/extensions/otel/extension.test.js.map +1 -0
- package/dist/extras/extensions/otel/index.d.ts +4 -0
- package/dist/extras/extensions/otel/index.d.ts.map +1 -0
- package/dist/extras/extensions/otel/index.js +3 -0
- package/dist/extras/extensions/otel/index.js.map +1 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.d.ts +60 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.d.ts.map +1 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.js +134 -0
- package/dist/extras/extensions/otel/jsonl-span-exporter.js.map +1 -0
- package/dist/extras/extensions/scripts/extension.d.ts +180 -0
- package/dist/extras/extensions/scripts/extension.d.ts.map +1 -0
- package/dist/extras/extensions/scripts/extension.js +618 -0
- package/dist/extras/extensions/scripts/extension.js.map +1 -0
- package/dist/extras/extensions/scripts/extension.json +7 -0
- package/dist/extras/extensions/scripts/extension.test.d.ts +2 -0
- package/dist/extras/extensions/scripts/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/scripts/extension.test.js +552 -0
- package/dist/extras/extensions/scripts/extension.test.js.map +1 -0
- package/dist/extras/extensions/scripts/index.d.ts +3 -0
- package/dist/extras/extensions/scripts/index.d.ts.map +1 -0
- package/dist/extras/extensions/scripts/index.js +2 -0
- package/dist/extras/extensions/scripts/index.js.map +1 -0
- package/dist/extras/extensions/skills/extension.d.ts +105 -0
- package/dist/extras/extensions/skills/extension.d.ts.map +1 -0
- package/dist/extras/extensions/skills/extension.js +419 -0
- package/dist/extras/extensions/skills/extension.js.map +1 -0
- package/dist/extras/extensions/skills/extension.json +7 -0
- package/dist/extras/extensions/skills/extension.test.d.ts +2 -0
- package/dist/extras/extensions/skills/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/skills/extension.test.js +184 -0
- package/dist/extras/extensions/skills/extension.test.js.map +1 -0
- package/dist/extras/extensions/skills/index.d.ts +4 -0
- package/dist/extras/extensions/skills/index.d.ts.map +1 -0
- package/dist/extras/extensions/skills/index.js +3 -0
- package/dist/extras/extensions/skills/index.js.map +1 -0
- package/dist/extras/extensions/streaming/extension.d.ts +15 -0
- package/dist/extras/extensions/streaming/extension.d.ts.map +1 -0
- package/dist/extras/extensions/streaming/extension.js +41 -0
- package/dist/extras/extensions/streaming/extension.js.map +1 -0
- package/dist/extras/extensions/streaming/extension.json +6 -0
- package/dist/extras/extensions/streaming/index.d.ts +2 -0
- package/dist/extras/extensions/streaming/index.d.ts.map +1 -0
- package/dist/extras/extensions/streaming/index.js +2 -0
- package/dist/extras/extensions/streaming/index.js.map +1 -0
- package/dist/extras/extensions/structured-output/extension.d.ts +11 -0
- package/dist/extras/extensions/structured-output/extension.d.ts.map +1 -0
- package/dist/extras/extensions/structured-output/extension.js +102 -0
- package/dist/extras/extensions/structured-output/extension.js.map +1 -0
- package/dist/extras/extensions/structured-output/extension.json +7 -0
- package/dist/extras/extensions/structured-output/index.d.ts +3 -0
- package/dist/extras/extensions/structured-output/index.d.ts.map +1 -0
- package/dist/extras/extensions/structured-output/index.js +2 -0
- package/dist/extras/extensions/structured-output/index.js.map +1 -0
- package/dist/extras/extensions/timestamp/extension.d.ts +11 -0
- package/dist/extras/extensions/timestamp/extension.d.ts.map +1 -0
- package/dist/extras/extensions/timestamp/extension.js +21 -0
- package/dist/extras/extensions/timestamp/extension.js.map +1 -0
- package/dist/extras/extensions/timestamp/extension.json +6 -0
- package/dist/extras/extensions/timestamp/index.d.ts +2 -0
- package/dist/extras/extensions/timestamp/index.d.ts.map +1 -0
- package/dist/extras/extensions/timestamp/index.js +2 -0
- package/dist/extras/extensions/timestamp/index.js.map +1 -0
- package/dist/extras/extensions/token-stats/extension.d.ts +50 -0
- package/dist/extras/extensions/token-stats/extension.d.ts.map +1 -0
- package/dist/extras/extensions/token-stats/extension.js +99 -0
- package/dist/extras/extensions/token-stats/extension.js.map +1 -0
- package/dist/extras/extensions/token-stats/extension.json +7 -0
- package/dist/extras/extensions/token-stats/extension.test.d.ts +2 -0
- package/dist/extras/extensions/token-stats/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/token-stats/extension.test.js +197 -0
- package/dist/extras/extensions/token-stats/extension.test.js.map +1 -0
- package/dist/extras/extensions/token-stats/index.d.ts +3 -0
- package/dist/extras/extensions/token-stats/index.d.ts.map +1 -0
- package/dist/extras/extensions/token-stats/index.js +2 -0
- package/dist/extras/extensions/token-stats/index.js.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.d.ts +89 -0
- package/dist/extras/extensions/tool-buffer/extension.d.ts.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.js +182 -0
- package/dist/extras/extensions/tool-buffer/extension.js.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.json +7 -0
- package/dist/extras/extensions/tool-buffer/extension.test.d.ts +2 -0
- package/dist/extras/extensions/tool-buffer/extension.test.d.ts.map +1 -0
- package/dist/extras/extensions/tool-buffer/extension.test.js +549 -0
- package/dist/extras/extensions/tool-buffer/extension.test.js.map +1 -0
- package/dist/extras/extensions/tool-buffer/index.d.ts +3 -0
- package/dist/extras/extensions/tool-buffer/index.d.ts.map +1 -0
- package/dist/extras/extensions/tool-buffer/index.js +2 -0
- package/dist/extras/extensions/tool-buffer/index.js.map +1 -0
- package/dist/extras/extensions/weather-tool/extension.d.ts +22 -0
- package/dist/extras/extensions/weather-tool/extension.d.ts.map +1 -0
- package/dist/extras/extensions/weather-tool/extension.js +33 -0
- package/dist/extras/extensions/weather-tool/extension.js.map +1 -0
- package/dist/extras/extensions/weather-tool/extension.json +7 -0
- package/dist/extras/extensions/weather-tool/index.d.ts +3 -0
- package/dist/extras/extensions/weather-tool/index.d.ts.map +1 -0
- package/dist/extras/extensions/weather-tool/index.js +2 -0
- package/dist/extras/extensions/weather-tool/index.js.map +1 -0
- package/dist/extras/models/ai-sdk-resolver.d.ts +15 -0
- package/dist/extras/models/ai-sdk-resolver.d.ts.map +1 -0
- package/dist/extras/models/ai-sdk-resolver.js +57 -0
- package/dist/extras/models/ai-sdk-resolver.js.map +1 -0
- package/dist/extras/models/index.d.ts +5 -0
- package/dist/extras/models/index.d.ts.map +1 -0
- package/dist/extras/models/index.js +3 -0
- package/dist/extras/models/index.js.map +1 -0
- package/dist/extras/models/routing-model.d.ts +18 -0
- package/dist/extras/models/routing-model.d.ts.map +1 -0
- package/dist/extras/models/routing-model.js +24 -0
- package/dist/extras/models/routing-model.js.map +1 -0
- package/dist/extras/openai-provider/index.d.ts +3 -0
- package/dist/extras/openai-provider/index.d.ts.map +1 -0
- package/dist/extras/openai-provider/index.js +2 -0
- package/dist/extras/openai-provider/index.js.map +1 -0
- package/dist/extras/openai-provider/server.d.ts +34 -0
- package/dist/extras/openai-provider/server.d.ts.map +1 -0
- package/dist/extras/openai-provider/server.js +335 -0
- package/dist/extras/openai-provider/server.js.map +1 -0
- package/dist/handle.d.ts +56 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +2 -0
- package/dist/handle.js.map +1 -0
- package/dist/hooks.d.ts +98 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +53 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/model.d.ts +75 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/tool.d.ts +78 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +78 -0
- package/dist/tool.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +178 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { mkdtempSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { Agent } from '@xandout/libra-harness';
|
|
6
|
+
import createFilesystemExtension from './extension.js';
|
|
7
|
+
// Minimal model that never actually calls the LLM — we just need the
|
|
8
|
+
// agent to register tools so we can call them directly.
|
|
9
|
+
function makeAgent() {
|
|
10
|
+
return new Agent({
|
|
11
|
+
model: {
|
|
12
|
+
async generate() {
|
|
13
|
+
return { message: { role: 'assistant', content: '' }, finishReason: 'stop' };
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
describe('filesystem extension', () => {
|
|
19
|
+
let sandbox;
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
sandbox = mkdtempSync(join(tmpdir(), 'fs-test-'));
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
rmSync(sandbox, { recursive: true, force: true });
|
|
25
|
+
});
|
|
26
|
+
function makeExt() {
|
|
27
|
+
return createFilesystemExtension({
|
|
28
|
+
directories: [{ name: 'sandbox', path: sandbox }],
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function getTool(agent, name) {
|
|
32
|
+
return agent.tools.get(name);
|
|
33
|
+
}
|
|
34
|
+
// ── Path safety ──────────────────────────────────────────────────
|
|
35
|
+
it('blocks path traversal with ..', () => {
|
|
36
|
+
const ext = makeExt();
|
|
37
|
+
expect(() => ext.resolvePath('sandbox/../etc/passwd')).toThrow('escapes');
|
|
38
|
+
});
|
|
39
|
+
it('blocks absolute paths', () => {
|
|
40
|
+
const ext = makeExt();
|
|
41
|
+
expect(() => ext.resolvePath('/etc/passwd')).toThrow('must start with a sandbox name');
|
|
42
|
+
});
|
|
43
|
+
it('blocks paths without a sandbox prefix', () => {
|
|
44
|
+
const ext = makeExt();
|
|
45
|
+
expect(() => ext.resolvePath('foo/bar.txt')).toThrow('must start with a sandbox name');
|
|
46
|
+
});
|
|
47
|
+
it('resolves normal paths within sandbox', () => {
|
|
48
|
+
const ext = makeExt();
|
|
49
|
+
const resolved = ext.resolvePath('sandbox/foo/bar.txt');
|
|
50
|
+
expect(resolved).toBe(join(sandbox, 'foo', 'bar.txt'));
|
|
51
|
+
});
|
|
52
|
+
// ── saveBytes ────────────────────────────────────────────────────
|
|
53
|
+
it('saveBytes writes file and creates parent dirs', () => {
|
|
54
|
+
const ext = makeExt();
|
|
55
|
+
ext.saveBytes('sandbox/subdir/file.bin', Buffer.from('hello'), 'text/plain');
|
|
56
|
+
const data = readFileSync(join(sandbox, 'subdir', 'file.bin'), 'utf-8');
|
|
57
|
+
expect(data).toBe('hello');
|
|
58
|
+
});
|
|
59
|
+
it('saveBytes returns the prefixed path', () => {
|
|
60
|
+
const ext = makeExt();
|
|
61
|
+
const path = ext.saveBytes('sandbox/test.txt', Buffer.from('data'));
|
|
62
|
+
expect(path).toBe('sandbox/test.txt');
|
|
63
|
+
});
|
|
64
|
+
// ── fs_write ─────────────────────────────────────────────────────
|
|
65
|
+
it('fs_write creates a text file', async () => {
|
|
66
|
+
const ext = makeExt();
|
|
67
|
+
const agent = makeAgent();
|
|
68
|
+
agent.use(ext);
|
|
69
|
+
const tool = getTool(agent, 'fs_write');
|
|
70
|
+
const result = await tool.execute({ path: 'sandbox/hello.txt', content: 'Hello world' });
|
|
71
|
+
expect(result.content).toContain('Wrote');
|
|
72
|
+
expect(existsSync(join(sandbox, 'hello.txt'))).toBe(true);
|
|
73
|
+
expect(readFileSync(join(sandbox, 'hello.txt'), 'utf-8')).toBe('Hello world');
|
|
74
|
+
});
|
|
75
|
+
it('fs_write creates parent directories', async () => {
|
|
76
|
+
const ext = makeExt();
|
|
77
|
+
const agent = makeAgent();
|
|
78
|
+
agent.use(ext);
|
|
79
|
+
const tool = getTool(agent, 'fs_write');
|
|
80
|
+
await tool.execute({ path: 'sandbox/a/b/c/file.txt', content: 'nested' });
|
|
81
|
+
expect(readFileSync(join(sandbox, 'a', 'b', 'c', 'file.txt'), 'utf-8')).toBe('nested');
|
|
82
|
+
});
|
|
83
|
+
it('fs_write overwrites existing files', async () => {
|
|
84
|
+
const ext = makeExt();
|
|
85
|
+
const agent = makeAgent();
|
|
86
|
+
agent.use(ext);
|
|
87
|
+
const tool = getTool(agent, 'fs_write');
|
|
88
|
+
await tool.execute({ path: 'sandbox/file.txt', content: 'first' });
|
|
89
|
+
await tool.execute({ path: 'sandbox/file.txt', content: 'second' });
|
|
90
|
+
expect(readFileSync(join(sandbox, 'file.txt'), 'utf-8')).toBe('second');
|
|
91
|
+
});
|
|
92
|
+
it('fs_write blocks path traversal', async () => {
|
|
93
|
+
const ext = makeExt();
|
|
94
|
+
const agent = makeAgent();
|
|
95
|
+
agent.use(ext);
|
|
96
|
+
const tool = getTool(agent, 'fs_write');
|
|
97
|
+
const result = await tool.execute({ path: 'sandbox/../escape.txt', content: 'bad' });
|
|
98
|
+
expect(result.content).toContain('escapes');
|
|
99
|
+
expect(existsSync(join(sandbox, '..', 'escape.txt'))).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
it('fs_write rejects paths without sandbox prefix', async () => {
|
|
102
|
+
const ext = makeExt();
|
|
103
|
+
const agent = makeAgent();
|
|
104
|
+
agent.use(ext);
|
|
105
|
+
const tool = getTool(agent, 'fs_write');
|
|
106
|
+
const result = await tool.execute({ path: 'file.txt', content: 'x' });
|
|
107
|
+
expect(result.content).toContain('must start with a sandbox name');
|
|
108
|
+
});
|
|
109
|
+
// ── fs_read ──────────────────────────────────────────────────────
|
|
110
|
+
it('fs_read returns text content for text files', async () => {
|
|
111
|
+
const ext = makeExt();
|
|
112
|
+
ext.saveBytes('sandbox/notes.txt', Buffer.from('Hello from the file'));
|
|
113
|
+
const agent = makeAgent();
|
|
114
|
+
agent.use(ext);
|
|
115
|
+
const tool = getTool(agent, 'fs_read');
|
|
116
|
+
const result = await tool.execute({ path: 'sandbox/notes.txt' });
|
|
117
|
+
expect(result.content).toContain('Hello from the file');
|
|
118
|
+
});
|
|
119
|
+
it('fs_read returns base64 for binary files', async () => {
|
|
120
|
+
const ext = makeExt();
|
|
121
|
+
ext.saveBytes('sandbox/data.bin', Buffer.from([0x89, 0x50, 0x4e, 0x47]));
|
|
122
|
+
const agent = makeAgent();
|
|
123
|
+
agent.use(ext);
|
|
124
|
+
const tool = getTool(agent, 'fs_read');
|
|
125
|
+
const result = await tool.execute({ path: 'sandbox/data.bin' });
|
|
126
|
+
expect(result.content).toContain('base64');
|
|
127
|
+
expect(result.content).toContain('iVBOR'); // base64 of PNG header
|
|
128
|
+
});
|
|
129
|
+
it('fs_read returns error for missing files', async () => {
|
|
130
|
+
const ext = makeExt();
|
|
131
|
+
const agent = makeAgent();
|
|
132
|
+
agent.use(ext);
|
|
133
|
+
const tool = getTool(agent, 'fs_read');
|
|
134
|
+
const result = await tool.execute({ path: 'sandbox/nope.txt' });
|
|
135
|
+
expect(result.content).toContain('not found');
|
|
136
|
+
});
|
|
137
|
+
it('fs_read returns error for directories', async () => {
|
|
138
|
+
const ext = makeExt();
|
|
139
|
+
ext.saveBytes('sandbox/dir/file.txt', Buffer.from('x'));
|
|
140
|
+
const agent = makeAgent();
|
|
141
|
+
agent.use(ext);
|
|
142
|
+
const tool = getTool(agent, 'fs_read');
|
|
143
|
+
const result = await tool.execute({ path: 'sandbox/dir' });
|
|
144
|
+
expect(result.content).toContain('directory');
|
|
145
|
+
});
|
|
146
|
+
it('fs_read blocks path traversal', async () => {
|
|
147
|
+
const ext = makeExt();
|
|
148
|
+
const agent = makeAgent();
|
|
149
|
+
agent.use(ext);
|
|
150
|
+
const tool = getTool(agent, 'fs_read');
|
|
151
|
+
const result = await tool.execute({ path: 'sandbox/../../../etc/passwd' });
|
|
152
|
+
expect(result.content).toContain('escapes');
|
|
153
|
+
});
|
|
154
|
+
// ── fs_list ──────────────────────────────────────────────────────
|
|
155
|
+
it('fs_list with no path lists sandbox directories', async () => {
|
|
156
|
+
const ext = makeExt();
|
|
157
|
+
ext.saveBytes('sandbox/file1.txt', Buffer.from('a'));
|
|
158
|
+
const agent = makeAgent();
|
|
159
|
+
agent.use(ext);
|
|
160
|
+
const tool = getTool(agent, 'fs_list');
|
|
161
|
+
const result = await tool.execute({});
|
|
162
|
+
expect(result.content).toContain('sandbox');
|
|
163
|
+
});
|
|
164
|
+
it('fs_list lists sandbox contents', async () => {
|
|
165
|
+
const ext = makeExt();
|
|
166
|
+
ext.saveBytes('sandbox/file1.txt', Buffer.from('a'));
|
|
167
|
+
ext.saveBytes('sandbox/file2.csv', Buffer.from('b'));
|
|
168
|
+
ext.saveBytes('sandbox/subdir/file3.txt', Buffer.from('c'));
|
|
169
|
+
const agent = makeAgent();
|
|
170
|
+
agent.use(ext);
|
|
171
|
+
const tool = getTool(agent, 'fs_list');
|
|
172
|
+
const result = await tool.execute({ path: 'sandbox' });
|
|
173
|
+
expect(result.content).toContain('file1.txt');
|
|
174
|
+
expect(result.content).toContain('file2.csv');
|
|
175
|
+
expect(result.content).toContain('[dir]');
|
|
176
|
+
expect(result.content).toContain('subdir/');
|
|
177
|
+
});
|
|
178
|
+
it('fs_list lists subdirectory contents', async () => {
|
|
179
|
+
const ext = makeExt();
|
|
180
|
+
ext.saveBytes('sandbox/data/a.txt', Buffer.from('1'));
|
|
181
|
+
ext.saveBytes('sandbox/data/b.txt', Buffer.from('2'));
|
|
182
|
+
const agent = makeAgent();
|
|
183
|
+
agent.use(ext);
|
|
184
|
+
const tool = getTool(agent, 'fs_list');
|
|
185
|
+
const result = await tool.execute({ path: 'sandbox/data' });
|
|
186
|
+
expect(result.content).toContain('a.txt');
|
|
187
|
+
expect(result.content).toContain('b.txt');
|
|
188
|
+
});
|
|
189
|
+
it('fs_list returns empty for empty directories', async () => {
|
|
190
|
+
const ext = makeExt();
|
|
191
|
+
ext.saveBytes('sandbox/empty/.keep', Buffer.from(''));
|
|
192
|
+
const agent = makeAgent();
|
|
193
|
+
agent.use(ext);
|
|
194
|
+
const tool = getTool(agent, 'fs_list');
|
|
195
|
+
// Remove the .keep to make it truly empty
|
|
196
|
+
rmSync(join(sandbox, 'empty', '.keep'));
|
|
197
|
+
const result = await tool.execute({ path: 'sandbox/empty' });
|
|
198
|
+
expect(result.content).toContain('empty');
|
|
199
|
+
});
|
|
200
|
+
// ── fs_delete ────────────────────────────────────────────────────
|
|
201
|
+
it('fs_delete removes a file', async () => {
|
|
202
|
+
const ext = makeExt();
|
|
203
|
+
ext.saveBytes('sandbox/temp.txt', Buffer.from('delete me'));
|
|
204
|
+
const agent = makeAgent();
|
|
205
|
+
agent.use(ext);
|
|
206
|
+
const tool = getTool(agent, 'fs_delete');
|
|
207
|
+
const result = await tool.execute({ path: 'sandbox/temp.txt' });
|
|
208
|
+
expect(result.content).toContain('Deleted');
|
|
209
|
+
expect(existsSync(join(sandbox, 'temp.txt'))).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
it('fs_delete removes an empty directory', async () => {
|
|
212
|
+
const ext = makeExt();
|
|
213
|
+
ext.saveBytes('sandbox/empty/.keep', Buffer.from(''));
|
|
214
|
+
rmSync(join(sandbox, 'empty', '.keep'));
|
|
215
|
+
const agent = makeAgent();
|
|
216
|
+
agent.use(ext);
|
|
217
|
+
const tool = getTool(agent, 'fs_delete');
|
|
218
|
+
const result = await tool.execute({ path: 'sandbox/empty' });
|
|
219
|
+
expect(result.content).toContain('Deleted');
|
|
220
|
+
expect(existsSync(join(sandbox, 'empty'))).toBe(false);
|
|
221
|
+
});
|
|
222
|
+
it('fs_delete refuses non-empty directories', async () => {
|
|
223
|
+
const ext = makeExt();
|
|
224
|
+
ext.saveBytes('sandbox/dir/file.txt', Buffer.from('x'));
|
|
225
|
+
const agent = makeAgent();
|
|
226
|
+
agent.use(ext);
|
|
227
|
+
const tool = getTool(agent, 'fs_delete');
|
|
228
|
+
const result = await tool.execute({ path: 'sandbox/dir' });
|
|
229
|
+
expect(result.content).toContain('not empty');
|
|
230
|
+
});
|
|
231
|
+
it('fs_delete refuses to delete sandbox root', async () => {
|
|
232
|
+
const ext = makeExt();
|
|
233
|
+
const agent = makeAgent();
|
|
234
|
+
agent.use(ext);
|
|
235
|
+
const tool = getTool(agent, 'fs_delete');
|
|
236
|
+
const result = await tool.execute({ path: 'sandbox' });
|
|
237
|
+
expect(result.content).toContain('Refusing');
|
|
238
|
+
});
|
|
239
|
+
it('fs_delete returns error for missing files', async () => {
|
|
240
|
+
const ext = makeExt();
|
|
241
|
+
const agent = makeAgent();
|
|
242
|
+
agent.use(ext);
|
|
243
|
+
const tool = getTool(agent, 'fs_delete');
|
|
244
|
+
const result = await tool.execute({ path: 'sandbox/nope.txt' });
|
|
245
|
+
expect(result.content).toContain('not found');
|
|
246
|
+
});
|
|
247
|
+
it('fs_delete blocks path traversal', async () => {
|
|
248
|
+
const ext = makeExt();
|
|
249
|
+
const agent = makeAgent();
|
|
250
|
+
agent.use(ext);
|
|
251
|
+
const tool = getTool(agent, 'fs_delete');
|
|
252
|
+
const result = await tool.execute({ path: 'sandbox/../../../etc/passwd' });
|
|
253
|
+
expect(result.content).toContain('escapes');
|
|
254
|
+
});
|
|
255
|
+
// ── fs_info ──────────────────────────────────────────────────────
|
|
256
|
+
it('fs_info returns file metadata', async () => {
|
|
257
|
+
const ext = makeExt();
|
|
258
|
+
ext.saveBytes('sandbox/report.csv', Buffer.from('a,b,c\n1,2,3'));
|
|
259
|
+
const agent = makeAgent();
|
|
260
|
+
agent.use(ext);
|
|
261
|
+
const tool = getTool(agent, 'fs_info');
|
|
262
|
+
const result = await tool.execute({ path: 'sandbox/report.csv' });
|
|
263
|
+
expect(result.content).toContain('report.csv');
|
|
264
|
+
expect(result.content).toContain('file');
|
|
265
|
+
expect(result.content).toContain('.csv');
|
|
266
|
+
expect(result.content).toContain('Text file: true');
|
|
267
|
+
});
|
|
268
|
+
it('fs_info returns directory metadata', async () => {
|
|
269
|
+
const ext = makeExt();
|
|
270
|
+
ext.saveBytes('sandbox/dir/file.txt', Buffer.from('x'));
|
|
271
|
+
const agent = makeAgent();
|
|
272
|
+
agent.use(ext);
|
|
273
|
+
const tool = getTool(agent, 'fs_info');
|
|
274
|
+
const result = await tool.execute({ path: 'sandbox/dir' });
|
|
275
|
+
expect(result.content).toContain('directory');
|
|
276
|
+
});
|
|
277
|
+
it('fs_info returns error for missing paths', async () => {
|
|
278
|
+
const ext = makeExt();
|
|
279
|
+
const agent = makeAgent();
|
|
280
|
+
agent.use(ext);
|
|
281
|
+
const tool = getTool(agent, 'fs_info');
|
|
282
|
+
const result = await tool.execute({ path: 'sandbox/nope' });
|
|
283
|
+
expect(result.content.toLowerCase()).toContain('not found');
|
|
284
|
+
});
|
|
285
|
+
// ── Multi-directory mode ─────────────────────────────────────────
|
|
286
|
+
describe('multi-directory mode', () => {
|
|
287
|
+
let dirA;
|
|
288
|
+
let dirB;
|
|
289
|
+
beforeEach(() => {
|
|
290
|
+
dirA = mkdtempSync(join(tmpdir(), 'fs-a-'));
|
|
291
|
+
dirB = mkdtempSync(join(tmpdir(), 'fs-b-'));
|
|
292
|
+
});
|
|
293
|
+
afterEach(() => {
|
|
294
|
+
rmSync(dirA, { recursive: true, force: true });
|
|
295
|
+
rmSync(dirB, { recursive: true, force: true });
|
|
296
|
+
});
|
|
297
|
+
function makeMultiExt() {
|
|
298
|
+
return createFilesystemExtension({
|
|
299
|
+
directories: [
|
|
300
|
+
{ name: 'downloads', path: dirA },
|
|
301
|
+
{ name: 'documents', path: dirB },
|
|
302
|
+
],
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
it('saveBytes with prefix saves to the named directory', () => {
|
|
306
|
+
const ext = makeMultiExt();
|
|
307
|
+
ext.saveBytes('documents/info.txt', Buffer.from('ACME Inc'));
|
|
308
|
+
expect(readFileSync(join(dirB, 'info.txt'), 'utf-8')).toBe('ACME Inc');
|
|
309
|
+
expect(existsSync(join(dirA, 'info.txt'))).toBe(false);
|
|
310
|
+
});
|
|
311
|
+
it('saveBytes returns the full prefixed path', () => {
|
|
312
|
+
const ext = makeMultiExt();
|
|
313
|
+
const path = ext.saveBytes('documents/info.txt', Buffer.from('x'));
|
|
314
|
+
expect(path).toBe('documents/info.txt');
|
|
315
|
+
});
|
|
316
|
+
it('resolvePath resolves to the correct directory', () => {
|
|
317
|
+
const ext = makeMultiExt();
|
|
318
|
+
expect(ext.resolvePath('downloads/report.txt')).toBe(join(dirA, 'report.txt'));
|
|
319
|
+
expect(ext.resolvePath('documents/data.json')).toBe(join(dirB, 'data.json'));
|
|
320
|
+
});
|
|
321
|
+
it('resolvePath blocks traversal within a named directory', () => {
|
|
322
|
+
const ext = makeMultiExt();
|
|
323
|
+
expect(() => ext.resolvePath('downloads/../../../etc/passwd')).toThrow('escapes');
|
|
324
|
+
});
|
|
325
|
+
it('resolvePath rejects paths without a sandbox prefix', () => {
|
|
326
|
+
const ext = makeMultiExt();
|
|
327
|
+
expect(() => ext.resolvePath('file.txt')).toThrow('must start with a sandbox name');
|
|
328
|
+
});
|
|
329
|
+
it('fs_write writes to the named directory', async () => {
|
|
330
|
+
const ext = makeMultiExt();
|
|
331
|
+
const agent = makeAgent();
|
|
332
|
+
agent.use(ext);
|
|
333
|
+
const tool = getTool(agent, 'fs_write');
|
|
334
|
+
await tool.execute({ path: 'documents/notes.md', content: '# Company' });
|
|
335
|
+
expect(readFileSync(join(dirB, 'notes.md'), 'utf-8')).toBe('# Company');
|
|
336
|
+
});
|
|
337
|
+
it('fs_read reads from the named directory', async () => {
|
|
338
|
+
const ext = makeMultiExt();
|
|
339
|
+
ext.saveBytes('documents/readme.txt', Buffer.from('Hello'));
|
|
340
|
+
const agent = makeAgent();
|
|
341
|
+
agent.use(ext);
|
|
342
|
+
const tool = getTool(agent, 'fs_read');
|
|
343
|
+
const result = await tool.execute({ path: 'documents/readme.txt' });
|
|
344
|
+
expect(result.content).toContain('Hello');
|
|
345
|
+
});
|
|
346
|
+
it('fs_list with no path lists the sandbox directories', async () => {
|
|
347
|
+
const ext = makeMultiExt();
|
|
348
|
+
ext.saveBytes('downloads/a.txt', Buffer.from('x'));
|
|
349
|
+
const agent = makeAgent();
|
|
350
|
+
agent.use(ext);
|
|
351
|
+
const tool = getTool(agent, 'fs_list');
|
|
352
|
+
const result = await tool.execute({});
|
|
353
|
+
expect(result.content).toContain('downloads');
|
|
354
|
+
expect(result.content).toContain('documents');
|
|
355
|
+
});
|
|
356
|
+
it('fs_list with a sandbox name lists its contents', async () => {
|
|
357
|
+
const ext = makeMultiExt();
|
|
358
|
+
ext.saveBytes('documents/a.txt', Buffer.from('1'));
|
|
359
|
+
ext.saveBytes('documents/b.txt', Buffer.from('2'));
|
|
360
|
+
const agent = makeAgent();
|
|
361
|
+
agent.use(ext);
|
|
362
|
+
const tool = getTool(agent, 'fs_list');
|
|
363
|
+
const result = await tool.execute({ path: 'documents' });
|
|
364
|
+
expect(result.content).toContain('a.txt');
|
|
365
|
+
expect(result.content).toContain('b.txt');
|
|
366
|
+
});
|
|
367
|
+
it('fs_delete refuses to delete a sandbox root', async () => {
|
|
368
|
+
const ext = makeMultiExt();
|
|
369
|
+
const agent = makeAgent();
|
|
370
|
+
agent.use(ext);
|
|
371
|
+
const tool = getTool(agent, 'fs_delete');
|
|
372
|
+
const result = await tool.execute({ path: 'downloads' });
|
|
373
|
+
expect(result.content).toContain('Refusing');
|
|
374
|
+
});
|
|
375
|
+
it('fs_delete deletes a file within a named directory', async () => {
|
|
376
|
+
const ext = makeMultiExt();
|
|
377
|
+
ext.saveBytes('documents/temp.txt', Buffer.from('x'));
|
|
378
|
+
const agent = makeAgent();
|
|
379
|
+
agent.use(ext);
|
|
380
|
+
const tool = getTool(agent, 'fs_delete');
|
|
381
|
+
const result = await tool.execute({ path: 'documents/temp.txt' });
|
|
382
|
+
expect(result.content).toContain('Deleted');
|
|
383
|
+
expect(existsSync(join(dirB, 'temp.txt'))).toBe(false);
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
//# sourceMappingURL=extension.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.test.js","sourceRoot":"","sources":["../../../../src/extras/extensions/filesystem/extension.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/extras/extensions/filesystem/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/extras/extensions/filesystem/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Extension } from '../../../extension.js';
|
|
2
|
+
import type { QueryAnalyzer } from './nlp.js';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for {@link createKeywordExtractorExtension}.
|
|
5
|
+
*/
|
|
6
|
+
export interface KeywordExtractorConfig {
|
|
7
|
+
/**
|
|
8
|
+
* The {@link QueryAnalyzer} to use. Defaults to the process-wide
|
|
9
|
+
* shared winkNLP-backed analyzer. Pass a custom instance (e.g. a
|
|
10
|
+
* test double) to control extraction behavior.
|
|
11
|
+
*/
|
|
12
|
+
analyzer?: QueryAnalyzer;
|
|
13
|
+
/**
|
|
14
|
+
* Optional logger sink. Defaults to `console.log` with a
|
|
15
|
+
* `[keywords]` prefix. Receives the extracted terms and the source
|
|
16
|
+
* message for each user turn.
|
|
17
|
+
*/
|
|
18
|
+
log?: (entry: KeywordExtractionEntry) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A single keyword-extraction record emitted on each user turn.
|
|
22
|
+
*/
|
|
23
|
+
export interface KeywordExtractionEntry {
|
|
24
|
+
/** The user's message for this turn. */
|
|
25
|
+
message: string;
|
|
26
|
+
/** Extracted single-word search terms. */
|
|
27
|
+
terms: string[];
|
|
28
|
+
/** Extracted multi-word phrases (if any). */
|
|
29
|
+
phrases: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extension that extracts keywords from each user message and publishes
|
|
33
|
+
* them into the turn's enrichment bag (`ctx.turn.metadata.sessionMeta`)
|
|
34
|
+
* so downstream extensions — notably disk-session — can persist them
|
|
35
|
+
* without knowing what a "keyword" is.
|
|
36
|
+
*
|
|
37
|
+
* Hooks `beforeTurn` so it sees the incoming user message before the
|
|
38
|
+
* agent runs. It writes `sessionMeta.keywords = { terms, phrases }`,
|
|
39
|
+
* merging with any existing bag contents (other extensions may write
|
|
40
|
+
* their own keys). It also logs the extracted terms for observability.
|
|
41
|
+
*
|
|
42
|
+
* Must run before any extension that reads `sessionMeta` in `beforeTurn`
|
|
43
|
+
* (e.g. disk-session). This is enforced via `priority: 50` (higher
|
|
44
|
+
* than disk-session's -100), so `use()` call order doesn't matter.
|
|
45
|
+
*
|
|
46
|
+
* ```
|
|
47
|
+
* User message → QueryAnalyzer → sessionMeta.keywords → session persists
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* The analyzer is initialized once and reused across all turns.
|
|
51
|
+
*/
|
|
52
|
+
export default function createKeywordExtractorExtension(config?: KeywordExtractorConfig): Extension;
|
|
53
|
+
//# sourceMappingURL=extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../../src/extras/extensions/keyword-extractor/extension.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB;;;;OAIG;IACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,+BAA+B,CACrD,MAAM,CAAC,EAAE,sBAAsB,GAC9B,SAAS,CA2CX"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { messageContentToText } from '../../../types.js';
|
|
2
|
+
import { getQueryAnalyzer } from './nlp.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extension that extracts keywords from each user message and publishes
|
|
5
|
+
* them into the turn's enrichment bag (`ctx.turn.metadata.sessionMeta`)
|
|
6
|
+
* so downstream extensions — notably disk-session — can persist them
|
|
7
|
+
* without knowing what a "keyword" is.
|
|
8
|
+
*
|
|
9
|
+
* Hooks `beforeTurn` so it sees the incoming user message before the
|
|
10
|
+
* agent runs. It writes `sessionMeta.keywords = { terms, phrases }`,
|
|
11
|
+
* merging with any existing bag contents (other extensions may write
|
|
12
|
+
* their own keys). It also logs the extracted terms for observability.
|
|
13
|
+
*
|
|
14
|
+
* Must run before any extension that reads `sessionMeta` in `beforeTurn`
|
|
15
|
+
* (e.g. disk-session). This is enforced via `priority: 50` (higher
|
|
16
|
+
* than disk-session's -100), so `use()` call order doesn't matter.
|
|
17
|
+
*
|
|
18
|
+
* ```
|
|
19
|
+
* User message → QueryAnalyzer → sessionMeta.keywords → session persists
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* The analyzer is initialized once and reused across all turns.
|
|
23
|
+
*/
|
|
24
|
+
export default function createKeywordExtractorExtension(config) {
|
|
25
|
+
const analyzer = config?.analyzer ?? getQueryAnalyzer();
|
|
26
|
+
const log = config?.log ??
|
|
27
|
+
((entry) => {
|
|
28
|
+
const parts = [`[keywords] terms=[${entry.terms.join(', ')}]`];
|
|
29
|
+
if (entry.phrases.length > 0) {
|
|
30
|
+
parts.push(`phrases=[${entry.phrases.join(', ')}]`);
|
|
31
|
+
}
|
|
32
|
+
console.log(parts.join(' '));
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
name: 'keyword-extractor',
|
|
36
|
+
// Higher than disk-session (-100) so our beforeTurn hook runs
|
|
37
|
+
// first and sessionMeta.keywords is populated before disk-session
|
|
38
|
+
// persists the user record. Priority makes this independent of
|
|
39
|
+
// use() call order.
|
|
40
|
+
priority: 50,
|
|
41
|
+
install(agent) {
|
|
42
|
+
agent.hook('beforeTurn', 'keyword-extractor', async (ctx) => {
|
|
43
|
+
const message = messageContentToText(ctx.turn.request.message);
|
|
44
|
+
const { terms, phrases } = analyzer.analyze(message);
|
|
45
|
+
// Publish into the enrichment bag. Merge — don't overwrite —
|
|
46
|
+
// so other extensions writing their own keys are preserved.
|
|
47
|
+
const existing = (ctx.turn.metadata.sessionMeta ?? {});
|
|
48
|
+
ctx.turn.metadata.sessionMeta = {
|
|
49
|
+
...existing,
|
|
50
|
+
keywords: { terms, phrases: phrases ?? [] },
|
|
51
|
+
};
|
|
52
|
+
log({
|
|
53
|
+
message,
|
|
54
|
+
terms,
|
|
55
|
+
phrases: phrases ?? [],
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../../src/extras/extensions/keyword-extractor/extension.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAgC5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,+BAA+B,CACrD,MAA+B;IAE/B,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,EAAE,CAAC;IACxD,MAAM,GAAG,GACP,MAAM,EAAE,GAAG;QACX,CAAC,CAAC,KAAK,EAAE,EAAE;YACT,MAAM,KAAK,GAAG,CAAC,qBAAqB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,8DAA8D;QAC9D,kEAAkE;QAClE,+DAA+D;QAC/D,oBAAoB;QACpB,QAAQ,EAAE,EAAE;QACZ,OAAO,CAAC,KAAK;YACX,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC1D,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC/D,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAErD,6DAA6D;gBAC7D,4DAA4D;gBAC5D,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,EAAE,CAGpD,CAAC;gBACF,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,GAAG;oBAC9B,GAAG,QAAQ;oBACX,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE;iBAC5C,CAAC;gBAEF,GAAG,CAAC;oBACF,OAAO;oBACP,KAAK;oBACL,OAAO,EAAE,OAAO,IAAI,EAAE;iBACvB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "keyword-extractor",
|
|
3
|
+
"description": "Extracts winkNLP keywords from each user message and publishes them into sessionMeta for persistence. Also logs them for observability. Must run before disk-session (priority 50 > -100).",
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"priority": 50
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.test.d.ts","sourceRoot":"","sources":["../../../../src/extras/extensions/keyword-extractor/extension.test.ts"],"names":[],"mappings":""}
|