Skip to content

fix: use task workspace for codebase search - #4

Open
WebMad wants to merge 9 commits into
refactor/1594-code-index-manager-registry-incrementalfrom
fix/codebase-search-task-workspace
Open

WebMad wants to merge 9 commits into
refactor/1594-code-index-manager-registry-incrementalfrom
fix/codebase-search-task-workspace

Conversation

@WebMad

@WebMad WebMad commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Pass the already resolved task workspace to the code index manager registry instead of allowing active-editor workspace selection.
  • Keep the existing fallback for empty/whitespace task working directories.
  • Add regression coverage using the real registry and mocked managers, verifying root B is searched while the active editor belongs to root A, query/path forwarding, result output, fallback selection, and missing workspace handling.

Stacked PR

Depends on Zoo-Code-Org#1622.
Branched from its exact head: 8637e48.
This PR targets the parent branch in WebMad/Zoo-Code so the diff contains only this bugfix and its tests, not the parent refactor. After the parent merges, this change needs an upstream-targeted PR (retarget/recreate as appropriate; the current fork PR cannot directly change its base repository). No changes to PR Zoo-Code-Org#1622 or Zoo-Code-Org#1628 and no workspace-scopes refactoring.

Verification

  • Observed the regression test fail before the production change: the task-root manager received zero search calls.
  • After the one-line fix: focused regression and registry suites passed (15 tests).
  • Relevant code-index suite plus regression tests: 27 files, 619 tests passed.
  • Changed-file ESLint with prune-suppressions and max-warnings=0 passed; suppression data unchanged.
  • Prettier completed and git diff whitespace check passed.
  • Extension TypeScript check passed.
  • Normal commit/push hooks passed repository lint and type-check tasks (11 tasks each, 10 cached).

Non-blocking environment warnings: Node v24.7.0 differs from required 22.23.1; Prettier reports an existing unknown ignore option. Full repository tests and extension-host E2E were not run.

