@agentex/agent 0.0.32 → 0.0.34

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.
@@ -64,6 +64,28 @@ function parseObject(value: unknown): Record<string, unknown> {
64
64
  return {};
65
65
  }
66
66
 
67
+ function parseStringArray(value: unknown): string[] {
68
+ return Array.isArray(value)
69
+ ? value.filter((entry): entry is string => typeof entry === "string" && entry.length > 0)
70
+ : [];
71
+ }
72
+
73
+ function codexBackgroundTaskState(
74
+ value: unknown,
75
+ ): { phase: "started" | "completed"; status: "running" | "completed" | "failed" | "stopped"; summary: string | null } {
76
+ const state = parseObject(value);
77
+ const nativeStatus = asString(state["status"], "");
78
+ const summary = asNullableString(state["message"]);
79
+ if (nativeStatus === "completed") return { phase: "completed", status: "completed", summary };
80
+ if (nativeStatus === "errored" || nativeStatus === "notFound") {
81
+ return { phase: "completed", status: "failed", summary };
82
+ }
83
+ if (nativeStatus === "interrupted" || nativeStatus === "shutdown") {
84
+ return { phase: "completed", status: "stopped", summary };
85
+ }
86
+ return { phase: "started", status: "running", summary };
87
+ }
88
+
67
89
  /**
68
90
  * Build base fields. For Codex, `eventId` is always null (neither wire
69
91
  * format emits a per-line UUID). `sessionId` and `turnId` come from the
@@ -413,6 +435,56 @@ function parseV2Notification(event: Record<string, unknown>): StreamEvent | null
413
435
  ...base,
414
436
  };
415
437
  }
438
+ if (itemType === "subAgentActivity") {
439
+ const taskId = asString(item["agentThreadId"], "");
440
+ const kind = asString(item["kind"], "");
441
+ if (!taskId || (kind !== "started" && kind !== "interacted" && kind !== "interrupted")) {
442
+ return {
443
+ type: "unknown",
444
+ subtype: `item/completed:${itemType}`,
445
+ ...base,
446
+ };
447
+ }
448
+ return {
449
+ type: "background_task",
450
+ taskId,
451
+ taskType: "subagent",
452
+ phase: kind === "started" ? "started" : kind === "interrupted" ? "completed" : "progress",
453
+ status: kind === "interrupted" ? "stopped" : "running",
454
+ description: asNullableString(item["agentPath"]),
455
+ summary: null,
456
+ parentTaskId: null,
457
+ ...base,
458
+ };
459
+ }
460
+ if (itemType === "collabAgentToolCall") {
461
+ const tool = asString(item["tool"], "");
462
+ const taskIds = parseStringArray(item["receiverThreadIds"]);
463
+ const states = parseObject(item["agentsStates"]);
464
+ const taskId = taskIds[0] ?? Object.keys(states)[0] ?? "";
465
+ // A completed spawnAgent call means the child exists, not that the
466
+ // child's own turn is complete. Its state (usually pendingInit) and a
467
+ // later thread/read response carry the child lifecycle.
468
+ if (!taskId || (tool !== "spawnAgent" && !(taskId in states))) {
469
+ return {
470
+ type: "unknown",
471
+ subtype: `item/completed:${itemType}`,
472
+ ...base,
473
+ };
474
+ }
475
+ const state = codexBackgroundTaskState(states[taskId]);
476
+ return {
477
+ type: "background_task",
478
+ taskId,
479
+ taskType: "subagent",
480
+ phase: state.phase,
481
+ status: state.status,
482
+ description: asNullableString(item["prompt"]),
483
+ summary: state.summary,
484
+ parentTaskId: null,
485
+ ...base,
486
+ };
487
+ }
416
488
  if (itemType === "userMessage") {
417
489
  // Consumer persists user input on the write path before calling send().
418
490
  // We don't re-emit it here to keep a single source of truth.