Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(agent-manager): pre-warm worktrees to speed up session creation - #14050

Open
marius-kilocode wants to merge 5 commits into
mainfrom
optimize-worktree-creation-latency
Open

feat(agent-manager): pre-warm worktrees to speed up session creation#14050
marius-kilocode wants to merge 5 commits into
mainfrom
optimize-worktree-creation-latency

Conversation

@marius-kilocode

Copy link
Copy Markdown
Collaborator

What Problem This Solves

Creating a new Agent Manager worktree blocks on git worktree add, which checks out every tracked file. On the Kilo repository (about 10,000 tracked files) that checkout takes about 2.1 s, and it scales with repository size, so large repositories pay many seconds before a new session is usable.

Why This Change Was Made

Register a detached worktree in the background and claim it for a new session with a cheap ref update instead of running a second full checkout at creation time. The behavior is scoped to the new "Pre-warm worktrees" Agent Manager setting (kilo-code.new.agentManager.worktreePool), enabled by default. Per-phase creation timing was added so the remaining cost is measurable. The change also fixes a claim path that could reset an existing local branch whose name matched a prepared worktree directory, and raises the fallback git worktree add worker count.

User Impact

  • Warm sessions start several times faster. A claim miss falls back to the previous creation path, so behavior and latency are unchanged when no worktree is ready.
  • Small repositories behave the same as before.
  • Pre-warming can be turned off in Agent Manager settings, which stops preparation and removes idle prepared worktrees.
  • Pre-warming uses the disk space of one extra checkout per open project.

Evidence

Creation timing measured through WorktreeManager.createWorktree on a local clone, median of 3 runs, macOS/APFS, no setup script.

Repository Pre-warm off No warm worktree Warm worktree claimed
About 10,200 tracked files 2167 ms 2126 ms 272 ms
120 tracked files 323 ms 319 ms 340 ms

Raw git on the large clone: full git worktree add about 2.1 s, registration only about 75 ms, a ref-only claim about 70 ms, and a cold-index git status about 400 ms. Raising the fallback worker count from 2 to 4 saves about 150 ms.

Limitations: these are worktree creation timings, not end-to-end time to first token. The model provider still dominates time to first token, and a configured setup script still runs after creation. Measurements were taken outside VS Code, so file watcher interaction is not included.

Register a detached worktree in the background and claim it for a new
session instead of running a full worktree checkout at creation time.
Add per-phase creation timing and the "Pre-warm worktrees" Agent Manager
setting, enabled by default.

Also fix a claim path that could reset an existing branch whose name
matched a pooled worktree directory, and raise the worktree add worker
count for the fallback path.
Comment thread packages/kilo-vscode/src/agent-manager/worktree-pool.ts Outdated
Comment thread packages/kilo-vscode/src/agent-manager/worktree-pool.ts
Comment thread packages/kilo-vscode/webview-ui/src/components/settings/Settings.tsx Outdated
Comment thread packages/kilo-vscode/tests/unit/worktree-pool.test.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 4 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts 986 prepareDirectory creates snapshot state that discard/failure teardown paths never remove
packages/opencode/src/kilocode/snapshot/prepare.ts 32 Prepared-but-never-tracked snapshot repo can never be cleaned up
packages/opencode/test/kilocode/snapshot-prepare.test.ts 201 Polls only for alternates, then asserts seed-objects gone - flaky

SUGGESTION

File Line Issue
packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts 1010 Awaiting unbounded preparation.pending delays failure and cleanup
Files Reviewed (20 files)
  • packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts
  • packages/kilo-vscode/src/agent-manager/provider-lifecycle.ts
  • packages/kilo-vscode/src/agent-manager/provider-multi-version.ts
  • packages/kilo-vscode/src/agent-manager/tool-start.ts
  • packages/kilo-vscode/src/agent-manager/creation-plan.ts
  • packages/kilo-vscode/src/agent-manager/mcp-warmup.ts
  • packages/opencode/src/kilocode/snapshot/prepare.ts
  • packages/opencode/src/snapshot/index.ts
  • packages/opencode/src/kilocode/server/httpapi/groups/kilocode.ts
  • packages/opencode/src/kilocode/server/httpapi/handlers/kilocode.ts
  • packages/opencode/test/kilocode/snapshot-prepare.test.ts
  • Updated kilo-vscode unit tests and generated SDK

Fix these issues in Kilo Cloud

Previous Review Summaries (2 snapshots, latest commit b5ab644)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit b5ab644)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (3 files)
  • packages/kilo-vscode/src/agent-manager/worktree-pool.ts
  • packages/kilo-vscode/tests/unit/worktree-pool.test.ts
  • packages/kilo-vscode/webview-ui/src/components/settings/Settings.tsx

All four findings from the previous review were re-verified against b5ab644 and are resolved: the warm-up resolves the start point before taking the git lock, adopt trusts the worktree's real HEAD over persisted metadata, the pre-warm toggle uses applySetting for immediate effect, and the fixed test sleeps were removed.

Previous review (commit f90f52a)

Status: 4 Issues Found | Recommendation: Address before merge

Fix these issues in Kilo Cloud

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 3
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/src/agent-manager/worktree-pool.ts 82 Warm-up holds the shared per-repo git lock across a possible git fetch (cold fetch cache), which can stall user-initiated worktree operations and contradicts the documented cache-only start contract.

SUGGESTION

