@link-assistant/hive-mind 1.57.0 → 1.57.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 1.57.1
4
+
5
+ ### Patch Changes
6
+
7
+ - e4ece4d: Treat Codex app-server stream-lag item errors as non-fatal warnings when the turn otherwise completes successfully, preventing successful Codex runs from being reported as failed solution drafts.
8
+
3
9
  ## 1.57.0
4
10
 
5
11
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "1.57.0",
3
+ "version": "1.57.1",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
package/src/codex.lib.mjs CHANGED
@@ -210,12 +210,23 @@ const unwrapCodexErrorMessage = value => {
210
210
  return text;
211
211
  };
212
212
 
213
+ const isNonFatalCodexItemErrorMessage = message => /^in-process app-server event stream lagged; dropped \d+ events?$/i.test(message || '');
214
+
213
215
  export const getCodexErrorEventSummary = codexJsonState => {
214
216
  const events = [];
217
+ const ignoredEvents = [];
215
218
  const addEvents = (type, items = []) => {
216
219
  for (const item of items) {
217
220
  const message = unwrapCodexErrorMessage(item?.message);
218
- events.push({ type, message: message || 'Codex emitted an error event' });
221
+ const event = { type, message: message || 'Codex emitted an error event' };
222
+ if (type === 'item' && isNonFatalCodexItemErrorMessage(message)) {
223
+ ignoredEvents.push({
224
+ ...event,
225
+ reason: 'Codex app-server backpressure warning; the turn can still complete successfully',
226
+ });
227
+ continue;
228
+ }
229
+ events.push(event);
219
230
  }
220
231
  };
221
232
 
@@ -223,11 +234,20 @@ export const getCodexErrorEventSummary = codexJsonState => {
223
234
  addEvents('turn', codexJsonState?.turnFailures);
224
235
  addEvents('stream', codexJsonState?.streamErrors);
225
236
 
237
+ const countByType = items => ({
238
+ item: items.filter(item => item.type === 'item').length,
239
+ turn: items.filter(item => item.type === 'turn').length,
240
+ stream: items.filter(item => item.type === 'stream').length,
241
+ });
242
+
226
243
  return {
227
244
  hasError: events.length > 0,
228
245
  message: events[0]?.message || null,
229
246
  events,
230
- counts: {
247
+ ignoredEvents,
248
+ counts: countByType(events),
249
+ ignoredCounts: countByType(ignoredEvents),
250
+ observedCounts: {
231
251
  item: codexJsonState?.itemErrors?.length || 0,
232
252
  turn: codexJsonState?.turnFailures?.length || 0,
233
253
  stream: codexJsonState?.streamErrors?.length || 0,
@@ -928,6 +948,10 @@ export const executeCodexCommand = async params => {
928
948
  }
929
949
 
930
950
  const codexErrorSummary = getCodexErrorEventSummary(codexJsonState);
951
+ if (codexErrorSummary.ignoredEvents.length > 0) {
952
+ const ignoredMessages = [...new Set(codexErrorSummary.ignoredEvents.map(event => event.message))].join('; ');
953
+ await log(`⚠️ Ignoring non-fatal Codex item error event(s): ${ignoredMessages}`, { level: 'warning', verbose: true });
954
+ }
931
955
  if (codexErrorSummary.hasError) {
932
956
  const limitInfo = detectUsageLimit(codexErrorSummary.message || lastMessage);
933
957
  const retryableError = classifyRetryableError(codexErrorSummary.message || lastMessage);