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.
Files changed (127) hide show
  1. package/README.md +68 -0
  2. package/dist/index.js +179297 -0
  3. package/package.json +88 -0
  4. package/src/agent/agent.ts +475 -0
  5. package/src/agent/contextManager.ts +141 -0
  6. package/src/agent/index.ts +14 -0
  7. package/src/agent/pendingChanges.ts +270 -0
  8. package/src/agent/prompts/AskPrompt.txt +10 -0
  9. package/src/agent/prompts/FastPrompt.txt +40 -0
  10. package/src/agent/prompts/PlannerPrompt.txt +51 -0
  11. package/src/agent/prompts/ReviewerPrompt.txt +57 -0
  12. package/src/agent/prompts/WorkerPrompt.txt +33 -0
  13. package/src/agent/subagents/askAgent.ts +37 -0
  14. package/src/agent/subagents/extractionAgent.ts +123 -0
  15. package/src/agent/subagents/fastAgent.ts +45 -0
  16. package/src/agent/subagents/managerAgent.ts +36 -0
  17. package/src/agent/subagents/relationAgent.ts +76 -0
  18. package/src/agent/subagents/researchSubAgent.ts +79 -0
  19. package/src/agent/subagents/reviewerSubAgent.ts +42 -0
  20. package/src/agent/subagents/workerSubAgent.ts +42 -0
  21. package/src/agent/tools/bashTool.ts +94 -0
  22. package/src/agent/tools/descriptions/bash.txt +47 -0
  23. package/src/agent/tools/descriptions/edit.txt +7 -0
  24. package/src/agent/tools/descriptions/glob.txt +4 -0
  25. package/src/agent/tools/descriptions/grep.txt +8 -0
  26. package/src/agent/tools/descriptions/lsp.txt +20 -0
  27. package/src/agent/tools/descriptions/plan.txt +3 -0
  28. package/src/agent/tools/descriptions/read.txt +9 -0
  29. package/src/agent/tools/descriptions/todo.txt +12 -0
  30. package/src/agent/tools/descriptions/write.txt +8 -0
  31. package/src/agent/tools/editTool.ts +44 -0
  32. package/src/agent/tools/globTool.ts +59 -0
  33. package/src/agent/tools/grepTool.ts +343 -0
  34. package/src/agent/tools/lspTool.ts +429 -0
  35. package/src/agent/tools/planTool.ts +118 -0
  36. package/src/agent/tools/readTool.ts +78 -0
  37. package/src/agent/tools/rememberTool.ts +91 -0
  38. package/src/agent/tools/testRunnerTool.ts +77 -0
  39. package/src/agent/tools/testTool.ts +44 -0
  40. package/src/agent/tools/todoTool.ts +224 -0
  41. package/src/agent/tools/writeTool.ts +33 -0
  42. package/src/commands/COMMANDS.ts +38 -0
  43. package/src/commands/cerebras/auth.ts +27 -0
  44. package/src/commands/cerebras/index.ts +31 -0
  45. package/src/commands/forget.ts +29 -0
  46. package/src/commands/google/auth.ts +24 -0
  47. package/src/commands/google/index.ts +31 -0
  48. package/src/commands/groq/add_model.ts +60 -0
  49. package/src/commands/groq/auth.ts +24 -0
  50. package/src/commands/groq/index.ts +33 -0
  51. package/src/commands/index.ts +65 -0
  52. package/src/commands/knowledge.ts +92 -0
  53. package/src/commands/log.ts +32 -0
  54. package/src/commands/mistral/auth.ts +27 -0
  55. package/src/commands/mistral/index.ts +31 -0
  56. package/src/commands/model/index.ts +145 -0
  57. package/src/commands/models/index.ts +16 -0
  58. package/src/commands/ollama/index.ts +29 -0
  59. package/src/commands/openrouter/add_model.ts +64 -0
  60. package/src/commands/openrouter/auth.ts +24 -0
  61. package/src/commands/openrouter/index.ts +33 -0
  62. package/src/commands/remember.ts +48 -0
  63. package/src/commands/serve.ts +31 -0
  64. package/src/commands/session/index.ts +21 -0
  65. package/src/commands/usage.ts +15 -0
  66. package/src/commands/visualize.ts +773 -0
  67. package/src/components/App.tsx +55 -0
  68. package/src/components/IntroComponent.tsx +70 -0
  69. package/src/components/LoaderComponent.tsx +68 -0
  70. package/src/components/OutputRenderer.tsx +88 -0
  71. package/src/components/SettingsRenderer.tsx +23 -0
  72. package/src/components/input/CommandSuggestions.tsx +41 -0
  73. package/src/components/input/FileSuggestions.tsx +61 -0
  74. package/src/components/input/InputBox.tsx +371 -0
  75. package/src/components/output/CheckpointView.tsx +13 -0
  76. package/src/components/output/CommandView.tsx +13 -0
  77. package/src/components/output/CommentView.tsx +12 -0
  78. package/src/components/output/ConfirmationView.tsx +179 -0
  79. package/src/components/output/ContextUsage.tsx +62 -0
  80. package/src/components/output/DiffView.tsx +202 -0
  81. package/src/components/output/ErrorView.tsx +14 -0
  82. package/src/components/output/InteractiveServerView.tsx +69 -0
  83. package/src/components/output/KnowledgeView.tsx +220 -0
  84. package/src/components/output/MarkdownView.tsx +15 -0
  85. package/src/components/output/ModelSelectView.tsx +71 -0
  86. package/src/components/output/ReasoningView.tsx +21 -0
  87. package/src/components/output/ToolCallView.tsx +45 -0
  88. package/src/components/settings/ModelList.tsx +250 -0
  89. package/src/components/settings/TokenUsage.tsx +274 -0
  90. package/src/config/schema.ts +19 -0
  91. package/src/config/settings.ts +229 -0
  92. package/src/index.tsx +100 -0
  93. package/src/parsers/tree-sitter-python.wasm +0 -0
  94. package/src/providers/providers.ts +71 -0
  95. package/src/services/PluginLoader.ts +123 -0
  96. package/src/services/cerebras.ts +69 -0
  97. package/src/services/embeddingService.ts +229 -0
  98. package/src/services/google.ts +65 -0
  99. package/src/services/graphSerializer.ts +248 -0
  100. package/src/services/groq.ts +23 -0
  101. package/src/services/knowledgeOrchestrator.ts +286 -0
  102. package/src/services/mistral.ts +79 -0
  103. package/src/services/ollama.ts +109 -0
  104. package/src/services/openrouter.ts +23 -0
  105. package/src/services/symbolExtractor.ts +277 -0
  106. package/src/store/useFraudeStore.ts +123 -0
  107. package/src/store/useSettingsStore.ts +38 -0
  108. package/src/theme.ts +26 -0
  109. package/src/types/Agent.ts +147 -0
  110. package/src/types/CommandDefinition.ts +8 -0
  111. package/src/types/Model.ts +94 -0
  112. package/src/types/OutputItem.ts +24 -0
  113. package/src/types/PluginContext.ts +55 -0
  114. package/src/types/TokenUsage.ts +5 -0
  115. package/src/types/assets.d.ts +4 -0
  116. package/src/utils/agentCognition.ts +1152 -0
  117. package/src/utils/fileSuggestions.ts +111 -0
  118. package/src/utils/index.ts +17 -0
  119. package/src/utils/initFraude.ts +8 -0
  120. package/src/utils/logger.ts +24 -0
  121. package/src/utils/lspClient.ts +1415 -0
  122. package/src/utils/paths.ts +24 -0
  123. package/src/utils/queryHandler.ts +227 -0
  124. package/src/utils/router.ts +278 -0
  125. package/src/utils/streamHandler.ts +132 -0
  126. package/src/utils/treeSitterQueries.ts +125 -0
  127. package/tsconfig.json +33 -0
