fix(cli): stop the agent-creation wizard stamping a hidden 200k hourly token cap#6212
Merged
Conversation
…y token cap
The TUI "create custom agent" wizard hard-coded [resources] max_llm_tokens_per_hour = 200000 into every generated agent.toml, so TUI-created agents silently hit "Resource quota exceeded: Token limit would be exceeded: N + 8192 reserved > 200000" after a few large-context turns — the compiled ResourceQuota default and the global [budget] default are both unlimited, so only this template produced the cap. The "+ 8192 reserved" is the wizard's own max_tokens = 8192 the scheduler pre-reserves.
Emit max_llm_tokens_per_hour = 0 (explicitly unlimited, matching every non-TUI agent) instead. Operators who want a cap set it via agent.toml [resources], the global [budget] default_max_llm_tokens_per_hour, or PATCH /api/agents/{id}/budget. Existing agents keep their stored cap and must be edited or PATCHed to lift it.
Add a regression test asserting the rendered template contains max_llm_tokens_per_hour = 0 and not 200000.
Closes #6206
houko
enabled auto-merge (squash)
June 18, 2026 15:39
added 2 commits
June 19, 2026 13:46
# Conflicts: # .secrets.baseline
GQAdonis
pushed a commit
to GQAdonis/librefang
that referenced
this pull request
Jun 19, 2026
Merge upstream/main into the BossFang fork; origin/main was 15 commits behind. Notable upstream changes: - librefang#6225 scope the compaction-summary banner to the compacted session (adds canonical_sessions.compacted_summary_session_id). - librefang#6196 deny WASM fs_write to the audit anchor via a capability deny-list. - librefang#6226 / librefang#6227 add agent label and exit-reason metrics to the agent loop. - librefang#6215 context-window usage indicator + honest quota-error classification. - librefang#6217 per-instance sidecar secrets so each agent owns its own handle. - librefang#6194 global Auto-Dream on/off switch on the Memory tab. - librefang#6211 / librefang#6214 / librefang#6212 token/context cap fixes; librefang#6208 refuse to delete the active prompt version. - librefang#6218 browser_tools.rs ToolError migration; librefang#6203 launchctl let-binding build fix; librefang#6224 docs dep bumps; librefang#6193 drop five orphaned email deps. Conflict resolution: - deny.toml: keep our RUSTSEC-2025-0141 (bincode 2.0.x) ignore entry (take ours). - deny.toml: ignore three pre-existing unmaintained advisories newly tripped by the RustSec DB (all transitive via the UAR provider chain, none introduced by this merge): RUSTSEC-2024-0384 (instant), RUSTSEC-2024-0436 (paste), RUSTSEC-2025-0119 (number_prefix). BossFang preservation (SurrealDB schema parity for upstream SQLite v46 / librefang#6225): - Add crates/librefang-storage/src/migrations/sql/032_canonical_sessions_compacted_summary_session_id.surql declaring the new field on the SCHEMAFULL canonical_sessions table (SCHEMAFULL silently drops undefined fields on write), registered as version 32 in migrations/mod.rs. - migrate/sqlite_to_surreal.rs: copy the new column so a SQLite to SurrealDB migration preserves the owning-session pointer rather than dropping it. - backends/surreal_session.rs: preserve compacted_summary_session_id across canonical appends, since the upsert replaces the whole record. - Cargo.lock: pick up the workspace version bump (beta.19 to beta.20) the merge introduced. Verification: - cargo check --workspace --lib — clean. - cargo check -p librefang-storage -p librefang-memory -p librefang-uar-spec — clean. - cargo test -p librefang-storage migration — ok (migration ordering / SurrealDB-3 flexible-syntax invariants). - cargo test -p librefang-memory --lib session — 50 passed (incl. upstream's store_llm_summary round-trip test). - cargo clippy -p librefang-storage -p librefang-memory — clean. - python3 scripts/enforce-branding.py --check — clean; Tauri desktop audit and URL-drift scan both clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #6206. Sending a message failed with
Resource quota exceeded: Token limit would be exceeded: 672776 + 8192 reserved > 200000, and the user expected far more headroom.Root cause
The compiled and global defaults for the per-agent hourly LLM-token budget are unlimited (
ResourceQuota.max_llm_tokens_per_hour: None,BudgetConfig.default_max_llm_tokens_per_hour: 0), so a clean install never produces a200000cap. The exact number comes from the CLI TUI "create custom agent" wizard, which hard-codes[resources] max_llm_tokens_per_hour = 200000into every generatedagent.toml(crates/librefang-cli/src/tui/screens/agents.rs:840). The+ 8192 reservedis the smoking gun — the scheduler pre-reserves the model'smax_tokensoutput cap, and the same template hard-codesmax_tokens = 8192.So any agent created through that wizard carried a hidden 200k tokens/hour cap (a context-window-sized number mis-used as an hourly budget), which a few large-context turns blow past.
Fix
crates/librefang-cli/src/tui/screens/agents.rs— the template now emitsmax_llm_tokens_per_hour = 0(explicitly unlimited, the documented meaning), matching every non-TUI agent. Operators who want a cap set it viaagent.toml [resources], the global[budget] default_max_llm_tokens_per_hour, orPATCH /api/agents/{id}/budget.#[test]asserting the rendered template containsmax_llm_tokens_per_hour = 0and not200000.Existing agents keep their stored cap — edit the manifest or PATCH the budget to lift it (noted in the CHANGELOG).
Out of scope (noted, not bundled)
dashboard/src/pages/AgentsPage.tsxcaps the modelmax_tokensinput atmax={200000}— a different knob (per-call output cap, not the hourly budget) and not the cause here, though it's the same context-window-vs-budget conflation and could clamp users on large-output models. Different domain (frontend); flagging for a separate decision rather than bundling.Verification