@northflare/runner 0.0.13 → 0.0.16

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 (119) hide show
  1. package/README.md +8 -5
  2. package/bin/northflare-runner +44 -16
  3. package/dist/components/claude-sdk-manager.d.ts +3 -3
  4. package/dist/components/claude-sdk-manager.d.ts.map +1 -1
  5. package/dist/components/claude-sdk-manager.js +80 -111
  6. package/dist/components/claude-sdk-manager.js.map +1 -1
  7. package/dist/components/codex-sdk-manager.d.ts +15 -6
  8. package/dist/components/codex-sdk-manager.d.ts.map +1 -1
  9. package/dist/components/codex-sdk-manager.js +128 -97
  10. package/dist/components/codex-sdk-manager.js.map +1 -1
  11. package/dist/components/enhanced-repository-manager.d.ts +2 -2
  12. package/dist/components/enhanced-repository-manager.d.ts.map +1 -1
  13. package/dist/components/enhanced-repository-manager.js +68 -75
  14. package/dist/components/enhanced-repository-manager.js.map +1 -1
  15. package/dist/components/message-handler-sse.d.ts +1 -1
  16. package/dist/components/message-handler-sse.d.ts.map +1 -1
  17. package/dist/components/message-handler-sse.js +205 -97
  18. package/dist/components/message-handler-sse.js.map +1 -1
  19. package/dist/components/{claude-manager.d.ts → northflare-agent-sdk-manager.d.ts} +17 -14
  20. package/dist/components/northflare-agent-sdk-manager.d.ts.map +1 -0
  21. package/dist/components/northflare-agent-sdk-manager.js +1456 -0
  22. package/dist/components/northflare-agent-sdk-manager.js.map +1 -0
  23. package/dist/components/repository-manager.d.ts +2 -2
  24. package/dist/components/repository-manager.d.ts.map +1 -1
  25. package/dist/components/repository-manager.js +34 -74
  26. package/dist/components/repository-manager.js.map +1 -1
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +115 -79
  30. package/dist/index.js.map +1 -1
  31. package/dist/runner-sse.d.ts +22 -5
  32. package/dist/runner-sse.d.ts.map +1 -1
  33. package/dist/runner-sse.js +95 -74
  34. package/dist/runner-sse.js.map +1 -1
  35. package/dist/services/RunnerAPIClient.d.ts +1 -1
  36. package/dist/services/RunnerAPIClient.d.ts.map +1 -1
  37. package/dist/services/RunnerAPIClient.js +3 -7
  38. package/dist/services/RunnerAPIClient.js.map +1 -1
  39. package/dist/services/SSEClient.js +5 -9
  40. package/dist/services/SSEClient.js.map +1 -1
  41. package/dist/types/claude.d.ts +16 -2
  42. package/dist/types/claude.d.ts.map +1 -1
  43. package/dist/types/claude.js +1 -2
  44. package/dist/types/claude.js.map +1 -1
  45. package/dist/types/index.d.ts +5 -3
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js +3 -19
  48. package/dist/types/index.js.map +1 -1
  49. package/dist/types/messages.js +1 -2
  50. package/dist/types/messages.js.map +1 -1
  51. package/dist/types/runner-interface.d.ts +8 -4
  52. package/dist/types/runner-interface.d.ts.map +1 -1
  53. package/dist/types/runner-interface.js +1 -2
  54. package/dist/types/runner-interface.js.map +1 -1
  55. package/dist/utils/StateManager.js +12 -19
  56. package/dist/utils/StateManager.js.map +1 -1
  57. package/dist/utils/config.d.ts +1 -1
  58. package/dist/utils/config.d.ts.map +1 -1
  59. package/dist/utils/config.js +19 -26
  60. package/dist/utils/config.js.map +1 -1
  61. package/dist/utils/console.js +3 -6
  62. package/dist/utils/console.js.map +1 -1
  63. package/dist/utils/debug.js +1 -4
  64. package/dist/utils/debug.js.map +1 -1
  65. package/dist/utils/expand-env.js +1 -4
  66. package/dist/utils/expand-env.js.map +1 -1
  67. package/dist/utils/inactivity-timeout.d.ts +19 -0
  68. package/dist/utils/inactivity-timeout.d.ts.map +1 -0
  69. package/dist/utils/inactivity-timeout.js +72 -0
  70. package/dist/utils/inactivity-timeout.js.map +1 -0
  71. package/dist/utils/logger.d.ts.map +1 -1
  72. package/dist/utils/logger.js +24 -35
  73. package/dist/utils/logger.js.map +1 -1
  74. package/dist/utils/model.d.ts +3 -1
  75. package/dist/utils/model.d.ts.map +1 -1
  76. package/dist/utils/model.js +18 -4
  77. package/dist/utils/model.js.map +1 -1
  78. package/dist/utils/status-line.d.ts +1 -0
  79. package/dist/utils/status-line.d.ts.map +1 -1
  80. package/dist/utils/status-line.js +25 -18
  81. package/dist/utils/status-line.js.map +1 -1
  82. package/dist/utils/tool-response-sanitizer.js +6 -10
  83. package/dist/utils/tool-response-sanitizer.js.map +1 -1
  84. package/lib/codex-sdk/dist/index.d.ts +1 -1
  85. package/lib/codex-sdk/dist/samples/basic_streaming.d.ts +3 -0
  86. package/lib/codex-sdk/dist/samples/basic_streaming.d.ts.map +1 -0
  87. package/lib/codex-sdk/dist/samples/basic_streaming.js +81 -0
  88. package/lib/codex-sdk/dist/samples/basic_streaming.js.map +1 -0
  89. package/lib/codex-sdk/dist/samples/helpers.d.ts +2 -0
  90. package/lib/codex-sdk/dist/samples/helpers.d.ts.map +1 -0
  91. package/lib/codex-sdk/dist/samples/helpers.js +6 -0
  92. package/lib/codex-sdk/dist/samples/helpers.js.map +1 -0
  93. package/lib/codex-sdk/dist/samples/structured_output.d.ts +3 -0
  94. package/lib/codex-sdk/dist/samples/structured_output.d.ts.map +1 -0
  95. package/lib/codex-sdk/dist/samples/structured_output.js +17 -0
  96. package/lib/codex-sdk/dist/samples/structured_output.js.map +1 -0
  97. package/lib/codex-sdk/dist/samples/structured_output_zod.d.ts +3 -0
  98. package/lib/codex-sdk/dist/samples/structured_output_zod.d.ts.map +1 -0
  99. package/lib/codex-sdk/dist/samples/structured_output_zod.js +16 -0
  100. package/lib/codex-sdk/dist/samples/structured_output_zod.js.map +1 -0
  101. package/lib/codex-sdk/dist/tsup.config.d.ts +3 -0
  102. package/lib/codex-sdk/dist/tsup.config.js +12 -0
  103. package/package.json +9 -4
  104. package/scripts/verify-openrouter-agent.ts +163 -0
  105. package/dist/collections/runner-messages.d.ts +0 -52
  106. package/dist/collections/runner-messages.d.ts.map +0 -1
  107. package/dist/collections/runner-messages.js +0 -161
  108. package/dist/collections/runner-messages.js.map +0 -1
  109. package/dist/components/claude-manager.d.ts.map +0 -1
  110. package/dist/components/claude-manager.js +0 -783
  111. package/dist/components/claude-manager.js.map +0 -1
  112. package/dist/components/message-handler.d.ts +0 -35
  113. package/dist/components/message-handler.d.ts.map +0 -1
  114. package/dist/components/message-handler.js +0 -689
  115. package/dist/components/message-handler.js.map +0 -1
  116. package/dist/runner.d.ts +0 -51
  117. package/dist/runner.d.ts.map +0 -1
  118. package/dist/runner.js +0 -530
  119. package/dist/runner.js.map +0 -1
@@ -1,17 +1,14 @@
1
- "use strict";
2
1
  /**
3
2
  * MessageHandler - Processes incoming JSONRPC messages from SSE events
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MessageHandler = void 0;
7
- const SSEClient_1 = require("../services/SSEClient");
8
- const RunnerAPIClient_1 = require("../services/RunnerAPIClient");
9
- const status_line_1 = require("../utils/status-line");
10
- const console_1 = require("../utils/console");
11
- const logger_1 = require("../utils/logger");
12
- const debug_1 = require("../utils/debug");
13
- const logger = (0, logger_1.createLogger)("MessageHandler");
14
- class MessageHandler {
4
+ import { SSEClient } from '../services/SSEClient.js';
5
+ import { RunnerAPIClient } from '../services/RunnerAPIClient.js';
6
+ import { statusLineManager } from '../utils/status-line.js';
7
+ import { console } from '../utils/console.js';
8
+ import { createLogger } from '../utils/logger.js';
9
+ import { isRunnerDebugEnabled } from '../utils/debug.js';
10
+ const logger = createLogger("MessageHandler");
11
+ export class MessageHandler {
15
12
  methodHandlers;
16
13
  runner;
17
14
  processedMessages = new Set();
@@ -21,11 +18,11 @@ class MessageHandler {
21
18
  constructor(runner) {
22
19
  this.runner = runner;
23
20
  this.methodHandlers = new Map();
24
- this.apiClient = new RunnerAPIClient_1.RunnerAPIClient(runner.config_);
21
+ this.apiClient = new RunnerAPIClient(runner.config_);
25
22
  this.registerHandlers();
26
23
  }
27
24
  async startProcessing() {
28
- console_1.console.log("MessageHandler: Starting message processing with SSE...");
25
+ console.log("MessageHandler: Starting message processing with SSE...");
29
26
  if (this.isProcessing) {
30
27
  logger.warn("Message processing already started");
31
28
  return;
@@ -42,7 +39,7 @@ class MessageHandler {
42
39
  await this.connectSSE();
43
40
  }
44
41
  async stopProcessing() {
45
- console_1.console.log("MessageHandler: Stopping message processing...");
42
+ console.log("MessageHandler: Stopping message processing...");
46
43
  this.isProcessing = false;
47
44
  // Stop SSE client
48
45
  if (this.sseClient) {
@@ -61,21 +58,21 @@ class MessageHandler {
61
58
  logger.debug("No lastProcessedAt timestamp, skipping catch-up");
62
59
  return;
63
60
  }
64
- console_1.console.log(`MessageHandler: Catching up on messages since ${lastProcessedAt.toISOString()}`);
61
+ console.log(`MessageHandler: Catching up on messages since ${lastProcessedAt.toISOString()}`);
65
62
  try {
66
63
  const messages = await this.apiClient.fetchMissedMessages({
67
64
  since: lastProcessedAt,
68
65
  limit: 1000,
69
66
  });
70
67
  if (messages.length > 0) {
71
- console_1.console.log(`MessageHandler: Processing ${messages.length} missed messages`);
68
+ console.log(`MessageHandler: Processing ${messages.length} missed messages`);
72
69
  // Process messages in order
73
70
  for (const message of messages) {
74
71
  await this.processMessage(message);
75
72
  }
76
73
  }
77
74
  else {
78
- console_1.console.log("MessageHandler: No missed messages to process");
75
+ console.log("MessageHandler: No missed messages to process");
79
76
  }
80
77
  }
81
78
  catch (error) {
@@ -95,8 +92,8 @@ class MessageHandler {
95
92
  if (!token) {
96
93
  throw new Error("Missing NORTHFLARE_RUNNER_TOKEN");
97
94
  }
98
- console_1.console.log("MessageHandler: Connecting to SSE endpoint...");
99
- this.sseClient = new SSEClient_1.SSEClient({
95
+ console.log("MessageHandler: Connecting to SSE endpoint...");
96
+ this.sseClient = new SSEClient({
100
97
  url: `${this.runner.config_.orchestratorUrl}/api/runner-events`,
101
98
  runnerId,
102
99
  token,
@@ -105,10 +102,10 @@ class MessageHandler {
105
102
  logger.error("SSE connection error:", error);
106
103
  },
107
104
  onConnect: () => {
108
- console_1.console.log("MessageHandler: SSE connection established");
105
+ console.log("MessageHandler: SSE connection established");
109
106
  },
110
107
  onDisconnect: () => {
111
- console_1.console.log("MessageHandler: SSE connection closed");
108
+ console.log("MessageHandler: SSE connection closed");
112
109
  },
113
110
  reconnectInterval: 1000,
114
111
  maxReconnectInterval: 30000,
@@ -124,7 +121,7 @@ class MessageHandler {
124
121
  async handleSSEEvent(event) {
125
122
  if (event.type === "runner.message") {
126
123
  const message = event.data;
127
- if ((0, debug_1.isRunnerDebugEnabled)()) {
124
+ if (isRunnerDebugEnabled()) {
128
125
  logger.debug("Received SSE event", {
129
126
  eventId: event.id,
130
127
  type: event.type,
@@ -152,7 +149,7 @@ class MessageHandler {
152
149
  }
153
150
  }
154
151
  async processMessage(message) {
155
- if ((0, debug_1.isRunnerDebugEnabled)()) {
152
+ if (isRunnerDebugEnabled()) {
156
153
  logger.debug("processMessage called", {
157
154
  messageId: message.id,
158
155
  method: message.payload?.method,
@@ -178,7 +175,7 @@ class MessageHandler {
178
175
  await this.sendError(message, `Unknown method: ${method}`);
179
176
  return;
180
177
  }
181
- if ((0, debug_1.isRunnerDebugEnabled)()) {
178
+ if (isRunnerDebugEnabled()) {
182
179
  logger.debug("Processing message", {
183
180
  messageId: message.id,
184
181
  method: method,
@@ -191,7 +188,7 @@ class MessageHandler {
191
188
  await this.markProcessed(message);
192
189
  // Acknowledge ALL messages to update lastProcessedAt
193
190
  await this.acknowledgeMessage(message);
194
- if ((0, debug_1.isRunnerDebugEnabled)()) {
191
+ if (isRunnerDebugEnabled()) {
195
192
  logger.debug("Message acknowledged", {
196
193
  messageId: message.id,
197
194
  method: method,
@@ -201,7 +198,7 @@ class MessageHandler {
201
198
  }
202
199
  }
203
200
  catch (error) {
204
- if ((0, debug_1.isRunnerDebugEnabled)()) {
201
+ if (isRunnerDebugEnabled()) {
205
202
  logger.debug("Message processing error", {
206
203
  messageId: message.id,
207
204
  method: method,
@@ -251,7 +248,7 @@ class MessageHandler {
251
248
  reason: "active runner, message after watermark",
252
249
  };
253
250
  })();
254
- if ((0, debug_1.isRunnerDebugEnabled)()) {
251
+ if (isRunnerDebugEnabled()) {
255
252
  logger.debug("Message processing decision", {
256
253
  messageId: message.id,
257
254
  method: message.payload?.method,
@@ -277,7 +274,7 @@ class MessageHandler {
277
274
  }
278
275
  async acknowledgeMessage(message) {
279
276
  const runnerId = this.runner.getRunnerId();
280
- console_1.console.log(`[MessageHandler] Sending message.acknowledge:`, {
277
+ console.log(`[MessageHandler] Sending message.acknowledge:`, {
281
278
  runnerId,
282
279
  messageTimestamp: message.createdAt,
283
280
  messageId: message.id,
@@ -287,7 +284,7 @@ class MessageHandler {
287
284
  await this.apiClient.acknowledgeMessage(message.createdAt);
288
285
  // Update local lastProcessedAt
289
286
  await this.runner.updateLastProcessedAt(new Date(message.createdAt));
290
- console_1.console.log(`[MessageHandler] ✅ message.acknowledge sent successfully`);
287
+ console.log(`[MessageHandler] ✅ message.acknowledge sent successfully`);
291
288
  }
292
289
  catch (error) {
293
290
  logger.error("Failed to acknowledge message:", error);
@@ -303,8 +300,8 @@ class MessageHandler {
303
300
  const conversationObjectType = message.conversationObjectType || (message.taskId ? "Task" : undefined);
304
301
  const conversationObjectId = message.conversationObjectId || message.taskId;
305
302
  if (!conversationObjectId) {
306
- console_1.console.error(`[MessageHandler] Cannot send error report - no conversationObjectId available. Error: ${errorMessage}`);
307
- if ((0, debug_1.isRunnerDebugEnabled)()) {
303
+ console.error(`[MessageHandler] Cannot send error report - no conversationObjectId available. Error: ${errorMessage}`);
304
+ if (isRunnerDebugEnabled()) {
308
305
  logger.debug("Error without conversationObjectId", {
309
306
  messageId: message.id,
310
307
  method: message.payload?.method,
@@ -333,8 +330,8 @@ class MessageHandler {
333
330
  const conversationObjectType = message.conversationObjectType || (message.taskId ? "Task" : undefined);
334
331
  const conversationObjectId = message.conversationObjectId || message.taskId;
335
332
  if (!conversationObjectId) {
336
- console_1.console.error(`[MessageHandler] Cannot send error report - no conversationObjectId available. Processing error: ${errorMessage}`);
337
- if ((0, debug_1.isRunnerDebugEnabled)()) {
333
+ console.error(`[MessageHandler] Cannot send error report - no conversationObjectId available. Processing error: ${errorMessage}`);
334
+ if (isRunnerDebugEnabled()) {
338
335
  logger.debug("Processing error without conversationObjectId", {
339
336
  messageId: message.id,
340
337
  method: message.payload?.method,
@@ -359,7 +356,7 @@ class MessageHandler {
359
356
  });
360
357
  }
361
358
  registerHandlers() {
362
- console_1.console.log("MessageHandler: Registering handlers...");
359
+ console.log("MessageHandler: Registering handlers...");
363
360
  this.methodHandlers = new Map([
364
361
  ["conversation.start", this.handleConversationStart.bind(this)],
365
362
  ["conversation.stop", this.handleConversationStop.bind(this)],
@@ -391,7 +388,7 @@ class MessageHandler {
391
388
  throw new Error("Missing conversationObjectId");
392
389
  }
393
390
  // Debug log the config
394
- console_1.console.log(`[MessageHandler] conversation.start config:`, {
391
+ console.log(`[MessageHandler] conversation.start config:`, {
395
392
  conversationObjectId,
396
393
  hasConfig: !!config,
397
394
  hasRepository: !!config?.repository,
@@ -401,7 +398,7 @@ class MessageHandler {
401
398
  fullConfig: JSON.stringify(config, null, 2),
402
399
  });
403
400
  // Debug log workspace instructions received
404
- console_1.console.log(`[MessageHandler] Received conversation with workspaceInstructions:`, {
401
+ console.log(`[MessageHandler] Received conversation with workspaceInstructions:`, {
405
402
  conversationId: conversationData.id,
406
403
  hasWorkspaceInstructions: !!conversationData.workspaceInstructions,
407
404
  workspaceInstructionsLength: conversationData.workspaceInstructions?.length ?? 0,
@@ -409,17 +406,34 @@ class MessageHandler {
409
406
  hasGlobalInstructions: !!conversationData.globalInstructions,
410
407
  globalInstructionsLength: conversationData.globalInstructions?.length ?? 0,
411
408
  });
409
+ // Check if conversation is already active (prevent duplicate starts on catch-up)
410
+ const conversationId = conversationData.id;
411
+ if (this.runner.activeConversations_.has(conversationId)) {
412
+ console.log(`[MessageHandler] Conversation ${conversationId} already active, skipping duplicate start`);
413
+ return;
414
+ }
415
+ // Check if this conversation was recently completed (prevent restart on catch-up)
416
+ if (this.runner.wasConversationCompleted(conversationId)) {
417
+ console.log(`[MessageHandler] Conversation ${conversationId} was already completed, skipping restart`);
418
+ return;
419
+ }
412
420
  const provider = this.resolveAgentProvider(conversationData, config);
413
421
  const manager = this.getManagerForProvider(provider);
414
422
  // Start the conversation with the provided/loaded conversation details
415
- await manager.startConversation(finalObjectType, finalObjectId, config, initialMessages || [], conversationData);
423
+ // For CodexManager (openai) we pass the provider to distinguish
424
+ if (provider === "openai") {
425
+ await manager.startConversation(finalObjectType, finalObjectId, config, initialMessages || [], conversationData, provider);
426
+ }
427
+ else {
428
+ await manager.startConversation(finalObjectType, finalObjectId, config, initialMessages || [], conversationData, provider);
429
+ }
416
430
  // Update status line
417
- status_line_1.statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
431
+ statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
418
432
  }
419
433
  async handleConversationStop(params, message) {
420
434
  // Require conversationId (present at message level); do not fall back to agentSessionId/taskId
421
435
  const { conversationId = message.conversationId, reason } = params;
422
- console_1.console.log(`[MessageHandler] handleConversationStop called with:`, {
436
+ console.log(`[MessageHandler] handleConversationStop called with:`, {
423
437
  conversationId,
424
438
  messageConversationId: message.conversationId,
425
439
  agentSessionId: params?.agentSessionId,
@@ -435,7 +449,7 @@ class MessageHandler {
435
449
  context = this.runner.getConversationContext(conversationId);
436
450
  targetConversationId = conversationId;
437
451
  }
438
- console_1.console.log(`[MessageHandler] handleConversationStop lookup result:`, {
452
+ console.log(`[MessageHandler] handleConversationStop lookup result:`, {
439
453
  contextFound: !!context,
440
454
  targetConversationId,
441
455
  contextTaskId: context?.taskId,
@@ -454,17 +468,17 @@ class MessageHandler {
454
468
  context.status = "stopped";
455
469
  this.runner.activeConversations_.delete(targetConversationId);
456
470
  // Update status line
457
- status_line_1.statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
471
+ statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
458
472
  }
459
473
  else {
460
474
  // No conversation found - this is expected as conversations may have already ended
461
475
  // or been cleaned up. Just log it and update status line.
462
- console_1.console.log(`Conversation stop requested for ${conversationId} - conversation not found or already cleaned up`);
476
+ console.log(`Conversation stop requested for ${conversationId} - conversation not found or already cleaned up`);
463
477
  // If we have a targetConversationId, ensure it's removed from tracking
464
478
  if (targetConversationId) {
465
479
  this.runner.activeConversations_.delete(targetConversationId);
466
480
  }
467
- status_line_1.statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
481
+ statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
468
482
  }
469
483
  }
470
484
  async handleConversationResume(params, message) {
@@ -484,11 +498,17 @@ class MessageHandler {
484
498
  }
485
499
  const provider = this.resolveAgentProvider(conversationData, config);
486
500
  const manager = this.getManagerForProvider(provider);
487
- await manager.resumeConversation(conversationData.objectType, conversationData.objectId, agentSessionId, config, conversationData, resumeMessage);
501
+ // For CodexManager (openai) we pass the provider to distinguish
502
+ if (provider === "openai") {
503
+ await manager.resumeConversation(conversationData.objectType, conversationData.objectId, agentSessionId, config, conversationData, resumeMessage, provider);
504
+ }
505
+ else {
506
+ await manager.resumeConversation(conversationData.objectType, conversationData.objectId, agentSessionId, config, conversationData, resumeMessage, provider);
507
+ }
488
508
  }
489
509
  async handleConversationConfig(params, message) {
490
510
  const { conversationId, model, permissionsMode, config } = params;
491
- console_1.console.log(`[MessageHandler] handleConversationConfig called with:`, {
511
+ console.log(`[MessageHandler] handleConversationConfig called with:`, {
492
512
  conversationId,
493
513
  model,
494
514
  permissionsMode,
@@ -513,28 +533,44 @@ class MessageHandler {
513
533
  ...(permissionsMode && { permissionsMode }),
514
534
  ...config, // Allow full config overrides if provided
515
535
  };
516
- console_1.console.log(`[MessageHandler] Stopping conversation ${context.conversationId} to apply new config`);
536
+ console.log(`[MessageHandler] Stopping conversation ${context.conversationId} to apply new config`);
517
537
  // Stop the current conversation
518
538
  const manager = this.getManagerForConversationContext(context);
519
539
  await manager.stopConversation(context.agentSessionId, context, false // Not a runner shutdown, just updating config
520
540
  );
521
541
  // Remove from active conversations
522
542
  this.runner.activeConversations_.delete(context.conversationId);
523
- console_1.console.log(`[MessageHandler] Resuming conversation ${context.conversationId} with new config`);
543
+ console.log(`[MessageHandler] Resuming conversation ${context.conversationId} with new config`);
524
544
  // Resume with new config
525
- await manager.resumeConversation(context.conversationObjectType, context.conversationObjectId, context.agentSessionId, newConfig, {
526
- id: context.conversationId,
527
- objectType: context.conversationObjectType,
528
- objectId: context.conversationObjectId,
529
- model: newConfig.model,
530
- globalInstructions: context.globalInstructions,
531
- workspaceInstructions: context.workspaceInstructions,
532
- permissionsMode: newConfig.permissionsMode,
533
- agentSessionId: context.agentSessionId,
534
- }, "<system-instructions>Configuration updated. Please continue with the new settings.</system-instructions>");
545
+ // For CodexManager (openai) we pass the provider to distinguish
546
+ const contextProvider = context.provider?.toLowerCase();
547
+ if (contextProvider === "openai") {
548
+ await manager.resumeConversation(context.conversationObjectType, context.conversationObjectId, context.agentSessionId, newConfig, {
549
+ id: context.conversationId,
550
+ objectType: context.conversationObjectType,
551
+ objectId: context.conversationObjectId,
552
+ model: newConfig.model,
553
+ globalInstructions: context.globalInstructions,
554
+ workspaceInstructions: context.workspaceInstructions,
555
+ permissionsMode: newConfig.permissionsMode,
556
+ agentSessionId: context.agentSessionId,
557
+ }, "<system-instructions>Configuration updated. Please continue with the new settings.</system-instructions>", contextProvider);
558
+ }
559
+ else {
560
+ await manager.resumeConversation(context.conversationObjectType, context.conversationObjectId, context.agentSessionId, newConfig, {
561
+ id: context.conversationId,
562
+ objectType: context.conversationObjectType,
563
+ objectId: context.conversationObjectId,
564
+ model: newConfig.model,
565
+ globalInstructions: context.globalInstructions,
566
+ workspaceInstructions: context.workspaceInstructions,
567
+ permissionsMode: newConfig.permissionsMode,
568
+ agentSessionId: context.agentSessionId,
569
+ }, "<system-instructions>Configuration updated. Please continue with the new settings.</system-instructions>");
570
+ }
535
571
  // Update status line
536
- status_line_1.statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
537
- console_1.console.log(`[MessageHandler] Conversation ${context.conversationId} config updated successfully`);
572
+ statusLineManager.updateActiveCount(this.runner.activeConversations_.size);
573
+ console.log(`[MessageHandler] Conversation ${context.conversationId} config updated successfully`);
538
574
  }
539
575
  async handleUserMessage(params, message) {
540
576
  const { conversationId, content, config, conversationObjectType = message.conversationObjectType || "Task", conversationObjectId = message.conversationObjectId, conversation, agentSessionId, } = params;
@@ -546,15 +582,22 @@ class MessageHandler {
546
582
  throw new Error("Missing required parameter: content");
547
583
  }
548
584
  const existingContext = this.runner.getConversationContext(conversationId);
549
- const manager = existingContext
550
- ? this.getManagerForConversationContext(existingContext)
551
- : this.getManagerForProvider(this.resolveAgentProvider(conversation, config));
552
- await manager.sendUserMessage(conversationId, content, config, conversationObjectType, conversationObjectId, conversation, agentSessionId);
585
+ const provider = existingContext
586
+ ? existingContext.provider
587
+ : this.resolveAgentProvider(conversation, config);
588
+ const manager = this.getManagerForProvider(provider);
589
+ // For CodexManager (openai), pass the provider
590
+ if (provider === "openai") {
591
+ await manager.sendUserMessage(conversationId, content, config, conversationObjectType, conversationObjectId, conversation, agentSessionId, provider);
592
+ }
593
+ else {
594
+ await manager.sendUserMessage(conversationId, content, config, conversationObjectType, conversationObjectId, conversation, agentSessionId);
595
+ }
553
596
  }
554
597
  async handleUidChanged(params, _message) {
555
598
  const { runnerUid, lastProcessedAt } = params;
556
- console_1.console.log(`MessageHandler: Handling UID change notification - new UID: ${runnerUid}, lastProcessedAt: ${lastProcessedAt}`);
557
- if ((0, debug_1.isRunnerDebugEnabled)()) {
599
+ console.log(`MessageHandler: Handling UID change notification - new UID: ${runnerUid}, lastProcessedAt: ${lastProcessedAt}`);
600
+ if (isRunnerDebugEnabled()) {
558
601
  logger.debug("UID change notification received", {
559
602
  newUid: runnerUid,
560
603
  currentUid: this.runner.getRunnerUid(),
@@ -568,10 +611,10 @@ class MessageHandler {
568
611
  // This ensures we activate even if we received the message during catch-up
569
612
  if (runnerUid === this.runner.getRunnerUid()) {
570
613
  // This is our UID - we're the active runner
571
- console_1.console.log("MessageHandler: We are now the active runner");
614
+ console.log("MessageHandler: We are now the active runner");
572
615
  this.runner.setIsActiveRunner(true);
573
616
  await this.runner.updateLastProcessedAt(lastProcessedAt ? new Date(lastProcessedAt) : null);
574
- if ((0, debug_1.isRunnerDebugEnabled)()) {
617
+ if (isRunnerDebugEnabled()) {
575
618
  logger.debug("Runner activated as primary", {
576
619
  runnerUid: runnerUid,
577
620
  lastProcessedAt: lastProcessedAt,
@@ -586,15 +629,15 @@ class MessageHandler {
586
629
  });
587
630
  }
588
631
  catch (error) {
589
- console_1.console.error("Failed to send activation notification:", error);
590
- if ((0, debug_1.isRunnerDebugEnabled)()) {
632
+ console.error("Failed to send activation notification:", error);
633
+ if (isRunnerDebugEnabled()) {
591
634
  logger.debug("Activation notification failed", {
592
635
  error: error instanceof Error ? error.message : String(error),
593
636
  });
594
637
  }
595
638
  }
596
639
  // Start processing messages from the lastProcessedAt point
597
- console_1.console.log(`MessageHandler: Will process messages after ${lastProcessedAt || "beginning"}`);
640
+ console.log(`MessageHandler: Will process messages after ${lastProcessedAt || "beginning"}`);
598
641
  }
599
642
  else {
600
643
  // Different UID - check if this is an old UID change that we should ignore
@@ -602,8 +645,8 @@ class MessageHandler {
602
645
  if (currentLastProcessedAt && lastProcessedAt) {
603
646
  const newTime = new Date(lastProcessedAt);
604
647
  if (newTime < currentLastProcessedAt) {
605
- console_1.console.log(`MessageHandler: Ignoring old UID change (${lastProcessedAt} < ${currentLastProcessedAt.toISOString()})`);
606
- if ((0, debug_1.isRunnerDebugEnabled)()) {
648
+ console.log(`MessageHandler: Ignoring old UID change (${lastProcessedAt} < ${currentLastProcessedAt.toISOString()})`);
649
+ if (isRunnerDebugEnabled()) {
607
650
  logger.debug("Ignoring old UID change", {
608
651
  newUid: runnerUid,
609
652
  newLastProcessedAt: lastProcessedAt,
@@ -614,7 +657,7 @@ class MessageHandler {
614
657
  }
615
658
  }
616
659
  // Different UID - we're being replaced
617
- console_1.console.log(`MessageHandler: We are being replaced by runner with UID ${runnerUid}`);
660
+ console.log(`MessageHandler: We are being replaced by runner with UID ${runnerUid}`);
618
661
  this.runner.setIsActiveRunner(false);
619
662
  // Remember which conversations were active before handoff (by conversationId)
620
663
  for (const [conversationId, context] of this.runner
@@ -623,7 +666,7 @@ class MessageHandler {
623
666
  this.runner.getPreHandoffConversations().add(conversationId);
624
667
  }
625
668
  }
626
- if ((0, debug_1.isRunnerDebugEnabled)()) {
669
+ if (isRunnerDebugEnabled()) {
627
670
  logger.debug("Runner deactivated - being replaced", {
628
671
  newRunnerUid: runnerUid,
629
672
  ourUid: this.runner.getRunnerUid(),
@@ -631,7 +674,7 @@ class MessageHandler {
631
674
  activeConversationsCount: this.runner.getPreHandoffConversations().size,
632
675
  });
633
676
  }
634
- console_1.console.log(`MessageHandler: Will complete ${this.runner.getPreHandoffConversations().size} active conversations`);
677
+ console.log(`MessageHandler: Will complete ${this.runner.getPreHandoffConversations().size} active conversations`);
635
678
  // Emit deactivation notification - wrap in try/catch to handle failures gracefully
636
679
  try {
637
680
  await this.runner.notify("runner.deactivate", {
@@ -641,8 +684,8 @@ class MessageHandler {
641
684
  });
642
685
  }
643
686
  catch (error) {
644
- console_1.console.error("Failed to send deactivation notification:", error);
645
- if ((0, debug_1.isRunnerDebugEnabled)()) {
687
+ console.error("Failed to send deactivation notification:", error);
688
+ if (isRunnerDebugEnabled()) {
646
689
  logger.debug("Deactivation notification failed", {
647
690
  error: error instanceof Error ? error.message : String(error),
648
691
  });
@@ -655,7 +698,7 @@ class MessageHandler {
655
698
  if (!taskId || !operation) {
656
699
  throw new Error("Missing required parameters: taskId and operation");
657
700
  }
658
- console_1.console.log(`MessageHandler: Handling Git operation ${operation} for task ${taskId}`);
701
+ console.log(`MessageHandler: Handling Git operation ${operation} for task ${taskId}`);
659
702
  const repoManager = this.runner.repositoryManager_;
660
703
  try {
661
704
  switch (operation) {
@@ -675,7 +718,7 @@ class MessageHandler {
675
718
  break;
676
719
  case "push":
677
720
  // TODO: Implement push operation
678
- console_1.console.log("Push operation not yet implemented");
721
+ console.log("Push operation not yet implemented");
679
722
  break;
680
723
  case "rebase":
681
724
  if (!opParams?.targetBranch) {
@@ -698,7 +741,7 @@ class MessageHandler {
698
741
  }
699
742
  }
700
743
  catch (error) {
701
- console_1.console.error(`Git operation ${operation} failed for task ${taskId}:`, error);
744
+ console.error(`Git operation ${operation} failed for task ${taskId}:`, error);
702
745
  await this.recordGitOperation(taskId, operation, "failed", {
703
746
  error: error instanceof Error ? error.message : String(error),
704
747
  });
@@ -710,14 +753,14 @@ class MessageHandler {
710
753
  if (!taskId) {
711
754
  throw new Error("Missing required parameter: taskId");
712
755
  }
713
- console_1.console.log(`MessageHandler: Cleaning up Git worktree for task ${taskId}`);
756
+ console.log(`MessageHandler: Cleaning up Git worktree for task ${taskId}`);
714
757
  const repoManager = this.runner.repositoryManager_;
715
758
  try {
716
759
  await repoManager.removeTaskWorktree(taskId, { preserveBranch });
717
- console_1.console.log(`Successfully cleaned up worktree for task ${taskId}`);
760
+ console.log(`Successfully cleaned up worktree for task ${taskId}`);
718
761
  }
719
762
  catch (error) {
720
- console_1.console.error(`Failed to clean up worktree for task ${taskId}:`, error);
763
+ console.error(`Failed to clean up worktree for task ${taskId}:`, error);
721
764
  throw error;
722
765
  }
723
766
  }
@@ -725,7 +768,7 @@ class MessageHandler {
725
768
  const repoManager = this.runner.repositoryManager_;
726
769
  const gitState = await repoManager.getTaskState(taskId);
727
770
  if (!gitState) {
728
- console_1.console.error(`No Git state found for task ${taskId}`);
771
+ console.error(`No Git state found for task ${taskId}`);
729
772
  return;
730
773
  }
731
774
  // Send state update to orchestrator
@@ -751,39 +794,104 @@ class MessageHandler {
751
794
  });
752
795
  }
753
796
  resolveAgentProvider(conversation, config) {
797
+ const model = conversation?.model ||
798
+ config?.model ||
799
+ config?.defaultModel ||
800
+ "";
801
+ const normalizedModel = model.toLowerCase();
802
+ // First check if model has explicit provider prefix
803
+ if (normalizedModel.startsWith("openrouter:") || normalizedModel.startsWith("openrouter/")) {
804
+ return "openrouter";
805
+ }
806
+ if (normalizedModel.startsWith("groq:") || normalizedModel.startsWith("groq/")) {
807
+ return "groq";
808
+ }
809
+ if (normalizedModel.startsWith("openai:") || normalizedModel.startsWith("openai/")) {
810
+ return "openai";
811
+ }
812
+ if (normalizedModel.startsWith("claude:") || normalizedModel.startsWith("claude/")) {
813
+ return "claude";
814
+ }
815
+ // Respect explicit provider, but let model-based OpenRouter routing win first
754
816
  const explicitProvider = conversation?.providerType ||
755
817
  conversation?.agentProviderType ||
756
818
  config?.providerType ||
757
819
  config?.agentProviderType;
758
820
  if (typeof explicitProvider === "string") {
759
821
  const normalized = explicitProvider.toLowerCase();
822
+ if (normalized === "openrouter")
823
+ return "openrouter";
824
+ if (normalized === "groq")
825
+ return "groq";
760
826
  if (normalized === "openai")
761
827
  return "openai";
762
828
  if (normalized === "claude")
763
829
  return "claude";
764
830
  }
765
- const model = conversation?.model ||
766
- config?.model ||
767
- config?.defaultModel ||
768
- "";
769
- const normalizedModel = model.toLowerCase();
770
- const looksLikeCodex = normalizedModel.includes("gpt") ||
771
- /^o\d/.test(normalizedModel) ||
772
- normalizedModel.includes("openai") ||
773
- normalizedModel.includes("codex");
774
- return looksLikeCodex ? "openai" : "claude";
831
+ // Check for known Claude models (direct access, not via OpenRouter)
832
+ const looksLikeClaude = normalizedModel.includes("claude") ||
833
+ normalizedModel.includes("opus") ||
834
+ normalizedModel.includes("sonnet") ||
835
+ normalizedModel.includes("haiku");
836
+ // Define specific OpenAI/Codex models that should use the OpenAI provider
837
+ // These are models directly from OpenAI/Codex, not via OpenRouter
838
+ const directOpenAIModels = [
839
+ "gpt-3.5-turbo",
840
+ "gpt-4",
841
+ "gpt-4-turbo",
842
+ "gpt-4o",
843
+ "gpt-4o-mini",
844
+ "gpt-5.1",
845
+ "gpt-5.1-codex",
846
+ "gpt-5.1-codex-max",
847
+ "gpt-5.1-codex-mini",
848
+ "o1",
849
+ "o1-preview",
850
+ "o1-mini",
851
+ "codex"
852
+ ];
853
+ // Check if it's a direct OpenAI model (exact match or starts with the model name followed by :)
854
+ const isDirectOpenAIModel = directOpenAIModels.some(directModel => {
855
+ // Check for exact match or model with reasoning effort suffix (e.g., "gpt-5.1:high")
856
+ return normalizedModel === directModel ||
857
+ normalizedModel.startsWith(directModel + ":") ||
858
+ normalizedModel.startsWith(directModel + "-") ||
859
+ (directModel.startsWith("o") && /^o\d/.test(normalizedModel));
860
+ });
861
+ if (looksLikeClaude)
862
+ return "claude";
863
+ if (isDirectOpenAIModel)
864
+ return "openai";
865
+ // If it doesn't match known Claude or direct OpenAI models, treat as OpenRouter
866
+ // This includes any remaining unknown models
867
+ if (model && model.length > 0) {
868
+ return "openrouter";
869
+ }
870
+ return "claude";
775
871
  }
776
872
  getManagerForProvider(provider) {
777
- if (provider?.toLowerCase() === "openai") {
873
+ const normalized = provider?.toLowerCase();
874
+ if (normalized === "openrouter" || normalized === "groq") {
875
+ // OpenRouter now handled by Northflare Agent manager
876
+ return this.runner.northflareAgentManager_;
877
+ }
878
+ if (normalized === "openai") {
778
879
  return this.runner.codexManager_;
779
880
  }
780
881
  return this.runner.claudeManager_;
781
882
  }
782
883
  getManagerForConversationContext(context) {
783
- return context.provider === "openai"
884
+ const provider = context.provider?.toLowerCase();
885
+ const model = (context.model || "").toLowerCase();
886
+ // Route any OpenRouter-style model strings to the Northflare Agent, even if the
887
+ // provider was previously tagged as openai/codex.
888
+ const looksLikeOpenRouter = model.startsWith("openrouter:");
889
+ if (provider === "openrouter" || provider === "groq" || looksLikeOpenRouter) {
890
+ return this.runner.northflareAgentManager_;
891
+ }
892
+ return provider === "openai"
784
893
  ? this.runner.codexManager_
785
894
  : this.runner.claudeManager_;
786
895
  }
787
896
  }
788
- exports.MessageHandler = MessageHandler;
789
897
  //# sourceMappingURL=message-handler-sse.js.map