@WebMad
WebMad force-pushed the fix/codebase-search-task-workspace branch from 8c5f6f3 to 8dcc696 Compare September 13, 2026 12:36
…lidateToolUse (Zoo-Code-Org#1625)

* fix(delegation): read task-local mode in getEnvironmentDetails and validateToolUse

* test(delegation): cover custom-tool execute context and state fallback
Co-authored-by: Roomote <roomote@roomote.dev>
@edelauna
edelauna force-pushed the refactor/1594-code-index-manager-registry-incremental branch from 47cea56 to 59135ca Compare September 16, 2026 01:49
WebMad and others added 3 commits September 16, 2026 02:14
* refactor(code-index): extract manager registry

* test(task): mock code index registry in task suite

* test(code-index): remove redundant context casts

* refactor(code-index): apply registry review feedback

* fix(code-index): dispose registry on deactivate; drop dead registerCommands call

* fix(coderabbit): limit neighbouring review scope creep

---------

Co-authored-by: Elliott de Launay <edelauna@gmail.com>
Co-authored-by: edelauna <54631123+edelauna@users.noreply.github.com>
…g#1649)

* fix(ci): preserve coverage cache for verifier changes

* fix(ci): isolate coverage input mutation check

* fix(ci): avoid self-mutating coverage verifier

* fix(ci): isolate coverage hash probes

* fix(ci): validate cache before publication

---------

Co-authored-by: Roomote <roomote@roomote.dev>
* fix(deepseek): enable images for current Flash models

* test(deepseek): cover vision alias defaults

---------

Co-authored-by: Roomote <roomote@roomote.dev>
Co-authored-by: edelauna <54631123+edelauna@users.noreply.github.com>
zoomote Bot and others added 3 commits September 17, 2026 01:36
…or domains containing "x.ai" (Zoo-Code-Org#1484)

* fix: _isGrokXAI false-positive substring match breaks token usage for domains containing 'x.ai'

Fixes Zoo-Code-Org#1483

The _isGrokXAI() method used urlHost.includes('x.ai') which matches any
domain containing 'x.ai' as a substring (e.g. box.ai, fox.ai, max.ai).
This false-positive causes stream_options:{include_usage:true} to be
omitted, so the API never returns usage data and the token bar shows 0.

Fix: Use exact host match (api.x.ai) or subdomain match (*.x.ai) instead
of substring includes.

Added tests for false-positive scenarios and valid x.ai domain detection.

AI-assisted: developed with Zoo Code/GLM-5.2, reviewed and verified by the contributor.

* Address CodeRabbit review: use URL.hostname, bracket notation, remove changeset

* test: add O3+Grok stream_options coverage for handleO3FamilyMessage

---------

Co-authored-by: Elliott de Launay <edelauna@gmail.com>
…-Code-Org#1505)

* initial fix for issues Zoo-Code-Org#1240 and Zoo-Code-Org#505

* 1st round of fixes

* fixed comments

* increase test coverage

* revert: remove Windows shell invocation from stryker-diff

* fix: address CodeRabbit review on tool-policy prompt unification

* fix(test): correct apiModelId in generateSystemPrompt state mock

* drop use_mcp_tool from policy when no MCP tool is permitted

* code hardening

* bound model fetch with timeout, typed provider state test doubles

* cover preview model fetch timeout path with tests

* pin completion-time history save ordering with unit tests

* poll history length in restart e2e to tolerate atomic write window

* share one model-info snapshot per request between prompt and tools

* resolve provider state once before the MCP wait

getSystemPrompt read provider state twice: once for the MCP gate and
again after the hub wait. When the caller threaded no state, the two
reads could observe different snapshots. Hoist the fallback resolution
to the top of the call so the prompt and the tool guidance share one
snapshot on the unthreaded path.

Type the test harness getSystemPrompt signature with ProviderState and
ModelInfo instead of unknown, and align the affected test title and
comments with the single-read behavior.

* cover the undefined provider state path in the system prompt tests

The provider state read can resolve to nothing even while the provider
reference stays alive. Add a test for that case so the system prompt
call keeps receiving undefined disabledTools instead of failing.

* reuse one model-info snapshot per request and honor cancellation

Request construction re-read model metadata twice after the streaming
turn's bounded fetch; thread the captured snapshot through
attemptApiRequest so prompt assembly, context sizing, and tool arrays
agree on a single view, resolving the fallback only when no snapshot
was supplied.

A cancellation that lands during a request's waits now stops the
request before any tool array, abort controller, or provider call is
issued for it.

* pin the retry count the request seam receives

The empty-response retry test now asserts that the retry iteration
reaches attemptApiRequest with its own incremented attempt count
(second call, retryAttempt 1), instead of only checking the resulting
conversation history.

* refactor(task): require callers to thread provider state into system prompt build

getSystemPrompt no longer falls back to re-reading provider state; the
provider-state snapshot parameter is now required. An explicit undefined
declares that the caller's own read came back empty because the provider was
already gone, and the prompt then resolves from defaults. The prompt and the
request's runtime tool array now resolve from a single snapshot by
construction rather than by caller convention.

Behavior is unchanged on all reachable paths. Task.spec.ts grows from 128 to
129 tests to cover the required-parameter contract.

* fix(api): cancel abandoned model-metadata waits via AbortSignal

The bounded metadata waits in Task.safeEnsureModelFetched and the system
prompt preview cleared their timer but left the handler-side promise
waiting on the model-catalog fetch. The ApiHandler contract now threads
an optional AbortSignal through ensureModelFetched(): RouterProvider
settles the waiter with a rejection when the signal aborts, so an
abandoned or cancelled caller detaches instead of parking a promise on
the shared fetch (which keeps running for other waiters and still
populates the cache, by design). The task aborts its waiter both when
the 5s bound expires and when cancelCurrentRequest runs (cancel and
dispose paths); the preview aborts at its bound and on completion.

The task-lifecycle doc's table padding was also reconciled with the
PR base: the remaining diff there is now only prettier's column
re-padding, which the repo's own pre-commit formatter enforces.

* test(api): cover abort-signal detach paths and thread request model snapshot

Mutation-diff gate kills (PR Zoo-Code-Org#1505):
- zoo-gateway: signal-aware ensureModelFetched tests for the fetch-wins
  and fetch-rejects branches (block/CallExpression NoCoverage), an
  addEventListener spy pinning the { once: true } options, and paired
  add/remove listener assertions pinning the abort event name on both
  detach sites (StringLiteral mutants).
- Task: ownership-guard tests for metadataFetchAbortController (clear on
  own completion, leave a replaced controller in place).
- generateSystemPrompt: signal-capture tests pinning the timeout-bound
  and finally-block controller.abort() detaches (CallExpression mutants).

CodeRabbit: thread the request model-info snapshot into
buildCleanConversationHistory so preserveReasoning resolves from the same
per-request snapshot as the prompt and tool arrays, plus regression tests.

No Stryker-disable directives were needed; all 14 mutants are killed
behaviorally.

* Apply disabled and excluded tool policy to dynamic MCP declarations

Gate dynamic MCP tool declarations through the shared effective-tool-policy predicate (alias-resolved disabled/excluded settings). Add filter-layer and builder-layer tests covering disabled, enabled, alias, and Gemini allowlist cases. Addresses maintainer review feedback.

* Forward request options through API retry recursion

Recursive attemptApiRequest retries dropped the options argument, losing caller-provided model info on retried attempts. Forward it at all three retry sites with regression tests.

* Forward derived model snapshot through API retry recursion

when the caller omitted requestModelInfo, each retry hop re-derived the model snapshot; the first hop's snapshot is now threaded into the recursive calls (caller-supplied values keep reference identity, no caller mutation), with a regression test pinning single derivation and snapshot arrival.

* Tighten build-tools test assertions and provider double

assert the MCP tool name is retained in Gemini-declared tool lists; replace double type assertions in the provider test double with a precisely-typed local shape.

* Use the request model snapshot for context-window recovery math

After a context-window overflow the recovery handler re-fetched model metadata, so truncation could run against a newer snapshot than the retry it feeds — history could be over-truncated. The pinned request snapshot is now passed into the handler and the stale re-fetch removed, with a regression test pinning one derivation per request.

* Stop manual condensation when the task is cancelled

condenseContext awaited the best-effort model metadata fetch and then
continued even when the task had already been cancelled or abandoned, so
a summarization request could still be issued for a task that was going
away. Check for cancellation after the fetch and return early.

Add regression tests for the cancelled and abandoned cases.

* Recheck cancellation before summarizing and rewriting history

condenseContext could still issue a summarization request, and rewrite
the persisted conversation history, when the task was cancelled while the
system prompt was being built or while summarization was in flight. Check
for cancellation after each of those awaits and return early.

Add regression tests that cancel at both points and assert that neither
summarizeConversation nor overwriteApiConversationHistory runs.

* Make the first cancellation checkpoint observable to tests

The second cancellation check in condenseContext also skips summarization, so
falsifying the first one left every test passing. The mutation gate caught
this: two mutants on the first check survived because nothing observed the
work between the two checks.

Assert that a task cancelled at the first checkpoint never builds the system
prompt, which is the behavior that check exists to guarantee.

* Correct a rationale comment in the cancellation tests

The comment claimed that skipping summarization is also achieved by the
checks placed after the prompt and summarize awaits. Only the check after
the prompt await can hide a missing first check: the later one runs once
summarization has already been called.

* Narrow the change set to the tool-policy work and its regression tests

Remove the task-lifecycle and history-persistence work from this
branch: the metadata-fetch timeout bound, the waiter-detach signal
plumbing, and the post-summarization cancellation guard revert to
main; that work is preserved outside the branch for a follow-up.

What remains is the prompt/tool-policy change for Zoo-Code-Org#1240 and Zoo-Code-Org#505,
plus two fixes the review asked for. A new builder-layer test pins
that modelInfo.excludedTools excluding use_mcp_tool removes the
dynamic mcp--* declarations from the sent tools, like a user-level
disable. And a disabled or excluded attempt_completion now honors
the tool allowlist end to end: it leaves the effective policy set
and the callable allowlist, and execution rejects the call with the
standard validation-error tool_result instead of completing the
task.

* Remove dead export, untriggerable timer guard, and duplicated prompt-spec coverage

Unexport hasAnyMcpResources (no external callers), make the skills section policy parameter required (the sole caller always passes one), and make the model-metadata timeout clear unconditional (the handle is always assigned). Inline the single-use SystemPromptRequest alias and drop stale comment narration. Delete prompt-spec tests that duplicated sections.spec coverage, moving the two assertions that carried unique mutation kills (empty edit-restriction description branch, terminal-output fallback tail) into the surviving sections.spec tests.

* fix(prompts): enforce effective tool policy guidance

* fix(task): restore caller-layer cancellation for model-metadata fetches

Model-metadata fetches (ensureModelFetched) could outlive the request that
started them: a canceled task or a timed-out prompt preview left the fetch
awaited, with no signal to abort it and no check before its result was
persisted. This restores cancellation handling at the caller layer:

- The bounded preview timeout now aborts the metadata fetch it races,
  instead of leaving the fetcher's promise dangling after the timeout.
- Condense paths now check abort/abandoned state before starting and
  before persisting summarized history, with an added guard before
  summarization so a canceled task cannot write summarize output.
- cancelCurrentRequest aborts the in-flight metadata fetch and detaches
  waiters, so stale promises no longer retain task state.
- Adds a standalone edit-tool coverage test for prompt-section rendering
  (coverage gap: the tool was only exercised via combined fixtures).

Related to Zoo-Code-Org#505, Zoo-Code-Org#1240.

* fix(task): set disposal state before cancelling metadata waits

Task disposal now marks the task as aborted before it cancels the
prompts that in-flight metadata fetches are waiting on. Marking the
disposal synchronously means any model request that could start after
cleanup begins already observes an aborted task, so no request starts
after disposal.

Adds a regression test for disposal racing a metadata wait, and an
assertion that getModels is not called when the signal is already
aborted.

* chore(ci): bump coverage-contract baseline for branch-added policy module

Coverage source population moved from 469 records / 30229 lines to 470 records / 30324 lines. The delta is attributable to src/core/prompts/tools/effective-tool-policy.ts, a production module added by this change; the remaining line growth comes from branch modifications to existing instrumented sources. No source files were removed; verified by regenerating all coverage lanes locally.

* test: mock CodeIndexManagerRegistry in build-tools.spec (upstream Zoo-Code-Org#1622 merge parity)

* fix: describe codebase_search as semantic search; anchor read_file in build-tools allowlist test

Address CodeRabbit review findings on the capabilities prompt and the
build-tools test suite:

- The codebase_search capability clause said "view source code
  definitions", wording inherited from the removed
  list_code_definition_names tool; it now reads "semantically search
  the codebase", matching the tool contract, and the
  generateSystemPrompt.spec.ts assertions quoting the old phrase are
  re-pointed.
- The disabled-tools test asserted only tool absence, so an empty
  allowlist would pass; it now anchors on read_file being present,
  mirroring the sibling test.

---------

Co-authored-by: Roomote <roomote@roomote.dev>
@WebMad
WebMad force-pushed the fix/codebase-search-task-workspace branch 2 times, most recently from 01a892c to 9b8b9f4 Compare September 18, 2026 20:09
@WebMad
WebMad force-pushed the fix/codebase-search-task-workspace branch from 9b8b9f4 to 3e09b14 Compare September 20, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants