Skip to content

Instantly share code, notes, and snippets.

@mfittko
Last active June 9, 2026 21:59
Show Gist options
  • Select an option

  • Save mfittko/3bb5f6983049c44e12037dd1294bf11d to your computer and use it in GitHub Desktop.

Select an option

Save mfittko/3bb5f6983049c44e12037dd1294bf11d to your computer and use it in GitHub Desktop.
pi-subagents patches: (1) Fix Fireworks API allOf/if schema conflict (2) Extend async subagent idle timeout from 60s to 5 min
diff --git a/node_modules/pi-subagents/src/extension/schemas.ts b/node_modules/pi-subagents/src/extension/schemas.ts
index 84eb36f..9aa5e6e 100644
--- a/node_modules/pi-subagents/src/extension/schemas.ts
+++ b/node_modules/pi-subagents/src/extension/schemas.ts
@@ -199,11 +199,14 @@ const ChainItem = Type.Object({
}, {
description: "Chain step: use {agent, task?, ...} for sequential, {parallel: [...]} for static concurrent execution, or {expand, parallel: {...}, collect} for dynamic fanout.",
additionalProperties: false,
- allOf: [
- { if: { required: ["expand"] }, then: { required: ["parallel", "collect"], properties: { parallel: { type: "object" } } } },
- { if: { required: ["collect"] }, then: { required: ["expand", "parallel"], properties: { parallel: { type: "object" } } } },
- { not: { required: ["expand"], properties: { parallel: { type: "array", items: {} } } } },
- ],
+ if: { required: ["expand"] },
+ then: {
+ required: ["collect", "parallel"],
+ properties: { parallel: { type: "object" } },
+ },
+ else: {
+ not: { required: ["collect"] },
+ },
});
const ControlOverrides = Type.Object({
diff --git a/node_modules/pi-subagents/src/runs/shared/subagent-control.ts b/node_modules/pi-subagents/src/runs/shared/subagent-control.ts
index 3cdb018..7a371e3 100644
--- a/node_modules/pi-subagents/src/runs/shared/subagent-control.ts
+++ b/node_modules/pi-subagents/src/runs/shared/subagent-control.ts
@@ -13,8 +13,8 @@ const DEFAULT_NOTIFY_ON: ControlEventType[] = ["active_long_running", "needs_att
export const DEFAULT_CONTROL_CONFIG: ResolvedControlConfig = {
enabled: true,
- needsAttentionAfterMs: 60_000,
- activeNoticeAfterMs: 240_000,
+ needsAttentionAfterMs: 300_000,
+ activeNoticeAfterMs: 300_000,
failedToolAttemptsBeforeAttention: 3,
notifyOn: DEFAULT_NOTIFY_ON,
notifyChannels: CONTROL_NOTIFICATION_CHANNELS,

pi-subagents patches

Patches for pi-subagents to fix provider compatibility and timeout defaults.

Fireworks API: allOf + if schema conflict

Issue: Fireworks API rejects tool parameter schemas containing allOf with multiple if keys, returning:

Error: 400 {"error":{"type":"invalid_request_error","message":"Conflict in schema definitions for key 'if'. Previous: {'required': ['expand']}, New: {'required': ['collect']}"}}

Root cause: ChainItem in src/extension/schemas.ts uses allOf with 3 separate if conditionals — valid JSON Schema Draft 7, but Fireworks can't handle multiple if keys at the same level.

Fix: Replace allOf + multiple if with a single if/then/else.

- allOf: [
-   { if: { required: ["expand"] }, then: { required: ["parallel", "collect"], ... } },
-   { if: { required: ["collect"] }, then: { required: ["expand", "parallel"], ... } },
-   { not: { required: ["expand"], properties: { parallel: { type: "array" } } } },
- ],
+ if: { required: ["expand"] },
+ then: { required: ["collect", "parallel"], properties: { parallel: { type: "object" } } },
+ else: { not: { required: ["collect"] } },

Behavior preserved:

  • expand present -> requires collect + parallel as object
  • collect present without expand -> rejected
  • Neither present -> parallel type unrestricted (array or object per field definition)

Async subagent idle timeout (needsAttentionAfterMs)

Issue: Async subagents running long silent processes (gh watch, CI watchers, etc.) hit needs_attention state after 60s of no activity. The control system emits a notification and the subagent appears to report back after 60s.

Root cause: DEFAULT_CONTROL_CONFIG.needsAttentionAfterMs in src/runs/shared/subagent-control.ts defaults to 60,000ms (60s).

Fix: Raise both needsAttentionAfterMs and activeNoticeAfterMs to 300,000ms (5 min).

- needsAttentionAfterMs: 60_000,
- activeNoticeAfterMs: 240_000,
+ needsAttentionAfterMs: 300_000,
+ activeNoticeAfterMs: 300_000,

Can also override per call:

subagent({agent: 'watcher', task: '...', async: true, control: { needsAttentionAfterMs: 300_000 }})

To disable control entirely:

subagent({agent: 'watcher', task: '...', async: true, control: { enabled: false }})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment