Skip to content

Conversation

@imarshallwidjaja
Copy link
Contributor

@imarshallwidjaja imarshallwidjaja commented Jan 10, 2026

Allow users to configure Sisyphus-Junior agent via agents["Sisyphus-Junior"] in oh-my-opencode.json, removing hardcoded defaults while preserving safety constraints.
Closes #623

Summary

  • Enable agents["Sisyphus-Junior"] configuration in oh-my-opencode.json
  • Implement safe override merging with guardrails for blocked tools and mode lock
  • Fix README documentation about categories being runtime presets, not separate agents

Changes

  • Add "Sisyphus-Junior" to AgentOverridesSchema and OverridableAgentNameSchema in schema.ts
  • Create createSisyphusJuniorAgentWithOverrides() helper with safety guardrails
  • Update config-handler.ts to use override helper instead of hardcoded values
  • Export SISYPHUS_JUNIOR_DEFAULTS for consistent default values
  • Re-export supportsNewPermissionSystem from permission-compat.ts
  • Fix README category wording (runtime presets, not Sisyphus-Junior-{category} agents)

Honored override fields:

  • model, temperature, top_p, tools, permission, description, color, prompt_append

Safety guardrails enforced post-merge:

  • mode forced to "subagent" (cannot change)
  • prompt is append-only (base discipline text preserved)
  • Blocked tools (task, sisyphus_task, call_omo_agent) always denied
  • disable: true ignores override block, uses defaults

Category interaction:

  • sisyphus_task(category=...) runs use the base Sisyphus-Junior agent config
  • Category model/temperature overrides take precedence at request time
  • To change model for a category, set categories.<cat>.model (not agent override)
  • Categories are runtime presets applied to Sisyphus-Junior, not separate agents

Testing

bun run typecheck
bun test
bun run build
  • 15 new tests in sisyphus-junior.test.ts
  • 3 new schema tests in schema.test.ts
  • All 975 tests pass

Related Issues

Closes #623


Summary by cubic

Enable Sisyphus-Junior customization via agents["Sisyphus-Junior"] in oh-my-opencode.json, removing hardcoded defaults while keeping strict safety rules. Closes #623.

  • New Features
    • Added schema support and createSisyphusJuniorAgentWithOverrides to merge user overrides with guardrails.
    • Honors: model, temperature, top_p, tools/permission, description, color, prompt_append. disable: true falls back to defaults.
    • Guardrails: mode locked to subagent, prompt is append-only, and task/sisyphus_task/call_omo_agent are always denied.
    • Updated config-handler to use overrides; exported SISYPHUS_JUNIOR_DEFAULTS; re-exported supportsNewPermissionSystem; clarified README that categories are runtime presets (use categories..model for per-category changes).
    • Added tests for agent overrides and schema.

Written for commit 9029c14. Summary will update on new commits.

…code.json

Allow users to configure Sisyphus-Junior agent via agents["Sisyphus-Junior"]
in oh-my-opencode.json, removing hardcoded defaults while preserving safety
constraints.
Closes code-yeongyu#623
Changes:
- Add "Sisyphus-Junior" to AgentOverridesSchema and OverridableAgentNameSchema
- Create createSisyphusJuniorAgentWithOverrides() helper with guardrails
- Update config-handler to use override helper instead of hardcoded values
- Fix README category wording (runtime presets, not separate agents)
Honored override fields:
- model, temperature, top_p, tools, permission, description, color, prompt_append
Safety guardrails enforced post-merge:
- mode forced to "subagent" (cannot change)
- prompt is append-only (base discipline text preserved)
- blocked tools (task, sisyphus_task, call_omo_agent) always denied
- disable: true ignores override block, uses defaults
Category interaction:
- sisyphus_task(category=...) runs use the base Sisyphus-Junior agent config
- Category model/temperature overrides take precedence at request time
- To change model for a category, set categories.<cat>.model (not agent override)
- Categories are runtime presets applied to Sisyphus-Junior, not separate agents
Tests: 15 new tests in sisyphus-junior.test.ts, 3 new schema tests

Co-Authored-By: Sisyphus <[email protected]>
@github-actions
Copy link
Contributor

github-actions bot commented Jan 10, 2026

All contributors have signed the CLA. Thank you! ✅
Posted by the CLA Assistant Lite bot.

@GollyJer
Copy link
Contributor

Came here to make this change and found you already did it. Thanks @imarshallwidjaja. Make sure to sign the contributor license.

@imarshallwidjaja
Copy link
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Jan 10, 2026
@GollyJer
Copy link
Contributor

For fun I did a check to see if all agents are now configurable.

After PR #648 merges, here's the complete picture:
All Agents in the System

Agent In builtinAgents In OverridableAgentNameSchema In AgentOverridesSchema Configurable?
Sisyphus
oracle
librarian
explore
frontend-ui-ux-engineer
document-writer
multimodal-looker
Metis (Plan Consultant)
Momus (Plan Reviewer)
orchestrator-sisyphus
Sisyphus-Junior ❌ (dynamic) ✅ (PR #648) ✅ (PR #648) ✅ (PR #648)
OpenCode-Builder ❌ (dynamic)
Prometheus (Planner) ❌ (dynamic)
build ❌ (OpenCode default)
plan ❌ (OpenCode default)
After PR #648, all agents are configurable via the agents config. ✅

Minor Note: BuiltinAgentNameSchema (for disabled_agents)
This schema doesn't include:

  • Sisyphus-Junior
  • OpenCode-Builder
  • Prometheus (Planner)
  • build / plan

But these are controlled by other mechanisms:

So there's no gap - users can configure and disable all agents through the appropriate config options.

@imarshallwidjaja imarshallwidjaja marked this pull request as ready for review January 10, 2026 08:13
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 8 files

Confidence score: 4/5

  • Missing baseEndIndex validation in src/agents/sisyphus-junior.test.ts means a prompt change could let the ordering test pass even when the reference text isn’t found, so regressions might slip through.
  • Risk is limited to test coverage—runtime behavior remains unaffected—but it’s worth tightening before relying on the test for future prompt edits.
  • Pay close attention to src/agents/sisyphus-junior.test.ts - ensure indexOf failures are explicitly handled.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="src/agents/sisyphus-junior.test.ts">

<violation number="1" location="src/agents/sisyphus-junior.test.ts:224">
P2: Missing validation that `baseEndIndex` is not -1. If "Dense > verbose." text changes in the base prompt, `indexOf` returns -1 and the ordering assertion becomes meaningless (any position > -1 passes).</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@imarshallwidjaja
Copy link
Contributor Author

I ran some manual tests asking for orchestrator to task all subagents and all categories and all categories still work as intended and can still be configured all individually or in tandem with junior being configured. (Junior tasked without a category also works with config now)

I'm afk rn will check the recommendation from the review bot when I'm back.

👍

Add validation that baseEndIndex is not -1 before using it for ordering
assertion. Previously, if "Dense > verbose." text changed in the base
prompt, indexOf would return -1 and any positive appendIndex would pass.

Co-Authored-By: Sisyphus <[email protected]>
Gladdonilli added a commit to Gladdonilli/oh-my-opencode that referenced this pull request Jan 10, 2026
…ing and sync mode

## Summary

This commit represents the culmination of extensive debugging and refinement
of the background agent and sisyphus_task systems, building upon changes from
PRs code-yeongyu#592, code-yeongyu#610, code-yeongyu#628, code-yeongyu#638, code-yeongyu#648, code-yeongyu#649, code-yeongyu#652, and code-yeongyu#653.

## Investigation Journey

### Initial Problem
Background tasks were getting stuck indefinitely. User config model overrides
were being ignored for certain agent types.

### Root Cause Analysis
1. Discovered validateSessionHasOutput and checkSessionTodos guards were
   blocking completion even when tasks had finished
2. Found that sync mode (run_in_background=false) was NOT passing categoryModel
   to session.prompt(), while async mode was
3. Traced config loading path and found JSONC files weren't being detected
4. Analyzed kdcokenny/opencode-background-agents for reference implementation

### Trial and Error Log

**Attempt 1: Add model to resume() in manager.ts**
- Hypothesis: Resume needs to pass stored model
- Result: REVERTED - PR code-yeongyu#638 intentionally removed this; agent config handles it

**Attempt 2: Add userAgents lookup for subagent_type**
- Hypothesis: Need to look up agent model from user config
- Result: REVERTED - Agent model already applied at creation in config-handler.ts

**Attempt 3: Add categoryModel to sync mode prompt**
- Hypothesis: Sync mode missing model that async mode passes
- Result: SUCCESS - This was the actual bug

**Attempt 4: Add debug logging throughout pipeline**
- Purpose: Trace model flow through config -> agent -> prompt
- Files: 6 files with appendFileSync to omo-debug.log
- Result: Confirmed fixes working, then REMOVED all debug logging

**Attempt 5: Investigate clickable sessions**
- Hypothesis: parentID should make child sessions clickable in UI
- Result: parentID IS passed correctly, but sessions don't appear clickable
- Analysis: kdcokenny uses same approach; may be OpenCode core limitation
- Status: UNRESOLVED - Needs further investigation or OpenCode core change

## Background Agent Completion Detection (PR code-yeongyu#638)

Simplified the completion detection logic that was causing tasks to get stuck:
- Removed overly complex validateSessionHasOutput and checkSessionTodos guards
- Tasks now complete after MIN_IDLE_TIME_MS (5s) elapsed on session.idle event
- Added 15-minute global timeout (MAX_RUN_TIME_MS) to prevent runaway tasks
- Pattern follows kdcokenny/opencode-background-agents reference implementation

## Model Override Architecture (PRs code-yeongyu#610, code-yeongyu#628, code-yeongyu#638)

Established clear separation between category-based and agent-based model handling:

| Path              | Model Source                              |
|-------------------|-------------------------------------------|
| category=X        | Explicit from category config (passed)    |
| subagent_type=X   | Agent's configured model (at creation)    |
| resume            | Agent's configured model (not passed)     |

Key insight from PR code-yeongyu#638: Don't pass model in prompt body for resume/subagent -
let OpenCode use the agent's configured model set at creation time in
config-handler.ts.

## Sync Mode Category Model Fix (NEW)

Fixed critical bug where sync mode (run_in_background=false) with categories
was NOT passing the categoryModel to session.prompt():

  // BEFORE: Model not passed in sync mode
  body: { agent: agentToUse, system: systemContent, ... }

  // AFTER: Model passed when available
  body: { agent: agentToUse, ...(categoryModel ? { model: categoryModel } : {}), ... }

This ensures category model overrides work consistently in both sync and async modes.

## JSONC Config File Support

Extended config file detection to support both .json and .jsonc extensions:
- getUserConfigDir() now checks for oh-my-opencode.jsonc first
- Both cross-platform (~/.config) and Windows (%APPDATA%) paths support JSONC
- Enables comments in config files for better documentation

## Test Improvements

- Increased sync resume test timeout from 5s to 10s
- Test was flaky because timeout = MIN_STABILITY_TIME_MS (race condition)
- Added clarifying comments about timing requirements

## Code Cleanup

- Removed unused 'os' imports from plugin-config.ts and config-handler.ts
- Removed ALL debug logging (hardcoded paths, appendFileSync calls)
- Added PR code-yeongyu#638 reference comments for future maintainers

## Verified Test Results (8/8 category + subagent tests pass)

| Test              | Type        | Mode  | Result |
|-------------------|-------------|-------|--------|
| quick             | category    | async | ✅     |
| ultrabrain        | category    | async | ✅     |
| most-capable      | category    | async | ✅     |
| quick             | category    | sync  | ✅     |
| librarian         | subagent    | async | ✅     |
| Metis             | subagent    | async | ✅     |
| oracle            | subagent    | sync  | ✅     |
| quick + git-master| category    | async | ✅     |

## Known Issues & Future Work

### 1. Explore Agent Hangs on Non-Exploration Tasks
The explore agent hung when given a simple math query (5+5). This is NOT a
regression - explore is a specialized codebase search agent (contextual grep)
designed for queries like 'Where is X implemented?' not general Q&A.

When given non-exploration tasks, it attempts to search for non-existent
patterns and may hang indefinitely due to no max_steps limit.

**Recommendation**: Add max_steps: 10 to explore agent config in future PR.

### 2. Clickable Child Sessions Not Working
Sessions created via sisyphus_task pass parentID correctly, but don't appear
as clickable child sessions in OpenCode's sidebar UI. Investigation showed:
- parentID IS being passed to session.create()
- kdcokenny/opencode-background-agents uses identical approach
- Sessions exist and complete, just not rendered as clickable in UI

**Recommendation**: May require OpenCode core change or UI setting discovery.

### 3. Prometheus Agent Correctly Blocked
Prometheus (Planner) is a primary agent and correctly rejected when called
via sisyphus_task with subagent_type. This is expected behavior - primary
agents should only be invoked directly, not via task delegation.

## Files Changed

- src/features/background-agent/manager.ts - PR code-yeongyu#638 reference comment
- src/tools/sisyphus-task/tools.ts - Sync mode categoryModel fix
- src/tools/sisyphus-task/tools.test.ts - Test timeout increase
- src/shared/config-path.ts - JSONC extension support
- src/plugin-config.ts - Cleanup unused import
- src/plugin-handlers/config-handler.ts - Cleanup unused import
Copy link
Contributor

@jkoelker jkoelker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also tested this successfully:

Image

@code-yeongyu code-yeongyu merged commit 0fada4d into code-yeongyu:dev Jan 12, 2026
3 checks passed
@imarshallwidjaja imarshallwidjaja deleted the fix/Allow-custom-model-configuration-for-Sisyphus-Junior-agent branch January 13, 2026 00:06
kdcokenny pushed a commit that referenced this pull request Jan 13, 2026
kdcokenny pushed a commit that referenced this pull request Jan 13, 2026
…code.json (#648)

* fix(config): allow Sisyphus-Junior agent customization via oh-my-opencode.json

Allow users to configure Sisyphus-Junior agent via agents["Sisyphus-Junior"]
in oh-my-opencode.json, removing hardcoded defaults while preserving safety
constraints.
Closes #623
Changes:
- Add "Sisyphus-Junior" to AgentOverridesSchema and OverridableAgentNameSchema
- Create createSisyphusJuniorAgentWithOverrides() helper with guardrails
- Update config-handler to use override helper instead of hardcoded values
- Fix README category wording (runtime presets, not separate agents)
Honored override fields:
- model, temperature, top_p, tools, permission, description, color, prompt_append
Safety guardrails enforced post-merge:
- mode forced to "subagent" (cannot change)
- prompt is append-only (base discipline text preserved)
- blocked tools (task, sisyphus_task, call_omo_agent) always denied
- disable: true ignores override block, uses defaults
Category interaction:
- sisyphus_task(category=...) runs use the base Sisyphus-Junior agent config
- Category model/temperature overrides take precedence at request time
- To change model for a category, set categories.<cat>.model (not agent override)
- Categories are runtime presets applied to Sisyphus-Junior, not separate agents
Tests: 15 new tests in sisyphus-junior.test.ts, 3 new schema tests

Co-Authored-By: Sisyphus <[email protected]>

* test(sisyphus-junior): add guard assertion for prompt anchor text

Add validation that baseEndIndex is not -1 before using it for ordering
assertion. Previously, if "Dense > verbose." text changed in the base
prompt, indexOf would return -1 and any positive appendIndex would pass.

Co-Authored-By: Sisyphus <[email protected]>

---------

Co-authored-by: Sisyphus <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Allow custom model configuration for Sisyphus-Junior agent

4 participants