The dynamic tool loader (#1449 + #1762) trims each turn's tool prompt to a semantically-matched subset to cut first-turn latency (TTFT numbers in #1449) — but it ships dark: reachable only via GAIA_DYNAMIC_TOOLS / config.dynamic_tools, with no Agent UI surface. Add a single Beta toggle in Settings so users can opt in without editing env vars. Stays off by default.
Code locations are as of this writing — confirm before editing.
Current state
Scope (keep it simple)
- One toggle, marked
Beta. No threshold/max controls in the UI (leave τ/max as env-var tuning).
- Default OFF.
Implementation
- Schema — add
dynamic_tools: bool to SettingsResponse + SettingsUpdateRequest (ui/models.py).
- Backend GET/PUT — persist via
db.get_setting/set_setting("dynamic_tools", …) in ui/routers/system.py, mirroring agent_mode (only touch when in model_fields_set).
- Wire setting → agent —
custom_model shows the pattern (read via db.get_setting, passed into ChatAgentConfig(...)). Set dynamic_tools at all three construction sites or the toggle silently won't apply on one path:
_chat_helpers.py ~L1230 (non-streaming chat)
_chat_helpers.py ~L1633 (streaming chat)
server.py:373 (scheduled-prompt agent)
Cleanest: thread it through _session_agent_kwargs so all sites share one source.
- Frontend — small toggle with a
Beta badge in SettingsPage.tsx, mirroring the existing custom_model control (useState + dirty-tracking + api.updateSettings). agent_mode is backend-only, so custom_model is the right precedent.
Precedence (decided — do not remove the env var)
Keep GAIA_DYNAMIC_TOOLS as the dev/CI/eval override; the UI toggle is the user-facing control, env var wins when set — same dual-surface pattern as context_size↔GAIA_CTX_SIZE and memory↔GAIA_MEMORY_DISABLED. Eval tooling (eval/tool_recall.py, tool_cost.py) and CI run headless and depend on the env var. UX nit: when the env override is set, the toggle should reflect/disable rather than silently no-op.
Tests
Files: ui/models.py · ui/routers/system.py · ui/_chat_helpers.py · server.py · SettingsPage.tsx(+.css) · tests. Follow-up to #1762.
The dynamic tool loader (#1449 + #1762) trims each turn's tool prompt to a semantically-matched subset to cut first-turn latency (TTFT numbers in #1449) — but it ships dark: reachable only via
GAIA_DYNAMIC_TOOLS/config.dynamic_tools, with no Agent UI surface. Add a single Beta toggle in Settings so users can opt in without editing env vars. Stays off by default.Code locations are as of this writing — confirm before editing.
Current state
ChatAgent._resolve_dynamic_tools_enabled()(chat/agent.py:463) —GAIA_DYNAMIC_TOOLS(if set) wins, elseconfig.dynamic_tools(defaultFalse).docprofile consumes it. The feat(agents): tool loader Part 2 — explicit escape hatch + tuning (#1450) #1762load_toolsescape hatch rides the same gate.Scope (keep it simple)
Beta. No threshold/max controls in the UI (leave τ/max as env-var tuning).Implementation
dynamic_tools: booltoSettingsResponse+SettingsUpdateRequest(ui/models.py).db.get_setting/set_setting("dynamic_tools", …)inui/routers/system.py, mirroringagent_mode(only touch when inmodel_fields_set).custom_modelshows the pattern (read viadb.get_setting, passed intoChatAgentConfig(...)). Setdynamic_toolsat all three construction sites or the toggle silently won't apply on one path:_chat_helpers.py~L1230 (non-streaming chat)_chat_helpers.py~L1633 (streaming chat)server.py:373(scheduled-prompt agent)Cleanest: thread it through
_session_agent_kwargsso all sites share one source.Betabadge inSettingsPage.tsx, mirroring the existingcustom_modelcontrol (useState+ dirty-tracking +api.updateSettings).agent_modeis backend-only, socustom_modelis the right precedent.Precedence (decided — do not remove the env var)
Keep
GAIA_DYNAMIC_TOOLSas the dev/CI/eval override; the UI toggle is the user-facing control, env var wins when set — same dual-surface pattern ascontext_size↔GAIA_CTX_SIZEand memory↔GAIA_MEMORY_DISABLED. Eval tooling (eval/tool_recall.py,tool_cost.py) and CI run headless and depend on the env var. UX nit: when the env override is set, the toggle should reflect/disable rather than silently no-op.Tests
config.dynamic_toolsset from the persisted value at each agent-build path.Files:
ui/models.py·ui/routers/system.py·ui/_chat_helpers.py·server.py·SettingsPage.tsx(+.css) · tests. Follow-up to #1762.