Skip to content

feat(config): drive effort capabilities from provider config (#2963)#3037

Open
Bernardxu123 wants to merge 5 commits into
esengine:main-v2from
Bernardxu123:feat/effort-config-driven
Open

feat(config): drive effort capabilities from provider config (#2963)#3037
Bernardxu123 wants to merge 5 commits into
esengine:main-v2from
Bernardxu123:feat/effort-config-driven

Conversation

@Bernardxu123
Copy link
Copy Markdown
Collaborator

Summary

Close #2963: drive /effort capability from provider config (instead of hard-coding the level list in internal/config/effort.go).

Two new optional [[providers]] keys land everywhere (TOML, Go struct, Go renderer, desktop settings panel, i18n, example toml):

  • supported_efforts = ["low", "medium", "high", ...] — non-empty list means /effort <level> is accepted for this provider (the literal auto is always prepended to the level set, matching the existing UI/UX).
  • default_effort = "medium" — applied when the user has not set an effort explicitly; falls back to supported_efforts[0] if blank or not in the list, and is required to be one of the supported levels.

Nothing changes for the bundled presets. mimo-pro / mimo-flash keep no supported_efforts, so they remain rejected by /effort (preserving TestEffortCommandRejectsUnsupportedProvider). DeepSeek and anthropic keep their hard-coded capability paths — users can still opt-in to a custom list by TOML-overriding, but they don't have to.

Why a v2

The earlier draft attached supported_efforts to the mimo-* presets in Default(). That made /effort start accepting mimo-pro (which the test in #2963 was specifically designed to reject), so v1 had to be reworked.

v2 instead treats supported_efforts as a pure opt-in knob:

  • The bundled Default() provider list is unchanged — the existing rejection test stays green.
  • Users with a real MiMo API get a documented opt-in path (a commented [[providers]] block in reasonix.example.toml).
  • RenderTOML only emits the new keys when non-empty, so existing ~/.config/reasonix/config.toml files round-trip byte-for-byte.

Commits (5)

  1. config: add SupportedEfforts/DefaultEffort to ProviderEntry — struct + TOML tags.
  2. config(effort): support config-driven SupportedEfforts/DefaultEffort — capability + normalize branches in effort.go; prepending auto; default-effort fallback to supported_efforts[0] when blank or unknown.
  3. config(render): emit supported_efforts/default_effort in TOML output — round-trip output; only emit when non-empty.
  4. config: cover config-driven effort paths in tests — 4 new tests: custom supported, custom normalize, custom default fallback, empty-slice behavior.
  5. desktop+ui: expose supported_efforts/default_effort in settings panel — desktop ProviderView + 2 fields, Settings() mapping, SaveProvider round-trip; TS interface + 2 fields; 2 inputs in SettingsPanel (en + zh locales); mock data updated; commented example in reasonix.example.toml.

MiMo opt-in story

User adds to ~/.config/reasonix/config.toml:

[[providers]]
name = "mimo-pro"
kind = "openai"
base_url = "https://api.xiaomimimo.com/v1"
api_key = "..."
models = ["mimo-v2-flash"]
supported_efforts = ["low", "medium", "high"]
default_effort = "medium"

/effort low|medium|high|auto then works for mimo-pro. Without supported_efforts set, the existing rejection path is unchanged.

Verification

  • go vet ./... (root + desktop) — exit 0
  • go test ./... (root, REASONIX_RELEASE_CACHE_GUARD=1) — exit 0
  • go test ./... (desktop) — exit 0
  • pnpm build (desktop frontend) — 0 TS errors
  • gofmt -l on changed Go files (in LF form) — clean
  • New tests: TestEffortCapabilityCustomSupportedEfforts, TestNormalizeEffortCustomSupportedEfforts, TestNormalizeEffortCustomDefaultEffort, TestEffortCapabilityEmptySupportedEffortsNotConfigurable — all pass
  • Pre-existing tests unchanged: TestEffortCommandRejectsUnsupportedProvider still passes

Risk register

  • i18n — only en.ts and zh.ts are updated; if a third locale exists it would lose the new keys. The repo currently only ships en + zh, but a TODO is left in code review for any future locale authors.
  • Settings round-tripSaveProvider now writes 2 new fields; users with provider entries that previously had effort = "high" would round-trip to effort = "high" + (empty default_effort), which RenderTOML skips. No data loss.
  • Lockfilepnpm-lock.yaml is intentionally not committed in log-frame: migrate plan-resumed role from ink to frame #5; an unrelated pnpm 11 housekeeping diff (deprecated overrides, new libc entries) was reverted.

Files

desktop/frontend/src/components/SettingsPanel.tsx | 14 ++++
desktop/frontend/src/lib/bridge.ts                |  4 +-
desktop/frontend/src/lib/types.ts                 |  2 +
desktop/frontend/src/locales/en.ts                |  6 ++
desktop/frontend/src/locales/zh.ts                |  6 ++
desktop/settings_app.go                           | 32 ++++----
internal/config/config.go                         |  9 +++
internal/config/edit_test.go                      | 94 +++++++++++++++++++++++
internal/config/effort.go                         | 25 ++++++
internal/config/render.go                         |  6 ++
reasonix.example.toml                             | 15 ++++
11 files changed, 198 insertions(+), 15 deletions(-)

Test plan

  • CI green on all 5 jobs: test (ubuntu/macos/windows), race (ubuntu), desktop (ubuntu), lint (golangci-lint), coverage
  • Manual: open desktop Settings → Providers → edit entry → enter supported_efforts = ["low","medium","high"] and default_effort = "medium" → save → reopen config.toml → see the keys present → start CLI session → /effort high accepted
  • Manual: same flow on mimo-pro without supported_efforts set → /effort high rejected with the same error message as before

Ref: #2963

@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jun 4, 2026
@esengine
Copy link
Copy Markdown
Owner

esengine commented Jun 4, 2026

Running the e2e suite to confirm this does not regress cache-hit % (watching the regression in #3091 before we merge any cache-sensitive change).

/e2e

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

🤖 Reasonix e2e benchmark

Accuracy: 3/4 (75%) · Cache hit: 78% · Tokens: 131,517 (prompt 129,698 / completion 1,819) · Compactions: 0 · Cost: ¥ 0.0336

Task Result Steps Prompt Completion Cache hit Compact Cost
compaction ❌ fail 6 73,942 595 63% 0 ¥ 0.0293
fix-add-bug ✅ pass 3 18,346 234 98% 0 ¥ 0.0011
fizzbuzz ✅ pass 3 18,633 389 99% 0 ¥ 0.0013
palindrome ✅ pass 3 18,777 601 99% 0 ¥ 0.0018

Real provider run. Cache-hit % is cached prompt tokens / total prompt tokens.

agent: PR head (1255687) · triggered by @esengine

@esengine
Copy link
Copy Markdown
Owner

esengine commented Jun 4, 2026

Re-running the suite — the previous run showed 3/4 (the compaction task failed) and a 63% cache hit on that task; checking whether that was a stochastic single-sample miss before we judge this PR.

/e2e

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

🤖 Reasonix e2e benchmark

Accuracy: 4/4 (100%) · Cache hit: 79% · Tokens: 167,392 (prompt 165,120 / completion 2,272) · Compactions: 0 · Cost: ¥ 0.0412

Task Result Steps Prompt Completion Cache hit Compact Cost
compaction ✅ pass 8 102,855 938 68% 0 ¥ 0.0365
fix-add-bug ✅ pass 3 18,373 263 98% 0 ¥ 0.0012
fizzbuzz ✅ pass 4 25,225 546 99% 0 ¥ 0.0019
palindrome ✅ pass 3 18,667 525 99% 0 ¥ 0.0017

Real provider run. Cache-hit % is cached prompt tokens / total prompt tokens.

agent: PR head (1255687) · triggered by @esengine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants