Skip to content

chore(config): remove deprecated default_agent schema field (closes #241)#550

Merged
Astro-Han merged 1 commit into
devfrom
chore/remove-default-agent
May 11, 2026
Merged

chore(config): remove deprecated default_agent schema field (closes #241)#550
Astro-Han merged 1 commit into
devfrom
chore/remove-default-agent

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 11, 2026

Copy link
Copy Markdown
Owner

Summary

Removed the deprecated default_agent config field from the opencode config schema, runtime dependency paths, migration file, tests, and SDK config types.

Why

Closes #241. default_agent was deprecated after the default-agent fallback cleanup shipped, and v0.2.14+ has had time to migrate most active user configs. The runtime should no longer expose or depend on this config field.

Related Issue

Closes #241

Human Review Status

Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.

Review Focus

  • Confirm runtime references to default_agent are limited to the narrow legacy read-time shim in normalizeLoadedConfig().
  • Confirm legacy configs with default_agent are ignored without disk writeback.
  • Confirm agent list/default behavior is unchanged: build still sorts first and remains the default primary agent.
  • Confirm SDK config types and OpenAPI schema no longer expose default_agent.

Risk Notes

Legacy user config files from v0.2.13 or earlier may still contain default_agent on disk. The loader ignores that field at read time and does not rewrite the file. No agent naming, agent ordering, or future autonomous-agent semantics are changed in this PR.

Behavior change for legacy configs

Legacy user config files that still contain default_agent are silently ignored by the loader. No automatic writeback is performed. Users may remove the field manually if they want a clean config file.

This intentionally accepts harmless dead noise in legacy configs to avoid maintaining the migration path indefinitely. v0.2.14+ has shipped for 2 weeks with the migration; subsequent loads after that release already cleaned most user configs in the wild.

Legacy config compatibility

Info.zod is strict on unknown keys in the normalizeLoadedConfig() decode path. Legacy user configs from v0.2.13 and earlier that still contain default_agent would otherwise fail validation. The loader keeps a single-key shim in normalizeLoadedConfig() that drops default_agent before schema decode.

  • No disk writeback; the legacy field stays on disk as harmless dead noise
  • No restoration of the deleted migrate-default-agent.ts migration path
  • No generalized unknown-key handler; this is intentionally narrow to one legacy key
  • Future deprecations should either follow the same single-key shim pattern here, or open a follow-up to revisit schema strictness as a whole

How To Verify

bun --cwd packages/opencode test: 2703 pass, 9 skip, 1 todo, 0 fail across 207 files
bun --cwd packages/opencode typecheck: passed
bun --cwd packages/opencode test test/agent/agent.test.ts: 32 pass, 0 fail
bun --cwd packages/opencode test test/config/pawwork-global-config.test.ts: 50 pass, 0 fail
SDK regen/check: packages/sdk/openapi.json and packages/sdk/js/src/v2/gen/types.gen.ts no longer expose default_agent
rg default_agent packages/opencode/src packages/opencode/test packages/sdk: src only has the normalizeLoadedConfig shim; tests only have legacy fixtures/assertions; SDK has 0 hits
git diff --check: passed
Manual legacy fixture: {"loaded":true,"hasDefaultAgent":false,"model":"anthropic/claude-3.5-sonnet","firstAgent":"build","diskUnchanged":true}

Screenshots or Recordings

Not applicable. No visible UI changes.

Checklist

  • Human review status is stated above as pending, approved, or not required
  • I linked the related issue, or stated why there is no issue
  • This PR has type, primary area, and priority labels, or I requested maintainer labeling
  • I described the review focus and any meaningful risks
  • I listed the relevant verification steps and the key result for each
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant
  • I reviewed the final diff for unrelated changes and suspicious dependency changes
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • New Features

    • Improved agent selection with a fallback mechanism that automatically selects the first available visible agent when needed.
  • Chores

    • Removed deprecated default_agent configuration field.
    • Added small_model configuration field to the schema.

Review Change Stack

@Astro-Han Astro-Han added enhancement New feature or request P3 Low priority harness Model harness, prompts, tool descriptions, and session mechanics task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work labels May 11, 2026
@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR removes the deprecated default_agent config field and its one-shot migration infrastructure. It replaces disk-level migration with read-time normalization that strips the field during config loading, updates agent selection logic with fallback behavior, and removes all supporting migration code and tests.

Changes

Remove default_agent infrastructure

Layer / File(s) Summary
Schema and type removals
packages/opencode/src/config/config.ts, packages/sdk/openapi.json
Remove default_agent field from config schema definition. Replace with small_model field in OpenAPI Config schema (string, provider/model pattern).
Agent selection logic
packages/opencode/src/agent/agent.ts
Agent.list() returns agents sorted with build first, then alphabetically by name. Agent.defaultAgent() implements gentle fallback: honors config-specified agent if it exists and is visible/primary, otherwise selects first visible primary agent, or throws.
Config loading and normalization
packages/opencode/src/config/config.ts
normalizeLoadedConfig deletes default_agent from loaded config at read time before schema validation. Global config loading bypasses migration flow. seedConfigValueFromSource relies on normalization instead of explicit stripDefaultAgent.
Migration module removal
packages/opencode/src/config/migrate-default-agent.ts
Delete entire module: removes stripDefaultAgent, migrateDefaultAgent, MigrationLogger type, and failure-tracking helpers.
CLI documentation update
packages/opencode/src/cli/cmd/github.ts
Update chat() prompt comment to clarify server chooses default primary agent when agent is omitted.
Agent selection test updates
packages/opencode/test/agent/agent.test.ts
Remove Agent.list() ordering test. Replace "no default_agent config" test with assertion that Agent.defaultAgent() returns "build" by default. Remove tests for default_agent pointing to custom/hidden/sub agents.
Migration test removal
packages/opencode/test/config/migrate-default-agent.test.ts
Delete entire test suite covering stripDefaultAgent and migrateDefaultAgent functionality, including sanitization, rewrite, idempotency, file-mode preservation, and retry behavior.
Global config test assertions
packages/opencode/test/config/pawwork-global-config.test.ts
Update assertions to verify default_agent absence using in-operator checks. Rename test descriptions from "schema or default_agent writeback" to "deprecated agent writeback".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #241: Directly addresses acceptance criteria to remove default_agent from schema, delete migration module, remove migration call sites, and update Agent.defaultAgent() fallback logic.

Possibly related PRs

  • Astro-Han/pawwork#242: Related agent registry changes—both PRs modify Agent.list() and Agent.defaultAgent() behavior to handle primary-agent logic and default-agent selection.

Suggested labels

P2

Poem

🐰 A field deprecated fades to dust,
Migration's work is done and just,
Read-time whispers sweep it clean,
The gentlest fallback ever seen—
Build stands proud, the rest align! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title is clear and specific: removes the deprecated default_agent schema field and directly references the issue being closed (#241).
Description check ✅ Passed Description is comprehensive, following the template with all major sections completed: summary, why, related issue, review focus, risk notes, verification steps, and checklist confirmation.
Linked Issues check ✅ Passed All coding requirements from issue #241 are met: default_agent removed from schema, migrate-default-agent.ts deleted, migration call site removed, Agent.defaultAgent() simplified, and SDK types updated.
Out of Scope Changes check ✅ Passed All changes are directly in scope: removing default_agent from schema, config handling, runtime, tests, and SDK types. No unrelated refactors or side changes observed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/remove-default-agent

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/opencode/src/agent/agent.ts (1)

285-290: 💤 Low value

Consider sourcing defaultAgent from the same sorted ordering as list().

Object.values(agents).find(...) returns the first visible primary in insertion order. Today that yields "build" for the common case (since natives are seeded first) and the first config-declared custom primary when build is disabled. Reusing the same sort key as list() (build first, then alphabetical by name) would make the disabled-build tie-break deterministic regardless of how users order their agent map, and keeps list()[0] and defaultAgent() consistent.

♻️ Optional refactor
       const defaultAgent = Effect.fnUntraced(function* () {
         yield* Effect.void
-        const visible = Object.values(agents).find((a) => a.mode !== "subagent" && a.hidden !== true)
+        const sorted = pipe(
+          agents,
+          values(),
+          sortBy([(x) => x.name === "build", "desc"], [(x) => x.name, "asc"]),
+        )
+        const visible = sorted.find((a) => a.mode !== "subagent" && a.hidden !== true)
         if (!visible) throw new Error("no primary visible agent found")
         return visible.name
       })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/src/agent/agent.ts` around lines 285 - 290, The
defaultAgent selection uses Object.values(agents).find(...) which picks the
first visible primary by insertion order; change defaultAgent (the
Effect.fnUntraced function) to derive its result using the same ordering as
list() so ties are deterministic: filter agents to mode !== "subagent" && hidden
!== true && primary, then sort using the list() sort key (prefer "build" first,
then alphabetical by name) and return the first entry's name; this ensures
defaultAgent() and list()[0] are consistent regardless of agents map insertion
order.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/opencode/src/agent/agent.ts`:
- Around line 285-290: The defaultAgent selection uses
Object.values(agents).find(...) which picks the first visible primary by
insertion order; change defaultAgent (the Effect.fnUntraced function) to derive
its result using the same ordering as list() so ties are deterministic: filter
agents to mode !== "subagent" && hidden !== true && primary, then sort using the
list() sort key (prefer "build" first, then alphabetical by name) and return the
first entry's name; this ensures defaultAgent() and list()[0] are consistent
regardless of agents map insertion order.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b704966b-ca25-4b5a-8806-1e3ed0182bdb

📥 Commits

Reviewing files that changed from the base of the PR and between df10ceb and d29f017.

⛔ Files ignored due to path filters (1)
  • packages/sdk/js/src/v2/gen/types.gen.ts is excluded by !**/gen/**
📒 Files selected for processing (8)
  • packages/opencode/src/agent/agent.ts
  • packages/opencode/src/cli/cmd/github.ts
  • packages/opencode/src/config/config.ts
  • packages/opencode/src/config/migrate-default-agent.ts
  • packages/opencode/test/agent/agent.test.ts
  • packages/opencode/test/config/migrate-default-agent.test.ts
  • packages/opencode/test/config/pawwork-global-config.test.ts
  • packages/sdk/openapi.json
💤 Files with no reviewable changes (3)
  • packages/opencode/src/config/migrate-default-agent.ts
  • packages/opencode/test/config/migrate-default-agent.test.ts
  • packages/sdk/openapi.json

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request removes the default_agent configuration field from the system, including its schema definition, migration logic, and associated tests. A read-time shim was added to normalizeLoadedConfig to strip the deprecated key from legacy configurations. The review feedback suggests optimizing this shim to avoid unnecessary object allocations and simplifying the agent-related Effect functions by replacing generator-based logic with synchronous wrappers, as the configuration context is no longer required in those paths.

Comment thread packages/opencode/src/config/config.ts
Comment thread packages/opencode/src/agent/agent.ts
Comment thread packages/opencode/src/agent/agent.ts
@Astro-Han

Astro-Han commented May 11, 2026

Copy link
Copy Markdown
Owner Author

First-pass Review — PR #550

P0-P3 findings

Severity Issue Status
P3 Missing area label (suggest config or app) To fix

1. default_agent reference scan (core verification)

Path Expected Actual Result
packages/opencode/src Only the normalize shim (1 site) 2 hits (comment + delete) ✓ Pass
packages/opencode/test Only legacy fixtures / test names / assertions 6 hits in pawwork-global-config.test.ts fixtures ✓ Pass
packages/sdk 0 0 ✓ Pass
docs / cli 0 0 ✓ Pass

Sole src reference (matches expectation):

// packages/opencode/src/config/config.ts:113-115
// Legacy compat for v0.2.13-era configs: ignore removed default_agent before strict schema decode.
delete copy["default_agent"]

2. PR body completeness

  • ✓ Summary section
  • ✓ Verification section (bun test, typecheck, rg default_agent results)
  • ✓ Legacy config compatibility section
  • ✓ Title follows Conventional Commits: chore(config): remove deprecated default_agent schema field (closes #241)
  • ⚠ Labels: enhancement / P3 / harness / task present, but area label missing (suggest config)

3. Issue #241 acceptance criteria match

Acceptance item Status Evidence
config.ts schema no longer defines default_agent ✓ Pass sed -n '164,320p' config.ts shows no default_agent field
migrate-default-agent.ts and its test deleted ✓ Pass ls returns No such file or directory
loadGlobal removes the migration call site ✓ Pass loadGlobal no longer calls migrateDefaultAgent
Agent.defaultAgent() no longer reads c.default_agent ✓ Pass Simplified to find first visible primary
Release notes explain legacy config behavior ✓ Pass PR body "Legacy config compatibility" section

4. Change summary

+18 -407 lines (9 files)
- Deleted migrate-default-agent.ts + its test
- config.ts: removed the schema field and the loadGlobal migration call
- agent.ts: defaultAgent simplified to first visible primary
- SDK: openapi.json + types.gen.ts no longer expose default_agent

Conclusion

P3 minor: add area label config (or app if config is not in the repo label set).

Acceptance pass: every #241 acceptance item is satisfied, reference scan matches the expected shape, and the diff is clean.


First-pass review by @glm (OpenCode). Rewritten in English by @Opus on behalf of GLM after a quota outage (2026-05-11 18:38).

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Opus second-pass review (product layer / three questions / user experience)

Conclusion: approve

PR is clean, matches the A+ scope, and does not break product semantics.

Three questions

Could this be even less? Already the minimum: a single-key normalize shim. Check.

Is what remains good enough?

  • agent.list / defaultAgent behavior is identical (build still sorts first and remains the default primary).
  • Legacy configs are silently ignored, not written back, and the deleted migration path is not reintroduced.
  • Regression tests cover both fallback branches (defaultAgent returns build by default and picks custom primary when build is disabled).
  • Check.

Is it reassuring? Legacy user upgrade path traced end-to-end:

  • A v0.2.13 config on disk still contains default_agent: "...".
  • normalizeLoadedConfig drops the field before schema decode.
  • Effective config exposes no default_agent.
  • Agent list still puts build first; default primary unchanged.
  • Disk file is untouched, so the user sees no change. Check.

Findings

P3-1 (not blocking, fixable in merge): the config label does not exist in the repo, so I added the app area label instead. The existing harness label leans toward model harness / session mechanics; app more accurately reflects the changed surface (config schema + agent fallback wiring).

P3-2 (nit, do not change in this PR): the "Risk Notes", "Behavior change for legacy configs", and "Legacy config compatibility" sections in the PR body restate the same point three times. Content is complete, so this is a stylistic concern. Worth consolidating in a future PR template pass.

Approve

@Astro-Han Astro-Han added the app Application behavior and product flows label May 11, 2026
@Astro-Han

Astro-Han commented May 11, 2026

Copy link
Copy Markdown
Owner Author

GPT-X engineering final review

Result: pass. I found no P0/P1/P2 issues.

Engineering checks

  • default_agent references are scoped as expected: packages/opencode/src only keeps the narrow legacy shim in normalizeLoadedConfig(), packages/opencode/test only keeps legacy fixtures/assertions, and SDK/OpenAPI have no remaining exposure.
  • The shim is read-time only: it does not write user config back to disk, does not restore migrate-default-agent.ts, and does not introduce a generalized unknown-key handler.
  • agent.ts does not change agent ordering or future agent semantics: build still stays first in the list, and defaultAgent() still uses the visible-primary fallback.
  • SDK regeneration is correct: both packages/sdk/js/src/v2/gen/types.gen.ts and packages/sdk/openapi.json removed default_agent.
  • The PR body explains the legacy config behavior clearly. I read “No automatic writeback” as no automatic writeback for removing default_agent; the existing $schema writeback behavior is outside this PR's scope.

Binary check

  • If this cleanup PR does not land, v1 does not immediately break. This is a P3 backlog cleanup.
  • Once the schema field is removed, however, the single-key shim in normalizeLoadedConfig() is necessary. Without it, legacy configs that still contain default_agent would fail validation on startup.

Notes

CodeRabbit's suggestion to make defaultAgent() use the same sorted order as list() should be handled only if the maintainer wants that behavior change in this PR. It would change the existing fallback semantics, so I treated it as out of scope for the original #241 cleanup boundary.

The prompt-input agent-pill cleanup mentioned in issue #241 is also outside this PR. It is a separate UI/prompt cleanup, not required for removing the config field.

@Astro-Han Astro-Han merged commit 59465cd into dev May 11, 2026
23 checks passed
@Astro-Han Astro-Han deleted the chore/remove-default-agent branch May 11, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows enhancement New feature or request harness Model harness, prompts, tool descriptions, and session mechanics P3 Low priority task Narrow execution, audit, spike, migration, tracking, or upstream follow-up work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Remove default_agent from config schema after v0.2.14 ships

1 participant