mcp-codex-worker 0.1.35 → 0.1.37

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.
@@ -37,6 +37,7 @@ export class CodexAdapter extends BaseProviderAdapter {
37
37
  let detachPauseFlow;
38
38
  let detachEventCapture;
39
39
  let removeExitListener;
40
+ let heartbeatTimer;
40
41
  // Clean up listeners only once, regardless of which path triggers it.
41
42
  const cleanup = () => {
42
43
  detachPauseFlow?.();
@@ -45,6 +46,10 @@ export class CodexAdapter extends BaseProviderAdapter {
45
46
  detachEventCapture = undefined;
46
47
  removeExitListener?.();
47
48
  removeExitListener = undefined;
49
+ if (heartbeatTimer) {
50
+ clearInterval(heartbeatTimer);
51
+ heartbeatTimer = undefined;
52
+ }
48
53
  };
49
54
  try {
50
55
  // 1. Create a new thread
@@ -67,17 +72,65 @@ export class CodexAdapter extends BaseProviderAdapter {
67
72
  .getCurrentClient();
68
73
  detachPauseFlow = attachPauseFlow(client, handle, threadId);
69
74
  detachEventCapture = attachEventCapture(client, handle, threadId, this.options.fileWriter);
70
- // 3b. Listen for app-server crashes. If the process exits while the
71
- // task is paused (WAITING_ANSWER), mark it failed so the
72
- // orchestrator doesn't wait on a ghost.
73
- const onExit = () => {
75
+ // 3b. Capture stderr for diagnostics logs to verbose + events.jsonl.
76
+ // Also accumulate recent stderr to detect auth token expiry on exit.
77
+ let recentStderr = '';
78
+ const onStderr = (chunk) => {
79
+ handle.writeOutputFileOnly(`[stderr] ${chunk.trimEnd()}`);
80
+ recentStderr += chunk;
81
+ // Cap at 10KB to avoid unbounded growth on verbose processes
82
+ if (recentStderr.length > 10_000) {
83
+ recentStderr = recentStderr.slice(-10_000);
84
+ }
85
+ if (this.options.fileWriter) {
86
+ this.options.fileWriter.appendEvent(handle.taskId, {
87
+ method: '_stderr',
88
+ data: chunk.trimEnd(),
89
+ }).catch(() => { });
90
+ }
91
+ };
92
+ client.on('stderr', onStderr);
93
+ // 3c. Listen for app-server exits. Detect the root cause from stderr
94
+ // and produce an actionable error message.
95
+ const onExit = (info) => {
74
96
  if (handle.isAlive()) {
75
- handle.markFailed('Codex app-server process exited unexpectedly');
97
+ const stderrLower = recentStderr.toLowerCase();
98
+ let errorMessage;
99
+ if (stderrLower.includes('refresh token') && stderrLower.includes('already used')) {
100
+ errorMessage = 'AUTH_TOKEN_EXPIRED: Codex refresh token was already consumed. Run `codex auth login` to re-authenticate, then retry.';
101
+ }
102
+ else if (stderrLower.includes('unauthorized') || stderrLower.includes('requires auth') || stderrLower.includes('log out and sign in')) {
103
+ errorMessage = 'AUTH_ERROR: Codex authentication failed. Run `codex auth login` to re-authenticate, then retry.';
104
+ }
105
+ else if (stderrLower.includes('rate limit') || stderrLower.includes('usage limit')) {
106
+ errorMessage = `RATE_LIMITED: Codex hit a rate or usage limit. Details in events.jsonl. Exit code=${String(info.code)}`;
107
+ }
108
+ else {
109
+ errorMessage = `Codex app-server exited (code=${String(info.code)}, signal=${String(info.signal)})`;
110
+ }
111
+ handle.markFailed(errorMessage);
112
+ }
113
+ if (this.options.fileWriter) {
114
+ this.options.fileWriter.appendEvent(handle.taskId, {
115
+ method: '_process_exit',
116
+ code: info.code,
117
+ signal: info.signal,
118
+ stderr_tail: recentStderr.slice(-2000),
119
+ }).catch(() => { });
76
120
  }
77
121
  cleanup();
78
122
  };
79
123
  client.on('exit', onExit);
80
- removeExitListener = () => client.off('exit', onExit);
124
+ removeExitListener = () => {
125
+ client.off('exit', onExit);
126
+ client.off('stderr', onStderr);
127
+ };
128
+ // 3d. Heartbeat — prevent Codex idle timeout during approval waits.
129
+ // Sends a lightweight request every 30s to keep the connection alive.
130
+ heartbeatTimer = setInterval(() => {
131
+ runtime.request('account/rateLimits/read', {}).catch(() => { });
132
+ }, 30_000);
133
+ heartbeatTimer.unref();
81
134
  // 4. Build turn params and start the turn via bridged request
82
135
  const { params: turnParams } = await runtime.buildTurnStartParams({
83
136
  threadId,
@@ -1 +1 @@
1
- {"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../../src/execution/codex-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../../src/execution/codex-adapter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-codex-worker",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "description": "MCP server bridge for Codex app-server",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -72,6 +72,7 @@ export class CodexAdapter extends BaseProviderAdapter {
72
72
  let detachPauseFlow: (() => void) | undefined;
73
73
  let detachEventCapture: (() => void) | undefined;
74
74
  let removeExitListener: (() => void) | undefined;
75
+ let heartbeatTimer: ReturnType<typeof setInterval> | undefined;
75
76
 
76
77
  // Clean up listeners only once, regardless of which path triggers it.
77
78
  const cleanup = () => {
@@ -81,6 +82,10 @@ export class CodexAdapter extends BaseProviderAdapter {
81
82
  detachEventCapture = undefined;
82
83
  removeExitListener?.();
83
84
  removeExitListener = undefined;
85
+ if (heartbeatTimer) {
86
+ clearInterval(heartbeatTimer);
87
+ heartbeatTimer = undefined;
88
+ }
84
89
  };
85
90
 
86
91
  try {
@@ -109,17 +114,66 @@ export class CodexAdapter extends BaseProviderAdapter {
109
114
  detachPauseFlow = attachPauseFlow(client, handle, threadId);
110
115
  detachEventCapture = attachEventCapture(client, handle, threadId, this.options.fileWriter);
111
116
 
112
- // 3b. Listen for app-server crashes. If the process exits while the
113
- // task is paused (WAITING_ANSWER), mark it failed so the
114
- // orchestrator doesn't wait on a ghost.
115
- const onExit = () => {
117
+ // 3b. Capture stderr for diagnostics logs to verbose + events.jsonl.
118
+ // Also accumulate recent stderr to detect auth token expiry on exit.
119
+ let recentStderr = '';
120
+ const onStderr = (chunk: string) => {
121
+ handle.writeOutputFileOnly(`[stderr] ${chunk.trimEnd()}`);
122
+ recentStderr += chunk;
123
+ // Cap at 10KB to avoid unbounded growth on verbose processes
124
+ if (recentStderr.length > 10_000) {
125
+ recentStderr = recentStderr.slice(-10_000);
126
+ }
127
+ if (this.options.fileWriter) {
128
+ this.options.fileWriter.appendEvent(handle.taskId, {
129
+ method: '_stderr',
130
+ data: chunk.trimEnd(),
131
+ }).catch(() => {});
132
+ }
133
+ };
134
+ client.on('stderr', onStderr);
135
+
136
+ // 3c. Listen for app-server exits. Detect the root cause from stderr
137
+ // and produce an actionable error message.
138
+ const onExit = (info: { code: number | null; signal: string | null }) => {
116
139
  if (handle.isAlive()) {
117
- handle.markFailed('Codex app-server process exited unexpectedly');
140
+ const stderrLower = recentStderr.toLowerCase();
141
+ let errorMessage: string;
142
+
143
+ if (stderrLower.includes('refresh token') && stderrLower.includes('already used')) {
144
+ errorMessage = 'AUTH_TOKEN_EXPIRED: Codex refresh token was already consumed. Run `codex auth login` to re-authenticate, then retry.';
145
+ } else if (stderrLower.includes('unauthorized') || stderrLower.includes('requires auth') || stderrLower.includes('log out and sign in')) {
146
+ errorMessage = 'AUTH_ERROR: Codex authentication failed. Run `codex auth login` to re-authenticate, then retry.';
147
+ } else if (stderrLower.includes('rate limit') || stderrLower.includes('usage limit')) {
148
+ errorMessage = `RATE_LIMITED: Codex hit a rate or usage limit. Details in events.jsonl. Exit code=${String(info.code)}`;
149
+ } else {
150
+ errorMessage = `Codex app-server exited (code=${String(info.code)}, signal=${String(info.signal)})`;
151
+ }
152
+
153
+ handle.markFailed(errorMessage);
154
+ }
155
+ if (this.options.fileWriter) {
156
+ this.options.fileWriter.appendEvent(handle.taskId, {
157
+ method: '_process_exit',
158
+ code: info.code,
159
+ signal: info.signal,
160
+ stderr_tail: recentStderr.slice(-2000),
161
+ }).catch(() => {});
118
162
  }
119
163
  cleanup();
120
164
  };
121
165
  client.on('exit', onExit);
122
- removeExitListener = () => client.off('exit', onExit);
166
+ removeExitListener = () => {
167
+ client.off('exit', onExit);
168
+ client.off('stderr', onStderr);
169
+ };
170
+
171
+ // 3d. Heartbeat — prevent Codex idle timeout during approval waits.
172
+ // Sends a lightweight request every 30s to keep the connection alive.
173
+ heartbeatTimer = setInterval(() => {
174
+ runtime.request('account/rateLimits/read', {}).catch(() => {});
175
+ }, 30_000);
176
+ heartbeatTimer.unref();
123
177
 
124
178
  // 4. Build turn params and start the turn via bridged request
125
179
  const { params: turnParams } = await runtime.buildTurnStartParams({