mirror of
https://github.com/langchain-ai/deepagents.git
synced 2026-08-28 05:00:04 -04:00
1d3feb1275
Auto approval mode can now use a separate, cheaper model to review actions instead of always reusing the main agent model. Set it with `--auto-classifier-model`, `DEEPAGENTS_CODE_AUTO_CLASSIFIER_MODEL`, `[models].auto_classifier`, or `/auto model` in the TUI. --- In Auto mode, any gated tool call that deterministic policy can't clear is reviewed by an LLM classifier. That review used the main agent model, so every batch paid frontier-model price and latency for a short verdict, in the middle of the turn. The classifier decides what runs without asking you, so the behavior around it is conservative: - **The default is unchanged.** With nothing configured, the classifier still uses the main agent model. - **Precedence:** `/auto model` → launch flag → env var → `config.toml` → inherit. A blank value anywhere means "inherit". - **Trusted sources only.** A project `.env` can't set the env var, so a cloned repo can't quietly point your review at a weaker model. Shell exports, the global `~/.deepagents/.env`, `config.toml`, the flag, and `/auto model` all work as usual. - **A broken classifier never falls back to the main model.** If the configured model can't be built (bad spec, missing credentials, missing provider package), the calls it would have reviewed are denied and don't run, and Auto starts asking you after repeated failures. The error names the model so you know what to fix. `/auto model` validates a spec before accepting it. - **You can always tell which model is reviewing.** The TUI names it when Auto turns on and in `/auto model`, including one set by env var or `config.toml`. - **Main-model settings don't leak.** Cache control, prompt cache keys, reasoning budgets and `--model-params` are provider-specific, so they only travel when the classifier is the main model. - **Nothing else about Auto changed.** Deterministic allow/deny, the denial counters, replay detection, control-state checks, and the fallback thresholds are all untouched. `--auto-classifier-model` only works where Auto runs — interactive TUI, no sandbox — and errors out otherwise instead of being quietly ignored. `THREAT_MODEL.md` gains T14 for the tradeoff: a weaker classifier means a weaker review, including against prompt injection in the content it reads. Not included: a recommended cheap model (there's no accuracy eval suite yet), classifier-specific invocation params, a configurable timeout, and cache invalidation when credentials rotate (a rotated key shows up as a named classifier failure). <details> <summary>Test plan</summary> Unit tests cover precedence, blank specs, the project/global `.env` split, model caching, settings hygiene, fail-closed resolution and its deadline, logging and trace fields, the per-run context for both setting and clearing, the sandbox and headless guards, and the `/auto model` paths. Manual: launch with `--auto-classifier-model <spec>`, confirm reviews use it, then `/auto model clear` to go back. </details> Made by [Open SWE](https://openswe.vercel.app/agents/a1237a94-e79b-6c84-c74f-b69b5acfc7c4) ## References - Plan: https://openswe.vercel.app/agents/a1237a94-e79b-6c84-c74f-b69b5acfc7c4/plan --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
27 lines
1013 B
Python
27 lines
1013 B
Python
"""Escaping for external text that reaches Rich/Textual markdown source."""
|
|
|
|
from __future__ import annotations
|
|
|
|
MARKDOWN_ESCAPES = str.maketrans({char: f"\\{char}" for char in "\\&`*_[]<>|~"})
|
|
"""Translation table backing `escape_markdown`.
|
|
|
|
Covers the inline constructs Rich's markdown parser acts on (emphasis, code
|
|
spans, links, autolinks/HTML, HTML entities, strikethrough) plus the `|`
|
|
table-cell separator. Block-level punctuation (`#`, `-`, `>`) only has meaning
|
|
at the start of a line; line breaks are normalized before translation, and `>`
|
|
is escaped anyway because it is cheap.
|
|
"""
|
|
|
|
|
|
def escape_markdown(text: str) -> str:
|
|
"""Normalize line breaks and escape markdown syntax in external text.
|
|
|
|
Args:
|
|
text: Display string that may contain markdown punctuation.
|
|
|
|
Returns:
|
|
`text` on one line with markdown-significant characters escaped.
|
|
"""
|
|
normalized = text.replace("\r\n", " ").replace("\r", " ").replace("\n", " ")
|
|
return normalized.translate(MARKDOWN_ESCAPES)
|