fraude-code 0.1.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 +68 -0
- package/dist/index.js +179297 -0
- package/package.json +88 -0
- package/src/agent/agent.ts +475 -0
- package/src/agent/contextManager.ts +141 -0
- package/src/agent/index.ts +14 -0
- package/src/agent/pendingChanges.ts +270 -0
- package/src/agent/prompts/AskPrompt.txt +10 -0
- package/src/agent/prompts/FastPrompt.txt +40 -0
- package/src/agent/prompts/PlannerPrompt.txt +51 -0
- package/src/agent/prompts/ReviewerPrompt.txt +57 -0
- package/src/agent/prompts/WorkerPrompt.txt +33 -0
- package/src/agent/subagents/askAgent.ts +37 -0
- package/src/agent/subagents/extractionAgent.ts +123 -0
- package/src/agent/subagents/fastAgent.ts +45 -0
- package/src/agent/subagents/managerAgent.ts +36 -0
- package/src/agent/subagents/relationAgent.ts +76 -0
- package/src/agent/subagents/researchSubAgent.ts +79 -0
- package/src/agent/subagents/reviewerSubAgent.ts +42 -0
- package/src/agent/subagents/workerSubAgent.ts +42 -0
- package/src/agent/tools/bashTool.ts +94 -0
- package/src/agent/tools/descriptions/bash.txt +47 -0
- package/src/agent/tools/descriptions/edit.txt +7 -0
- package/src/agent/tools/descriptions/glob.txt +4 -0
- package/src/agent/tools/descriptions/grep.txt +8 -0
- package/src/agent/tools/descriptions/lsp.txt +20 -0
- package/src/agent/tools/descriptions/plan.txt +3 -0
- package/src/agent/tools/descriptions/read.txt +9 -0
- package/src/agent/tools/descriptions/todo.txt +12 -0
- package/src/agent/tools/descriptions/write.txt +8 -0
- package/src/agent/tools/editTool.ts +44 -0
- package/src/agent/tools/globTool.ts +59 -0
- package/src/agent/tools/grepTool.ts +343 -0
- package/src/agent/tools/lspTool.ts +429 -0
- package/src/agent/tools/planTool.ts +118 -0
- package/src/agent/tools/readTool.ts +78 -0
- package/src/agent/tools/rememberTool.ts +91 -0
- package/src/agent/tools/testRunnerTool.ts +77 -0
- package/src/agent/tools/testTool.ts +44 -0
- package/src/agent/tools/todoTool.ts +224 -0
- package/src/agent/tools/writeTool.ts +33 -0
- package/src/commands/COMMANDS.ts +38 -0
- package/src/commands/cerebras/auth.ts +27 -0
- package/src/commands/cerebras/index.ts +31 -0
- package/src/commands/forget.ts +29 -0
- package/src/commands/google/auth.ts +24 -0
- package/src/commands/google/index.ts +31 -0
- package/src/commands/groq/add_model.ts +60 -0
- package/src/commands/groq/auth.ts +24 -0
- package/src/commands/groq/index.ts +33 -0
- package/src/commands/index.ts +65 -0
- package/src/commands/knowledge.ts +92 -0
- package/src/commands/log.ts +32 -0
- package/src/commands/mistral/auth.ts +27 -0
- package/src/commands/mistral/index.ts +31 -0
- package/src/commands/model/index.ts +145 -0
- package/src/commands/models/index.ts +16 -0
- package/src/commands/ollama/index.ts +29 -0
- package/src/commands/openrouter/add_model.ts +64 -0
- package/src/commands/openrouter/auth.ts +24 -0
- package/src/commands/openrouter/index.ts +33 -0
- package/src/commands/remember.ts +48 -0
- package/src/commands/serve.ts +31 -0
- package/src/commands/session/index.ts +21 -0
- package/src/commands/usage.ts +15 -0
- package/src/commands/visualize.ts +773 -0
- package/src/components/App.tsx +55 -0
- package/src/components/IntroComponent.tsx +70 -0
- package/src/components/LoaderComponent.tsx +68 -0
- package/src/components/OutputRenderer.tsx +88 -0
- package/src/components/SettingsRenderer.tsx +23 -0
- package/src/components/input/CommandSuggestions.tsx +41 -0
- package/src/components/input/FileSuggestions.tsx +61 -0
- package/src/components/input/InputBox.tsx +371 -0
- package/src/components/output/CheckpointView.tsx +13 -0
- package/src/components/output/CommandView.tsx +13 -0
- package/src/components/output/CommentView.tsx +12 -0
- package/src/components/output/ConfirmationView.tsx +179 -0
- package/src/components/output/ContextUsage.tsx +62 -0
- package/src/components/output/DiffView.tsx +202 -0
- package/src/components/output/ErrorView.tsx +14 -0
- package/src/components/output/InteractiveServerView.tsx +69 -0
- package/src/components/output/KnowledgeView.tsx +220 -0
- package/src/components/output/MarkdownView.tsx +15 -0
- package/src/components/output/ModelSelectView.tsx +71 -0
- package/src/components/output/ReasoningView.tsx +21 -0
- package/src/components/output/ToolCallView.tsx +45 -0
- package/src/components/settings/ModelList.tsx +250 -0
- package/src/components/settings/TokenUsage.tsx +274 -0
- package/src/config/schema.ts +19 -0
- package/src/config/settings.ts +229 -0
- package/src/index.tsx +100 -0
- package/src/parsers/tree-sitter-python.wasm +0 -0
- package/src/providers/providers.ts +71 -0
- package/src/services/PluginLoader.ts +123 -0
- package/src/services/cerebras.ts +69 -0
- package/src/services/embeddingService.ts +229 -0
- package/src/services/google.ts +65 -0
- package/src/services/graphSerializer.ts +248 -0
- package/src/services/groq.ts +23 -0
- package/src/services/knowledgeOrchestrator.ts +286 -0
- package/src/services/mistral.ts +79 -0
- package/src/services/ollama.ts +109 -0
- package/src/services/openrouter.ts +23 -0
- package/src/services/symbolExtractor.ts +277 -0
- package/src/store/useFraudeStore.ts +123 -0
- package/src/store/useSettingsStore.ts +38 -0
- package/src/theme.ts +26 -0
- package/src/types/Agent.ts +147 -0
- package/src/types/CommandDefinition.ts +8 -0
- package/src/types/Model.ts +94 -0
- package/src/types/OutputItem.ts +24 -0
- package/src/types/PluginContext.ts +55 -0
- package/src/types/TokenUsage.ts +5 -0
- package/src/types/assets.d.ts +4 -0
- package/src/utils/agentCognition.ts +1152 -0
- package/src/utils/fileSuggestions.ts +111 -0
- package/src/utils/index.ts +17 -0
- package/src/utils/initFraude.ts +8 -0
- package/src/utils/logger.ts +24 -0
- package/src/utils/lspClient.ts +1415 -0
- package/src/utils/paths.ts +24 -0
- package/src/utils/queryHandler.ts +227 -0
- package/src/utils/router.ts +278 -0
- package/src/utils/streamHandler.ts +132 -0
- package/src/utils/treeSitterQueries.ts +125 -0
- package/tsconfig.json +33 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import useSettingsStore from "@/store/useSettingsStore";
|
|
2
|
+
import Agent from "../agent";
|
|
3
|
+
import planTool from "../tools/planTool";
|
|
4
|
+
import todoTool from "../tools/todoTool";
|
|
5
|
+
import researchSubAgentTool from "../subagents/researchSubAgent";
|
|
6
|
+
import managerPrompt from "../prompts/PlannerPrompt.txt" with { type: "text" };
|
|
7
|
+
|
|
8
|
+
let _managerAgent: Agent | null = null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get the manager agent instance.
|
|
12
|
+
* Uses lazy initialization to ensure settings are loaded before reading primaryModel.
|
|
13
|
+
*/
|
|
14
|
+
export function getManagerAgent(): Agent {
|
|
15
|
+
const currentModel = useSettingsStore.getState().primaryModel;
|
|
16
|
+
|
|
17
|
+
if (!_managerAgent) {
|
|
18
|
+
_managerAgent = new Agent({
|
|
19
|
+
model: currentModel,
|
|
20
|
+
systemPrompt: managerPrompt,
|
|
21
|
+
tools: {
|
|
22
|
+
planTool,
|
|
23
|
+
todoTool,
|
|
24
|
+
researchSubAgentTool,
|
|
25
|
+
},
|
|
26
|
+
temperature: 0.7,
|
|
27
|
+
maxSteps: 20,
|
|
28
|
+
reasoningEffort: "high",
|
|
29
|
+
});
|
|
30
|
+
} else if (_managerAgent.getModel() !== currentModel) {
|
|
31
|
+
_managerAgent.setModel(currentModel);
|
|
32
|
+
}
|
|
33
|
+
return _managerAgent;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default getManagerAgent;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import useSettingsStore from "@/store/useSettingsStore";
|
|
2
|
+
import Agent from "../agent";
|
|
3
|
+
import log from "@/utils/logger";
|
|
4
|
+
|
|
5
|
+
let _relationAgent: Agent | null = null;
|
|
6
|
+
|
|
7
|
+
const RELATION_PROMPT = `You classify relationships between knowledge facts.
|
|
8
|
+
|
|
9
|
+
Given two facts, determine their relationship type. Output ONLY one of:
|
|
10
|
+
- DEPENDS_ON: First fact relies on or requires the second
|
|
11
|
+
- IMPLEMENTS: First fact is a concrete implementation of the second
|
|
12
|
+
- MODIFIES: First fact changes or affects the second
|
|
13
|
+
- USES: First fact utilizes or references the second
|
|
14
|
+
- RELATED_TO: General semantic relationship (default if unsure)
|
|
15
|
+
|
|
16
|
+
Output format: Just the relationship type, nothing else.`;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get the relation classification agent instance.
|
|
20
|
+
*/
|
|
21
|
+
export function getRelationAgent(): Agent {
|
|
22
|
+
const store = useSettingsStore.getState();
|
|
23
|
+
const currentModel = store.secondaryModel || store.primaryModel;
|
|
24
|
+
|
|
25
|
+
if (!_relationAgent) {
|
|
26
|
+
_relationAgent = new Agent({
|
|
27
|
+
model: currentModel,
|
|
28
|
+
systemPrompt: RELATION_PROMPT,
|
|
29
|
+
tools: {},
|
|
30
|
+
temperature: 0.1,
|
|
31
|
+
maxSteps: 1,
|
|
32
|
+
useIsolatedContext: true,
|
|
33
|
+
});
|
|
34
|
+
} else if (_relationAgent.getModel() !== currentModel) {
|
|
35
|
+
_relationAgent.setModel(currentModel);
|
|
36
|
+
}
|
|
37
|
+
return _relationAgent;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type RelationType =
|
|
41
|
+
| "DEPENDS_ON"
|
|
42
|
+
| "IMPLEMENTS"
|
|
43
|
+
| "MODIFIES"
|
|
44
|
+
| "USES"
|
|
45
|
+
| "RELATED_TO";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Classify the relationship between two facts using LLM.
|
|
49
|
+
*/
|
|
50
|
+
export async function classifyRelation(
|
|
51
|
+
factA: string,
|
|
52
|
+
factB: string,
|
|
53
|
+
): Promise<RelationType> {
|
|
54
|
+
const agent = getRelationAgent();
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const response = await agent.chat(
|
|
58
|
+
`Fact A: "${factA}"\nFact B: "${factB}"\n\nRelationship type:`,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const text = response.text.trim().toUpperCase();
|
|
62
|
+
|
|
63
|
+
// Parse response to valid relation type
|
|
64
|
+
if (text.includes("DEPENDS_ON")) return "DEPENDS_ON";
|
|
65
|
+
if (text.includes("IMPLEMENTS")) return "IMPLEMENTS";
|
|
66
|
+
if (text.includes("MODIFIES")) return "MODIFIES";
|
|
67
|
+
if (text.includes("USES")) return "USES";
|
|
68
|
+
|
|
69
|
+
return "RELATED_TO";
|
|
70
|
+
} catch (e) {
|
|
71
|
+
log("Relation classification failed: " + e);
|
|
72
|
+
return "RELATED_TO";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default getRelationAgent;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { Agent } from "@/agent";
|
|
4
|
+
import readTool from "../tools/readTool";
|
|
5
|
+
import bashTool from "../tools/bashTool";
|
|
6
|
+
import grepTool from "../tools/grepTool";
|
|
7
|
+
import globTool from "../tools/globTool";
|
|
8
|
+
import useFraudeStore from "@/store/useFraudeStore";
|
|
9
|
+
import useSettingsStore from "@/store/useSettingsStore";
|
|
10
|
+
import lspTool from "../tools/lspTool";
|
|
11
|
+
|
|
12
|
+
const researchSubAgentTool = tool({
|
|
13
|
+
description: `Ask a specialized researcher to find information in the codebase.
|
|
14
|
+
Use this BEFORE making edits to ensure you know the file structure and logic.`,
|
|
15
|
+
strict: true,
|
|
16
|
+
inputSchema: z.object({
|
|
17
|
+
question: z
|
|
18
|
+
.string()
|
|
19
|
+
.describe("The specific question about the code to answer."),
|
|
20
|
+
}),
|
|
21
|
+
execute: async ({ question }) => {
|
|
22
|
+
const { updateOutput, researchCache } = useFraudeStore.getState();
|
|
23
|
+
updateOutput(
|
|
24
|
+
"toolCall",
|
|
25
|
+
JSON.stringify({
|
|
26
|
+
action: "Searching for context",
|
|
27
|
+
details: question,
|
|
28
|
+
result: "",
|
|
29
|
+
}),
|
|
30
|
+
{ dontOverride: true },
|
|
31
|
+
);
|
|
32
|
+
if (researchCache?.[question]) {
|
|
33
|
+
updateOutput(
|
|
34
|
+
"toolCall",
|
|
35
|
+
JSON.stringify({
|
|
36
|
+
action: "Explored context",
|
|
37
|
+
details: question,
|
|
38
|
+
result: researchCache[question],
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
return researchCache[question];
|
|
42
|
+
}
|
|
43
|
+
const subagent = new Agent({
|
|
44
|
+
model: useSettingsStore.getState().secondaryModel,
|
|
45
|
+
systemPrompt: prompt,
|
|
46
|
+
tools: { readTool, bashTool, grepTool, globTool, lspTool },
|
|
47
|
+
temperature: 0.7,
|
|
48
|
+
maxSteps: 10,
|
|
49
|
+
useIsolatedContext: true,
|
|
50
|
+
});
|
|
51
|
+
const result = await subagent.chat(question);
|
|
52
|
+
updateOutput(
|
|
53
|
+
"toolCall",
|
|
54
|
+
JSON.stringify({
|
|
55
|
+
action: "Explored context",
|
|
56
|
+
details: question,
|
|
57
|
+
result: result.text,
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
useFraudeStore.setState({
|
|
61
|
+
researchCache: {
|
|
62
|
+
...researchCache,
|
|
63
|
+
[question]: result.text,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
return result.text;
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export default researchSubAgentTool;
|
|
71
|
+
|
|
72
|
+
const prompt = `
|
|
73
|
+
You are a read-only research assistant.
|
|
74
|
+
Your goal is to answer the user's question by exploring the file system.
|
|
75
|
+
- You cannot edit files.
|
|
76
|
+
- Be aggressive with your tools to find answers.
|
|
77
|
+
- When finding code relevant to the question, extract the *signature* (function names, params, types) and *critical logic*.
|
|
78
|
+
- Do not dump entire files, but provide enough technical detail that a developer could call this function without seeing the code.
|
|
79
|
+
`;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Agent } from "@/agent";
|
|
2
|
+
import readTool from "../tools/readTool";
|
|
3
|
+
import grepTool from "../tools/grepTool";
|
|
4
|
+
import lspTool from "../tools/lspTool";
|
|
5
|
+
import useSettingsStore from "@/store/useSettingsStore";
|
|
6
|
+
import todoTool from "../tools/todoTool";
|
|
7
|
+
import testRunnerTool from "../tools/testRunnerTool";
|
|
8
|
+
import testTool from "../tools/testTool";
|
|
9
|
+
import ReviewerPrompt from "../prompts/ReviewerPrompt.txt" with { type: "text" };
|
|
10
|
+
|
|
11
|
+
let _reviewerSubAgent: Agent | null = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get the reviewer subagent instance.
|
|
15
|
+
* Uses lazy initialization to ensure settings are loaded before reading secondaryModel.
|
|
16
|
+
*/
|
|
17
|
+
export function getReviewerSubAgent(): Agent {
|
|
18
|
+
const currentModel = useSettingsStore.getState().secondaryModel;
|
|
19
|
+
|
|
20
|
+
if (!_reviewerSubAgent) {
|
|
21
|
+
_reviewerSubAgent = new Agent({
|
|
22
|
+
model: currentModel,
|
|
23
|
+
systemPrompt: ReviewerPrompt,
|
|
24
|
+
tools: {
|
|
25
|
+
readTool,
|
|
26
|
+
grepTool,
|
|
27
|
+
lspTool,
|
|
28
|
+
testTool,
|
|
29
|
+
todoTool,
|
|
30
|
+
testRunnerTool,
|
|
31
|
+
},
|
|
32
|
+
temperature: 0.7,
|
|
33
|
+
maxSteps: 10,
|
|
34
|
+
useIsolatedContext: true,
|
|
35
|
+
});
|
|
36
|
+
} else if (_reviewerSubAgent.getModel() !== currentModel) {
|
|
37
|
+
_reviewerSubAgent.setModel(currentModel);
|
|
38
|
+
}
|
|
39
|
+
return _reviewerSubAgent;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default getReviewerSubAgent;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Agent } from "@/agent";
|
|
2
|
+
import readTool from "../tools/readTool";
|
|
3
|
+
import grepTool from "../tools/grepTool";
|
|
4
|
+
import writeTool from "../tools/writeTool";
|
|
5
|
+
import editTool from "../tools/editTool";
|
|
6
|
+
import bashTool from "../tools/bashTool";
|
|
7
|
+
import todoTool from "../tools/todoTool";
|
|
8
|
+
import useSettingsStore from "@/store/useSettingsStore";
|
|
9
|
+
import WorkerPrompt from "../prompts/WorkerPrompt.txt" with { type: "text" };
|
|
10
|
+
|
|
11
|
+
let _workerSubAgent: Agent | null = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get the worker subagent instance.
|
|
15
|
+
* Uses lazy initialization to ensure settings are loaded before reading primaryModel.
|
|
16
|
+
*/
|
|
17
|
+
export function getWorkerSubAgent(): Agent {
|
|
18
|
+
const currentModel = useSettingsStore.getState().primaryModel;
|
|
19
|
+
|
|
20
|
+
if (!_workerSubAgent) {
|
|
21
|
+
_workerSubAgent = new Agent({
|
|
22
|
+
model: currentModel,
|
|
23
|
+
systemPrompt: WorkerPrompt,
|
|
24
|
+
tools: {
|
|
25
|
+
readTool,
|
|
26
|
+
grepTool,
|
|
27
|
+
writeTool,
|
|
28
|
+
editTool,
|
|
29
|
+
bashTool,
|
|
30
|
+
todoTool,
|
|
31
|
+
},
|
|
32
|
+
temperature: 0.7,
|
|
33
|
+
maxSteps: 10,
|
|
34
|
+
useIsolatedContext: true,
|
|
35
|
+
});
|
|
36
|
+
} else if (_workerSubAgent.getModel() !== currentModel) {
|
|
37
|
+
_workerSubAgent.setModel(currentModel);
|
|
38
|
+
}
|
|
39
|
+
return _workerSubAgent;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default getWorkerSubAgent;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import useFraudeStore from "@/store/useFraudeStore";
|
|
4
|
+
import DESCRIPTION from "./descriptions/bash.txt" with { type: "text" };
|
|
5
|
+
|
|
6
|
+
const { updateOutput } = useFraudeStore.getState();
|
|
7
|
+
|
|
8
|
+
const bashTool = tool({
|
|
9
|
+
description: DESCRIPTION,
|
|
10
|
+
strict: true,
|
|
11
|
+
inputSchema: z.object({
|
|
12
|
+
command: z.string().describe("The command to execute"),
|
|
13
|
+
timeout: z
|
|
14
|
+
.number()
|
|
15
|
+
.describe("Optional timeout in milliseconds")
|
|
16
|
+
.default(120000),
|
|
17
|
+
workdir: z
|
|
18
|
+
.string()
|
|
19
|
+
.describe(
|
|
20
|
+
`The working directory to run the command in. Defaults to project root ${process.cwd()}. Use this instead of 'cd' commands.`,
|
|
21
|
+
)
|
|
22
|
+
.optional(),
|
|
23
|
+
description: z
|
|
24
|
+
.string()
|
|
25
|
+
.describe(
|
|
26
|
+
"Clear, concise description of what this command does in 5-10 words. Examples:\nInput: ls\nOutput: Lists files in current directory\n\nInput: git status\nOutput: Shows working tree status\n\nInput: npm install\nOutput: Installs package dependencies\n\nInput: mkdir foo\nOutput: Creates directory 'foo'",
|
|
27
|
+
),
|
|
28
|
+
}),
|
|
29
|
+
execute: async ({
|
|
30
|
+
command,
|
|
31
|
+
timeout,
|
|
32
|
+
workdir,
|
|
33
|
+
description,
|
|
34
|
+
}: {
|
|
35
|
+
command: string;
|
|
36
|
+
timeout: number;
|
|
37
|
+
workdir?: string;
|
|
38
|
+
description: string;
|
|
39
|
+
}) => {
|
|
40
|
+
const forbidden = ["rm -rf /", ":(){:|:&};:"];
|
|
41
|
+
if (forbidden.some((bad) => command.includes(bad))) {
|
|
42
|
+
throw new Error("Command blocked by safety policy");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
updateOutput(
|
|
47
|
+
"toolCall",
|
|
48
|
+
JSON.stringify({
|
|
49
|
+
action: "Executing Bash",
|
|
50
|
+
details: command,
|
|
51
|
+
result: "",
|
|
52
|
+
}),
|
|
53
|
+
{ dontOverride: true },
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const proc = Bun.spawn(["sh", "-c", command], {
|
|
57
|
+
cwd: workdir || process.cwd(),
|
|
58
|
+
stdout: "pipe",
|
|
59
|
+
stderr: "pipe",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const timeoutSignal = AbortSignal.timeout(timeout);
|
|
63
|
+
|
|
64
|
+
const outputPromise = new Response(proc.stdout).text();
|
|
65
|
+
const errorPromise = new Response(proc.stderr).text();
|
|
66
|
+
if (timeoutSignal.aborted) {
|
|
67
|
+
proc.kill();
|
|
68
|
+
throw new Error("Command timed out");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const [stdout, stderr] = await Promise.all([outputPromise, errorPromise]);
|
|
72
|
+
const exitCode = await proc.exited;
|
|
73
|
+
|
|
74
|
+
updateOutput(
|
|
75
|
+
"toolCall",
|
|
76
|
+
JSON.stringify({
|
|
77
|
+
action: "Bash",
|
|
78
|
+
details: command,
|
|
79
|
+
result: stdout.trim(),
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
return {
|
|
83
|
+
stdout: stdout.trim(),
|
|
84
|
+
stderr: stderr.trim(),
|
|
85
|
+
code: exitCode,
|
|
86
|
+
cwd: workdir || process.cwd(),
|
|
87
|
+
};
|
|
88
|
+
} catch (err: any) {
|
|
89
|
+
throw new Error(`Execution failed: ${err.message}`);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
export default bashTool;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.
|
|
2
|
+
|
|
3
|
+
All commands run in ${directory} by default. Use the `workdir` parameter if you need to run a command in a different directory. AVOID using `cd <directory> && <command>` patterns - use `workdir` instead.
|
|
4
|
+
|
|
5
|
+
IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead.
|
|
6
|
+
|
|
7
|
+
Before executing the command, please follow these steps:
|
|
8
|
+
|
|
9
|
+
1. Directory Verification:
|
|
10
|
+
- If the command will create new directories or files, first use `ls` to verify the parent directory exists and is the correct location
|
|
11
|
+
- For example, before running "mkdir foo/bar", first use `ls foo` to check that "foo" exists and is the intended parent directory
|
|
12
|
+
|
|
13
|
+
2. Command Execution:
|
|
14
|
+
- Always quote file paths that contain spaces with double quotes (e.g., rm "path with spaces/file.txt")
|
|
15
|
+
- Examples of proper quoting:
|
|
16
|
+
- mkdir "/Users/name/My Documents" (correct)
|
|
17
|
+
- mkdir /Users/name/My Documents (incorrect - will fail)
|
|
18
|
+
- python "/path/with spaces/script.py" (correct)
|
|
19
|
+
- python /path/with spaces/script.py (incorrect - will fail)
|
|
20
|
+
- After ensuring proper quoting, execute the command.
|
|
21
|
+
- Capture the output of the command.
|
|
22
|
+
|
|
23
|
+
Usage notes:
|
|
24
|
+
- The command argument is required.
|
|
25
|
+
- You can specify an optional timeout in milliseconds. If not specified, commands will time out after 120000ms (2 minutes).
|
|
26
|
+
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
|
|
27
|
+
- If the output exceeds ${maxLines} lines or ${maxBytes} bytes, it will be truncated and the full output will be written to a file. You can use Read with offset/limit to read specific sections or Grep to search the full content. Because of this, you do NOT need to use `head`, `tail`, or other truncation commands to limit output - just run the command directly.
|
|
28
|
+
|
|
29
|
+
- Avoid using Bash with the `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
|
|
30
|
+
- File search: Use Glob tool (NOT find or ls)
|
|
31
|
+
- Content search: Use Grep tool (NOT grep or rg)
|
|
32
|
+
- Read files: Use Read tool (NOT cat/head/tail)
|
|
33
|
+
- Edit files: Use Edit tool (NOT sed/awk)
|
|
34
|
+
- Write files: Use Write tool (NOT echo >/cat <<EOF)
|
|
35
|
+
- Communication: Output text directly (NOT echo/printf)
|
|
36
|
+
- When issuing multiple commands:
|
|
37
|
+
- If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel.
|
|
38
|
+
- If the commands depend on each other and must run sequentially, use a single Bash call with '&&' to chain them together (e.g., `git add . && git commit -m "message" && git push`). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead.
|
|
39
|
+
- Use ';' only when you need to run commands sequentially but don't care if earlier commands fail
|
|
40
|
+
- DO NOT use newlines to separate commands (newlines are ok in quoted strings)
|
|
41
|
+
- AVOID using `cd <directory> && <command>`. Use the `workdir` parameter to change directories instead.
|
|
42
|
+
<good-example>
|
|
43
|
+
Use workdir="/foo/bar" with command: pytest tests
|
|
44
|
+
</good-example>
|
|
45
|
+
<bad-example>
|
|
46
|
+
cd /foo/bar && pytest tests
|
|
47
|
+
</bad-example>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Edit an existing file by replacing a specific block of text with new content. Use the read tool first to understand the current content of the file.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
- Make sure the old_content is a unique block of text within the file.
|
|
5
|
+
- Include enough context in the old_content to ensure uniqueness.
|
|
6
|
+
- If adding new content, include context around the new content to ensure uniqueness and to specify the location of the new content in the file.
|
|
7
|
+
- If removing, new content should be empty.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Search for a chunk of text in the codebase using grep. Use this tool when looking for a specific pattern in the codebase.
|
|
2
|
+
|
|
3
|
+
- Fast content search tool that works with any codebase size
|
|
4
|
+
- Searches file contents using regular expressions
|
|
5
|
+
- Supports full regex syntax (eg. "log.*Error", "function\s+\w+", etc.)
|
|
6
|
+
- Filter files by pattern with the include parameter (eg. "*.js", "*.{ts,tsx}")
|
|
7
|
+
- Returns file paths and line numbers with at least one match sorted by modification time
|
|
8
|
+
- Use this tool when you need to find files containing specific patterns
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Interact with Language Server Protocol (LSP) servers to get code intelligence features.
|
|
2
|
+
|
|
3
|
+
Supported operations:
|
|
4
|
+
- goToDefinition: Find where a symbol is defined
|
|
5
|
+
- findReferences: Find all references to a symbol
|
|
6
|
+
- hover: Get hover information (documentation, type info) for a symbol
|
|
7
|
+
- documentSymbol: Get all symbols (functions, classes, variables) in a document
|
|
8
|
+
- workspaceSymbol: Search for symbols across the entire workspace
|
|
9
|
+
- goToImplementation: Find implementations of an interface or abstract method
|
|
10
|
+
- prepareCallHierarchy: Get call hierarchy item at a position (functions/methods)
|
|
11
|
+
- incomingCalls: Find all functions/methods that call the function at a position
|
|
12
|
+
- outgoingCalls: Find all functions/methods called by the function at a position
|
|
13
|
+
|
|
14
|
+
## Parameters:
|
|
15
|
+
- **filePath**: Path to the file containing the symbol
|
|
16
|
+
- **symbol**: The exact name of the function, class, variable, or import to look up
|
|
17
|
+
- **occurrence**: If symbol appears multiple times, which one to use (default: 1 = first)
|
|
18
|
+
|
|
19
|
+
## Supported Languages:
|
|
20
|
+
TypeScript, JavaScript, Python, Rust, Go, C/C++, JSON, CSS, HTML
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Read a file from the local file system.
|
|
2
|
+
If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
- The filePath parameter must be an absolute path, not a relative path
|
|
6
|
+
- By default, this tool will read up to 500 lines of the file.
|
|
7
|
+
- You can optionally specify the offset and limit parameters to read a specific range of lines.
|
|
8
|
+
- The offset parameter is the line number to start reading from (inclusive). Line 0 is the first line.
|
|
9
|
+
- The limit parameter is the number of lines to read (inclusive).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Manage tasks for worker agents.
|
|
2
|
+
|
|
3
|
+
Operations:
|
|
4
|
+
- "add": Create task with description and context (files + instructions)
|
|
5
|
+
- "update": Update task status or add notes
|
|
6
|
+
- "complete": Mark task done with optional completion note
|
|
7
|
+
- "list": Get all tasks with summary
|
|
8
|
+
- "clear": Remove completed tasks
|
|
9
|
+
|
|
10
|
+
Task context includes:
|
|
11
|
+
- files: Array of file paths relevant to the task
|
|
12
|
+
- instructions: Specific instructions for the worker agent
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Writes a file to the local filesystem. Use to create new files or overwrite entire files.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
- This tool will overwrite the existing file if there is one at the provided path.
|
|
5
|
+
- If this is an existing file, you MUST use the Read tool first to read the file's contents.
|
|
6
|
+
- ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
|
|
7
|
+
- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
|
|
8
|
+
- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import useFraudeStore from "@/store/useFraudeStore";
|
|
4
|
+
import { projectPath } from "@/utils";
|
|
5
|
+
import pendingChanges from "@/agent/pendingChanges";
|
|
6
|
+
|
|
7
|
+
import DESCRIPTION from "./descriptions/edit.txt" with { type: "text" };
|
|
8
|
+
const { updateOutput } = useFraudeStore.getState();
|
|
9
|
+
|
|
10
|
+
const editTool = tool({
|
|
11
|
+
description: DESCRIPTION,
|
|
12
|
+
strict: true,
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
path: z.string().describe("The path to the file to edit"),
|
|
15
|
+
old_content: z
|
|
16
|
+
.string()
|
|
17
|
+
.describe(
|
|
18
|
+
"Must be unique and match the file exactly (whitespace matters)",
|
|
19
|
+
),
|
|
20
|
+
new_content: z.string().describe("The new content of the file"),
|
|
21
|
+
}),
|
|
22
|
+
execute: async ({ path, old_content, new_content }) => {
|
|
23
|
+
const fileContent = await pendingChanges.getLatestContent(path);
|
|
24
|
+
if (!fileContent.includes(old_content)) {
|
|
25
|
+
throw new Error("Old content does not match file");
|
|
26
|
+
}
|
|
27
|
+
const newFileContent = fileContent.replace(old_content, new_content);
|
|
28
|
+
|
|
29
|
+
const change = await pendingChanges.addChange(path, newFileContent, "edit");
|
|
30
|
+
const stats = pendingChanges.getDiffStats(change.diff);
|
|
31
|
+
updateOutput(
|
|
32
|
+
"toolCall",
|
|
33
|
+
JSON.stringify({
|
|
34
|
+
action: "Edited File",
|
|
35
|
+
details: path,
|
|
36
|
+
result: `(+${stats.added} / -${stats.removed})`,
|
|
37
|
+
}),
|
|
38
|
+
{ dontOverride: true },
|
|
39
|
+
);
|
|
40
|
+
return { success: true };
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export default editTool;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import useFraudeStore from "@/store/useFraudeStore";
|
|
4
|
+
import DESCRIPTION from "./descriptions/glob.txt" with { type: "text" };
|
|
5
|
+
import { Glob } from "bun";
|
|
6
|
+
|
|
7
|
+
const { updateOutput } = useFraudeStore.getState();
|
|
8
|
+
|
|
9
|
+
const globTool = tool({
|
|
10
|
+
description: DESCRIPTION,
|
|
11
|
+
strict: true,
|
|
12
|
+
inputSchema: z.object({
|
|
13
|
+
pattern: z.string().describe("The glob pattern to match files with"),
|
|
14
|
+
path: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe(
|
|
18
|
+
`The directory to search in. If not specified, the current directory will be searched. DO NOT enter "undefined" or "null" - simply omit it for the default behavior. Must be a valid directory path if provided.`,
|
|
19
|
+
),
|
|
20
|
+
}),
|
|
21
|
+
execute: async ({ pattern, path }: { pattern: string; path?: string }) => {
|
|
22
|
+
updateOutput(
|
|
23
|
+
"toolCall",
|
|
24
|
+
JSON.stringify({
|
|
25
|
+
action: "Searching Files in " + path,
|
|
26
|
+
details: pattern,
|
|
27
|
+
}),
|
|
28
|
+
{ dontOverride: true },
|
|
29
|
+
);
|
|
30
|
+
const searchPath = path || process.cwd();
|
|
31
|
+
const glob = new Glob(pattern);
|
|
32
|
+
const files: { file: string; modifiedAt: number }[] = [];
|
|
33
|
+
const MAX_FILES = 100;
|
|
34
|
+
for await (const file of glob.scan({ cwd: searchPath, absolute: false })) {
|
|
35
|
+
if (file.includes("node_modules") || file.includes(".git")) continue;
|
|
36
|
+
const f = Bun.file(file);
|
|
37
|
+
const stats = await f.stat().catch(() => null);
|
|
38
|
+
const modifiedAt = stats?.mtime.getTime() || 0;
|
|
39
|
+
files.push({ file, modifiedAt });
|
|
40
|
+
if (files.length >= MAX_FILES) {
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
updateOutput(
|
|
45
|
+
"toolCall",
|
|
46
|
+
JSON.stringify({
|
|
47
|
+
action: "Found " + files.length + " Files",
|
|
48
|
+
details: pattern,
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
if (files.length === 0) return "No files found matching that pattern.";
|
|
52
|
+
return files
|
|
53
|
+
.sort((a, b) => b.modifiedAt - a.modifiedAt)
|
|
54
|
+
.map((f) => f.file)
|
|
55
|
+
.join("\n");
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export default globTool;
|