@geoffai/coder 1.0.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 +281 -0
- package/dist/cli.cjs +205 -0
- package/dist/cli.js +205 -0
- package/dist/index.cjs +182 -0
- package/dist/index.d.cts +1019 -0
- package/dist/index.d.ts +1019 -0
- package/dist/index.js +182 -0
- package/package.json +59 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1019 @@
|
|
|
1
|
+
import { ChildProcess } from 'child_process';
|
|
2
|
+
import OpenAI from 'openai';
|
|
3
|
+
|
|
4
|
+
interface Message {
|
|
5
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
6
|
+
content: string | ContentPart[];
|
|
7
|
+
tool_calls?: ToolCall[];
|
|
8
|
+
tool_call_id?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
}
|
|
11
|
+
interface ContentPart {
|
|
12
|
+
type: "text" | "image_url";
|
|
13
|
+
text?: string;
|
|
14
|
+
image_url?: {
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
interface ToolCall {
|
|
19
|
+
id: string;
|
|
20
|
+
type: "function";
|
|
21
|
+
function: {
|
|
22
|
+
name: string;
|
|
23
|
+
arguments: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
interface ToolDefinition {
|
|
27
|
+
type: "function";
|
|
28
|
+
function: {
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
parameters: {
|
|
32
|
+
type: "object";
|
|
33
|
+
properties: Record<string, PropertyDefinition>;
|
|
34
|
+
required: string[];
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface PropertyDefinition {
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
enum?: string[];
|
|
42
|
+
}
|
|
43
|
+
interface CompletionRequest {
|
|
44
|
+
model: string;
|
|
45
|
+
messages: Message[];
|
|
46
|
+
tools?: ToolDefinition[];
|
|
47
|
+
tool_choice?: "auto" | "none" | {
|
|
48
|
+
type: "function";
|
|
49
|
+
function: {
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
stream?: boolean;
|
|
54
|
+
max_tokens?: number;
|
|
55
|
+
temperature?: number;
|
|
56
|
+
}
|
|
57
|
+
interface CompletionResponse {
|
|
58
|
+
id: string;
|
|
59
|
+
object: string;
|
|
60
|
+
created: number;
|
|
61
|
+
model: string;
|
|
62
|
+
choices: Choice[];
|
|
63
|
+
usage?: {
|
|
64
|
+
prompt_tokens: number;
|
|
65
|
+
completion_tokens: number;
|
|
66
|
+
total_tokens: number;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
interface Choice {
|
|
70
|
+
index: number;
|
|
71
|
+
message: Message;
|
|
72
|
+
finish_reason: "stop" | "tool_calls" | "length" | "content_filter" | null;
|
|
73
|
+
}
|
|
74
|
+
interface StreamChunk {
|
|
75
|
+
id: string;
|
|
76
|
+
object: string;
|
|
77
|
+
created: number;
|
|
78
|
+
model: string;
|
|
79
|
+
choices: StreamChoice[];
|
|
80
|
+
}
|
|
81
|
+
interface StreamChoice {
|
|
82
|
+
index: number;
|
|
83
|
+
delta: Partial<Message> & {
|
|
84
|
+
tool_calls?: Partial<ToolCall>[];
|
|
85
|
+
};
|
|
86
|
+
finish_reason: string | null;
|
|
87
|
+
}
|
|
88
|
+
interface ToolResult {
|
|
89
|
+
success: boolean;
|
|
90
|
+
output: string;
|
|
91
|
+
error?: string;
|
|
92
|
+
}
|
|
93
|
+
type AgentEventType = 'iteration_start' | 'llm_call' | 'llm_response' | 'tool_call' | 'tool_result' | 'file_written' | 'file_modified' | 'command_executed' | 'task_complete' | 'error' | 'thinking';
|
|
94
|
+
interface AgentEvent {
|
|
95
|
+
type: AgentEventType;
|
|
96
|
+
timestamp: number;
|
|
97
|
+
data: Record<string, unknown>;
|
|
98
|
+
}
|
|
99
|
+
type AgentEventCallback = (event: AgentEvent) => void;
|
|
100
|
+
interface AgentConfig {
|
|
101
|
+
apiKey: string;
|
|
102
|
+
baseUrl: string;
|
|
103
|
+
model: string;
|
|
104
|
+
maxIterations: number;
|
|
105
|
+
maxTokens: number;
|
|
106
|
+
temperature: number;
|
|
107
|
+
workingDirectory: string;
|
|
108
|
+
autoApprove: boolean;
|
|
109
|
+
verbose: boolean;
|
|
110
|
+
onEvent?: AgentEventCallback;
|
|
111
|
+
sandboxId?: string;
|
|
112
|
+
}
|
|
113
|
+
interface AgentState {
|
|
114
|
+
messages: Message[];
|
|
115
|
+
iteration: number;
|
|
116
|
+
isRunning: boolean;
|
|
117
|
+
lastToolCalls: ToolCall[];
|
|
118
|
+
tokensUsed: number;
|
|
119
|
+
metrics: AgentMetrics;
|
|
120
|
+
}
|
|
121
|
+
interface AgentMetrics {
|
|
122
|
+
tokensUsed: number;
|
|
123
|
+
promptTokens: number;
|
|
124
|
+
completionTokens: number;
|
|
125
|
+
contextSize: number;
|
|
126
|
+
filesCreated: number;
|
|
127
|
+
filesModified: number;
|
|
128
|
+
linesAdded: number;
|
|
129
|
+
linesRemoved: number;
|
|
130
|
+
commandsExecuted: number;
|
|
131
|
+
toolCallsTotal: number;
|
|
132
|
+
apiCalls: number;
|
|
133
|
+
startTime: number;
|
|
134
|
+
modifiedFiles: Set<string>;
|
|
135
|
+
createdFiles: Set<string>;
|
|
136
|
+
}
|
|
137
|
+
type ToolHandler = (args: Record<string, unknown>) => Promise<ToolResult>;
|
|
138
|
+
interface ToolRegistry {
|
|
139
|
+
definitions: ToolDefinition[];
|
|
140
|
+
handlers: Map<string, ToolHandler>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class AgentLoop {
|
|
144
|
+
private client;
|
|
145
|
+
private config;
|
|
146
|
+
private state;
|
|
147
|
+
private tools;
|
|
148
|
+
private logger;
|
|
149
|
+
private aborted;
|
|
150
|
+
constructor(config: AgentConfig);
|
|
151
|
+
/**
|
|
152
|
+
* Emit an event to the callback if configured
|
|
153
|
+
*/
|
|
154
|
+
private emit;
|
|
155
|
+
private createInitialMetrics;
|
|
156
|
+
private createInitialState;
|
|
157
|
+
private getSystemMessage;
|
|
158
|
+
private estimateContextSize;
|
|
159
|
+
private manageContextWindow;
|
|
160
|
+
private checkContextLimits;
|
|
161
|
+
run(userPrompt: string): Promise<string>;
|
|
162
|
+
private callLLM;
|
|
163
|
+
/**
|
|
164
|
+
* Process XML-style tool calls from LLM response
|
|
165
|
+
*
|
|
166
|
+
* This method checks if the response contains XML-style tool calls
|
|
167
|
+
* (e.g., <function=name><parameter=...>...</parameter></function>)
|
|
168
|
+
* and converts them to OpenAI-compatible JSON format.
|
|
169
|
+
*
|
|
170
|
+
* If regex parsing fails and content contains XML patterns,
|
|
171
|
+
* it optionally uses an AI inference to convert them.
|
|
172
|
+
*/
|
|
173
|
+
private processXmlToolCalls;
|
|
174
|
+
/**
|
|
175
|
+
* AI-assisted tool call parsing
|
|
176
|
+
*
|
|
177
|
+
* Uses a lightweight LLM call to convert XML tool calls to JSON format.
|
|
178
|
+
* This is a fallback when regex parsing fails.
|
|
179
|
+
*/
|
|
180
|
+
private aiAssistedToolParsing;
|
|
181
|
+
private handleToolCalls;
|
|
182
|
+
private trackToolMetrics;
|
|
183
|
+
private addToolResultMessage;
|
|
184
|
+
private looksLikeCompletion;
|
|
185
|
+
/**
|
|
186
|
+
* Check if we should stop the loop based on state
|
|
187
|
+
* Returns true if we should stop
|
|
188
|
+
*/
|
|
189
|
+
private shouldStopLoop;
|
|
190
|
+
abort(): void;
|
|
191
|
+
getState(): Readonly<AgentState>;
|
|
192
|
+
getMetrics(): Readonly<AgentMetrics>;
|
|
193
|
+
getTokensUsed(): number;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* ContentGenerator interface for GeoffNet Qwen integration
|
|
198
|
+
* Simplified from qwen-code to focus on OpenAI-compatible generation
|
|
199
|
+
*/
|
|
200
|
+
/**
|
|
201
|
+
* Gemini-compatible types for internal use
|
|
202
|
+
* These mirror the @google/genai types but are simplified for our use case
|
|
203
|
+
*/
|
|
204
|
+
interface Part {
|
|
205
|
+
text?: string;
|
|
206
|
+
thought?: boolean;
|
|
207
|
+
functionCall?: FunctionCall;
|
|
208
|
+
functionResponse?: FunctionResponse;
|
|
209
|
+
inlineData?: {
|
|
210
|
+
data: string;
|
|
211
|
+
mimeType: string;
|
|
212
|
+
};
|
|
213
|
+
fileData?: {
|
|
214
|
+
fileUri: string;
|
|
215
|
+
mimeType: string;
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
interface Content {
|
|
219
|
+
role: 'user' | 'model';
|
|
220
|
+
parts: Part[];
|
|
221
|
+
}
|
|
222
|
+
interface FunctionCall {
|
|
223
|
+
id?: string;
|
|
224
|
+
name?: string;
|
|
225
|
+
args?: Record<string, unknown>;
|
|
226
|
+
}
|
|
227
|
+
interface FunctionResponse {
|
|
228
|
+
id?: string;
|
|
229
|
+
name?: string;
|
|
230
|
+
response?: unknown;
|
|
231
|
+
}
|
|
232
|
+
interface FunctionDeclaration {
|
|
233
|
+
name: string;
|
|
234
|
+
description: string;
|
|
235
|
+
parameters?: Record<string, unknown>;
|
|
236
|
+
parametersJsonSchema?: Record<string, unknown>;
|
|
237
|
+
}
|
|
238
|
+
interface Tool {
|
|
239
|
+
functionDeclarations?: FunctionDeclaration[];
|
|
240
|
+
}
|
|
241
|
+
type ToolListUnion = (Tool | CallableTool)[];
|
|
242
|
+
interface CallableTool {
|
|
243
|
+
tool: () => Promise<Tool>;
|
|
244
|
+
}
|
|
245
|
+
interface UsageMetadata {
|
|
246
|
+
promptTokenCount?: number;
|
|
247
|
+
candidatesTokenCount?: number;
|
|
248
|
+
totalTokenCount?: number;
|
|
249
|
+
cachedContentTokenCount?: number;
|
|
250
|
+
thoughtsTokenCount?: number;
|
|
251
|
+
}
|
|
252
|
+
interface Candidate {
|
|
253
|
+
content: Content;
|
|
254
|
+
finishReason?: FinishReason;
|
|
255
|
+
index: number;
|
|
256
|
+
safetyRatings?: unknown[];
|
|
257
|
+
}
|
|
258
|
+
declare enum FinishReason {
|
|
259
|
+
FINISH_REASON_UNSPECIFIED = 0,
|
|
260
|
+
STOP = 1,
|
|
261
|
+
MAX_TOKENS = 2,
|
|
262
|
+
SAFETY = 3,
|
|
263
|
+
RECITATION = 4,
|
|
264
|
+
OTHER = 5
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Gemini-style response wrapper
|
|
268
|
+
*/
|
|
269
|
+
declare class GenerateContentResponse {
|
|
270
|
+
candidates?: Candidate[];
|
|
271
|
+
usageMetadata?: UsageMetadata;
|
|
272
|
+
responseId?: string;
|
|
273
|
+
createTime?: string;
|
|
274
|
+
modelVersion?: string;
|
|
275
|
+
promptFeedback?: {
|
|
276
|
+
safetyRatings: unknown[];
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
interface GenerateContentParameters {
|
|
280
|
+
contents: Content[] | string;
|
|
281
|
+
config?: {
|
|
282
|
+
systemInstruction?: string | Content;
|
|
283
|
+
tools?: ToolListUnion;
|
|
284
|
+
temperature?: number;
|
|
285
|
+
topP?: number;
|
|
286
|
+
maxOutputTokens?: number;
|
|
287
|
+
abortSignal?: AbortSignal;
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
interface CountTokensParameters {
|
|
291
|
+
contents: Content[] | string;
|
|
292
|
+
}
|
|
293
|
+
interface CountTokensResponse {
|
|
294
|
+
totalTokens: number;
|
|
295
|
+
}
|
|
296
|
+
interface EmbedContentParameters {
|
|
297
|
+
contents: Content[] | string;
|
|
298
|
+
}
|
|
299
|
+
interface EmbedContentResponse {
|
|
300
|
+
embeddings: {
|
|
301
|
+
values: number[];
|
|
302
|
+
}[];
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Authentication types supported
|
|
306
|
+
*/
|
|
307
|
+
declare enum AuthType {
|
|
308
|
+
USE_OPENAI = "openai",
|
|
309
|
+
USE_OLLAMA = "ollama"
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Configuration for content generation
|
|
313
|
+
*/
|
|
314
|
+
interface ContentGeneratorConfig {
|
|
315
|
+
model: string;
|
|
316
|
+
apiKey?: string;
|
|
317
|
+
baseUrl?: string;
|
|
318
|
+
authType?: AuthType;
|
|
319
|
+
enableOpenAILogging?: boolean;
|
|
320
|
+
openAILoggingDir?: string;
|
|
321
|
+
timeout?: number;
|
|
322
|
+
maxRetries?: number;
|
|
323
|
+
enableTextToolCallParsing?: boolean;
|
|
324
|
+
samplingParams?: {
|
|
325
|
+
top_p?: number;
|
|
326
|
+
top_k?: number;
|
|
327
|
+
repetition_penalty?: number;
|
|
328
|
+
presence_penalty?: number;
|
|
329
|
+
frequency_penalty?: number;
|
|
330
|
+
temperature?: number;
|
|
331
|
+
max_tokens?: number;
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Interface for content generation implementations
|
|
336
|
+
*/
|
|
337
|
+
interface ContentGenerator {
|
|
338
|
+
generateContent(request: GenerateContentParameters, userPromptId: string): Promise<GenerateContentResponse>;
|
|
339
|
+
generateContentStream(request: GenerateContentParameters, userPromptId: string): Promise<AsyncGenerator<GenerateContentResponse>>;
|
|
340
|
+
countTokens(request: CountTokensParameters): Promise<CountTokensResponse>;
|
|
341
|
+
embedContent(request: EmbedContentParameters): Promise<EmbedContentResponse>;
|
|
342
|
+
setAvailableTools?(toolNames: string[]): void;
|
|
343
|
+
}
|
|
344
|
+
declare const DEFAULT_QWEN_MODEL = "qwen3-coder:30b";
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Interface for OpenAI-compatible providers
|
|
348
|
+
*/
|
|
349
|
+
interface OpenAICompatibleProvider {
|
|
350
|
+
buildHeaders(): Record<string, string | undefined>;
|
|
351
|
+
buildClient(): OpenAI;
|
|
352
|
+
buildRequest(request: OpenAI.Chat.ChatCompletionCreateParams, userPromptId: string): OpenAI.Chat.ChatCompletionCreateParams;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Content Generation Pipeline
|
|
357
|
+
* Handles the complete request/response flow for OpenAI-compatible APIs
|
|
358
|
+
*/
|
|
359
|
+
|
|
360
|
+
interface PipelineConfig {
|
|
361
|
+
provider: OpenAICompatibleProvider;
|
|
362
|
+
contentGeneratorConfig: ContentGeneratorConfig;
|
|
363
|
+
}
|
|
364
|
+
declare class ContentGenerationPipeline {
|
|
365
|
+
private config;
|
|
366
|
+
client: OpenAI;
|
|
367
|
+
private converter;
|
|
368
|
+
private contentGeneratorConfig;
|
|
369
|
+
constructor(config: PipelineConfig);
|
|
370
|
+
/**
|
|
371
|
+
* Set available tool names for text-based tool call parsing
|
|
372
|
+
*/
|
|
373
|
+
setAvailableTools(toolNames: string[]): void;
|
|
374
|
+
/**
|
|
375
|
+
* Execute a non-streaming request
|
|
376
|
+
*/
|
|
377
|
+
execute(request: GenerateContentParameters, userPromptId: string): Promise<GenerateContentResponse>;
|
|
378
|
+
/**
|
|
379
|
+
* Execute a streaming request
|
|
380
|
+
*/
|
|
381
|
+
executeStream(request: GenerateContentParameters, userPromptId: string): Promise<AsyncGenerator<GenerateContentResponse>>;
|
|
382
|
+
/**
|
|
383
|
+
* Process the OpenAI stream and convert to Gemini format
|
|
384
|
+
*/
|
|
385
|
+
private processStream;
|
|
386
|
+
private buildRequest;
|
|
387
|
+
private buildSamplingParameters;
|
|
388
|
+
private handleError;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* OpenAI Content Generator
|
|
393
|
+
* Main implementation of ContentGenerator for OpenAI-compatible APIs
|
|
394
|
+
*/
|
|
395
|
+
|
|
396
|
+
declare class OpenAIContentGenerator implements ContentGenerator {
|
|
397
|
+
protected pipeline: ContentGenerationPipeline;
|
|
398
|
+
constructor(contentGeneratorConfig: ContentGeneratorConfig, provider: OpenAICompatibleProvider);
|
|
399
|
+
/**
|
|
400
|
+
* Set available tool names for text-based tool call parsing
|
|
401
|
+
*/
|
|
402
|
+
setAvailableTools(toolNames: string[]): void;
|
|
403
|
+
generateContent(request: GenerateContentParameters, userPromptId: string): Promise<GenerateContentResponse>;
|
|
404
|
+
generateContentStream(request: GenerateContentParameters, userPromptId: string): Promise<AsyncGenerator<GenerateContentResponse>>;
|
|
405
|
+
countTokens(request: CountTokensParameters): Promise<CountTokensResponse>;
|
|
406
|
+
embedContent(request: EmbedContentParameters): Promise<EmbedContentResponse>;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* OpenAI <-> Gemini format converter
|
|
411
|
+
* Handles bidirectional conversion between OpenAI Chat Completion format
|
|
412
|
+
* and internal Gemini-style format, including streaming tool call parsing.
|
|
413
|
+
*/
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Converter class for transforming data between Gemini and OpenAI formats
|
|
417
|
+
*/
|
|
418
|
+
declare class OpenAIContentConverter {
|
|
419
|
+
private model;
|
|
420
|
+
private streamingToolCallParser;
|
|
421
|
+
private textToolCallParser;
|
|
422
|
+
private enableTextToolCallParsing;
|
|
423
|
+
private streamingTextAccumulator;
|
|
424
|
+
private streamingHasNativeToolCalls;
|
|
425
|
+
constructor(model: string, enableTextToolCallParsing?: boolean);
|
|
426
|
+
/**
|
|
427
|
+
* Set available tool names for text-based tool call parsing
|
|
428
|
+
*/
|
|
429
|
+
setAvailableTools(toolNames: string[]): void;
|
|
430
|
+
/**
|
|
431
|
+
* Enable or disable text-based tool call parsing
|
|
432
|
+
*/
|
|
433
|
+
setTextToolCallParsing(enabled: boolean): void;
|
|
434
|
+
/**
|
|
435
|
+
* Reset streaming state for new stream processing
|
|
436
|
+
*/
|
|
437
|
+
resetStreamingToolCalls(): void;
|
|
438
|
+
/**
|
|
439
|
+
* Convert Gemini tools to OpenAI format
|
|
440
|
+
*/
|
|
441
|
+
convertGeminiToolsToOpenAI(geminiTools: ToolListUnion): Promise<OpenAI.Chat.ChatCompletionTool[]>;
|
|
442
|
+
/**
|
|
443
|
+
* Convert Gemini tool parameters to OpenAI JSON Schema format
|
|
444
|
+
*/
|
|
445
|
+
convertGeminiToolParametersToOpenAI(parameters: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
446
|
+
/**
|
|
447
|
+
* Convert Gemini request to OpenAI message format
|
|
448
|
+
*/
|
|
449
|
+
convertGeminiRequestToOpenAI(request: GenerateContentParameters): OpenAI.Chat.ChatCompletionMessageParam[];
|
|
450
|
+
private addSystemInstructionMessage;
|
|
451
|
+
private processContents;
|
|
452
|
+
private processContent;
|
|
453
|
+
private parseParts;
|
|
454
|
+
private extractFunctionResponseContent;
|
|
455
|
+
private getMediaType;
|
|
456
|
+
private createMultimodalMessage;
|
|
457
|
+
private extractTextFromContentUnion;
|
|
458
|
+
/**
|
|
459
|
+
* Convert OpenAI response to Gemini format
|
|
460
|
+
*/
|
|
461
|
+
convertOpenAIResponseToGemini(openaiResponse: OpenAI.Chat.ChatCompletion): GenerateContentResponse;
|
|
462
|
+
/**
|
|
463
|
+
* Convert OpenAI stream chunk to Gemini format
|
|
464
|
+
*/
|
|
465
|
+
convertOpenAIChunkToGemini(chunk: OpenAI.Chat.ChatCompletionChunk): GenerateContentResponse;
|
|
466
|
+
private mapOpenAIFinishReasonToGemini;
|
|
467
|
+
private cleanOrphanedToolCalls;
|
|
468
|
+
private mergeConsecutiveAssistantMessages;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* StreamingToolCallParser - Handles streaming tool call objects with inconsistent chunk formats
|
|
473
|
+
*
|
|
474
|
+
* Problems this parser addresses:
|
|
475
|
+
* - Tool calls arrive with varying chunk shapes (empty strings, partial JSON, complete objects)
|
|
476
|
+
* - Tool calls may lack IDs, names, or have inconsistent indices
|
|
477
|
+
* - Multiple tool calls can be processed simultaneously with interleaved chunks
|
|
478
|
+
* - Index collisions occur when the same index is reused for different tool calls
|
|
479
|
+
* - JSON arguments are fragmented across multiple chunks and need reconstruction
|
|
480
|
+
*/
|
|
481
|
+
/**
|
|
482
|
+
* Type definition for the result of parsing a JSON chunk in tool calls
|
|
483
|
+
*/
|
|
484
|
+
interface ToolCallParseResult {
|
|
485
|
+
/** Whether the JSON parsing is complete */
|
|
486
|
+
complete: boolean;
|
|
487
|
+
/** The parsed JSON value (only present when complete is true) */
|
|
488
|
+
value?: Record<string, unknown>;
|
|
489
|
+
/** Error information if parsing failed */
|
|
490
|
+
error?: Error;
|
|
491
|
+
/** Whether the JSON was repaired (e.g., auto-closed unclosed strings) */
|
|
492
|
+
repaired?: boolean;
|
|
493
|
+
}
|
|
494
|
+
declare class StreamingToolCallParser {
|
|
495
|
+
/** Accumulated buffer containing all received chunks for each tool call index */
|
|
496
|
+
private buffers;
|
|
497
|
+
/** Current nesting depth in JSON structure for each tool call index */
|
|
498
|
+
private depths;
|
|
499
|
+
/** Whether we're currently inside a string literal for each tool call index */
|
|
500
|
+
private inStrings;
|
|
501
|
+
/** Whether the next character should be treated as escaped for each tool call index */
|
|
502
|
+
private escapes;
|
|
503
|
+
/** Metadata for each tool call index */
|
|
504
|
+
private toolCallMeta;
|
|
505
|
+
/** Map from tool call ID to actual index used for storage */
|
|
506
|
+
private idToIndexMap;
|
|
507
|
+
/** Counter for generating new indices when collisions occur */
|
|
508
|
+
private nextAvailableIndex;
|
|
509
|
+
/**
|
|
510
|
+
* Processes a new chunk of tool call data and attempts to parse complete JSON objects
|
|
511
|
+
*/
|
|
512
|
+
addChunk(index: number, chunk: string, id?: string, name?: string): ToolCallParseResult;
|
|
513
|
+
/**
|
|
514
|
+
* Gets the current tool call metadata for a specific index
|
|
515
|
+
*/
|
|
516
|
+
getToolCallMeta(index: number): {
|
|
517
|
+
id?: string;
|
|
518
|
+
name?: string;
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Gets all completed tool calls that are ready to be emitted
|
|
522
|
+
*/
|
|
523
|
+
getCompletedToolCalls(): Array<{
|
|
524
|
+
id?: string;
|
|
525
|
+
name?: string;
|
|
526
|
+
args: Record<string, unknown>;
|
|
527
|
+
index: number;
|
|
528
|
+
}>;
|
|
529
|
+
private findNextAvailableIndex;
|
|
530
|
+
private findMostRecentIncompleteIndex;
|
|
531
|
+
/**
|
|
532
|
+
* Resets the parser state for a specific tool call index
|
|
533
|
+
*/
|
|
534
|
+
resetIndex(index: number): void;
|
|
535
|
+
/**
|
|
536
|
+
* Resets the entire parser state for processing a new stream
|
|
537
|
+
*/
|
|
538
|
+
reset(): void;
|
|
539
|
+
/**
|
|
540
|
+
* Gets the current accumulated buffer content for a specific index
|
|
541
|
+
*/
|
|
542
|
+
getBuffer(index: number): string;
|
|
543
|
+
/**
|
|
544
|
+
* Gets the current parsing state information for a specific index
|
|
545
|
+
*/
|
|
546
|
+
getState(index: number): {
|
|
547
|
+
depth: number;
|
|
548
|
+
inString: boolean;
|
|
549
|
+
escape: boolean;
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Text-based tool call parser for models that don't support native OpenAI tool_calls.
|
|
555
|
+
* Supports multiple XML and JSON formats used by Qwen and other models.
|
|
556
|
+
*/
|
|
557
|
+
/**
|
|
558
|
+
* Parsed tool call from text content
|
|
559
|
+
*/
|
|
560
|
+
interface ParsedTextToolCall {
|
|
561
|
+
id: string;
|
|
562
|
+
name: string;
|
|
563
|
+
args: Record<string, unknown>;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Result of text tool call parsing
|
|
567
|
+
*/
|
|
568
|
+
interface TextToolCallParseResult {
|
|
569
|
+
toolCalls: ParsedTextToolCall[];
|
|
570
|
+
remainingText: string;
|
|
571
|
+
/** Extracted thinking/reasoning content from <think> tags */
|
|
572
|
+
thinkingContent?: string;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Parses tool calls from text content for models that don't support native OpenAI tool_calls.
|
|
576
|
+
*
|
|
577
|
+
* Supports multiple formats:
|
|
578
|
+
* 1. XML-style: <tool_call>{"name": "tool_name", "arguments": {...}}</tool_call>
|
|
579
|
+
* 2. Function notation: tool_name({"arg": "value"})
|
|
580
|
+
* 3. JSON block: ```json\n{"tool": "name", "args": {...}}\n```
|
|
581
|
+
* 4. Bracket notation: [tool_call: tool_name(args)]
|
|
582
|
+
* 5. Llama/Qwen style: <function=name><parameter=key>value</parameter></function>
|
|
583
|
+
*/
|
|
584
|
+
declare class TextToolCallParser {
|
|
585
|
+
private toolCallCounter;
|
|
586
|
+
private availableToolNames;
|
|
587
|
+
constructor(availableToolNames?: string[]);
|
|
588
|
+
/**
|
|
589
|
+
* Set the available tool names for validation
|
|
590
|
+
*/
|
|
591
|
+
setAvailableTools(toolNames: string[]): void;
|
|
592
|
+
/**
|
|
593
|
+
* Generate a unique tool call ID
|
|
594
|
+
*/
|
|
595
|
+
private generateId;
|
|
596
|
+
/**
|
|
597
|
+
* Check if a tool name is valid
|
|
598
|
+
*/
|
|
599
|
+
private isValidTool;
|
|
600
|
+
/**
|
|
601
|
+
* Parse tool calls from text content
|
|
602
|
+
*/
|
|
603
|
+
parse(content: string): TextToolCallParseResult;
|
|
604
|
+
/**
|
|
605
|
+
* Parse thinking/reasoning content from <think> tags (Qwen models)
|
|
606
|
+
* Supports: <think>...</think>, <thinking>...</thinking>, <reasoning>...</reasoning>
|
|
607
|
+
*/
|
|
608
|
+
private parseThinkTags;
|
|
609
|
+
/**
|
|
610
|
+
* Parse XML-style tool calls: <tool_call>{"name": "...", "arguments": {...}}</tool_call>
|
|
611
|
+
*/
|
|
612
|
+
private parseXmlStyle;
|
|
613
|
+
/**
|
|
614
|
+
* Parse function call XML: <function_call>{"name": "...", "parameters": {...}}</function_call>
|
|
615
|
+
*/
|
|
616
|
+
private parseFunctionCallXml;
|
|
617
|
+
/**
|
|
618
|
+
* Parse Llama/Qwen style tool calls: <function=name><parameter=key>value</parameter></function>
|
|
619
|
+
* Also handles variations like </tool_call> at the end
|
|
620
|
+
*/
|
|
621
|
+
private parseLlamaStyleXml;
|
|
622
|
+
/**
|
|
623
|
+
* Parse JSON code blocks that contain tool call structures
|
|
624
|
+
*/
|
|
625
|
+
private parseJsonBlocks;
|
|
626
|
+
/**
|
|
627
|
+
* Parse bracket notation: [tool_call: name(args)] or [name: args]
|
|
628
|
+
*/
|
|
629
|
+
private parseBracketNotation;
|
|
630
|
+
/**
|
|
631
|
+
* Parse inline function calls: tool_name({...})
|
|
632
|
+
*/
|
|
633
|
+
private parseInlineFunctionCalls;
|
|
634
|
+
/**
|
|
635
|
+
* Parse various JSON formats for tool calls
|
|
636
|
+
*/
|
|
637
|
+
private parseToolCallJson;
|
|
638
|
+
/**
|
|
639
|
+
* Reset the parser state
|
|
640
|
+
*/
|
|
641
|
+
reset(): void;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* OpenAI Content Generator exports
|
|
646
|
+
*/
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Create an OpenAI-compatible content generator with the default provider
|
|
650
|
+
*/
|
|
651
|
+
declare function createOpenAIContentGenerator(contentGeneratorConfig: ContentGeneratorConfig): ContentGenerator;
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* QwenAgentAdapter
|
|
655
|
+
*
|
|
656
|
+
* Adapter layer that wraps the Qwen-style content generator and provides
|
|
657
|
+
* the same interface as AgentLoop. This enables:
|
|
658
|
+
* - Text-based XML tool call parsing for Qwen models
|
|
659
|
+
* - Streaming tool call reconstruction
|
|
660
|
+
* - Same event emission interface for frontend compatibility
|
|
661
|
+
*/
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Extended configuration for QwenAgentAdapter
|
|
665
|
+
*/
|
|
666
|
+
interface QwenAgentConfig extends AgentConfig {
|
|
667
|
+
/** Enable text-based tool call parsing (XML format support) */
|
|
668
|
+
enableTextToolCallParsing?: boolean;
|
|
669
|
+
/** Sampling parameters for the model */
|
|
670
|
+
samplingParams?: ContentGeneratorConfig['samplingParams'];
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* QwenAgentAdapter provides an AgentLoop-compatible interface
|
|
674
|
+
* while using the Qwen content generator with XML tool call parsing
|
|
675
|
+
*/
|
|
676
|
+
declare class QwenAgentAdapter {
|
|
677
|
+
private config;
|
|
678
|
+
private state;
|
|
679
|
+
private tools;
|
|
680
|
+
private logger;
|
|
681
|
+
private aborted;
|
|
682
|
+
private contentGenerator;
|
|
683
|
+
constructor(config: QwenAgentConfig);
|
|
684
|
+
/**
|
|
685
|
+
* Emit an event to the callback if configured
|
|
686
|
+
*/
|
|
687
|
+
private emit;
|
|
688
|
+
private createInitialMetrics;
|
|
689
|
+
private createInitialState;
|
|
690
|
+
private getSystemMessage;
|
|
691
|
+
private estimateContextSize;
|
|
692
|
+
private manageContextWindow;
|
|
693
|
+
private checkContextLimits;
|
|
694
|
+
/**
|
|
695
|
+
* Convert internal messages to Gemini-style Content format
|
|
696
|
+
*/
|
|
697
|
+
private messagesToContents;
|
|
698
|
+
/**
|
|
699
|
+
* Convert tool definitions to Gemini Tool format
|
|
700
|
+
*/
|
|
701
|
+
private toolsToGeminiFormat;
|
|
702
|
+
/**
|
|
703
|
+
* Extract tool calls from Gemini response
|
|
704
|
+
*/
|
|
705
|
+
private extractToolCalls;
|
|
706
|
+
/**
|
|
707
|
+
* Extract text content from Gemini response
|
|
708
|
+
*/
|
|
709
|
+
private extractTextContent;
|
|
710
|
+
/**
|
|
711
|
+
* Main agent loop - runs until task completion or max iterations
|
|
712
|
+
*/
|
|
713
|
+
run(userPrompt: string): Promise<string>;
|
|
714
|
+
private callLLM;
|
|
715
|
+
private handleToolCalls;
|
|
716
|
+
private trackToolMetrics;
|
|
717
|
+
private addToolResultMessage;
|
|
718
|
+
private looksLikeCompletion;
|
|
719
|
+
private shouldStopLoop;
|
|
720
|
+
private serializeMetrics;
|
|
721
|
+
abort(): void;
|
|
722
|
+
getState(): Readonly<AgentState>;
|
|
723
|
+
getMetrics(): Readonly<AgentMetrics>;
|
|
724
|
+
getTokensUsed(): number;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
interface RetryConfig {
|
|
728
|
+
maxRetries: number;
|
|
729
|
+
baseDelayMs: number;
|
|
730
|
+
maxDelayMs: number;
|
|
731
|
+
retryableStatuses: number[];
|
|
732
|
+
}
|
|
733
|
+
declare class APIClient {
|
|
734
|
+
private apiKey;
|
|
735
|
+
private baseUrl;
|
|
736
|
+
private model;
|
|
737
|
+
private retryConfig;
|
|
738
|
+
constructor(config: {
|
|
739
|
+
apiKey: string;
|
|
740
|
+
baseUrl: string;
|
|
741
|
+
model: string;
|
|
742
|
+
retryConfig?: Partial<RetryConfig>;
|
|
743
|
+
});
|
|
744
|
+
private sleep;
|
|
745
|
+
private calculateBackoff;
|
|
746
|
+
private shouldRetry;
|
|
747
|
+
createCompletion(messages: Message[], tools?: ToolDefinition[], options?: {
|
|
748
|
+
stream?: boolean;
|
|
749
|
+
maxTokens?: number;
|
|
750
|
+
temperature?: number;
|
|
751
|
+
}): Promise<CompletionResponse>;
|
|
752
|
+
createStreamingCompletion(messages: Message[], tools?: ToolDefinition[], options?: {
|
|
753
|
+
maxTokens?: number;
|
|
754
|
+
temperature?: number;
|
|
755
|
+
}): AsyncGenerator<StreamChunk, void, unknown>;
|
|
756
|
+
accumulateStream(messages: Message[], tools?: ToolDefinition[], options?: {
|
|
757
|
+
maxTokens?: number;
|
|
758
|
+
temperature?: number;
|
|
759
|
+
onToken?: (token: string) => void;
|
|
760
|
+
}): Promise<Message>;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
interface ToolRegistryConfig {
|
|
764
|
+
workingDir: string;
|
|
765
|
+
ignorePatterns?: string[];
|
|
766
|
+
}
|
|
767
|
+
declare function createToolRegistry(config: ToolRegistryConfig | string): ToolRegistry;
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* TodoWrite Tool
|
|
771
|
+
*
|
|
772
|
+
* Creates and manages a structured task list for coding sessions.
|
|
773
|
+
* This helps track progress, organize complex tasks, and demonstrates
|
|
774
|
+
* thoroughness to the user.
|
|
775
|
+
*/
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Todo item structure
|
|
779
|
+
*/
|
|
780
|
+
interface TodoItem {
|
|
781
|
+
id: string;
|
|
782
|
+
content: string;
|
|
783
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
784
|
+
/** Active form description for UI display during execution */
|
|
785
|
+
activeForm?: string;
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Read todos from file
|
|
789
|
+
*/
|
|
790
|
+
declare function readTodos(sessionId?: string): Promise<TodoItem[]>;
|
|
791
|
+
/**
|
|
792
|
+
* Write todos to file
|
|
793
|
+
*/
|
|
794
|
+
declare function writeTodos(todos: TodoItem[], sessionId?: string): Promise<void>;
|
|
795
|
+
/**
|
|
796
|
+
* Create the todo_write tool handler
|
|
797
|
+
*/
|
|
798
|
+
declare function createTodoWriteHandler(sessionId?: string): ToolHandler;
|
|
799
|
+
/**
|
|
800
|
+
* Todo write tool definition
|
|
801
|
+
*/
|
|
802
|
+
declare const todoWriteDefinition: ToolDefinition;
|
|
803
|
+
/**
|
|
804
|
+
* List all todo sessions
|
|
805
|
+
*/
|
|
806
|
+
declare function listTodoSessions(): Promise<string[]>;
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Plan Mode Tools
|
|
810
|
+
*
|
|
811
|
+
* Tools for entering/exiting plan mode where the agent plans before executing.
|
|
812
|
+
* Plan mode ensures user approval before the agent starts writing code.
|
|
813
|
+
*/
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Plan mode state interface
|
|
817
|
+
*/
|
|
818
|
+
interface PlanModeState {
|
|
819
|
+
enabled: boolean;
|
|
820
|
+
plan?: string;
|
|
821
|
+
awaitingApproval: boolean;
|
|
822
|
+
approved: boolean;
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Get or create plan mode state for a session
|
|
826
|
+
*/
|
|
827
|
+
declare function getPlanModeState(sessionId?: string): PlanModeState;
|
|
828
|
+
/**
|
|
829
|
+
* Set plan mode approval status (called by frontend)
|
|
830
|
+
*/
|
|
831
|
+
declare function setPlanApproval(sessionId: string, approved: boolean): void;
|
|
832
|
+
/**
|
|
833
|
+
* Enter plan mode for a session
|
|
834
|
+
*/
|
|
835
|
+
declare function enterPlanMode(sessionId?: string): void;
|
|
836
|
+
/**
|
|
837
|
+
* Check if plan mode is enabled
|
|
838
|
+
*/
|
|
839
|
+
declare function isPlanModeEnabled(sessionId?: string): boolean;
|
|
840
|
+
/**
|
|
841
|
+
* Create exit_plan_mode tool handler
|
|
842
|
+
*/
|
|
843
|
+
declare function createExitPlanModeHandler(sessionId?: string, onEvent?: AgentEventCallback): ToolHandler;
|
|
844
|
+
/**
|
|
845
|
+
* exit_plan_mode tool definition
|
|
846
|
+
*/
|
|
847
|
+
declare const exitPlanModeDefinition: ToolDefinition;
|
|
848
|
+
/**
|
|
849
|
+
* Create enter_plan_mode tool handler (for explicit plan mode entry)
|
|
850
|
+
*/
|
|
851
|
+
declare function createEnterPlanModeHandler(sessionId?: string, onEvent?: AgentEventCallback): ToolHandler;
|
|
852
|
+
/**
|
|
853
|
+
* enter_plan_mode tool definition
|
|
854
|
+
*/
|
|
855
|
+
declare const enterPlanModeDefinition: ToolDefinition;
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Background Process Tools
|
|
859
|
+
*
|
|
860
|
+
* Tools for running processes in the background and managing them.
|
|
861
|
+
* Enables long-running tasks like dev servers without blocking the agent.
|
|
862
|
+
*/
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Background process info
|
|
866
|
+
*/
|
|
867
|
+
interface BackgroundProcess {
|
|
868
|
+
id: string;
|
|
869
|
+
pid: number;
|
|
870
|
+
command: string;
|
|
871
|
+
startTime: number;
|
|
872
|
+
output: string[];
|
|
873
|
+
isComplete: boolean;
|
|
874
|
+
exitCode: number | null;
|
|
875
|
+
process: ChildProcess;
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Background process manager
|
|
879
|
+
*/
|
|
880
|
+
declare class BackgroundProcessManager {
|
|
881
|
+
private processes;
|
|
882
|
+
private counter;
|
|
883
|
+
/**
|
|
884
|
+
* Start a background process
|
|
885
|
+
*/
|
|
886
|
+
start(command: string, workingDir: string, onEvent?: AgentEventCallback): BackgroundProcess;
|
|
887
|
+
/**
|
|
888
|
+
* Get a background process by ID
|
|
889
|
+
*/
|
|
890
|
+
get(id: string): BackgroundProcess | undefined;
|
|
891
|
+
/**
|
|
892
|
+
* Get all background processes
|
|
893
|
+
*/
|
|
894
|
+
getAll(): BackgroundProcess[];
|
|
895
|
+
/**
|
|
896
|
+
* Kill a background process
|
|
897
|
+
*/
|
|
898
|
+
kill(id: string): boolean;
|
|
899
|
+
/**
|
|
900
|
+
* Get output from a background process
|
|
901
|
+
*/
|
|
902
|
+
getOutput(id: string, tail?: number): string;
|
|
903
|
+
/**
|
|
904
|
+
* Clean up completed processes
|
|
905
|
+
*/
|
|
906
|
+
cleanup(): void;
|
|
907
|
+
}
|
|
908
|
+
declare const manager: BackgroundProcessManager;
|
|
909
|
+
/**
|
|
910
|
+
* Create run_background handler
|
|
911
|
+
*/
|
|
912
|
+
declare function createRunBackgroundHandler(workingDir: string, onEvent?: AgentEventCallback): ToolHandler;
|
|
913
|
+
/**
|
|
914
|
+
* Create get_process_output handler
|
|
915
|
+
*/
|
|
916
|
+
declare function createGetProcessOutputHandler(): ToolHandler;
|
|
917
|
+
/**
|
|
918
|
+
* Create kill_process handler
|
|
919
|
+
*/
|
|
920
|
+
declare function createKillProcessHandler(): ToolHandler;
|
|
921
|
+
/**
|
|
922
|
+
* Create list_processes handler
|
|
923
|
+
*/
|
|
924
|
+
declare function createListProcessesHandler(): ToolHandler;
|
|
925
|
+
declare const runBackgroundDefinition: ToolDefinition;
|
|
926
|
+
declare const getProcessOutputDefinition: ToolDefinition;
|
|
927
|
+
declare const killProcessDefinition: ToolDefinition;
|
|
928
|
+
declare const listProcessesDefinition: ToolDefinition;
|
|
929
|
+
|
|
930
|
+
type LogEventType = 'tool_call' | 'tool_result' | 'context_truncated' | 'assistant_message' | 'user_message' | 'info' | 'warn' | 'error' | 'success' | 'metrics_update' | 'iteration_start' | 'task_complete';
|
|
931
|
+
interface LogEvent {
|
|
932
|
+
type: LogEventType;
|
|
933
|
+
timestamp: number;
|
|
934
|
+
data: {
|
|
935
|
+
message?: string;
|
|
936
|
+
toolName?: string;
|
|
937
|
+
toolArgs?: string;
|
|
938
|
+
success?: boolean;
|
|
939
|
+
output?: string;
|
|
940
|
+
error?: string;
|
|
941
|
+
iteration?: number;
|
|
942
|
+
maxIterations?: number;
|
|
943
|
+
metrics?: AgentMetrics;
|
|
944
|
+
removedCount?: number;
|
|
945
|
+
tokenLimit?: number;
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
type LogEventCallback = (event: LogEvent) => void;
|
|
949
|
+
declare class Logger {
|
|
950
|
+
private verbose;
|
|
951
|
+
private currentMetricsLine;
|
|
952
|
+
private onLogEvent?;
|
|
953
|
+
constructor(verbose?: boolean, onLogEvent?: LogEventCallback);
|
|
954
|
+
setLogEventCallback(callback: LogEventCallback | undefined): void;
|
|
955
|
+
private emit;
|
|
956
|
+
private timestamp;
|
|
957
|
+
private num;
|
|
958
|
+
private truncate;
|
|
959
|
+
private colorize;
|
|
960
|
+
private statusIcon;
|
|
961
|
+
private line;
|
|
962
|
+
private label;
|
|
963
|
+
private section;
|
|
964
|
+
private clearStatusLine;
|
|
965
|
+
private restoreStatusLine;
|
|
966
|
+
private print;
|
|
967
|
+
info(message: string): void;
|
|
968
|
+
debug(message: string): void;
|
|
969
|
+
warn(message: string): void;
|
|
970
|
+
error(message: string): void;
|
|
971
|
+
success(message: string): void;
|
|
972
|
+
tool(name: string, args: string): void;
|
|
973
|
+
toolResult(name: string, result: ToolResult): void;
|
|
974
|
+
assistant(message: string): void;
|
|
975
|
+
user(message: string): void;
|
|
976
|
+
separator(): void;
|
|
977
|
+
banner(): void;
|
|
978
|
+
config(config: Record<string, unknown>): void;
|
|
979
|
+
metricsUpdate(metrics: AgentMetrics, iteration: number): void;
|
|
980
|
+
clearMetricsLine(): void;
|
|
981
|
+
metricsSummary(metrics: AgentMetrics, iteration: number): void;
|
|
982
|
+
iterationHeader(iteration: number, maxIterations: number): void;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
interface GeoffConfig {
|
|
986
|
+
model?: string;
|
|
987
|
+
baseUrl?: string;
|
|
988
|
+
apiKey?: string;
|
|
989
|
+
maxIterations?: number;
|
|
990
|
+
maxTokens?: number;
|
|
991
|
+
temperature?: number;
|
|
992
|
+
verbose?: boolean;
|
|
993
|
+
ignorePatterns?: string[];
|
|
994
|
+
blockedCommands?: string[];
|
|
995
|
+
retry?: {
|
|
996
|
+
maxRetries?: number;
|
|
997
|
+
baseDelayMs?: number;
|
|
998
|
+
maxDelayMs?: number;
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Load configuration from .geoff.json files only.
|
|
1003
|
+
* Priority (highest to lowest):
|
|
1004
|
+
* 1. Project config (.geoff.json in working directory)
|
|
1005
|
+
* 2. User config (~/.geoff.json)
|
|
1006
|
+
* 3. Default config
|
|
1007
|
+
*
|
|
1008
|
+
* Model configuration (model, baseUrl, apiKey) comes exclusively from .geoff.json
|
|
1009
|
+
*/
|
|
1010
|
+
declare function loadConfig(workingDirectory: string): GeoffConfig;
|
|
1011
|
+
/**
|
|
1012
|
+
* Validate configuration values
|
|
1013
|
+
*/
|
|
1014
|
+
declare function validateConfig(config: GeoffConfig): {
|
|
1015
|
+
valid: boolean;
|
|
1016
|
+
errors: string[];
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
export { APIClient, type AgentConfig, type AgentEvent, type AgentEventCallback, type AgentEventType, AgentLoop, type AgentMetrics, type AgentState, type BackgroundProcess, type CompletionRequest, type CompletionResponse, ContentGenerationPipeline, type ContentGenerator, type ContentGeneratorConfig, DEFAULT_QWEN_MODEL, type GenerateContentParameters, GenerateContentResponse, type GeoffConfig, Logger, type Message, OpenAIContentConverter, OpenAIContentGenerator, type PlanModeState, QwenAgentAdapter, type QwenAgentConfig, StreamingToolCallParser, TextToolCallParser, type TodoItem, type ToolCall, type ToolDefinition, type ToolHandler, type ToolRegistry, type ToolResult, manager as backgroundProcessManager, createEnterPlanModeHandler, createExitPlanModeHandler, createGetProcessOutputHandler, createKillProcessHandler, createListProcessesHandler, createOpenAIContentGenerator, createRunBackgroundHandler, createTodoWriteHandler, createToolRegistry, enterPlanMode, enterPlanModeDefinition, exitPlanModeDefinition, getPlanModeState, getProcessOutputDefinition, isPlanModeEnabled, killProcessDefinition, listProcessesDefinition, listTodoSessions, loadConfig, readTodos, runBackgroundDefinition, setPlanApproval, todoWriteDefinition, validateConfig, writeTodos };
|