* fix(ollama): resolve web search secret refs
* fix(ollama): preserve blocked search secret refs
* fix(ollama): share web search credential policy
* fix(ollama): resolve web search secret refs via shared resolver
Route configured models.providers.ollama.apiKey resolution through the
existing shared resolveWebSearchProviderCredential helper so env-backed
SecretRefs resolve for web search, and resolve the ambient OLLAMA_API_KEY
independently of the configured selected-host key so mixed setups still
reach the Ollama Cloud fallback after both selected-host attempts fail
(regression fixed at web-search-provider.ts:195).
Drop the two optional plugin-SDK resolver hooks (provider normalization
and unavailable-configured-ref callback) added earlier: the fix does not
depend on them, so the shared resolver and its generated plugin-SDK
baseline stay identical to main and no new plugin-SDK contract surface is
introduced. Ollama applies its own non-secret-marker filter locally on
the resolver output instead.
Add a mixed-credential regression test (configured host key plus a
distinct ambient OLLAMA_API_KEY reaching the cloud fallback) and drop the
tests for the removed fail-closed-throw behavior.
* fix(ollama): fail closed on unavailable web search refs
* fix(web-search): resolve env shorthand secret refs
* docs(changelog): note Ollama web-search SecretRef fix
* chore(changelog): remove release-owned entry
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(session): preserve reset message payloads
Use the raw command body when it directly matches a reset trigger so code, logs, bracketed text, and line breaks reach the new session intact. Keep structural normalization only for prefixed messages that require it to match.
* fix(session): anchor reset payloads to original input
* fix(session): anchor reset parsing to inbound projections
* fix(session): keep reset result type internal
* test(qa): prove reset payload preservation
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(edit): preserve bytes outside fuzzy-match span on matched lines
When an edit tool call falls back to fuzzy matching (e.g. plain space vs
NBSP, straight quotes vs smart quotes), the entire overlapped line was
rebuilt from the NFKC-normalized copy, silently destroying unrelated
bytes on that line — fullwidth punctuation, halfwidth katakana, em-dashes,
and other Unicode characters outside the edited span.
Root cause:
- applyEdits() set replacementBaseContent to
normalizeForFuzzyMatch(normalizedContent) when any edit needed fuzzy
matching.
- applyReplacementsPreservingUnchangedLines then emitted untouched lines
from the original content but rebuilt touched lines wholesale from the
normalized base, applying NFKC folding to bytes the edit never
referenced.
Fix:
- normalizeForFuzzyMatch now optionally returns an offset map that
translates every normalized position back to the original text.
- fuzzyFindText uses this map to translate match indices from fuzzy-
normalized coordinates to original-content coordinates.
- applyEdits keeps replacementBaseContent as the original (LF-normalized)
content and uses direct applyReplacements instead of the line-preserving
variant. Touch-untouched line distinction is no longer needed because
replacements splice at byte granularity in the original content.
Fixes#116459
* fix(edit): map fuzzy spans to stable source boundaries
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>