Skip to content

librefang-runtime is a god-crate (agent_loop 10k LOC, tool_runner 9.7k LOC) — extract subsystems #3710

Description

@houko

Severity

High for maintainability — runtime crate has the same god-crate shape as kernel, and at 77k LOC dwarfs the kernel.

Location

  • crates/librefang-runtime/src/agent_loop.rs10,403 lines
  • crates/librefang-runtime/src/tool_runner.rs9,789 lines
  • crates/librefang-runtime/src/context_engine.rs — 5,116 lines
  • crates/librefang-runtime/src/plugin_manager.rs — 4,341 lines
  • crates/librefang-runtime/src/session_repair.rs — 2,837 lines
  • crates/librefang-runtime/src/model_catalog.rs — 2,758 lines
  • librefang-runtime total: 67 files, 77,313 LOC
  • Inconsistent split with siblings:
    • librefang-runtime-mcp/src/lib.rs — 3,581 lines (a single-file crate)
    • librefang-runtime-oauth/src/lib.rs — ~3 lines (re-export shell)
    • librefang-runtime-wasm/src/lib.rs — ~3 lines (re-export shell)

Finding

The runtime split is incoherent:

  • MCP, OAuth, WASM each get their own crate. OAuth and WASM crates contain ~3 lines of re-exports — pure overhead.
  • Meanwhile, audit, media, apply_patch, docker sandbox, browser automation, prompt injection guards, auth_cooldown, command_lane all live as massive in-tree modules of librefang-runtime.

The result: a dependency graph with two oversized nodes (kernel ≈ 50k LOC, runtime ≈ 77k LOC) and a constellation of tiny shell crates around them. This is monorepo cosmetics, not modularity.

librefang-extensions (395 LOC) was apparently intended as the extension boundary, but the actual extension surface — Docker sandbox, browser, audit, media — is hard-wired into runtime. Plugins cannot be separately versioned, separately compiled, or selectively enabled at build time.

Suggested split (Phase 1 — extract from runtime)

Promote the following to standalone crates so they can be turned off, swapped, or developed in isolation:

New crate Source modules Approx LOC
librefang-runtime-audit audit/, audit-related parts of agent_loop ~2k
librefang-runtime-sandbox-docker docker_sandbox.rs ~1.5k
librefang-runtime-browser browser/ tool subsystem ~3k
librefang-runtime-media media/ subsystem ~2k
librefang-runtime-apply-patch apply_patch tool ~1k

Internal split for the remaining librefang-runtime core:

Module Responsibility
agent_loop/dispatch.rs top-level message → result
agent_loop/tool_call.rs tool invocation envelope
agent_loop/streaming.rs provider streaming aggregation
tool_runner/registry.rs tool registration
tool_runner/<tool_name>.rs one file per tool (currently all in tool_runner.rs)

Phase 2 — collapse useless shell crates

Move the contents of librefang-runtime-oauth and librefang-runtime-wasm (sub-100-LOC re-export shells) back into librefang-runtime as modules. Crate count is not a quality metric.

Why now

  1. Compile times: a one-line change to tool_runner.rs rebuilds 9,789 lines of dependent code in librefang-runtime.
  2. Tool isolation: an audit/security review of "what can a tool plugin do" requires reading agent_loop + tool_runner together, ~20k LOC of intertwined code.
  3. Selective build features: production deployments may not need browser automation or Docker sandbox, but currently can't compile them out.

Acceptance criteria

  • No file in librefang-runtime/src/ exceeds 2,000 LOC
  • cargo build -p librefang-runtime --no-default-features excludes browser/docker/media without compile errors
  • Crate count goes down (collapse oauth/wasm shells), not up arbitrarily
  • Each tool implementation is in its own file under tool_runner/

Related

  • Companion issue: kernel/mod.rs is also a god-file (17,943 LOC). These two should be tackled in coordination since they share the KernelHandle boundary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/runtimeAgent loop, LLM drivers, WASM sandboxdifficulty/hard1 day+, requires understanding multiple cratesenhancementNew feature or requesthas-prA pull request has been linked to this issueseverity/highSignificant functional, security, or performance impact

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions