converse-mcp-server 2.0.2-beta.1 → 2.0.2-beta.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "converse-mcp-server",
3
- "version": "2.0.2-beta.1",
3
+ "version": "2.0.2-beta.3",
4
4
  "description": "Converse MCP Server - Converse with other LLMs with chat and consensus tools",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -305,16 +305,67 @@ export const codexProvider = {
305
305
  debugLog('[Codex] Using reasoning_effort:', reasoning_effort);
306
306
  }
307
307
 
308
- // Use streaming when requested
308
+ // WORKAROUND: SDK's thread.run() hangs due to missing break after turn.completed
309
+ // Always use streaming internally, consume synchronously when stream=false
309
310
  if (stream) {
310
- debugLog('[Codex] invoke: Returning streaming generator');
311
- const generator = createStreamingGenerator(thread, prompt, signal, runOptions);
312
- debugLog('[Codex] invoke: Generator created, returning it');
313
- return generator;
311
+ debugLog('[Codex] invoke: Returning streaming generator (async mode)');
312
+ return createStreamingGenerator(thread, prompt, signal, runOptions);
314
313
  }
315
314
 
316
- // Non-streaming execution (disabled due to SDK bug - see above)
315
+ // Synchronous mode: consume streaming internally and return complete response
316
+ debugLog('[Codex] invoke: Using streaming internally for sync execution (SDK bug workaround)');
317
317
  const startTime = Date.now();
318
+ const generator = createStreamingGenerator(thread, prompt, signal, runOptions);
319
+
320
+ let content = '';
321
+ let usage = null;
322
+ let threadIdFromStream = null;
323
+
324
+ debugLog('[Codex] invoke: Consuming stream synchronously...');
325
+ for await (const event of generator) {
326
+ debugLog('[Codex] invoke: Sync consume event', { type: event?.type });
327
+
328
+ if (event?.type === 'thread.started') {
329
+ threadIdFromStream = event.thread_id;
330
+ } else if (event?.type === 'item.completed' && event.item?.type === 'agent_message') {
331
+ content += event.item.text || '';
332
+ } else if (event?.type === 'turn.completed') {
333
+ usage = event.usage;
334
+ debugLog('[Codex] invoke: turn.completed received in sync mode');
335
+ break; // Exit after turn.completed
336
+ } else if (event?.type === 'turn.failed') {
337
+ throw new CodexProviderError(event.error?.message || 'Turn failed', 'TURN_FAILED');
338
+ }
339
+ }
340
+
341
+ const responseTime = Date.now() - startTime;
342
+ debugLog('[Codex] invoke: Sync execution completed', {
343
+ responseTime,
344
+ contentLength: content.length,
345
+ hasUsage: !!usage
346
+ });
347
+
348
+ return {
349
+ content,
350
+ stop_reason: StopReasons.STOP,
351
+ rawResponse: { content, usage },
352
+ metadata: {
353
+ provider: 'codex',
354
+ model,
355
+ threadId: threadIdFromStream || thread.id,
356
+ usage: usage ? {
357
+ input_tokens: usage.input_tokens || 0,
358
+ output_tokens: usage.output_tokens || 0,
359
+ total_tokens: (usage.input_tokens || 0) + (usage.output_tokens || 0),
360
+ cached_input_tokens: usage.cached_input_tokens || 0
361
+ } : null,
362
+ response_time_ms: responseTime,
363
+ finish_reason: 'stop'
364
+ }
365
+ };
366
+
367
+ // Legacy non-streaming code below (now unreachable - kept for reference)
368
+ const legacyStartTime = Date.now();
318
369
  debugLog('[Codex] invoke: Starting non-streaming execution with thread.run()', {
319
370
  threadId: thread.id,
320
371
  hasRunOptions: !!Object.keys(runOptions).length,