@@ -0,0 +1,277 @@
1
+ import { getLSPClient } from "@/utils/lspClient";
2
+ import type { Fact } from "@/utils/agentCognition";
3
+ import fs from "fs";
4
+ import path from "path";
5
+
6
+ /**
7
+ * Map LSP symbol kinds to specific graph node types.
8
+ */
9
+ function kindToType(kind: string): Fact["type"] {
10
+ const map: Record<string, Fact["type"]> = {
11
+ Function: "function",
12
+ Class: "class",
13
+ Interface: "interface",
14
+ Variable: "variable",
15
+ Method: "function",
16
+ Property: "variable",
17
+ Struct: "class",
18
+ Enum: "class",
19
+ Trait: "interface",
20
+ };
21
+ return map[kind] || "symbol";
22
+ }
23
+
24
+ interface SymbolRelation {
25
+ source: string; // Symbol name
26
+ target: string; // Symbol name
27
+ type: "CALLS" | "DEFINES" | "INHERITS" | "IMPORTS";
28
+ weight: number;
29
+ }
30
+
31
+ export class SymbolExtractor {
32
+ private lsp = getLSPClient();
33
+
34
+ /**
35
+ * Resolve an import module to a file path.
36
+ * Handles relative imports and attempts common resolutions.
37
+ */
38
+ private resolveImport(
39
+ fromFile: string,
40
+ module: string,
41
+ isRelative: boolean,
42
+ ): string | null {
43
+ const dir = path.dirname(fromFile);
44
+ const ext = fromFile.split(".").pop() || "";
45
+
46
+ if (isRelative) {
47
+ // Relative import - try common extensions
48
+ const extensions =
49
+ ext === "py" ? [".py"] : [".ts", ".tsx", ".js", ".jsx"];
50
+ const basePath = path.resolve(dir, module.replace(/\./g, "/"));
51
+
52
+ for (const extTry of extensions) {
53
+ const candidate = basePath + extTry;
54
+ if (fs.existsSync(candidate)) {
55
+ return candidate;
56
+ }
57
+ // Try as directory with index
58
+ const indexCandidate = path.join(basePath, `index${extTry}`);
59
+ if (fs.existsSync(indexCandidate)) {
60
+ return indexCandidate;
61
+ }
62
+ }
63
+ }
64
+
65
+ // Return module name for external imports (can be linked later)
66
+ return null;
67
+ }
68
+
69
+ async analyze(filePath: string): Promise<{
70
+ facts: Omit<Fact, "id" | "timestamp" | "sessionId">[];
71
+ relations: { sourceIdx: number; targetIdx: number; type: string }[];
72
+ }> {
73
+ if (!fs.existsSync(filePath)) return { facts: [], relations: [] };
74
+
75
+ // Standardize on relative paths for the graph
76
+ const relativePath = path.relative(process.cwd(), filePath);
77
+ const content = fs.readFileSync(filePath, "utf-8");
78
+
79
+ // Get symbols with detail - this now includes children
80
+ const symbols = await this.lsp.getDocumentSymbolsWithDetails(
81
+ filePath,
82
+ content,
83
+ );
84
+
85
+ const facts: Omit<Fact, "id" | "timestamp" | "sessionId">[] = [];
86
+ const relations: { sourceIdx: number; targetIdx: number; type: string }[] =
87
+ [];
88
+
89
+ // Track symbol facts to link relations
90
+ const symbolToIdx = new Map<string, number>();
91
+ const filePathToIdx = new Map<string, number>();
92
+
93
+ // 1. Create a fact for the file itself using RELATIVE path
94
+ const fileFact: Omit<Fact, "id" | "timestamp" | "sessionId"> = {
95
+ type: "file",
96
+ content: `File: ${relativePath}`,
97
+ data: { file: relativePath },
98
+ confidence: 1.0,
99
+ validated: Date.now(),
100
+ };
101
+ facts.push(fileFact);
102
+ const fileIdx = 0;
103
+ filePathToIdx.set(relativePath, fileIdx);
104
+
105
+ // 2. Process imports -> IMPORTS relations
106
+ const imports = await this.lsp.getImports(filePath, content);
107
+ for (const imp of imports) {
108
+ const resolvedAbsPath = this.resolveImport(
109
+ filePath,
110
+ imp.module,
111
+ imp.isRelative,
112
+ );
113
+
114
+ const resolvedPath = resolvedAbsPath
115
+ ? path.relative(process.cwd(), resolvedAbsPath)
116
+ : null;
117
+
118
+ // Create a fact for the imported module
119
+ const importFact: Omit<Fact, "id" | "timestamp" | "sessionId"> = {
120
+ type: "module",
121
+ content: `Module: ${imp.alias || imp.module}`,
122
+ data: {
123
+ file: resolvedPath || imp.module,
124
+ module: imp.module,
125
+ alias: imp.alias,
126
+ isExternal: !resolvedPath,
127
+ },
128
+ confidence: resolvedPath ? 1.0 : 0.7,
129
+ validated: Date.now(),
130
+ };
131
+ facts.push(importFact);
132
+ const importIdx = facts.length - 1;
133
+
134
+ relations.push({
135
+ sourceIdx: fileIdx,
136
+ targetIdx: importIdx,
137
+ type: "IMPORTS",
138
+ });
139
+ }
140
+
141
+ // 3. Process symbols recursively
142
+ const processSymbol = (sym: any, parentIdx: number) => {
143
+ // Build rich content string for LLM consumption
144
+ let content = `${sym.kind}: ${sym.name} (${relativePath})`;
145
+ if (sym.signature) {
146
+ content += ` ${sym.signature}`;
147
+ }
148
+ if (sym.docstring) {
149
+ content += ` - ${sym.docstring.slice(0, 150)}`;
150
+ }
151
+
152
+ // Create symbol fact with enhanced data
153
+ const fact: Omit<Fact, "id" | "timestamp" | "sessionId"> = {
154
+ type: kindToType(sym.kind),
155
+ content,
156
+ data: {
157
+ file: relativePath,
158
+ symbol: sym.name,
159
+ kind: sym.kind,
160
+ type: kindToType(sym.kind),
161
+ line: sym.line,
162
+ signature: sym.signature,
163
+ docstring: sym.docstring,
164
+ exported: sym.exported,
165
+ },
166
+ confidence: 1.0,
167
+ validated: Date.now(),
168
+ };
169
+
170
+ facts.push(fact);
171
+ const symIdx = facts.length - 1;
172
+ symbolToIdx.set(sym.name, symIdx); // Note: Flat map might clash if same name used in nested scopes effectively, but ok for now
173
+
174
+ // Link: Parent DEFINES/CONTAINS Symbol
175
+ relations.push({
176
+ sourceIdx: parentIdx,
177
+ targetIdx: symIdx,
178
+ type: parentIdx === fileIdx ? "DEFINES" : "CONTAINS",
179
+ });
180
+
181
+ // Inherits relation if applicable (class extension)
182
+ // Note: LSP usually gives inheritance at top level, but if nested classes existed...
183
+
184
+ // Recurse for children
185
+ if (sym.children && sym.children.length > 0) {
186
+ for (const child of sym.children) {
187
+ processSymbol(child, symIdx);
188
+ }
189
+ }
190
+ };
191
+
192
+ for (const sym of symbols) {
193
+ processSymbol(sym, fileIdx);
194
+ }
195
+
196
+ // 4. Extract inheritance -> INHERITS relations
197
+ const inheritance = await this.lsp.getInheritance(filePath, content);
198
+ for (const inh of inheritance) {
199
+ const childIdx = symbolToIdx.get(inh.className);
200
+ let parentIdx = symbolToIdx.get(inh.parentName);
201
+
202
+ if (!parentIdx) {
203
+ // Parent is external - create a symbol fact
204
+ const parentFact: Omit<Fact, "id" | "timestamp" | "sessionId"> = {
205
+ type: "class",
206
+ content: `Class: ${inh.parentName}`,
207
+ data: { symbol: inh.parentName, kind: "Class" },
208
+ confidence: 0.8,
209
+ validated: Date.now(),
210
+ };
211
+ facts.push(parentFact);
212
+ parentIdx = facts.length - 1;
213
+ symbolToIdx.set(inh.parentName, parentIdx);
214
+ }
215
+
216
+ if (childIdx !== undefined) {
217
+ relations.push({
218
+ sourceIdx: childIdx,
219
+ targetIdx: parentIdx,
220
+ type: "INHERITS",
221
+ });
222
+ }
223
+ }
224
+
225
+ // 5. Extract calls with source context -> CALLS relations
226
+ // Get all calls from the file
227
+ const allCalls = await this.lsp.getOutgoingCalls(filePath, content, 1, 1);
228
+
229
+ // Group calls by sourceContext and deduplicate
230
+ const processedCalls = new Set<string>();
231
+ for (const call of allCalls) {
232
+ const callKey = `${call.sourceContext || ""}:${call.name}`;
233
+ if (processedCalls.has(callKey)) continue;
234
+ processedCalls.add(callKey);
235
+
236
+ // Find or create target fact
237
+ let targetIdx = symbolToIdx.get(call.name);
238
+ if (targetIdx === undefined) {
239
+ // External call - create a weak symbol fact
240
+ const targetFact: Omit<Fact, "id" | "timestamp" | "sessionId"> = {
241
+ type: "symbol",
242
+ content: `Symbol: ${call.name}`,
243
+ data: {
244
+ file: call.file
245
+ ? path.relative(process.cwd(), call.file)
246
+ : undefined,
247
+ symbol: call.name,
248
+ },
249
+ confidence: 0.8,
250
+ validated: Date.now(),
251
+ };
252
+ facts.push(targetFact);
253
+ targetIdx = facts.length - 1;
254
+ symbolToIdx.set(call.name, targetIdx);
255
+ }
256
+
257
+ // Find source (calling function)
258
+ let sourceIdx: number | undefined;
259
+ if (call.sourceContext) {
260
+ sourceIdx = symbolToIdx.get(call.sourceContext);
261
+ }
262
+ if (sourceIdx === undefined) {
263
+ sourceIdx = fileIdx; // Top-level call, link from file
264
+ }
265
+
266
+ relations.push({
267
+ sourceIdx,
268
+ targetIdx,
269
+ type: "CALLS",
270
+ });
271
+ }
272
+
273
+ return { facts, relations };
274
+ }
275
+ }
276
+
277
+ export default SymbolExtractor;
@@ -0,0 +1,123 @@
1
+ import { create } from "zustand";
2
+ import type { OutputItem, OutputItemType } from "@/types/OutputItem";
3
+ import ContextManager from "@/agent/contextManager";
4
+ import log from "@/utils/logger";
5
+
6
+ interface ModelSelectionRequest {
7
+ originalModel: string;
8
+ errorMessage: string;
9
+ resolve: (modelName: string | null) => void;
10
+ }
11
+
12
+ interface FraudeStore {
13
+ executionMode: 0 | 1 | 2; // 0 = Fast, 1 = Plan, 2 = Ask
14
+ outputItems: OutputItem[];
15
+ started: boolean;
16
+ status: number; // 0 = idle, 1 = running, 2 = waiting, 3 = reviewing changes, 4 = awaiting model selection, -1 = interrupted
17
+ elapsedTime: number;
18
+ lastBreak: number;
19
+ statusText?: string;
20
+ contextManager: ContextManager;
21
+ researchCache?: Record<string, string>;
22
+ abortController: AbortController | null;
23
+ pendingModelSelection: ModelSelectionRequest | null;
24
+ interruptAgent: () => void;
25
+ updateOutput: (
26
+ type: OutputItemType,
27
+ content: string,
28
+ config?: {
29
+ duration?: number;
30
+ dontOverride?: boolean;
31
+ },
32
+ ) => void;
33
+ requestModelSelection: (
34
+ originalModel: string,
35
+ errorMessage: string,
36
+ ) => Promise<string | null>;
37
+ resolveModelSelection: (modelName: string | null) => void;
38
+ }
39
+
40
+ const useFraudeStore = create<FraudeStore>((set, get) => ({
41
+ executionMode: 0 as 0 | 1 | 2,
42
+ outputItems: [],
43
+ started: false,
44
+ status: 0,
45
+ elapsedTime: 0,
46
+ lastBreak: 0,
47
+ statusText: "",
48
+ contextManager: new ContextManager(),
49
+ researchCache: undefined,
50
+ abortController: null,
51
+ pendingModelSelection: null,
52
+ interruptAgent: () => {
53
+ const controller = get().abortController;
54
+ if (controller && !controller.signal.aborted) {
55
+ try {
56
+ controller.abort();
57
+ } catch (e) {
58
+ log(`Abort caught: ${e}`);
59
+ }
60
+ }
61
+ },
62
+ updateOutput: (type, rawContent, config) => {
63
+ set((state) => {
64
+ const outputItems = [...state.outputItems];
65
+ const latestOutput = outputItems[outputItems.length - 1];
66
+ const dontOverrideType = new Set(["log", "interrupted", "command"]);
67
+ let content = rawContent.replaceAll(process.cwd(), "@");
68
+ if (
69
+ latestOutput &&
70
+ latestOutput.type === type &&
71
+ !dontOverrideType.has(type) &&
72
+ !config?.dontOverride
73
+ ) {
74
+ outputItems[outputItems.length - 1] = {
75
+ ...latestOutput,
76
+ content,
77
+ duration: config?.duration,
78
+ };
79
+ } else {
80
+ outputItems.push({
81
+ id: crypto.randomUUID(),
82
+ type,
83
+ content,
84
+ duration: config?.duration,
85
+ });
86
+ }
87
+ return {
88
+ outputItems,
89
+ };
90
+ });
91
+ },
92
+ requestModelSelection: (originalModel: string, errorMessage: string) => {
93
+ return new Promise<string | null>((resolve) => {
94
+ set({
95
+ status: 4, // awaiting model selection
96
+ statusText: "Awaiting model selection...",
97
+ pendingModelSelection: {
98
+ originalModel,
99
+ errorMessage,
100
+ resolve,
101
+ },
102
+ });
103
+ // Also add to output items so it renders
104
+ get().updateOutput(
105
+ "modelSelect",
106
+ JSON.stringify({ originalModel, errorMessage }),
107
+ );
108
+ });
109
+ },
110
+ resolveModelSelection: (modelName: string | null) => {
111
+ const pending = get().pendingModelSelection;
112
+ if (pending) {
113
+ pending.resolve(modelName);
114
+ set({
115
+ status: modelName ? 1 : 0, // back to running or idle
116
+ statusText: modelName ? "Retrying with new model..." : "",
117
+ pendingModelSelection: null,
118
+ });
119
+ }
120
+ },
121
+ }));
122
+
123
+ export default useFraudeStore;
@@ -0,0 +1,38 @@
1
+ import { create } from "zustand";
2
+ import { Settings, UpdateSettings } from "../config/settings";
3
+ import { SettingsSchema, type Config } from "../config/schema";
4
+
5
+ interface SettingsActions {
6
+ setOllamaUrl: (url: string) => void;
7
+ syncWithSettings: () => void;
8
+ }
9
+
10
+ type SettingsState = Config & SettingsActions;
11
+
12
+ const DEFAULTS = SettingsSchema.parse({});
13
+
14
+ const useSettingsStore = create<SettingsState>()((set) => {
15
+ return {
16
+ ...DEFAULTS,
17
+
18
+ setOllamaUrl: (url) => {
19
+ try {
20
+ UpdateSettings({ ollamaUrl: url });
21
+ } catch (e) {
22
+ console.error("Failed to save setting ollamaUrl:", e);
23
+ }
24
+ set({ ollamaUrl: url });
25
+ },
26
+
27
+ syncWithSettings: () => {
28
+ try {
29
+ const settings = Settings.getInstance();
30
+ set(settings.getAll());
31
+ } catch (e) {
32
+ console.error("Failed to sync settings:", e);
33
+ }
34
+ },
35
+ } as SettingsState;
36
+ });
37
+
38
+ export default useSettingsStore;
package/src/theme.ts ADDED
@@ -0,0 +1,26 @@
1
+ export const THEME = {
2
+ primary: "#f5c2e7", // Flamingo - Modern muted pink highlight
3
+ primaryLight: "#f5e0dc", // Rosewater - Very faint for selections/highlights
4
+ primaryDark: "#eba0ac", // Maroon - Muted for borders/non-focus
5
+ primaryDim: "#94e2d5", // Teal - Modern secondary accent
6
+ success: "#a6e3a1", // Green - Standard terminal success
7
+ error: "#f38ba8", // Red - Standard terminal error
8
+ warning: "#f9e2af", // Yellow - Standard terminal warning
9
+ info: "#89b4fa", // Blue - Standard terminal info
10
+ text: "#cdd6f4", // Text - Off-white based on modern palettes
11
+ dim: "#6c7086", // Overlay - Muted grey for metadata
12
+ border: "#313244", // Surface - Subtle dark border
13
+ borderFocus: "#f5c2e7", // Match primary for focused state
14
+ gradient: [
15
+ { r: 245, g: 194, b: 231 }, // flamingo
16
+ { r: 203, g: 166, b: 247 }, // mauve
17
+ { r: 180, g: 190, b: 254 }, // lavender
18
+ { r: 137, g: 180, b: 250 }, // blue
19
+ { r: 116, g: 199, b: 236 }, // sapphire
20
+ { r: 137, g: 220, b: 235 }, // sky
21
+ { r: 148, g: 226, b: 213 }, // teal
22
+ { r: 166, g: 227, b: 161 }, // green
23
+ { r: 249, g: 226, b: 175 }, // yellow
24
+ { r: 250, g: 179, b: 135 }, // peach
25
+ ],
26
+ };
@@ -0,0 +1,147 @@
1
+ import type { z } from "zod";
2
+ import type { ModelMessage, ToolSet, TextStreamPart } from "ai";
3
+ import type { TokenUsage } from "./TokenUsage";
4
+
5
+ // ============================================================================
6
+ // Agent Configuration Types
7
+ // ============================================================================
8
+
9
+ /** Reasoning effort levels for reasoning models (e.g., OpenAI o-series, GPT-5) */
10
+ export type ReasoningEffort =
11
+ | "none"
12
+ | "minimal"
13
+ | "low"
14
+ | "medium"
15
+ | "high"
16
+ | "xhigh";
17
+
18
+ export interface AgentConfig {
19
+ /** Model identifier (e.g., "llama3.1:latest", "gpt-4", etc.) */
20
+ model: string;
21
+
22
+ /** System prompt that defines agent behavior */
23
+ systemPrompt?: string;
24
+
25
+ /** Temperature for response generation (0.0 - 2.0) */
26
+ temperature?: number;
27
+
28
+ /** Maximum tokens to generate */
29
+ maxTokens?: number;
30
+
31
+ /** Tools available to the agent */
32
+ tools?: ToolSet;
33
+
34
+ /** Maximum number of tool execution steps (default: 5) */
35
+ maxSteps?: number;
36
+
37
+ /** Optional name for the agent instance */
38
+ name?: string;
39
+
40
+ /** Whether to automatically execute tools (default: true) */
41
+ autoExecuteTools?: boolean;
42
+
43
+ /**
44
+ * Reasoning effort for reasoning models (OpenAI o-series, GPT-5, etc.)
45
+ * - 'none': No reasoning (only GPT-5.1 models)
46
+ * - 'minimal': Minimal reasoning
47
+ * - 'low': Low reasoning effort
48
+ * - 'medium': Medium reasoning effort (default)
49
+ * - 'high': High reasoning effort
50
+ * - 'xhigh': Extra high reasoning (only GPT-5.1-Codex-Max)
51
+ */
52
+ reasoningEffort?: ReasoningEffort;
53
+
54
+ /** Callback for tool calls */
55
+ onToolCall?: (toolCall: ToolCallInfo) => void;
56
+
57
+ /** Callback for step completion */
58
+ onStepComplete?: (step: StepInfo) => void;
59
+
60
+ /** Callback for each raw stream chunk (for custom handling like usage tracking) */
61
+ onStreamChunk?: (chunk: TextStreamPart<ToolSet>) => void | Promise<void>;
62
+
63
+ /** Abort signal for cancelling the request */
64
+ abortSignal?: AbortSignal;
65
+
66
+ /**
67
+ * Whether to use an isolated context manager instead of the shared global one.
68
+ * Set to true for subagents to prevent context contamination with parent agents.
69
+ * Default: false (uses shared context manager)
70
+ */
71
+ useIsolatedContext?: boolean;
72
+ }
73
+
74
+ // ============================================================================
75
+ // Tool-Related Types
76
+ // ============================================================================
77
+
78
+ export interface ToolCallInfo {
79
+ toolCallId?: string;
80
+ toolName: string;
81
+ args: unknown;
82
+ result?: unknown;
83
+ }
84
+
85
+ export interface StepInfo {
86
+ stepNumber: number;
87
+ actions: { role: string; content: string }[];
88
+ toolCalls: ToolCallInfo[];
89
+ finishReason: string;
90
+ }
91
+
92
+ // ============================================================================
93
+ // Agent Response Types
94
+ // ============================================================================
95
+
96
+ export interface AgentResponse {
97
+ /** The final text response */
98
+ text: string;
99
+
100
+ /** Token usage statistics */
101
+ usage: TokenUsage;
102
+
103
+ /** Finish reason for the generation */
104
+ finishReason: string;
105
+
106
+ /** All steps taken during generation (for multi-step tool use) */
107
+ steps: StepInfo[];
108
+
109
+ /** All tool calls (and results) made during the conversation */
110
+ toolCalls: ToolCallInfo[];
111
+
112
+ /** Raw response from the provider (for advanced use cases) */
113
+ raw?: unknown;
114
+ }
115
+
116
+ export interface StructuredAgentResponse<T> {
117
+ /** The structured object matching the provided schema */
118
+ object: T;
119
+
120
+ /** Token usage statistics */
121
+ usage: TokenUsage;
122
+
123
+ /** Finish reason for the generation */
124
+ finishReason: string;
125
+
126
+ /** Raw response from the provider */
127
+ raw?: unknown;
128
+ }
129
+
130
+ // ============================================================================
131
+ // Message Types (Unified format)
132
+ // ============================================================================
133
+
134
+ export type AgentMessage = ModelMessage;
135
+
136
+ export type MessageRole = "system" | "user" | "assistant" | "tool";
137
+
138
+ export interface SimpleMessage {
139
+ role: MessageRole;
140
+ content: string;
141
+ }
142
+
143
+ // ============================================================================
144
+ // Schema Types for Structured Generation
145
+ // ============================================================================
146
+
147
+ export type StructuredSchema<T> = z.ZodType<T>;
@@ -0,0 +1,8 @@
1
+ export interface Command {
2
+ name: string;
3
+ description: string;
4
+ subcommands?: Command[];
5
+ action?: (args: string[]) => Promise<void>;
6
+ usage: string;
7
+ renderedOptions?: string[];
8
+ }