File Line Issue
packages/kilo-vscode/src/agent-manager/worktree-pool.ts 195 Exact claim creates the branch from HEAD rather than the matched oid; an adopted slot with stale metadata can yield the wrong base commit.
packages/kilo-vscode/webview-ui/src/components/settings/Settings.tsx 188 Uses updateSetting, so toggling pre-warm off does not stop the pool until Save; applySetting is the pattern for app-level gates.
packages/kilo-vscode/tests/unit/worktree-pool.test.ts 163 Fixed setTimeout sleeps make the pool tests timing-dependent and potentially flaky on loaded CI.
Files Reviewed (43 files)
  • .changeset/worktree-pool-prewarm.md
  • packages/kilo-vscode/package.json
  • packages/kilo-vscode/src/KiloProvider.ts
  • packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts
  • packages/kilo-vscode/src/agent-manager/WorktreeManager.ts
  • packages/kilo-vscode/src/agent-manager/creation-timing.ts
  • packages/kilo-vscode/src/agent-manager/host.ts
  • packages/kilo-vscode/src/agent-manager/project/context.ts
  • packages/kilo-vscode/src/agent-manager/project/init.ts
  • packages/kilo-vscode/src/agent-manager/project/wiring.ts
  • packages/kilo-vscode/src/agent-manager/provider-lifecycle.ts
  • packages/kilo-vscode/src/agent-manager/provider-multi-version.ts
  • packages/kilo-vscode/src/agent-manager/tool-start.ts
  • packages/kilo-vscode/src/agent-manager/vscode-host.ts
  • packages/kilo-vscode/src/agent-manager/worktree-pool.ts
  • packages/kilo-vscode/src/kilo-provider/config-snapshot.ts
  • packages/kilo-vscode/tests/unit/agent-manager-tool-start.test.ts
  • packages/kilo-vscode/tests/unit/creation-timing.test.ts
  • packages/kilo-vscode/tests/unit/provider-multi-version.test.ts
  • packages/kilo-vscode/tests/unit/worktree-manager.test.ts
  • packages/kilo-vscode/tests/unit/worktree-pool.test.ts
  • packages/kilo-vscode/webview-ui/agent-manager/i18n/*.ts (21 locale files)
  • packages/kilo-vscode/webview-ui/src/components/settings/Settings.tsx

Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

…ed slots

Resolve the base ref and its commit before taking the shared git lock so a
cold fetch cache never stalls user worktree operations. When adopting a
leftover slot, use the worktree's real HEAD instead of persisted metadata.
Apply the pre-warm toggle immediately instead of on Save, and drop fixed
sleeps from the pool tests.
const preparation = { pending: Promise.resolve() }
try {
const metadata = await sandboxSessionMetadata(this.connectionService.sandboxPreference, client, worktreePath)
preparation.pending = prepareDirectory(client, worktreePath).catch((err) =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: prepareDirectory is started but never awaited on the success path, and it creates a snapshot repository via the new snapshot.prepare endpoint. The teardown paths that can run after a worktree session is created - discardWorktree (multi-version sandbox reconciliation failure), the !session cleanup in createLifecycleWorktree, and tool-start's cleanupWorktree - never call kilocode.removeSnapshot (the only caller is deleteLifecycleWorktree). A failed or discarded worktree can therefore leave an orphaned snapshot repo under Global.Path.data/snapshot/<project>/<hash> that is never removed, and because the promise is not joined, teardown can race an in-flight snapshot.prepare that recreates the directory after cleanup. Consider awaiting/serializing preparation before teardown and ensuring every discard path removes the snapshot.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

timing?.mark("session")
return session
} catch (error) {
await preparation.pending

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Awaiting preparation.pending here gates the user-visible error and the caller's worktree cleanup on Promise.allSettled, which has no timeout or cancellation. A slow or hung snapshot.prepare / mcp.status (MCP connect, large-repo seeding) now delays the failure message and leaves the worktree in place, whereas the error previously surfaced immediately. Consider bounding the wait (for example Promise.race with a timeout) or not blocking error reporting on background preparation.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"--format=%(refname)",
"refs/kilo/snapshots",
])
if (refs.code === 0 && !refs.text.trim()) return false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: When the kilo-prepared marker exists but there are no refs/kilo/snapshots, this returns false and leaves the marker plus the seed artifacts written by prepare (seed-objects/ and objects/info/alternates) in place. KiloSnapshotCleanup.pending (packages/opencode/src/kilocode/snapshot/cleanup.ts:126) treats exactly seed-objects/alternates as materialization-in-progress, so KiloSnapshotCleanup.remove then fails with snapshot repository materialization is still pending (cleanup.ts:192). A worktree that is prepared but never tracked - for example a session created and then deleted before the first prompt, or a discarded multi-version worktree - can therefore never have its snapshot repository removed. Consider distinguishing prepared from materialization pending (drop the marker and let KiloSnapshotMaterialize.run clean the seed artifacts, or teach cleanup to recognize the prepared state).


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"5 seconds",
)
yield* wait
expect(existsSync(staging)).toBe(false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: wait only polls for objects/info/alternates to disappear, but KiloSnapshotMaterialize.run removes alternates and then seed-objects in sequence (materialize.ts:222-225). The immediate expect(existsSync(staging)).toBe(false) can observe the window between the two removals and flake. Poll for staging too, or use a single predicate that requires both paths to be gone.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant