agileflow 2.96.0 → 2.96.2

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.
@@ -20,7 +20,7 @@ import {
20
20
  CLICommand,
21
21
  IREventHandler,
22
22
  CODEX_CAPABILITIES,
23
- } from "../protocol/driver";
23
+ } from '../protocol/driver';
24
24
  import {
25
25
  IREnvelope,
26
26
  IRSource,
@@ -33,19 +33,19 @@ import {
33
33
  IRError,
34
34
  IRFileOp,
35
35
  IRShell,
36
- } from "../protocol/ir";
36
+ } from '../protocol/ir';
37
37
 
38
38
  // ============================================================================
39
39
  // Tool Name Mapping (Codex -> IR normalized names)
40
40
  // ============================================================================
41
41
 
42
42
  const CODEX_TOOL_MAPPING: Record<string, string> = {
43
- "exec_command": "shell_exec", // Used for both shell and file reads
44
- "apply_patch": "file_edit",
45
- "web_search": "web_search",
46
- "read_file": "file_read",
47
- "write_file": "file_write",
48
- "container_exec": "shell_exec",
43
+ exec_command: 'shell_exec', // Used for both shell and file reads
44
+ apply_patch: 'file_edit',
45
+ web_search: 'web_search',
46
+ read_file: 'file_read',
47
+ write_file: 'file_write',
48
+ container_exec: 'shell_exec',
49
49
  };
50
50
 
51
51
  /**
@@ -59,8 +59,8 @@ function normalizeToolName(codexName: string): string {
59
59
  * Determine if an exec_command is a file read operation
60
60
  */
61
61
  function isFileReadCommand(params: CodexExecCommandParams): boolean {
62
- const cmd = params.command?.trim() || "";
63
- return cmd.startsWith("cat ") || cmd.startsWith("head ") || cmd.startsWith("tail ");
62
+ const cmd = params.command?.trim() || '';
63
+ return cmd.startsWith('cat ') || cmd.startsWith('head ') || cmd.startsWith('tail ');
64
64
  }
65
65
 
