orquesta-cli 0.2.99 → 0.2.101

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.
@@ -44,7 +44,7 @@ export declare class LLMClient {
44
44
  private model;
45
45
  private modelName;
46
46
  private triedBatutaFallback;
47
- private currentAbortController;
47
+ private activeControllers;
48
48
  private isInterrupted;
49
49
  onStreamingContent: ((token: string) => void) | null;
50
50
  private static readonly DEFAULT_MAX_RETRIES;
@@ -123,7 +123,7 @@ export class LLMClient {
123
123
  model;
124
124
  modelName;
125
125
  triedBatutaFallback = false;
126
- currentAbortController = null;
126
+ activeControllers = new Set();
127
127
  isInterrupted = false;
128
128
  onStreamingContent = null;
129
129
  static DEFAULT_MAX_RETRIES = 3;
@@ -220,6 +220,7 @@ export class LLMClient {
220
220
  maxRetries
221
221
  });
222
222
  const url = '/chat/completions';
223
+ let controller = null;
223
224
  try {
224
225
  logger.flow('Starting message preprocessing');
225
226
  const modelId = options.model || this.model;
@@ -251,13 +252,14 @@ export class LLMClient {
251
252
  logger.llmRequest(processedMessages, modelId, options.tools);
252
253
  }
253
254
  logger.startTimer('llm-api-call');
254
- this.currentAbortController = new AbortController();
255
+ controller = new AbortController();
256
+ this.activeControllers.add(controller);
255
257
  let response;
256
258
  if (this.onStreamingContent) {
257
259
  const streamRequestBody = { ...requestBody, stream: true };
258
260
  const streamResp = await this.axiosInstance.post(url, streamRequestBody, {
259
261
  responseType: 'stream',
260
- signal: this.currentAbortController.signal,
262
+ signal: controller.signal,
261
263
  headers: buildPerRequestHeaders(),
262
264
  });
263
265
  captureBatutaHeaders(streamResp.headers);
@@ -325,7 +327,6 @@ export class LLMClient {
325
327
  catch { }
326
328
  }
327
329
  }
328
- this.currentAbortController = null;
329
330
  const toolCalls = Array.from(toolCallsMap.values())
330
331
  .filter(tc => tc.id && tc.function.name)
331
332
  .map(tc => ({ id: tc.id, type: 'function', function: { name: tc.function.name, arguments: tc.function.arguments } }));
@@ -350,10 +351,9 @@ export class LLMClient {
350
351
  }
351
352
  else {
352
353
  const httpResp = await this.axiosInstance.post(url, requestBody, {
353
- signal: this.currentAbortController.signal,
354
+ signal: controller.signal,
354
355
  headers: buildPerRequestHeaders(),
355
356
  });
356
- this.currentAbortController = null;
357
357
  response = { data: httpResp.data, status: httpResp.status, statusText: httpResp.statusText, headers: httpResp.headers };
358
358
  captureBatutaHeaders(response.headers);
359
359
  }
@@ -397,7 +397,6 @@ export class LLMClient {
397
397
  return response.data;
398
398
  }
399
399
  catch (error) {
400
- this.currentAbortController = null;
401
400
  if (axios.isCancel(error) || (error instanceof Error && error.name === 'CanceledError')) {
402
401
  logger.flow('API call canceled (user interrupt)');
403
402
  logger.exit('chatCompletion', { success: false, aborted: true });
@@ -444,14 +443,21 @@ export class LLMClient {
444
443
  body: options,
445
444
  });
446
445
  }
446
+ finally {
447
+ if (controller)
448
+ this.activeControllers.delete(controller);
449
+ }
447
450
  }
448
451
  abort() {
449
452
  logger.flow('LLM interrupt - Stopping all operations');
450
453
  this.isInterrupted = true;
451
- if (this.currentAbortController) {
452
- this.currentAbortController.abort();
453
- this.currentAbortController = null;
454
+ for (const controller of this.activeControllers) {
455
+ try {
456
+ controller.abort();
457
+ }
458
+ catch { }
454
459
  }
460
+ this.activeControllers.clear();
455
461
  }
456
462
  checkInterrupted() {
457
463
  return this.isInterrupted;
@@ -460,7 +466,7 @@ export class LLMClient {
460
466
  this.isInterrupted = false;
461
467
  }
462
468
  isRequestActive() {
463
- return this.currentAbortController !== null;
469
+ return this.activeControllers.size > 0;
464
470
  }
465
471
  isConnectionError(error) {
466
472
  if (!axios.isAxiosError(error))
@@ -521,6 +527,7 @@ export class LLMClient {
521
527
  }
522
528
  async *chatCompletionStream(options) {
523
529
  const url = '/chat/completions';
530
+ let controller = null;
524
531
  try {
525
532
  const modelId = options.model || this.model;
526
533
  const processedMessages = options.messages ?
@@ -543,10 +550,11 @@ export class LLMClient {
543
550
  max_tokens: requestBody.max_tokens,
544
551
  });
545
552
  logger.verbose('Full Streaming Request Body', requestBody);
546
- this.currentAbortController = new AbortController();
553
+ controller = new AbortController();
554
+ this.activeControllers.add(controller);
547
555
  const response = await this.axiosInstance.post(url, requestBody, {
548
556
  responseType: 'stream',
549
- signal: this.currentAbortController.signal,
557
+ signal: controller.signal,
550
558
  headers: buildPerRequestHeaders(),
551
559
  });
552
560
  captureBatutaHeaders(response.headers);
@@ -594,7 +602,8 @@ export class LLMClient {
594
602
  }
595
603
  }
596
604
  finally {
597
- this.currentAbortController = null;
605
+ if (controller)
606
+ this.activeControllers.delete(controller);
598
607
  }
599
608
  logger.debug('Streaming response completed', { chunkCount });
600
609
  }
@@ -605,6 +614,10 @@ export class LLMClient {
605
614
  body: options,
606
615
  });
607
616
  }
617
+ finally {
618
+ if (controller)
619
+ this.activeControllers.delete(controller);
620
+ }
608
621
  }
