joonecli 0.2.0 → 0.2.1
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/__tests__/config.test.js +1 -0
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/installHostDeps.test.js +45 -0
- package/dist/__tests__/installHostDeps.test.js.map +1 -0
- package/dist/__tests__/whitelistedBackend.test.js +18 -0
- package/dist/__tests__/whitelistedBackend.test.js.map +1 -0
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.js +1 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/index.js +84 -100
- package/dist/cli/index.js.map +1 -1
- package/dist/core/agentLoop.d.ts +10 -29
- package/dist/core/agentLoop.js +66 -237
- package/dist/core/agentLoop.js.map +1 -1
- package/dist/core/promptBuilder.js.map +1 -1
- package/dist/hitl/bridge.js +1 -27
- package/dist/hitl/bridge.js.map +1 -1
- package/dist/middleware/loopDetection.d.ts +7 -23
- package/dist/middleware/loopDetection.js +38 -42
- package/dist/middleware/loopDetection.js.map +1 -1
- package/dist/sandbox/whitelistedBackend.d.ts +5 -0
- package/dist/sandbox/whitelistedBackend.js +27 -0
- package/dist/sandbox/whitelistedBackend.js.map +1 -0
- package/dist/tools/askUser.d.ts +12 -3
- package/dist/tools/askUser.js +16 -28
- package/dist/tools/askUser.js.map +1 -1
- package/dist/tools/bashTool.d.ts +11 -0
- package/dist/tools/bashTool.js +51 -0
- package/dist/tools/bashTool.js.map +1 -0
- package/dist/tools/index.d.ts +15 -28
- package/dist/tools/index.js +9 -189
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/installHostDeps.d.ts +8 -2
- package/dist/tools/installHostDeps.js +38 -31
- package/dist/tools/installHostDeps.js.map +1 -1
- package/dist/ui/App.js +112 -56
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/MessageBubble.js +1 -1
- package/dist/ui/components/MessageBubble.js.map +1 -1
- package/package.json +7 -2
- package/dist/__tests__/m55.test.js +0 -160
- package/dist/__tests__/m55.test.js.map +0 -1
- package/dist/__tests__/middleware.test.js +0 -169
- package/dist/__tests__/middleware.test.js.map +0 -1
- package/dist/__tests__/optimizations.test.d.ts +0 -1
- package/dist/__tests__/optimizations.test.js +0 -136
- package/dist/__tests__/optimizations.test.js.map +0 -1
- package/dist/__tests__/security.test.d.ts +0 -1
- package/dist/__tests__/security.test.js +0 -86
- package/dist/__tests__/security.test.js.map +0 -1
- package/dist/__tests__/streaming.test.d.ts +0 -1
- package/dist/__tests__/streaming.test.js +0 -71
- package/dist/__tests__/streaming.test.js.map +0 -1
- package/dist/__tests__/toolRouter.test.d.ts +0 -1
- package/dist/__tests__/toolRouter.test.js +0 -37
- package/dist/__tests__/toolRouter.test.js.map +0 -1
- package/dist/__tests__/tools.test.d.ts +0 -1
- package/dist/__tests__/tools.test.js +0 -112
- package/dist/__tests__/tools.test.js.map +0 -1
- package/dist/core/subAgent.d.ts +0 -56
- package/dist/core/subAgent.js +0 -240
- package/dist/core/subAgent.js.map +0 -1
- package/dist/debug_google.d.ts +0 -1
- package/dist/debug_google.js +0 -23
- package/dist/debug_google.js.map +0 -1
- package/dist/middleware/commandSanitizer.d.ts +0 -18
- package/dist/middleware/commandSanitizer.js +0 -50
- package/dist/middleware/commandSanitizer.js.map +0 -1
- package/dist/middleware/permission.d.ts +0 -17
- package/dist/middleware/permission.js +0 -60
- package/dist/middleware/permission.js.map +0 -1
- package/dist/middleware/pipeline.d.ts +0 -31
- package/dist/middleware/pipeline.js +0 -62
- package/dist/middleware/pipeline.js.map +0 -1
- package/dist/middleware/preCompletion.d.ts +0 -29
- package/dist/middleware/preCompletion.js +0 -82
- package/dist/middleware/preCompletion.js.map +0 -1
- package/dist/middleware/types.d.ts +0 -40
- package/dist/middleware/types.js +0 -8
- package/dist/middleware/types.js.map +0 -1
- package/dist/skills/loader.d.ts +0 -55
- package/dist/skills/loader.js +0 -132
- package/dist/skills/loader.js.map +0 -1
- package/dist/skills/tools.d.ts +0 -5
- package/dist/skills/tools.js +0 -78
- package/dist/skills/tools.js.map +0 -1
- package/dist/test_cache.d.ts +0 -1
- package/dist/test_cache.js +0 -55
- package/dist/test_cache.js.map +0 -1
- package/dist/test_google.d.ts +0 -1
- package/dist/test_google.js +0 -36
- package/dist/test_google.js.map +0 -1
- package/dist/tools/browser.d.ts +0 -19
- package/dist/tools/browser.js +0 -114
- package/dist/tools/browser.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -31
- package/dist/tools/registry.js +0 -168
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/router.d.ts +0 -34
- package/dist/tools/router.js +0 -76
- package/dist/tools/router.js.map +0 -1
- package/dist/tools/security.d.ts +0 -28
- package/dist/tools/security.js +0 -183
- package/dist/tools/security.js.map +0 -1
- package/dist/tools/spawnAgent.d.ts +0 -19
- package/dist/tools/spawnAgent.js +0 -132
- package/dist/tools/spawnAgent.js.map +0 -1
- package/dist/tools/webSearch.d.ts +0 -6
- package/dist/tools/webSearch.js +0 -120
- package/dist/tools/webSearch.js.map +0 -1
- /package/dist/__tests__/{m55.test.d.ts → installHostDeps.test.d.ts} +0 -0
- /package/dist/__tests__/{middleware.test.d.ts → whitelistedBackend.test.d.ts} +0 -0
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { MiddlewarePipeline } from "../middleware/pipeline.js";
|
|
3
|
-
import { LoopDetectionMiddleware } from "../middleware/loopDetection.js";
|
|
4
|
-
import { CommandSanitizerMiddleware } from "../middleware/commandSanitizer.js";
|
|
5
|
-
import { PreCompletionMiddleware } from "../middleware/preCompletion.js";
|
|
6
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
-
// Pipeline Core
|
|
8
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
9
|
-
describe("MiddlewarePipeline", () => {
|
|
10
|
-
const makeCtx = (overrides) => ({
|
|
11
|
-
toolName: "bash",
|
|
12
|
-
args: { command: "echo hello" },
|
|
13
|
-
callId: "call-1",
|
|
14
|
-
...overrides,
|
|
15
|
-
});
|
|
16
|
-
// ─── Test #44: Runs before/after hooks in order ───
|
|
17
|
-
it("runs before hooks in registration order and after hooks in reverse", async () => {
|
|
18
|
-
const order = [];
|
|
19
|
-
const pipeline = new MiddlewarePipeline();
|
|
20
|
-
pipeline.use({
|
|
21
|
-
name: "A",
|
|
22
|
-
before: (ctx) => { order.push("A:before"); return ctx; },
|
|
23
|
-
after: (_ctx, r) => { order.push("A:after"); return r; },
|
|
24
|
-
});
|
|
25
|
-
pipeline.use({
|
|
26
|
-
name: "B",
|
|
27
|
-
before: (ctx) => { order.push("B:before"); return ctx; },
|
|
28
|
-
after: (_ctx, r) => { order.push("B:after"); return r; },
|
|
29
|
-
});
|
|
30
|
-
const executeFn = vi.fn(async () => ({ content: "result" }));
|
|
31
|
-
await pipeline.run(makeCtx(), executeFn);
|
|
32
|
-
expect(order).toEqual(["A:before", "B:before", "B:after", "A:after"]);
|
|
33
|
-
expect(executeFn).toHaveBeenCalledOnce();
|
|
34
|
-
});
|
|
35
|
-
// ─── Test #45: Short-circuits when before returns string ───
|
|
36
|
-
it("short-circuits and does NOT execute the tool when before returns a string", async () => {
|
|
37
|
-
const pipeline = new MiddlewarePipeline();
|
|
38
|
-
pipeline.use({
|
|
39
|
-
name: "Blocker",
|
|
40
|
-
before: () => "⚠ Blocked!",
|
|
41
|
-
});
|
|
42
|
-
const executeFn = vi.fn(async () => ({ content: "should not reach this" }));
|
|
43
|
-
const result = await pipeline.run(makeCtx(), executeFn);
|
|
44
|
-
expect(result).toBe("⚠ Blocked!");
|
|
45
|
-
expect(executeFn).not.toHaveBeenCalled();
|
|
46
|
-
});
|
|
47
|
-
// ─── Test #46: After hooks can transform the result ───
|
|
48
|
-
it("after hooks can transform the tool result", async () => {
|
|
49
|
-
const pipeline = new MiddlewarePipeline();
|
|
50
|
-
pipeline.use({
|
|
51
|
-
name: "Uppercaser",
|
|
52
|
-
after: (_ctx, result) => { result.content = result.content.toUpperCase(); return result; },
|
|
53
|
-
});
|
|
54
|
-
const result = await pipeline.run(makeCtx(), async () => ({ content: "hello" }));
|
|
55
|
-
expect(result).toBe("HELLO");
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
59
|
-
// LoopDetectionMiddleware
|
|
60
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
61
|
-
describe("LoopDetectionMiddleware", () => {
|
|
62
|
-
const makeCtx = (cmd = "echo hello") => ({
|
|
63
|
-
toolName: "bash",
|
|
64
|
-
args: { command: cmd },
|
|
65
|
-
callId: "call-x",
|
|
66
|
-
});
|
|
67
|
-
// ─── Test #47: Allows first 2 identical calls ───
|
|
68
|
-
it("allows calls below the threshold", () => {
|
|
69
|
-
const mw = new LoopDetectionMiddleware(3);
|
|
70
|
-
expect(mw.before(makeCtx())).toEqual(makeCtx());
|
|
71
|
-
expect(mw.before(makeCtx())).toEqual(makeCtx());
|
|
72
|
-
});
|
|
73
|
-
// ─── Test #48: Blocks on 3rd identical call ───
|
|
74
|
-
it("blocks on the Nth identical consecutive call", () => {
|
|
75
|
-
const mw = new LoopDetectionMiddleware(3);
|
|
76
|
-
mw.before(makeCtx());
|
|
77
|
-
mw.before(makeCtx());
|
|
78
|
-
const result = mw.before(makeCtx());
|
|
79
|
-
expect(typeof result).toBe("string");
|
|
80
|
-
expect(result).toMatch(/loop detected/i);
|
|
81
|
-
});
|
|
82
|
-
// ─── Test #49: Resets when args change ───
|
|
83
|
-
it("resets the count when a different call is made", () => {
|
|
84
|
-
const mw = new LoopDetectionMiddleware(3);
|
|
85
|
-
mw.before(makeCtx("echo a"));
|
|
86
|
-
mw.before(makeCtx("echo a"));
|
|
87
|
-
// Different call breaks the streak
|
|
88
|
-
mw.before(makeCtx("echo b"));
|
|
89
|
-
// Back to "echo a" — only 1 in a row now
|
|
90
|
-
const result = mw.before(makeCtx("echo a"));
|
|
91
|
-
expect(typeof result).not.toBe("string");
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
95
|
-
// CommandSanitizerMiddleware
|
|
96
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
97
|
-
describe("CommandSanitizerMiddleware", () => {
|
|
98
|
-
const mw = new CommandSanitizerMiddleware();
|
|
99
|
-
const makeCtx = (cmd) => ({
|
|
100
|
-
toolName: "bash",
|
|
101
|
-
args: { command: cmd },
|
|
102
|
-
callId: "call-x",
|
|
103
|
-
});
|
|
104
|
-
// ─── Test #50: Blocks rm -rf / ───
|
|
105
|
-
it("blocks rm -rf /", () => {
|
|
106
|
-
const result = mw.before(makeCtx("rm -rf /"));
|
|
107
|
-
expect(typeof result).toBe("string");
|
|
108
|
-
expect(result).toMatch(/blocked/i);
|
|
109
|
-
});
|
|
110
|
-
// ─── Test #51: Blocks interactive commands ───
|
|
111
|
-
it("blocks interactive commands like vim", () => {
|
|
112
|
-
const result = mw.before(makeCtx("vim src/index.ts"));
|
|
113
|
-
expect(typeof result).toBe("string");
|
|
114
|
-
expect(result).toMatch(/interactive/i);
|
|
115
|
-
});
|
|
116
|
-
// ─── Test #52: Allows safe commands ───
|
|
117
|
-
it("allows safe commands through", () => {
|
|
118
|
-
const result = mw.before(makeCtx("npm test"));
|
|
119
|
-
expect(result).toEqual(makeCtx("npm test"));
|
|
120
|
-
});
|
|
121
|
-
// ─── Test #53: Ignores non-bash tools ───
|
|
122
|
-
it("ignores non-bash tool calls entirely", () => {
|
|
123
|
-
const ctx = {
|
|
124
|
-
toolName: "read_file",
|
|
125
|
-
args: { path: "/etc/passwd" },
|
|
126
|
-
callId: "call-x",
|
|
127
|
-
};
|
|
128
|
-
expect(mw.before(ctx)).toEqual(ctx);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
132
|
-
// PreCompletionMiddleware
|
|
133
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
134
|
-
describe("PreCompletionMiddleware", () => {
|
|
135
|
-
// ─── Test #54: Blocks completion without tests ───
|
|
136
|
-
it("blocks task_complete when no tests have been run", () => {
|
|
137
|
-
const mw = new PreCompletionMiddleware();
|
|
138
|
-
const ctx = {
|
|
139
|
-
toolName: "task_complete",
|
|
140
|
-
args: {},
|
|
141
|
-
callId: "call-x",
|
|
142
|
-
};
|
|
143
|
-
const result = mw.before(ctx);
|
|
144
|
-
expect(typeof result).toBe("string");
|
|
145
|
-
expect(result).toMatch(/must run tests/i);
|
|
146
|
-
});
|
|
147
|
-
// ─── Test #55: Allows completion after tests ───
|
|
148
|
-
it("allows task_complete after a test command has been run", () => {
|
|
149
|
-
const mw = new PreCompletionMiddleware();
|
|
150
|
-
// Simulate running tests
|
|
151
|
-
const testCtx = {
|
|
152
|
-
toolName: "bash",
|
|
153
|
-
args: { command: "npm test" },
|
|
154
|
-
callId: "call-1",
|
|
155
|
-
};
|
|
156
|
-
mw.before(testCtx);
|
|
157
|
-
mw.after(testCtx, { content: "tests passed", metadata: { exitCode: 0 }, isError: false });
|
|
158
|
-
expect(mw.hasPassedTests()).toBe(true);
|
|
159
|
-
// Now try completion
|
|
160
|
-
const completeCtx = {
|
|
161
|
-
toolName: "task_complete",
|
|
162
|
-
args: {},
|
|
163
|
-
callId: "call-2",
|
|
164
|
-
};
|
|
165
|
-
const result = mw.before(completeCtx);
|
|
166
|
-
expect(result).toEqual(completeCtx);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
//# sourceMappingURL=middleware.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.test.js","sourceRoot":"","sources":["../../src/__tests__/middleware.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
-
import { HumanMessage, AIMessage } from "@langchain/core/messages";
|
|
3
|
-
import { SearchToolsTool, ActivateToolTool, activateTool, getActivatedTools, resetActivatedTools, } from "../tools/registry.js";
|
|
4
|
-
import { estimateTokens, countMessageTokens, isNearCapacity, } from "../core/tokenCounter.js";
|
|
5
|
-
import { CacheOptimizedPromptBuilder } from "../core/promptBuilder.js";
|
|
6
|
-
import { ReasoningRouter, ReasoningLevel, } from "../core/reasoningRouter.js";
|
|
7
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
8
|
-
// 5a: Enhanced Tool Registry
|
|
9
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
10
|
-
describe("Enhanced Tool Registry", () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
resetActivatedTools();
|
|
13
|
-
});
|
|
14
|
-
// ─── Test #56: Fuzzy search matches by description keyword ───
|
|
15
|
-
it("fuzzy search matches tools by description keyword", async () => {
|
|
16
|
-
const result = await SearchToolsTool.execute({ query: "commit" });
|
|
17
|
-
expect(result.content).toContain("git_commit");
|
|
18
|
-
});
|
|
19
|
-
// ─── Test #57: Fuzzy search matches by name ───
|
|
20
|
-
it("fuzzy search matches tools by name", async () => {
|
|
21
|
-
const result = await SearchToolsTool.execute({ query: "grep" });
|
|
22
|
-
expect(result.content).toContain("grep_search");
|
|
23
|
-
});
|
|
24
|
-
// ─── Test #58: activateTool adds tool to the active set ───
|
|
25
|
-
it("activateTool adds a tool to the active set", () => {
|
|
26
|
-
expect(getActivatedTools()).toHaveLength(0);
|
|
27
|
-
const tool = activateTool("git_commit");
|
|
28
|
-
expect(tool).toBeDefined();
|
|
29
|
-
expect(tool.name).toBe("git_commit");
|
|
30
|
-
expect(getActivatedTools()).toHaveLength(1);
|
|
31
|
-
});
|
|
32
|
-
// ─── Test #59: ActivateToolTool returns schema on activation ───
|
|
33
|
-
it("ActivateToolTool returns the schema on successful activation", async () => {
|
|
34
|
-
const result = await ActivateToolTool.execute({ name: "git_diff" });
|
|
35
|
-
expect(result.content).toContain("activated");
|
|
36
|
-
expect(result.content).toContain("Schema");
|
|
37
|
-
expect(getActivatedTools()).toHaveLength(1);
|
|
38
|
-
});
|
|
39
|
-
// ─── Test #60: ActivateToolTool returns error for unknown tool ───
|
|
40
|
-
it("ActivateToolTool returns error for unknown tool", async () => {
|
|
41
|
-
const result = await ActivateToolTool.execute({ name: "nonexistent" });
|
|
42
|
-
expect(result.content).toMatch(/not found/i);
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
46
|
-
// 5b: Token Counter & Context Compaction
|
|
47
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
48
|
-
describe("Token Counter", () => {
|
|
49
|
-
// ─── Test #61: Estimates tokens for short string ───
|
|
50
|
-
it("estimates tokens using ~4 chars per token", () => {
|
|
51
|
-
const tokens = estimateTokens("Hello world!"); // 12 chars → 3 tokens
|
|
52
|
-
expect(tokens).toBe(3);
|
|
53
|
-
});
|
|
54
|
-
// ─── Test #62: Counts tokens across messages ───
|
|
55
|
-
it("counts tokens across multiple messages", () => {
|
|
56
|
-
const messages = [
|
|
57
|
-
new HumanMessage("Hello"), // 5 chars → 2 tokens + 4 overhead = 6
|
|
58
|
-
new AIMessage("Hi there"), // 8 chars → 2 tokens + 4 overhead = 6
|
|
59
|
-
];
|
|
60
|
-
const total = countMessageTokens(messages);
|
|
61
|
-
expect(total).toBeGreaterThan(0);
|
|
62
|
-
expect(total).toBe(12); // (2+4) + (2+4)
|
|
63
|
-
});
|
|
64
|
-
// ─── Test #63: isNearCapacity detects threshold ───
|
|
65
|
-
it("returns true when messages exceed 80% of capacity", () => {
|
|
66
|
-
// Create a big message ~320 chars → ~80 tokens
|
|
67
|
-
const bigMsg = new HumanMessage("x".repeat(320));
|
|
68
|
-
const messages = [bigMsg];
|
|
69
|
-
// maxTokens=100, threshold=0.8 → trigger at 80 tokens
|
|
70
|
-
// 320/4=80 + 4 overhead = 84 > 80
|
|
71
|
-
expect(isNearCapacity(messages, 100, 0.8)).toBe(true);
|
|
72
|
-
});
|
|
73
|
-
// ─── Test #64: isNearCapacity returns false below threshold ───
|
|
74
|
-
it("returns false when well below capacity", () => {
|
|
75
|
-
const messages = [new HumanMessage("short")];
|
|
76
|
-
expect(isNearCapacity(messages, 100000, 0.8)).toBe(false);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
describe("Context Compaction", () => {
|
|
80
|
-
// ─── Test #65: compactHistory preserves last N messages ───
|
|
81
|
-
it("preserves the last N messages and prepends summary", () => {
|
|
82
|
-
const builder = new CacheOptimizedPromptBuilder();
|
|
83
|
-
const history = [
|
|
84
|
-
new HumanMessage("msg 1"),
|
|
85
|
-
new AIMessage("response 1"),
|
|
86
|
-
new HumanMessage("msg 2"),
|
|
87
|
-
new AIMessage("response 2"),
|
|
88
|
-
new HumanMessage("msg 3"),
|
|
89
|
-
new AIMessage("response 3"),
|
|
90
|
-
];
|
|
91
|
-
const compacted = builder.compactHistory(history, "Summary of turns 1-2.", 4);
|
|
92
|
-
// Should have: 1 summary + 4 preserved
|
|
93
|
-
expect(compacted).toHaveLength(5);
|
|
94
|
-
expect(compacted[0].content).toContain("compacted");
|
|
95
|
-
expect(compacted[0].content).toContain("Summary of turns 1-2.");
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
99
|
-
// 5c: Reasoning Sandwich
|
|
100
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
101
|
-
describe("ReasoningRouter", () => {
|
|
102
|
-
// ─── Test #66: First turns are HIGH (planning) ───
|
|
103
|
-
it("returns HIGH for the first turn (planning phase)", () => {
|
|
104
|
-
const router = new ReasoningRouter();
|
|
105
|
-
router.advanceTurn(false, false);
|
|
106
|
-
const level = router.getLevel();
|
|
107
|
-
expect(level).toBe(ReasoningLevel.HIGH);
|
|
108
|
-
});
|
|
109
|
-
// ─── Test #67: Tool-heavy turns are MEDIUM ───
|
|
110
|
-
it("returns MEDIUM for tool-heavy turns after planning", () => {
|
|
111
|
-
const router = new ReasoningRouter({ planningTurns: 1 });
|
|
112
|
-
router.advanceTurn(false, false); // turn 1
|
|
113
|
-
router.getLevel(); // HIGH (planning)
|
|
114
|
-
router.advanceTurn(true, false); // turn 2
|
|
115
|
-
const level = router.getLevel(); // tool call shouldn't be high
|
|
116
|
-
expect(level).toBe(ReasoningLevel.MEDIUM);
|
|
117
|
-
});
|
|
118
|
-
// ─── Test #68: Post-error turns are HIGH (recovery) ───
|
|
119
|
-
it("returns HIGH for recovery after an error", () => {
|
|
120
|
-
const router = new ReasoningRouter({ planningTurns: 1 });
|
|
121
|
-
router.advanceTurn(false, false); // turn 1
|
|
122
|
-
router.getLevel(); // planning
|
|
123
|
-
router.advanceTurn(true, false); // turn 2
|
|
124
|
-
router.getLevel(); // tool call (MEDIUM)
|
|
125
|
-
router.advanceTurn(false, true); // turn 3
|
|
126
|
-
const level = router.getLevel(); // error!
|
|
127
|
-
expect(level).toBe(ReasoningLevel.HIGH);
|
|
128
|
-
});
|
|
129
|
-
// ─── Test #69: Temperature mapping ───
|
|
130
|
-
it("maps reasoning levels to correct temperatures", () => {
|
|
131
|
-
const router = new ReasoningRouter({ highTemp: 0, mediumTemp: 0.3 });
|
|
132
|
-
expect(router.getTemperature(ReasoningLevel.HIGH)).toBe(0);
|
|
133
|
-
expect(router.getTemperature(ReasoningLevel.MEDIUM)).toBe(0.3);
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
//# sourceMappingURL=optimizations.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"optimizations.test.js","sourceRoot":"","sources":["../../src/__tests__/optimizations.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { SecurityScanTool, DepScanTool, bindSecuritySandbox, } from "../tools/security.js";
|
|
3
|
-
import { LazyInstaller } from "../sandbox/bootstrap.js";
|
|
4
|
-
// Helpers
|
|
5
|
-
const createMockSandbox = (active = true) => ({
|
|
6
|
-
exec: vi.fn(),
|
|
7
|
-
isActive: vi.fn().mockReturnValue(active),
|
|
8
|
-
create: vi.fn(),
|
|
9
|
-
destroy: vi.fn(),
|
|
10
|
-
uploadFile: vi.fn(),
|
|
11
|
-
getSandbox: vi.fn(),
|
|
12
|
-
});
|
|
13
|
-
describe("SecurityScanTool", () => {
|
|
14
|
-
let mockSandbox;
|
|
15
|
-
let installer;
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
vi.clearAllMocks();
|
|
18
|
-
mockSandbox = createMockSandbox();
|
|
19
|
-
// Use custom template mode so ensureGeminiCli is instant
|
|
20
|
-
installer = new LazyInstaller(true);
|
|
21
|
-
bindSecuritySandbox(mockSandbox, installer);
|
|
22
|
-
});
|
|
23
|
-
// ─── Test #39: Runs security:analyze and returns report ───
|
|
24
|
-
it("runs gemini security:analyze and returns the report", async () => {
|
|
25
|
-
mockSandbox.exec.mockResolvedValueOnce({
|
|
26
|
-
exitCode: 0,
|
|
27
|
-
stdout: "## Security Report\n\nNo critical vulnerabilities found.",
|
|
28
|
-
stderr: "",
|
|
29
|
-
});
|
|
30
|
-
const result = await SecurityScanTool.execute({ target: "changes" });
|
|
31
|
-
expect(result.content).toContain("Security Report");
|
|
32
|
-
expect(mockSandbox.exec).toHaveBeenCalledWith(expect.stringContaining("security:analyze"));
|
|
33
|
-
});
|
|
34
|
-
// ─── Test #40: Returns error for file scan without path ───
|
|
35
|
-
it("returns error when target is 'file' but no path provided", async () => {
|
|
36
|
-
const result = await SecurityScanTool.execute({ target: "file" });
|
|
37
|
-
expect(result.content).toMatch(/path.*required/i);
|
|
38
|
-
});
|
|
39
|
-
// ─── Test #41: Handles failed scans gracefully ───
|
|
40
|
-
it("returns failure info when scan exits with non-zero code", async () => {
|
|
41
|
-
mockSandbox.exec.mockResolvedValueOnce({
|
|
42
|
-
exitCode: 1,
|
|
43
|
-
stdout: "",
|
|
44
|
-
stderr: "Some error occurred",
|
|
45
|
-
});
|
|
46
|
-
const result = await SecurityScanTool.execute({ target: "changes" });
|
|
47
|
-
expect(result.content).toContain("failed");
|
|
48
|
-
expect(result.content).toContain("Some error occurred");
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
describe("DepScanTool", () => {
|
|
52
|
-
let mockSandbox;
|
|
53
|
-
let installer;
|
|
54
|
-
beforeEach(() => {
|
|
55
|
-
vi.clearAllMocks();
|
|
56
|
-
mockSandbox = createMockSandbox();
|
|
57
|
-
installer = new LazyInstaller(true); // pre-baked template
|
|
58
|
-
bindSecuritySandbox(mockSandbox, installer);
|
|
59
|
-
});
|
|
60
|
-
// ─── Test #42: OSV-Scanner returns vulnerability report ───
|
|
61
|
-
it("runs osv-scanner and returns the report", async () => {
|
|
62
|
-
mockSandbox.exec.mockResolvedValueOnce({
|
|
63
|
-
exitCode: 0,
|
|
64
|
-
stdout: "Found 2 vulnerabilities:\n- CVE-2024-1234\n- CVE-2024-5678",
|
|
65
|
-
stderr: "",
|
|
66
|
-
});
|
|
67
|
-
const result = await DepScanTool.execute({ format: "summary" });
|
|
68
|
-
expect(result.content).toContain("CVE-2024-1234");
|
|
69
|
-
expect(result.content).toContain("CVE-2024-5678");
|
|
70
|
-
});
|
|
71
|
-
// ─── Test #43: Falls back to npm audit when OSV-Scanner fails ───
|
|
72
|
-
it("falls back to npm audit if osv-scanner returns empty output", async () => {
|
|
73
|
-
// OSV-Scanner: empty output
|
|
74
|
-
mockSandbox.exec
|
|
75
|
-
.mockResolvedValueOnce({ exitCode: 1, stdout: "", stderr: "error" })
|
|
76
|
-
// npm audit fallback
|
|
77
|
-
.mockResolvedValueOnce({
|
|
78
|
-
exitCode: 0,
|
|
79
|
-
stdout: "found 0 vulnerabilities",
|
|
80
|
-
stderr: "",
|
|
81
|
-
});
|
|
82
|
-
const result = await DepScanTool.execute({ format: "summary" });
|
|
83
|
-
expect(result.content).toContain("0 vulnerabilities");
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
//# sourceMappingURL=security.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"security.test.js","sourceRoot":"","sources":["../../src/__tests__/security.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { AIMessageChunk } from "@langchain/core/messages";
|
|
3
|
-
import { ExecutionHarness } from "../core/agentLoop.js";
|
|
4
|
-
/**
|
|
5
|
-
* Creates a mock LLM that yields predefined chunks when .stream() is called.
|
|
6
|
-
* This avoids real API calls while testing streaming behavior.
|
|
7
|
-
*/
|
|
8
|
-
function createMockStreamingLlm(chunks) {
|
|
9
|
-
return {
|
|
10
|
-
invoke: vi.fn(),
|
|
11
|
-
stream: vi.fn().mockResolvedValue({
|
|
12
|
-
async *[Symbol.asyncIterator]() {
|
|
13
|
-
for (const chunk of chunks) {
|
|
14
|
-
yield chunk;
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
}),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
describe("ExecutionHarness Streaming", () => {
|
|
21
|
-
const baseState = {
|
|
22
|
-
globalSystemInstructions: "You are a helpful assistant.",
|
|
23
|
-
projectMemory: "",
|
|
24
|
-
sessionContext: "",
|
|
25
|
-
conversationHistory: [],
|
|
26
|
-
};
|
|
27
|
-
// ─── RED Test #8: streamStep emits text chunks to a callback ───
|
|
28
|
-
it("emits text content chunks to an onToken callback", async () => {
|
|
29
|
-
const chunks = [
|
|
30
|
-
new AIMessageChunk({ content: "Hello" }),
|
|
31
|
-
new AIMessageChunk({ content: " world" }),
|
|
32
|
-
new AIMessageChunk({ content: "!" }),
|
|
33
|
-
];
|
|
34
|
-
const mockLlm = createMockStreamingLlm(chunks);
|
|
35
|
-
const harness = new ExecutionHarness(mockLlm);
|
|
36
|
-
const receivedTokens = [];
|
|
37
|
-
const result = await harness.streamStep(baseState, {
|
|
38
|
-
onToken: (token) => receivedTokens.push(token),
|
|
39
|
-
});
|
|
40
|
-
// Callback should have received each text chunk
|
|
41
|
-
expect(receivedTokens).toEqual(["Hello", " world", "!"]);
|
|
42
|
-
// The returned message should contain the full concatenated content
|
|
43
|
-
expect(result.content).toBe("Hello world!");
|
|
44
|
-
});
|
|
45
|
-
// ─── RED Test #9: streamStep buffers tool calls and returns complete AIMessage ───
|
|
46
|
-
it("buffers tool call chunks and returns a complete AIMessage with tool_calls", async () => {
|
|
47
|
-
const chunks = [
|
|
48
|
-
new AIMessageChunk({
|
|
49
|
-
content: "",
|
|
50
|
-
tool_call_chunks: [
|
|
51
|
-
{ name: "read_file", args: '{"path": "', index: 0, id: "tc_1", type: "tool_call_chunk" },
|
|
52
|
-
],
|
|
53
|
-
}),
|
|
54
|
-
new AIMessageChunk({
|
|
55
|
-
content: "",
|
|
56
|
-
tool_call_chunks: [
|
|
57
|
-
{ name: undefined, args: 'src/index.ts"}', index: 0, id: undefined, type: "tool_call_chunk" },
|
|
58
|
-
],
|
|
59
|
-
}),
|
|
60
|
-
];
|
|
61
|
-
const mockLlm = createMockStreamingLlm(chunks);
|
|
62
|
-
const harness = new ExecutionHarness(mockLlm);
|
|
63
|
-
const result = await harness.streamStep(baseState, {});
|
|
64
|
-
// The result should have tool_calls populated
|
|
65
|
-
expect(result.tool_calls).toBeDefined();
|
|
66
|
-
expect(result.tool_calls.length).toBe(1);
|
|
67
|
-
expect(result.tool_calls[0].name).toBe("read_file");
|
|
68
|
-
expect(result.tool_calls[0].args).toEqual({ path: "src/index.ts" });
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
//# sourceMappingURL=streaming.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"streaming.test.js","sourceRoot":"","sources":["../../src/__tests__/streaming.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
-
import { ToolRouter, ToolTarget } from "../tools/router.js";
|
|
3
|
-
describe("Tool Router", () => {
|
|
4
|
-
let router;
|
|
5
|
-
beforeEach(() => {
|
|
6
|
-
router = new ToolRouter();
|
|
7
|
-
});
|
|
8
|
-
// ─── Test #20: Routes write_file to host ───
|
|
9
|
-
it("routes write_file to the host", () => {
|
|
10
|
-
expect(router.getTarget("write_file")).toBe(ToolTarget.HOST);
|
|
11
|
-
});
|
|
12
|
-
// ─── Test #21: Routes read_file to host ───
|
|
13
|
-
it("routes read_file to the host", () => {
|
|
14
|
-
expect(router.getTarget("read_file")).toBe(ToolTarget.HOST);
|
|
15
|
-
});
|
|
16
|
-
// ─── Test #22: Routes bash to sandbox ───
|
|
17
|
-
it("routes bash to the sandbox", () => {
|
|
18
|
-
expect(router.getTarget("bash")).toBe(ToolTarget.SANDBOX);
|
|
19
|
-
});
|
|
20
|
-
// ─── Test #23: Routes run_tests to sandbox ───
|
|
21
|
-
it("routes run_tests to the sandbox", () => {
|
|
22
|
-
expect(router.getTarget("run_tests")).toBe(ToolTarget.SANDBOX);
|
|
23
|
-
});
|
|
24
|
-
// ─── Test #24: Routes install_deps to sandbox ───
|
|
25
|
-
it("routes install_deps to the sandbox", () => {
|
|
26
|
-
expect(router.getTarget("install_deps")).toBe(ToolTarget.SANDBOX);
|
|
27
|
-
});
|
|
28
|
-
// ─── Test #25: Routes search_tools to host ───
|
|
29
|
-
it("routes search_tools to the host", () => {
|
|
30
|
-
expect(router.getTarget("search_tools")).toBe(ToolTarget.HOST);
|
|
31
|
-
});
|
|
32
|
-
// ─── Test #26: Unknown tools default to sandbox (safe) ───
|
|
33
|
-
it("defaults unknown tools to sandbox for safety", () => {
|
|
34
|
-
expect(router.getTarget("unknown_tool")).toBe(ToolTarget.SANDBOX);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
//# sourceMappingURL=toolRouter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolRouter.test.js","sourceRoot":"","sources":["../../src/__tests__/toolRouter.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAM,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE5D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,MAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,8CAA8C;IAE9C,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,6CAA6C;IAE7C,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,2CAA2C;IAE3C,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,gDAAgD;IAEhD,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,mDAAmD;IAEnD,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,gDAAgD;IAEhD,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,4DAA4D;IAE5D,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|