Chutes Build preserves the proven upstream Rust agent runtime while replacing public identity, authentication, provider integration, and privacy-sensitive cloud behavior.
- Terminal and CLI: command parsing, interactive rendering, sessions, approvals, keyboard input, and the animated Chutes Build welcome identity.
- Agent loop: prompt construction, planning, tool dispatch, compaction, goals, and subagent orchestration.
- Chutes routing: model selection, live capability lookup, ordered fallback, image-capability delegation, retry classification, and streaming safeguards.
- Tools: coding/filesystem tools, MCP, Context7, web search, isolated browser control, and native Chutes media invocation.
- Safety and lifecycle: folder trust, permission classification, endpoint policy, bounded tool output, cancellation, and loop-stationarity handling.
- Local state: configuration, credentials, sessions, logs, exports, and
secret-filtered
memories.mdmaintenance.
Auto (Chutes Router) is inserted as the first catalog entry and is selected by
default when the user has no stored model preference. It sends a native
Chutes routing string — default (the pool saved at chutes.ai/app), a
strategy alias, or an inline CHUTES_ROUTING_POOL — to the normal inference
host; Chutes resolves the pool server-side per request. The legacy local ID
model-router is still accepted and mapped to that string. A concrete
selection is attempted first, followed by CHUTES_FALLBACK_MODELS, then Auto.
When the Auto string is the bare dashboard alias, a live inline pool built
from the current catalogue follows it (:latency by default), so accounts
without a saved routing pool still serve; if the whole chain fails to resolve,
the surfaced error explains how to configure routing.
Duplicates are removed. Only transient/model-unavailable failures before
stream start can advance the chain. Authentication, permission,
invalid-request, and mid-stream errors do not silently switch models.
The chain covers both request paths, which it did not always: it was wired
into chat_completion_stream and not into chat_completion, so an interactive
turn recovered from 429 Infrastructure is at maximum capacity while
compaction and title generation surfaced it raw. Both now share
one chain and one FallbackPolicy. Nothing on the non-streaming path can be
mid-stream, so the rule that matters — never switch models once bytes have
reached the user — holds there by construction, and the streaming path keeps
enforcing it explicitly.
Waiting and retrying is a separate layer and stays there. The sampler actor
honours the server's Retry-After on a 429 and retries the same model with a
cancellable backoff, up to rate_limit_retry_threshold. The client chain does
not sleep: a sleep inside chat_completion_stream would be uninterruptible,
because run_one_attempt is not wrapped in a select on the cancellation token.
Each fallback attempt is rebuilt from the unchanged logical request after its candidate model is selected. This is important for mixed-family chains: Qwen, Kimi, DeepSeek, GLM, MiniMax, and future generations cannot inherit one another's template switches or scalar reasoning fields.
Vision inputs are checked against the live Chutes model catalog. If the selected model cannot accept images, the request is delegated to a vision-capable Chutes route. Media generation uses the dedicated Chutes media catalog rather than legacy provider tools.
New media generation returns a versioned MediaArtifact through the tool
protocol. The model receives a compact path receipt, while ACP and the pager
retain kind, MIME type, size, provider/model provenance, cost, and sidecar path.
The pager prepares image and poster previews serially in a background worker,
only while inference is idle. Images are reduced to a 1280-pixel display bound,
individual prepared artifacts are capped at 8 MiB, and the shared CPU-side
cache is capped at 16 MiB. Video playback keeps one visible frame and a bounded
two-frame decode queue; pausing or dropping playback cancels its single-threaded
FFmpeg process. Music and speech use process-owned pause/resume, seek, volume,
duration, and lazy waveform state with native-open fallback. Media-only activity
uses the low-frequency TUI tick instead of the normal animation tick. Legacy
media variants remain readable for session compatibility.
Media HTTP success bodies that are not JSON stream to a temporary file instead of accumulating in memory. The default download limit is 128 MiB with a 512 MiB hard ceiling; error and JSON bodies are capped at 32 MiB. Workspace inputs default to 64 MiB with the same 512 MiB hard ceiling. Final artifact bundles use create-new writes and roll back partial persistence.
Reasoning behavior is resolved by one registry in chutes-build-core. Exact
known model generations map the user-facing mode to their native chat-template
control. Explicit capability menus returned by Chutes or supplied in model
configuration take precedence. Unknown future generations keep explicit
catalog controls but do not inherit guessed behavior from a broad family-name
match.
Auto and fixed-reasoning models expose no effort selector. This prevents a model-specific field from constraining the router or being silently ignored by a model whose reasoning mode cannot be changed. See Model reasoning compatibility.
All sampling clients reuse a process-wide HTTP connection pool. TCP no-delay, bounded connect timeouts, HTTP/2 keepalive, and an HTTP/1 fallback are configured centrally. SSE chunks are parsed and forwarded as they arrive; there is no default application-level replay buffer. Fallback is permitted only before a successful stream begins, so a response never changes model mid-stream.
The main agent and every worker receive the same primary-source rule. Before
answering or making implementation claims about Chutes, they consult both
chutes.ai/docs and
chutes.ai/news. Direct official pages and indexes
are preferred over broad web queries; third-party sources are supporting
evidence only. If official coverage is absent or unavailable, the agent must
label the claim as unverified and separate it from inference. Queries must not
contain credentials, private code, prompts, or repository content.
Account reads start subscription usage, quotas, optional aggregate quota usage, and optional model statistics concurrently. Model statistics are opt-in. If the aggregate quota response is absent or empty, the client reads each quota through the documented per-chute endpoint concurrently and normalizes the results.
The shell preserves every independently enforced usage window and separately
selects the highest consumed percentage for warnings and severity. The pager
shows the monthly and rolling four-hour percentages in the compact status item
when both are available, exposes all windows through /usage, and preserves
each window type even when the API omits a reset timestamp.
The executor owns the main loop and all mutations. Worker subagents can run concurrently in foreground/background modes, wait as a group, and use isolated worktrees. Nesting is bounded to prevent unreviewable recursive swarms.
Outbound provider calls are allowlisted. Telemetry and remote error pipelines are compile-time deadened (the external OTEL stream can never activate — no exporter is constructed), traces export locally, the upstream relay defaults to a closed loopback endpoint, and public commands that depended on upstream cloud services are not registered. See PRIVACY.md.
All Chutes endpoint overrides pass a central URL and DNS policy before use. Without an explicit development opt-in, endpoints must be allowlisted HTTPS hosts with no embedded credentials or custom port, and resolved addresses must not be private, loopback, link-local, multicast, documentation, or other special-use ranges. Ambient credentials are attached only when the final URL is still an official credential destination. Context7 applies the same fail-closed shape and never forwards its optional API key to a custom endpoint.
Automatic permission mode has a narrow no-latency prepass for deterministic read-only shell commands. Project-controlled code, builds, mutations, and network-capable actions go through the classifier or normal permission prompt; classifier timeouts, transport failures, and malformed responses do not become implicit approvals or denials.
Repeated identical tool-call signatures receive a corrective reminder and are
eventually terminated as a silent stationarity outcome. A repeated true
no-op uses a shorter threshold. This prevents unbounded token/tool loops without
fabricating a final assistant answer.
Remote ACP background terminals poll cumulative output into the same local log contract as local tasks and retain the real remote exit status. Session-creation failures clear loading state and remove orphan entries. Fork/rewind filters dead history before copying and transfers only referenced, regular compaction checkpoint files.
This is a fork, not a rewrite: most of the runtime is upstream grok-build
infrastructure, unmodified or lightly adapted. Since 2.0.0 the whole runtime
carries chutes-* names — the total rebrand renamed every crate and module
(upstream synchronization is now frozen; see docs/upstream-sync.md), so this
section documents the intended ownership boundary instead: which layer a
change belongs to, not which names are inherited. It's a map of intent, not a
strict enforcement boundary; treat crate placement as one useful signal among
several, not a guarantee.
Chutes-owned (product identity, provider integration, privacy posture):
chutes-build-core— the domain layer for everything Chutes-specific that isn't a user-facing tool: native routing-string composition and legacy-id mapping, live capability catalog + cache, reasoning-compatibility registry, media catalog/invocation client, Context7 client, credential-endpoint trust policy and SSRF-safe DNS resolution, memory secret-filtering, and wellness nudges.chutes-tools::implementations::chutes— the agent-callable tools backed by the above (media generation/discovery, Context7 lookup, OCR transcription, account usage, isolated browser control). Despite living inside the (upstream) generic tool-runtime crate, this module is Chutes-owned; everything else underimplementations/is upstream-style generic tooling (read_file,bash,grep,web_search, LSP, ...).chutes-voice,chutes-models— Chutes-hosted STT integration and the trimmed Chutes default model catalog, respectively.chutes-secrets— upstream-authored, but per this fork's policy it is now the single canonical secret-detection/redaction layer; Chutes-specific call sites (memory persistence, Context7's outbound guard) and upstream call sites (telemetry/log sanitization) both route through it rather than keeping separate detectors.- Product-identity slices scattered through otherwise-upstream crates:
rebranded welcome screen and API-key entry in
chutes-pager/chutes-shell, plus compile-time product policy inchutes-build-core::productthat disables remote session sharing/search, workspace exposure, feedback/data-retention controls, trace upload, and automatic updates.
Retained upstream infrastructure (the proven agent runtime this fork builds on, not specific to any provider):
chutes-agent— prompt construction, planning, subagent orchestration, goal tracking.chutes-shell,chutes-shell-base— session lifecycle, config resolution/persistence, credential provider, ACP session handling.chutes-sampler,chutes-sampling-types— the HTTP/streaming client and wire types for chat completions (Chutes-specific handling, e.g. legacy auto-id mapping and role-run merging, is a small, explicitly-commented carve-out inside otherwise-generic client code, not a separate Chutes crate).chutes-tool-runtime,chutes-tool-protocol,chutes-tool-types— the tool trait, wire protocol, and shared type definitions any tool (Chutes-owned or not) is built on.chutes-tools(outsideimplementations::chutes) — the generic tool implementations: filesystem, shell, search, LSP, MCP, skills.chutes-pager,chutes-pager-render— the TUI: rendering, input, scrollback, views. Chutes product identity is layered on top (see above), the rendering engine itself is upstream.chutes-workspace— permission model, sandboxing, worktrees.chutes-auth— OAuth/credential machinery in general; the Chutes issuer configuration is a caller-supplied parameter, not a fork of this crate.- Supporting crates upstream factored out after 1.0.0, all retained and
rebranded:
chutes-active-sessions/chutes-foreign-sessions(session registries),chutes-session-events/chutes-session-search(per-session event log and local FTS search),chutes-dirs/chutes-paths(home-dir resolution),chutes-workspace-daemon/chutes-diag-server(workspace-server process lifecycle and in-guest loopback diagnostics),chutes-bundle(subagent bundle cache),chutes-compaction-transcript(compacted-segment markdown), andchutes-fuzzy-file-search(walk + nucleo matcher).chutes-file-utils's oldeventsmodule and the shell'sactive_sessions/storage/search_*modules moved into them.
Ownership is not the whole picture: a Chutes-owned tool is only reachable if an upstream file lists it. Two places do, and the 1.0.0 re-base lost both — every implementation survived and not one tool was callable.
chutes-agent::config— the toolset presets. A tool absent from the preset the session runs under does not exist as far as the model is concerned. The presets also decide which sessions get it: the read-onlyexploreandplantoolsets carry the documentation lookups and nothing heavier.chutes-agent::builder—ensure_chutes_toolscovers agents whose toolset came from a config file rather than a preset, and the lazy pair (take_lazy_chutes_tools/register_lazy_chutes_tools) moves these tools off the per-turn schema list while registering them on the bridge souse_toolcan still call them. Both halves or neither: taking them off the list without registering them deletes the feature silently.
config::tests::chutes_ecosystem_tools_are_in_the_default_toolsets and
legacy_imagine_tools_are_not_advertised guard this. They exist because a tool's
own unit tests pass whether or not anything can reach it — which is how six
thousand lines of working code sat unreachable through a green gate.
The same shape caught the docs: chutes-pager::docs::USER_GUIDE lists which
guide chapters ship, and the fork's two chapters were on disk, unlisted, for the
same reason.
Crates not listed here are unremarkable utility/support code (formatting, markdown rendering, terminal primitives, telemetry plumbing that is disabled by default, etc.) and follow the same rule of thumb: if it encodes a decision specific to Chutes as a provider or to this fork's product identity, it's Chutes-owned; if it would make equal sense in the upstream project, it's retained infrastructure.
The root Cargo.toml is generated and read-only. Dependency ownership belongs
to crate manifests or the generator, which keeps the retained workspace shape
reviewable against upstream.