609
622
  async sendMessage(userMessage, systemPrompt) {
610
623
  logger.enter('sendMessage', {
@@ -1,2 +1,12 @@
1
- export declare const AVAILABLE_TOOLS = "\n## Available Tools\n\n- **read_file**: Read file contents to understand existing code\n- **create_file**: Create a NEW file (fails if file exists)\n- **edit_file**: Edit an EXISTING file by replacing specific lines\n- **list_files**: List directory contents\n- **find_files**: Search for files by pattern \u2014 ALWAYS use this to locate files. NEVER run ", find: any;
1
+ export declare const AVAILABLE_TOOLS: string;
2
+ export declare const AVAILABLE_TOOLS_WITH_TODO: string;
3
+ export declare const TOOL_REASON_GUIDE: string;
4
+ export declare const FILE_MODIFICATION_RULES: string;
5
+ declare const _default: {
6
+ AVAILABLE_TOOLS: string;
7
+ AVAILABLE_TOOLS_WITH_TODO: string;
8
+ TOOL_REASON_GUIDE: string;
9
+ FILE_MODIFICATION_RULES: string;
10
+ };
11
+ export default _default;
2
12
  //# sourceMappingURL=tool-usage.d.ts.map
@@ -5,198 +5,47 @@ export const AVAILABLE_TOOLS = `
5
5
  - **create_file**: Create a NEW file (fails if file exists)
6
6
  - **edit_file**: Edit an EXISTING file by replacing specific lines
7
7
  - **list_files**: List directory contents
8
- - **find_files**: Search for files by pattern — ALWAYS use this to locate files. NEVER run `, find;
9
- /` or scan from the filesystem root via bash; it is slow, noisy, and crosses out of the project. Search within the project (relative paths /;
10
- cwd;
11
- only.
12
- - ** search_content ** ;
13
- Search;
14
- for (text; patterns in files(grep - like)
15
- - ** bash ** ; )
16
- : Execute;
17
- shell;
18
- commands(git, npm, etc.) `.trim();
8
+ - **find_files**: Search for files by pattern — ALWAYS use this to locate files. NEVER run "find /" or scan from the filesystem root via bash; it is slow, noisy, and crosses out of the project. Search within the project (relative paths / cwd) only.
9
+ - **search_content**: Search for text patterns in files (grep-like)
10
+ - **bash**: Execute shell commands (git, npm, etc.)
11
+ `.trim();
12
+ export const AVAILABLE_TOOLS_WITH_TODO = `
13
+ ## Available Tools
19
14
 
20
- /**
21
- * File tool usage with TODO tools
22
- */
23
- export const AVAILABLE_TOOLS_WITH_TODO = `;
24
- #;
25
- #;
26
- Available;
27
- Tools
28
- - ** read_file ** ;
29
- Read;
30
- file;
31
- contents;
32
- to;
33
- understand;
34
- existing;
35
- code
36
- - ** create_file ** ;
37
- Create;
38
- a;
39
- NEW;
40
- file(fails);
41
- if (file)
42
- exists;
43
- - ** edit_file ** ;
44
- Edit;
45
- an;
46
- EXISTING;
47
- file;
48
- by;
49
- replacing;
50
- specific;
51
- lines
52
- - ** list_files ** ;
53
- List;
54
- directory;
55
- contents
56
- - ** find_files ** ;
57
- Search;
58
- for (files; by; pattern)
59
- ;
60
- ALWAYS;
61
- use;
62
- this;
63
- to;
64
- locate;
65
- files.NEVER;
66
- run `find /`;
67
- or;
68
- scan;
69
- from;
70
- the;
71
- filesystem;
72
- root;
73
- via;
74
- bash;
75
- it;
76
- is;
77
- slow, noisy, and;
78
- crosses;
79
- out;
80
- of;
81
- the;
82
- project.Search;
83
- within;
84
- the;
85
- project(relative, paths / cwd);
86
- only.
87
- - ** search_content ** ;
88
- Search;
89
- for (text; patterns in files(grep - like)
90
- - ** bash ** ; )
91
- : Execute;
92
- shell;
93
- commands(git, npm, etc.)
94
- - ** tell_to_user ** ;
95
- Send;
96
- status;
97
- updates;
98
- to;
99
- the;
100
- user
101
- - ** ask_to_user ** ;
102
- Ask;
103
- user;
104
- a;
105
- question;
106
- with (multiple)
107
- choice;
108
- options
109
- - ** write_todos ** ;
110
- Update;
111
- entire;
112
- TODO;
113
- list(replaces, current, list)
114
- - ** call_docs_search_agent ** ;
115
- Search;
116
- local;
117
- documentation(~/.local-cli/docs) `.trim();
15
+ - **read_file**: Read file contents to understand existing code
16
+ - **create_file**: Create a NEW file (fails if file exists)
17
+ - **edit_file**: Edit an EXISTING file by replacing specific lines
18
+ - **list_files**: List directory contents
19
+ - **find_files**: Search for files by pattern — ALWAYS use this to locate files. NEVER run "find /" or scan from the filesystem root via bash; it is slow, noisy, and crosses out of the project. Search within the project (relative paths / cwd) only.
20
+ - **search_content**: Search for text patterns in files (grep-like)
21
+ - **bash**: Execute shell commands (git, npm, etc.)
22
+ - **tell_to_user**: Send status updates to the user
23
+ - **ask_to_user**: Ask user a question with multiple choice options
24
+ - **write_todos**: Update entire TODO list (replaces current list)
25
+ - **call_docs_search_agent**: Search local documentation (~/.local-cli/docs)
26
+ `.trim();
27
+ export const TOOL_REASON_GUIDE = `
28
+ ## CRITICAL - Tool "reason" Parameter
118
29
 
119
- /**
120
- * Tool reason parameter guidance
121
- */
122
- export const TOOL_REASON_GUIDE = `;
123
- #;
124
- #;
125
- CRITICAL - Tool;
126
- "reason";
127
- Parameter;
128
- Every;
129
- tool;
130
- has;
131
- a;
132
- required;
133
- "reason";
134
- parameter.This;
135
- will;
136
- be;
137
- shown;
138
- directly;
139
- to;
140
- the;
141
- user.
142
- ;
143
- Write;
144
- naturally;
145
- talking;
146
- to;
147
- the;
148
- user.Examples;
149
- -"Checking how the current authentication logic is implemented"
150
- - "Fixing the buggy section"
151
- - "Creating a new component file";
152
- The;
153
- reason;
154
- helps;
155
- users;
156
- understand;
157
- what;
158
- you;
159
- 're doing and why.;
160
- Remember;
161
- to;
162
- write;
163
- the;
164
- reason in the;
165
- user;
166
- 's language. `.trim();
30
+ Every tool has a required "reason" parameter. This will be shown directly to the user.
31
+ Write naturally as if talking to the user. Examples:
32
+ - "Checking how the current authentication logic is implemented"
33
+ - "Fixing the buggy section"
34
+ - "Creating a new component file"
167
35
 
168
- /**
169
- * File modification rules
170
- */
171
- export const FILE_MODIFICATION_RULES = `;
172
- #;
173
- #;
174
- File;
175
- Modification;
176
- Rules
177
- - For;
178
- NEW;
179
- files: Use;
180
- create_file
181
- - For;
182
- EXISTING;
183
- files: First;
184
- use;
185
- read_file;
186
- to;
187
- see;
188
- content, then;
189
- use;
190
- edit_file;
191
- with (exact)
192
- line;
193
- matches `.trim();
36
+ The reason helps users understand what you're doing and why.
37
+ Remember to write the reason in the user's language.
38
+ `.trim();
39
+ export const FILE_MODIFICATION_RULES = `
40
+ ## File Modification Rules
194
41
 
42
+ - For NEW files: Use create_file
43
+ - For EXISTING files: First use read_file to see content, then use edit_file with exact line matches
44
+ `.trim();
195
45
  export default {
196
- AVAILABLE_TOOLS,
197
- AVAILABLE_TOOLS_WITH_TODO,
198
- TOOL_REASON_GUIDE,
199
- FILE_MODIFICATION_RULES,
46
+ AVAILABLE_TOOLS,
47
+ AVAILABLE_TOOLS_WITH_TODO,
48
+ TOOL_REASON_GUIDE,
49
+ FILE_MODIFICATION_RULES,
200
50
  };
201
- ;
202
51
  //# sourceMappingURL=tool-usage.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquesta-cli",
3
- "version": "0.2.99",
3
+ "version": "0.2.101",
4
4
  "description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",