Commit Graph

208 Commits

Author SHA1 Message Date
x-x-gpu 0b9cc80ecf fix: pass resolved model to session.create so sub-agent sessions use the correct model
Sub-agent sessions created via the task tool or call_omo_agent tool were
being created without a model. The resolved model was only passed as a
promptAsync body override, which opencode core ignores, causing fallback
to the client's system default model (often a reasoning model that hangs).

OpenCode's session.create API supports model: { id, providerID, variant }
at creation time. This fix ensures the resolved category/agent model is
passed during session creation across all paths:

- createSyncSession() (delegate task / category-based)
- createOrGetSession() (call_omo_agent / direct agent calls)
- BackgroundManager.startTask() (background tasks)

This guarantees each sub-agent session is created with the correct model
regardless of whether promptAsync honors its model override.
2026-05-08 20:52:30 +08:00
YeonGyu-Kim ee938aa097 fix full-suite isolation regressions 2026-05-07 18:36:03 +09:00
YeonGyu-Kim 25d183fbe8 fix(agent): sanitize backslash/quote from agent name in launch() and background-executor
Agent names like \hephaestus\ cause 'Agent not found' errors because
sanitizeSubagentType() was only called in subagent-resolver.ts but not
in the direct manager.launch() path or background-executor.ts.

- manager.ts: strip leading/trailing backslash/quote chars from input.agent
  before validation so \hephaestus\ → hephaestus
- background-executor.ts: call sanitizeSubagentType(args.subagent_type)
  instead of passing raw value to manager.launch()
- agent-display-names.ts: reuse sanitizeSubagentType in stripAgentListSortPrefix
- Add unit tests for all three fix points

Fixes: sessions dying with 'Agent not found: \hephaestus\'
2026-05-06 17:41:41 +09:00
YeonGyu-Kim 503df29195 fix(team-mode): register spawned sessions early 2026-05-06 14:20:50 +09:00
YeonGyu-Kim a0d122b1e6 feat(background-agent): integrate team-mode into background manager 2026-05-06 14:19:39 +09:00
YeonGyu-Kim 6323fa8ef9 fix(background-agent): fix parentSessionID -> parentSessionId typo causing TS build failure
Property 'parentSessionID' does not exist on type 'LaunchInput' / 'BackgroundTask'.
The correct casing is 'parentSessionId' (camelCase with lowercase 'd').
Fixes CI build failure on dev branch.
2026-05-05 03:53:44 +09:00
YeonGyu-Kim e699f3388d Merge pull request #3455 from CHLK/fix/cli-run-premature-exit-with-background-tasks
fix(cli-run): prevent premature exit when background tasks are active
2026-05-04 23:58:34 +09:00
YeonGyu-Kim 3ae9f5f104 fix(background-agent): prevent false task completion on status API outage
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-04 16:30:06 +09:00
YeonGyu-Kim da251c9b30 refactor(background-agent): normalize task ID field naming
Rename BackgroundTask and attempt ID fields to camelCase across background-agent consumers while moving BackgroundManager construction to a single config object.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-02 03:01:03 +09:00
Choi Kijin / 최 기진 / チョイ キジン 7adb725960 Merge remote-tracking branch 'origin/dev' into fix/retry-recovery-and-observability 2026-04-29 12:25:02 +09:00
Choi Kijin / 최 기진 / チョイ キジン 2237c1accd fix(background-agent): guard stale launch errors and retry links
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-28 21:43:09 +09:00
YeonGyu-Kim 24201ea951 perf(background-agent): index tasks by parent session
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-28 18:00:04 +09:00
Choi Kijin / 최 기진 / チョイ キジン a4968a3d1d feat(background-task): track retry attempts across sessions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-28 15:27:35 +09:00
柯杨 eaa3837d0b Merge remote-tracking branch 'origin/dev' into fix/cli-run-premature-exit-with-background-tasks 2026-04-22 09:45:56 +08:00
YeonGyu-Kim 611f1cc932 fix(background-agent): remove descendant spawn cap 2026-04-16 23:02:27 +09:00
柯杨 dd95d59402 fix(cli-run): cover all terminal paths for background task marker cleanup
Address review feedback: add updateBackgroundTaskMarker() calls to
three additional terminal paths in BackgroundManager that were missing
marker cleanup, which could leave stale "active" markers and prevent
CLI run mode from exiting:

- processKey() startTask error handler
- handleEvent() session error (non-retryable)
- pruneStaleTasksAndNotifications() stale task cleanup

Closes #3452
2026-04-16 12:02:43 +08:00
柯杨 aa90cff9cc fix(cli-run): prevent premature exit when background tasks are active
When using `opencode run`, the process exits prematurely if the main
agent dispatches background subtasks. The CLI completion checker relies
on `session.children()` + `session.status()` APIs which cannot see
tasks in "pending" state (no session created yet) or tasks whose
sessions are momentarily idle between operations.

This fix bridges BackgroundManager state to the CLI completion checker
using the existing run-continuation-state marker system:

- Add "background-task" continuation marker source
- BackgroundManager writes/clears markers on task lifecycle events
  (launch, cancel, complete, crash)
- CLI completion checker blocks exit when marker is active
- Fix todo-continuation-enforcer to also check "pending" task status

Closes #3452
2026-04-16 11:59:11 +08:00
YeonGyu-Kim 3bfa3bd608 fix(background-agent): pass query directory to session.get in 4 call-sites (#2937)
resolveSubagentSpawnContext and related lookups called client.session.get
without the query.directory parameter, causing project-scoped sessions
to 404 under newer OpenCode SDK versions. Threaded directory through
SpawnerContext/BackgroundManager so all four call-sites pass it.

🤖 Generated with OhMyOpenCode assistance
https://github.com/code-yeongyu/oh-my-opencode
2026-04-12 02:30:01 +09:00
YeonGyu-Kim 80c74c8849 fix(background): prevent double-decrement of descendant quota in processKey error cleanup 2026-04-08 17:15:18 +09:00
YeonGyu-Kim 1cf4119dd4 fix(background): use parent session variant in notifyParentSession instead of child task variant 2026-04-08 17:15:02 +09:00
YeonGyu-Kim c3fe0ae09e fix(background): propagate variant in parent notifications
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-08 13:23:08 +09:00
YeonGyu-Kim 5622d154fd fix: prevent background agent race condition in session prompt (#2932)
Added await for session ready state before sending prompt in
background-agent/manager.ts. Also improved image resizer error handling.

132 tests pass, tsc clean.

Closes #2932
2026-04-07 15:29:11 +09:00
Jim Park 9470cbe090 fix: address systems review findings for agent-not-found fallback
1. [HIGH] Tool restrictions recomputed for fallback agent via
   buildFallbackBody() — no longer inherits original agent's restrictions.

2. [HIGH] Double-retry race prevented — handleSessionErrorEvent now
   returns early for agent-not-found errors, since the prompt catch
   block already handles them with agent fallback. This prevents
   tryFallbackRetry from racing with a model-level retry on the same
   error (the "not found" pattern in RETRYABLE_MESSAGE_PATTERNS).

3. [MEDIUM] task.agent updated to FALLBACK_AGENT after successful
   fallback — notifications, toast, and logging reflect actual agent.

4. [MEDIUM] FALLBACK_AGENT exported from spawner.ts and imported into
   manager.ts — single source of truth.

5. [LOW] resumeTask fallback now uses promptWithModelSuggestionRetry
   (consistent with startTask), getting timeout protection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:13:05 -07:00
Jim Park 050502f8d0 fix(background-agent): retry with fallback agent on Agent not found error
When a model/mode switch happens while a background task is in-flight,
the oh-my-openagent agent registry can be rebuilt without custom agents
(e.g., Sisyphus-Junior). The SDK then rejects the promptAsync call with
"Agent not found", killing the task.

This adds retry logic: when promptAsync fails with "Agent not found",
retry with the "general" agent (always available in opencode). The
original prompt, model, and skill content are preserved — only the
agent routing changes.

Fixes both the spawner (startTask/resumeTask) and manager (inline
launch) code paths. Also improves the error message detection in
manager.ts to recognize "Agent not found" alongside the existing
"agent.name"/"undefined" checks.

Related: #2052, #2875, #2882

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 21:57:37 -07:00
YeonGyu-Kim 51d2f8b3e9 fix(tmux-subagent): avoid transcript fetches during idle stability checks 2026-04-04 18:48:03 +09:00
YeonGyu-Kim f9a9a60b82 fix(background-agent): cache observed output for completion checks
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-04 18:39:26 +09:00
YeonGyu-Kim b31dfa6928 fix(background-agent): clean tmux cancel bookkeeping
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-04 15:40:21 +09:00
YeonGyu-Kim 7f1497fc43 fix(background-agent): prevent cancelled task from being revived after tmux callback 2026-04-04 14:19:18 +09:00
YeonGyu-Kim f5740d68c7 fix(background-agent): bound session abort waits
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-04 01:19:52 +09:00
YeonGyu-Kim c7afc795be refactor(features): fix empty catches and remove AI slop from manager modules 2026-04-03 21:42:10 +09:00
YeonGyu-Kim ec9ed0a381 Merge pull request #3056 from code-yeongyu/fix/p2-12-notification-template-consolidation
Consolidate background task notification template
2026-04-03 18:03:36 +09:00
YeonGyu-Kim 9bcaddf732 Use shared background task notification template
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-03 17:43:33 +09:00
YeonGyu-Kim 49ea082855 fix(background-agent): await shutdown aborts before cleanup
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-03 17:42:51 +09:00
YeonGyu-Kim 3cce7406ea fix: distinguish transient errors from missing sessions in crash detection 2026-03-31 17:04:07 -07:00
YeonGyu-Kim 324dbb119c fix(#2791): await session.abort() in all subagent completion/cancel paths
Fire-and-forget session.abort() calls during subagent completion left
dangling promises that raced with parent session teardown. In Bun on
WSL2/Linux, this triggered a StringImplShape assertion (SIGABRT) as
WebKit GC collected string data still referenced by the inflight request.

Fix: await session.abort() in all four completion/error paths:
- startTask promptAsync error handler (launch path)
- resume promptAsync error handler (resume path)
- cancelTask (explicit cancel path)
- tryCompleteTask (normal completion path)

Also marks the two .catch() error callbacks as async so the await is
valid.

Test: update session.deleted cascade test to flush two microtask rounds
since cancelTask now awaits abort before cleanupPendingByParent.
2026-03-27 19:57:57 +09:00
YeonGyu-Kim c41e59e9ab fix(#2825): secondary agents no longer pruned after 30 min of total runtime
TTL (pruneStaleTasksAndNotifications) now resets on last activity:
- Uses task.progress.lastUpdate as TTL anchor for running tasks
  (was always using startedAt, causing 30-min hard deadline)
- Added taskTtlMs config option for user-adjustable TTL
- Error message shows actual TTL duration, not hardcoded '30 minutes'
- 3 new tests for the new behavior
2026-03-27 16:06:38 +09:00
YeonGyu-Kim 3be26cb97f fix(#2732): enhance notification for failed/crashed subagent tasks
- completedTaskSummaries now includes status and error info
- notifyParentSession: noReply=false for failed tasks so parent reacts
- Batch notification distinguishes successful vs failed/cancelled tasks
- notification-template updated to show task errors
- task-poller: session-gone tests (85 new lines)
- CI: add Bun shim to PATH for legacy plugin migration tests
2026-03-27 15:48:07 +09:00
YeonGyu-Kim e22e13cd29 fix(#2732): detect crashed subagent sessions with shorter timeout
When a subagent session disappears from the status registry (process
crashed), the main agent was waiting the full stale timeout before
acting. Fix:

- Add sessionGoneTimeoutMs config option (default 60s, vs 30min normal)
- task-poller: use shorter timeout when session is gone from status
- manager: verify session existence when gone, fail crashed tasks
  immediately with descriptive error
- Add legacy-plugin-toast hook for #2823 migration warnings
- Update schema with new config option
2026-03-27 15:43:01 +09:00
YeonGyu-Kim 5df54bced4 Merge pull request #2725 from cphoward/fix/spawn-budget-lifetime-semantics-clean
fix(background-agent): decrement spawn budget on task completion, cancellation, error, and interrupt
2026-03-25 21:46:51 +09:00
Ravi Tharuma f86b8b3336 fix(review): align model compatibility and prompt param helpers 2026-03-25 11:14:04 +01:00
Ravi Tharuma a77a16c494 feat(config): support object-style fallback_models with per-model settings
Add support for object-style entries in fallback_models arrays, enabling
per-model configuration of variant, reasoningEffort, temperature, top_p,
maxTokens, and thinking settings.

- Zod schema for FallbackModelObject with full validation
- normalizeFallbackModels() and flattenToFallbackModelStrings() utilities
- Provider-agnostic model resolution pipeline with fallback chain
- Session prompt params state management
- Fallback chain construction with prefix-match lookup
- Integration across delegate-task, background-agent, and plugin layers
2026-03-25 11:04:49 +01:00
YeonGyu-Kim 42fb2548d6 fix(agent): always keep agent when model is explicitly configured
Previously, when an explicit model was configured, the agent name was
omitted to prevent opencode's built-in agent fallback chain from
overriding the user-specified model. This removes that conditional logic
and always passes the agent name alongside the model. Tests are updated
to reflect this behavior change.

🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:46:07 +09:00
YeonGyu-Kim 3b41191980 fix(background-agent): honor explicit model override in manager
Keep BackgroundManager launch and resume from sending both agent and model so OpenCode does not override configured subagent models. Add launch and resume regressions for the live production path.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-24 20:28:01 +09:00
Casey Howard 5986583641 fix(background-agent): decrement spawn budget on task completion, cancellation, error, and interrupt
rootDescendantCounts was incremented on every spawn but never decremented
when tasks reached terminal states (completed, cancelled, error, interrupt,
stale-pruned). This made maxDescendants=50 a session-lifetime quota instead
of its intended semantics as a concurrent-active agent cap.

Fix: add unregisterRootDescendant() in five terminal-state handlers:
- tryCompleteTask(): task completes successfully
- cancelTask(): running task cancelled (wasRunning guard prevents
  double-decrement for pending tasks already handled by
  rollbackPreStartDescendantReservation)
- session.error handler: task errors
- promptAsync catch (startTask): task interrupted on launch
- promptAsync catch (resume): task interrupted on resume
- onTaskPruned callback: stale task pruned (wasPending guard)

Fixes: code-yeongyu/oh-my-openagent#2700
2026-03-20 12:51:21 -04:00
YeonGyu-Kim d48ea025f0 refactor(circuit-breaker): replace sliding window with consecutive call detection
Switch background task loop detection from percentage-based sliding window
(80% of 20-call window) to consecutive same-tool counting. Triggers when
same tool signature is called 20+ times in a row; a different tool resets
the counter.
2026-03-18 14:32:27 +09:00
YeonGyu-Kim 2da19fe608 perf(background-agent): use Set for countedToolPartIDs, cache circuit breaker settings, optimize loop detector
- Replace countedToolPartIDs string[] with Set<string> for O(1) has/add vs O(n) includes/spread (C2)
- Cache resolveCircuitBreakerSettings at manager level to avoid repeated object creation (C3)
- Optimize recordToolCall to avoid full array copy with slice (L1)
2026-03-18 14:18:38 +09:00
YeonGyu-Kim 952bd5338d fix(background-agent): treat non-active session statuses as terminal to prevent parent session hang
Previously, pollRunningTasks() and checkAndInterruptStaleTasks() treated
any non-"idle" session status as "still running", which caused tasks with
terminal statuses like "interrupted" to be skipped indefinitely — both
for completion detection AND stale timeout. This made the parent session
hang forever waiting for an ALL COMPLETE notification that never came.

Extract isActiveSessionStatus() and isTerminalSessionStatus() that
classify session statuses explicitly. Only known active statuses
("busy", "retry", "running") protect tasks from completion/stale checks.
Known terminal statuses ("interrupted") trigger immediate completion.
Unknown statuses fall through to the standard idle/gone path with output
validation as a conservative default.

Introduced by: a0c93816 (2026-02-14), dc370f7f (2026-03-08)
2026-03-18 14:06:23 +09:00
tad-hq 5d5755f29d fix(circuit-breaker): wire target-aware detection into background manager 2026-03-17 13:40:46 -06:00
YeonGyu-Kim 0b4d092cf6 Merge pull request #2639 from code-yeongyu/feature/2635-smart-circuit-breaker
feat(background-agent): add smart circuit breaker for repeated tool calls
2026-03-17 16:43:08 +09:00
YeonGyu-Kim 53285617d3 Merge pull request #2636 from code-yeongyu/fix/pre-publish-blockers
fix: resolve 12 pre-publish blockers (security, correctness, migration)
2026-03-17 16:36:04 +09:00