66
66
  /**
@@ -70,11 +70,11 @@ function extractFilePath(command: string): string {
70
70
  const parts = command.trim().split(/\s+/);
71
71
  // Skip command and flags, find the file path
72
72
  for (let i = 1; i < parts.length; i++) {
73
- if (!parts[i].startsWith("-")) {
74
- return parts[i].replace(/^['"]|['"]$/g, ""); // Remove quotes
73
+ if (!parts[i].startsWith('-')) {
74
+ return parts[i].replace(/^['"]|['"]$/g, ''); // Remove quotes
75
75
  }
76
76
  }
77
- return "";
77
+ return '';
78
78
  }
79
79
 
80
80
  // ============================================================================
@@ -82,22 +82,25 @@ function extractFilePath(command: string): string {
82
82
  // ============================================================================
83
83
 
84
84
  export class CodexDriver implements Driver {
85
- readonly id: IRSource = "codex";
86
- readonly name = "Codex CLI";
85
+ readonly id: IRSource = 'codex';
86
+ readonly name = 'Codex CLI';
87
87
 
88
88
  private _status: DriverStatus = {
89
- state: "stopped",
90
- provider: "codex",
89
+ state: 'stopped',
90
+ provider: 'codex',
91
91
  };
92
92
 
93
93
  private _capabilities: Capability[] = [...CODEX_CAPABILITIES];
94
94
  private _eventHandlers: Set<IREventHandler> = new Set();
95
- private _sessions: Map<string, {
96
- config: DriverConfig;
97
- seqCounter: number;
98
- threadId?: string;
99
- parentThreadId?: string;
100
- }> = new Map();
95
+ private _sessions: Map<
96
+ string,
97
+ {
98
+ config: DriverConfig;
99
+ seqCounter: number;
100
+ threadId?: string;
101
+ parentThreadId?: string;
102
+ }
103
+ > = new Map();
101
104
 
102
105
  // Rate limiting
103
106
  private _lastRequestTime = 0;
@@ -119,21 +122,21 @@ export class CodexDriver implements Driver {
119
122
  this._sessions.set(sessionId, { config, seqCounter: 0 });
120
123
 
121
124
  this._status = {
122
- state: "ready",
123
- provider: "codex",
124
- model: config.model || "codex-1",
125
+ state: 'ready',
126
+ provider: 'codex',
127
+ model: config.model || 'codex-1',
125
128
  contextMax: config.maxTokens || 128000,
126
129
  };
127
130
 
128
131
  // Emit init event
129
132
  const initPayload: IRInit = {
130
- provider: "codex",
131
- version: "1.0.0",
133
+ provider: 'codex',
134
+ version: '1.0.0',
132
135
  capabilities: this._capabilities.filter(c => c.available).map(c => c.name),
133
136
  maxContext: config.maxTokens || 128000,
134
137
  };
135
138
 
136
- this._emit(createIREnvelope("init", sessionId, "codex", initPayload));
139
+ this._emit(createIREnvelope('init', sessionId, 'codex', initPayload));
137
140
  }
138
141
 
139
142
  async stop(sessionId: string): Promise<void> {
@@ -142,7 +145,7 @@ export class CodexDriver implements Driver {
142
145
  if (this._sessions.size === 0) {
143
146
  this._status = {
144
147
  ...this._status,
145
- state: "stopped",
148
+ state: 'stopped',
146
149
  };
147
150
  }
148
151
  }
@@ -171,12 +174,12 @@ export class CodexDriver implements Driver {
171
174
  // -------------------------------------------------------------------------
172
175
 
173
176
  async send(sessionId: string, command: CLICommand): Promise<void> {
174
- this._status = { ...this._status, state: "busy" };
177
+ this._status = { ...this._status, state: 'busy' };
175
178
 
176
179
  const sessionPayload: IRSession = {
177
- state: "thinking",
180
+ state: 'thinking',
178
181
  };
179
- this._emit(createIREnvelope("session", sessionId, "codex", sessionPayload));
182
+ this._emit(createIREnvelope('session', sessionId, 'codex', sessionPayload));
180
183
  }
181
184
 
182
185
  // -------------------------------------------------------------------------
@@ -199,10 +202,12 @@ export class CodexDriver implements Driver {
199
202
  });
200
203
 
201
204
  // Emit session fork event
202
- this._emit(createIREnvelope<IRSession>("session", newSessionId, "codex", {
203
- state: "connected",
204
- message: `Forked from ${sessionId}`,
205
- }));
205
+ this._emit(
206
+ createIREnvelope<IRSession>('session', newSessionId, 'codex', {
207
+ state: 'connected',
208
+ message: `Forked from ${sessionId}`,
209
+ })
210
+ );
206
211
  }
207
212
 
208
213
  /**
@@ -213,10 +218,12 @@ export class CodexDriver implements Driver {
213
218
  if (!session) return;
214
219
 
215
220
  // In a real implementation, this would call the Codex CLI rollback command
216
- this._emit(createIREnvelope<IRSession>("session", sessionId, "codex", {
217
- state: "idle",
218
- message: `Rolled back to sequence ${targetSeq}`,
219
- }));
221
+ this._emit(
222
+ createIREnvelope<IRSession>('session', sessionId, 'codex', {
223
+ state: 'idle',
224
+ message: `Rolled back to sequence ${targetSeq}`,
225
+ })
226
+ );
220
227
  }
221
228
 
222
229
  // -------------------------------------------------------------------------
@@ -245,39 +252,42 @@ export class CodexDriver implements Driver {
245
252
 
246
253
  private _translateMethod(sessionId: string, msg: CodexJsonRpcMessage): IREnvelope | null {
247
254
  switch (msg.method) {
248
- case "item/agentMessage/delta":
255
+ case 'item/agentMessage/delta':
249
256
  // Streaming text delta
250
- return createIREnvelope<IRTextDelta>("text_delta", sessionId, "codex", {
251
- text: msg.params?.content || "",
257
+ return createIREnvelope<IRTextDelta>('text_delta', sessionId, 'codex', {
258
+ text: msg.params?.content || '',
252
259
  done: false,
253
260
  });
254
261
 
255
- case "item/agentMessage":
262
+ case 'item/agentMessage':
256
263
  // Complete text message
257
- return createIREnvelope<IRTextDelta>("text_delta", sessionId, "codex", {
258
- text: msg.params?.content || "",
264
+ return createIREnvelope<IRTextDelta>('text_delta', sessionId, 'codex', {
265
+ text: msg.params?.content || '',
259
266
  done: true,
260
267
  });
261
268
 
262
- case "item/started":
269
+ case 'item/started':
263
270
  // Tool call started
264
- if (msg.params?.item?.type === "function_call") {
265
- const toolName = msg.params.item.name || "unknown";
271
+ if (msg.params?.item?.type === 'function_call') {
272
+ const toolName = msg.params.item.name || 'unknown';
266
273
  const toolInput = msg.params.item.arguments || {};
267
274
 
268
275
  // Check if this is exec_command being used as file_read
269
- if (toolName === "exec_command" && isFileReadCommand(toolInput as CodexExecCommandParams)) {
270
- return createIREnvelope<IRToolStart>("tool_start", sessionId, "codex", {
276
+ if (
277
+ toolName === 'exec_command' &&
278
+ isFileReadCommand(toolInput as CodexExecCommandParams)
279
+ ) {
280
+ return createIREnvelope<IRToolStart>('tool_start', sessionId, 'codex', {
271
281
  id: msg.params.item.id || `tool_${Date.now()}`,
272
- name: "file_read",
273
- nativeName: "exec_command",
282
+ name: 'file_read',
283
+ nativeName: 'exec_command',
274
284
  input: {
275
- path: extractFilePath((toolInput as CodexExecCommandParams).command || ""),
285
+ path: extractFilePath((toolInput as CodexExecCommandParams).command || ''),
276
286
  },
277
287
  });
278
288
  }
279
289
 
280
- return createIREnvelope<IRToolStart>("tool_start", sessionId, "codex", {
290
+ return createIREnvelope<IRToolStart>('tool_start', sessionId, 'codex', {
281
291
  id: msg.params.item.id || `tool_${Date.now()}`,
282
292
  name: normalizeToolName(toolName),
283
293
  nativeName: toolName,
@@ -286,17 +296,17 @@ export class CodexDriver implements Driver {
286
296
  }
287
297
  return null;
288
298
 
289
- case "item/completed":
299
+ case 'item/completed':
290
300
  // Tool call completed
291
301
  const output = msg.params?.item?.output;
292
- const isError = msg.params?.item?.status === "error";
302
+ const isError = msg.params?.item?.status === 'error';
293
303
 
294
304
  // Check if this was a file operation
295
- if (msg.params?.item?.name === "exec_command" && msg.params?.item?.arguments) {
305
+ if (msg.params?.item?.name === 'exec_command' && msg.params?.item?.arguments) {
296
306
  const args = msg.params.item.arguments as CodexExecCommandParams;
297
307
  if (isFileReadCommand(args)) {
298
- return createIREnvelope<IRToolResult>("tool_result", sessionId, "codex", {
299
- id: msg.params.item.id || "",
308
+ return createIREnvelope<IRToolResult>('tool_result', sessionId, 'codex', {
309
+ id: msg.params.item.id || '',
300
310
  ok: !isError,
301
311
  output: output,
302
312
  error: isError ? String(output) : undefined,
@@ -305,49 +315,49 @@ export class CodexDriver implements Driver {
305
315
  }
306
316
 
307
317
  // Check if this was apply_patch (file edit)
308
- if (msg.params?.item?.name === "apply_patch") {
318
+ if (msg.params?.item?.name === 'apply_patch') {
309
319
  const patchArgs = msg.params.item.arguments as CodexApplyPatchParams;
310
- return createIREnvelope<IRFileOp>("file_op", sessionId, "codex", {
311
- action: "edit",
312
- path: patchArgs.path || "",
320
+ return createIREnvelope<IRFileOp>('file_op', sessionId, 'codex', {
321
+ action: 'edit',
322
+ path: patchArgs.path || '',
313
323
  diff: {
314
- before: "", // Would need to parse from patch
315
- after: "",
324
+ before: '', // Would need to parse from patch
325
+ after: '',
316
326
  },
317
327
  });
318
328
  }
319
329
 
320
- return createIREnvelope<IRToolResult>("tool_result", sessionId, "codex", {
321
- id: msg.params?.item?.id || "",
330
+ return createIREnvelope<IRToolResult>('tool_result', sessionId, 'codex', {
331
+ id: msg.params?.item?.id || '',
322
332
  ok: !isError,
323
333
  output: output,
324
334
  error: isError ? String(output) : undefined,
325
335
  });
326
336
 
327
- case "turn/started":
328
- return createIREnvelope<IRSession>("session", sessionId, "codex", {
329
- state: "thinking",
337
+ case 'turn/started':
338
+ return createIREnvelope<IRSession>('session', sessionId, 'codex', {
339
+ state: 'thinking',
330
340
  });
331
341
 
332
- case "turn/completed":
333
- this._status = { ...this._status, state: "ready" };
334
- return createIREnvelope<IRSession>("session", sessionId, "codex", {
335
- state: "idle",
342
+ case 'turn/completed':
343
+ this._status = { ...this._status, state: 'ready' };
344
+ return createIREnvelope<IRSession>('session', sessionId, 'codex', {
345
+ state: 'idle',
336
346
  });
337
347
 
338
- case "thread/created":
348
+ case 'thread/created':
339
349
  const session = this._sessions.get(sessionId);
340
350
  if (session) {
341
351
  session.threadId = msg.params?.threadId;
342
352
  }
343
- return createIREnvelope<IRSession>("session", sessionId, "codex", {
344
- state: "connected",
353
+ return createIREnvelope<IRSession>('session', sessionId, 'codex', {
354
+ state: 'connected',
345
355
  message: `Thread created: ${msg.params?.threadId}`,
346
356
  });
347
357
 
348
- case "thread/forked":
349
- return createIREnvelope<IRSession>("session", sessionId, "codex", {
350
- state: "connected",
358
+ case 'thread/forked':
359
+ return createIREnvelope<IRSession>('session', sessionId, 'codex', {
360
+ state: 'connected',
351
361
  message: `Thread forked from ${msg.params?.parentThreadId}`,
352
362
  });
353
363
 
@@ -358,9 +368,9 @@ export class CodexDriver implements Driver {
358
368
 
359
369
  private _translateResult(sessionId: string, msg: CodexJsonRpcMessage): IREnvelope | null {
360
370
  if (msg.error) {
361
- return createIREnvelope<IRError>("error", sessionId, "codex", {
362
- code: String(msg.error.code || "UNKNOWN"),
363
- message: msg.error.message || "Unknown error",
371
+ return createIREnvelope<IRError>('error', sessionId, 'codex', {
372
+ code: String(msg.error.code || 'UNKNOWN'),
373
+ message: msg.error.message || 'Unknown error',
364
374
  details: msg.error.data,
365
375
  recoverable: true,
366
376
  });
@@ -390,11 +400,11 @@ export class CodexDriver implements Driver {
390
400
  }
391
401
 
392
402
  private _emit(envelope: IREnvelope): void {
393
- Array.from(this._eventHandlers).forEach((handler) => {
403
+ Array.from(this._eventHandlers).forEach(handler => {
394
404
  try {
395
405
  handler(envelope);
396
406
  } catch (error) {
397
- console.error("[CodexDriver] Event handler error:", error);
407
+ console.error('[CodexDriver] Event handler error:', error);
398
408
  }
399
409
  });
400
410
  }
@@ -405,7 +415,7 @@ export class CodexDriver implements Driver {
405
415
  // ============================================================================
406
416
 
407
417
  export interface CodexJsonRpcMessage {
408
- jsonrpc?: "2.0";
418
+ jsonrpc?: '2.0';
409
419
  id?: string | number;
410
420
  method?: string;
411
421
  params?: {
@@ -5,8 +5,8 @@
5
5
  * for the dashboard to interact with any supported CLI.
6
6
  */
7
7
 
8
- import { Driver, DriverManager, IREventHandler } from "../protocol/driver";
9
- import { IRSource, IREnvelope } from "../protocol/ir";
8
+ import { Driver, DriverManager, IREventHandler } from '../protocol/driver';
9
+ import { IRSource, IREnvelope } from '../protocol/ir';
10
10
 
11
11
  /**
12
12
  * Default driver manager implementation
@@ -29,7 +29,7 @@ export class DefaultDriverManager implements DriverManager {
29
29
  }
30
30
 
31
31
  // Forward driver events to global handlers
32
- driver.onEvent((envelope) => {
32
+ driver.onEvent(envelope => {
33
33
  this._emitGlobal(envelope);
34
34
  });
35
35
 
@@ -99,11 +99,11 @@ export class DefaultDriverManager implements DriverManager {
99
99
  }
100
100
 
101
101
  private _emitGlobal(envelope: IREnvelope): void {
102
- Array.from(this._globalHandlers).forEach((handler) => {
102
+ Array.from(this._globalHandlers).forEach(handler => {
103
103
  try {
104
104
  handler(envelope);
105
105
  } catch (error) {
106
- console.error("[DriverManager] Global handler error:", error);
106
+ console.error('[DriverManager] Global handler error:', error);
107
107
  }
108
108
  });
109
109
  }
@@ -126,8 +126,9 @@ export class DefaultDriverManager implements DriverManager {
126
126
  id: driver.id,
127
127
  name: driver.name,
128
128
  status: driver.status.state,
129
- available: driver.status.state !== "error",
130
- capabilities: driver.capabilities()
129
+ available: driver.status.state !== 'error',
130
+ capabilities: driver
131
+ .capabilities()
131
132
  .filter(c => c.available)
132
133
  .map(c => c.name),
133
134
  }));