* Deferred (lazy) tool loading: tool_search + auto threshold for large MCP tool sets
Adds deferred tool loading so a large MCP tool set no longer sends every tool's full JSON schema each turn. When the number of visible MCP tools crosses a threshold (config tools.deferThreshold, default 10; 0 disables), their schemas are withheld and advertised compactly in a per-turn system-reminder; the model pulls a tool's full schema on demand via a new tool_search tool. Strictly additive: below the threshold behaviour is byte-identical to today. No new module dependencies.
- Eligibility: MCP tools opt in via an optional Deferred() bool interface (tools.IsDeferred); built-ins stay eager. No change to the core Tool interface.
- Formatting (internal/tools/deferred.go): compact one-liners wrapped in a <system-reminder> by BuildDeferredReminder; server label via MCPServerName().
- tool_search (internal/tools/tool_search.go): SideEffectNone/PermissionAllow/AdvertiseInAuto; select:Name1,Name2 (exact) or keyword (ranked); returns full schemas and signals the loop via Meta["load_tools"]. Operator-filter-aware (never lists tools hidden by --enabled-tools/--disabled-tools).
- Agent loop: partitionTools is the single source of truth; eligible counts only ToolVisible deferred tools; Meta["load_tools"] lifts to ToolResult.LoadedTools and unions into a per-run loaded-set advertised next turn. Reminder appended only to the per-turn request copy (never persisted), including both reactive-compaction retry paths. tool_search stays reachable when deferral is active (exempt from the EnabledTools allowlist).
- Config + wiring: tools.deferThreshold (default 10; 0 disables; negative rejected); tool_search registered and DeferThreshold threaded in exec and TUI, gated on the same visible-deferred count the loop uses.
Recreated on top of current main; resolves the SideEffectNone clash with #146 (escalate_model). Supersedes #147.
* deferred-tools: activate deferral only when tool_search is runnable; drop dead deferredTools()
Addresses #148 review:
- partitionTools gates 'active' on a registered, non-disabled, mode-advertised
tool_search (mirrors the executeToolCall dispatch gate). When the loader is
unavailable (explicitly disabled, missing, or not advertised e.g. spec-draft),
fall back to the eager/inactive path instead of hiding deferred tools behind a
loader the model can never call (the dead-end).
- Flip TestDisabledToolSearch... to assert the eager fallback; register a real
tool_search in the active-path tests that previously relied on activation
without a usable loader.
- Remove unused toolSearchTool.deferredTools().
* deferred-tools: disable deferral in exec when tool_search disabled; drop unused toolDefinitions shim
Further #148 review:
- exec computes one effective DeferThreshold, forced to 0 when tool_search is in
--disabled-tools, and feeds it to both registerToolSearchIfEligible and
agent.Options.DeferThreshold — so the registration gate and the loop partition
gate agree, and a disabled loader never enables deferral.
- Remove the unused toolDefinitions shim (golangci-lint unused; no callers).
* CLI wiring: skills/zeroline commands, --mode presets, exec checkpoints, sandbox --effective, sessions rewind
Final module of the runtime-core split. Wires the new runtime features into the cli, PRESERVING main's merged specialist cli (the source branch predates specialist and drops it; this keeps it via a 3-way merge from the common base, adding the reskin features as ours/theirs-only changes).
- skills command (internal/cli/skills.go) listing internal/skills; zeroline-skin TUI launcher (internal/cli/zeroline.go) via runInteractiveTUIWithSkin.
- exec: --mode presets (smart/deep/fast/large/precise) via applyExecMode; model-registry alias resolution + deprecation/effort notices; ContextWindow sizing (modelContextWindow); before-mutation checkpoint recording in OnToolCall; enhanced tool-result output (ChangedFiles/Redacted/Display); permission-mode validation fix.
- sandbox policy --effective (resolved guards); sessions rewind (executes the rewind plan); interactive TUI defaults to Ask mode (advertises write/edit/bash + gates via prompts).
- internal/streamjson: EventCheckpoint/EventRestore + CheckpointInfo for structured checkpoint output.
Specialist cli preserved (specialist.go + flags + runtime + tests all intact). build/vet/-race/full-suite + GOOS=windows build green; no new deps.
* Address #128 review: make sessions rewind reachable + honor --exclude-target, mode/notice/redaction fixes
- sessions: add "rewind" to the parser whitelist (isSessionsCommand) — it was wired in dispatch + help but parseSessionsArgs rejected it as 'unknown sessions command', so it was unreachable. Regression test TestRunSessionsRewindIsReachableAndHonorsExcludeTarget.
- sessions rewind: honor --exclude-target — ApplyRewind keeps THROUGH a sequence, so when KeepTarget is false apply through TargetSequence-1, matching rewind-plan (previously rewind always applied TO the target, disagreeing with the plan). The test asserts --exclude-target keeps fewer events than the default.
- sessions rewind: redact the session id in the success + not-found messages (consistent with every other human-readable path).
- exec_parse: reject empty inline --mode= via requiredInlineFlagValue (was a silent no-op running defaults).
- exec: notice writes (model-deprecation + reasoning-effort advisories) now treat write failures as exitCrash, consistent with the rest of the command.
build/vet/-race/full-suite + GOOS=windows build green.
---------
Co-authored-by: KRATOS <[email protected]>