Skip to content

Commit ff20416

Browse files
Zeph Gillenclaude
andcommitted
Merge upstream v3.68.0 into local/daily-driver
Sync the fork from its v3.62.0-era point (merge-base 8c3ae1e) to upstream v3.68.0 — 63 commits, 337 files. Conflict resolution: Provider cluster (all from upstream's Claude Sonnet 5, Zoo-Code-Org#778): - anthropic.ts: keep both `case claude-fable-5` + `case claude-sonnet-5` in the two cache-control switches. - Reshape Sonnet 5 from upstream's budget/binary shape to the fork's effort-shape (supportsReasoningEffort incl. "max", requiredReasoningEffort, drop supportsReasoningBudget) across the Anthropic + Vertex type registries and the openrouter + requesty fetcher overrides. Without this, getAnthropicReasoning routes Sonnet 5 to the legacy budget branch, which 400s (it is adaptive-only). - Bedrock already routes sonnet-5 via the shared isAdaptiveThinkingModel guard. - Updated the Sonnet 5 tests (anthropic / anthropic-vertex / requesty specs, incl. the requesty getModels mock) to assert the effort-shape rather than upstream's budget/binary, per FORK.md convention. Mechanical: version -> 3.68.0, announcement id, README/CHANGELOG/i18n highlights. openai-error-handler shim removed upstream (Zoo-Code-Org#767); all callers use error-handler. Verified: pnpm check-types clean (@roo-code/types + src); all Sonnet 5 provider/fetcher specs green; the FORK.md 22-failure baseline (reasoning + model-params specs) is unchanged. Remaining suite failures are environment-only (tree-sitter WASM grammars + dist assets not built — the sandbox has no network for the ripgrep/grammar postinstall or the VSIX bundle). A full `pnpm install && pnpm build && pnpm vsix --force` is still required in a networked environment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 parents 92b09c0 + 1833f5a commit ff20416

338 files changed

Lines changed: 21913 additions & 5652 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"zoo-code": patch
3+
---
4+
5+
Fix Anthropic provider silently replacing a custom/unrecognized `apiModelId` with the hardcoded default model.
6+
7+
`AnthropicHandler.getModel()` coerced any `apiModelId` not present in the static `anthropicModels` table down to `anthropicDefaultModelId` ("claude-sonnet-4-5"), and that coerced id was what actually got sent as `model` in the API request -- silently ignoring a user-configured custom model name (e.g. a custom Anthropic-compatible deployment or proxy). This produced confusing "model does not exist" errors for the default model instead of the model the user actually selected (#418).
8+
9+
The same fallback also affected capability lookups used to build the `thinking` request parameter: an unrecognized id fell back to the default model's info, which can be from an older model generation with a different API contract, causing the request to use the legacy `thinking: {type: "enabled", budget_tokens}` shape and get rejected with a 400 by models that require `{type: "adaptive"}`.
10+
11+
The model id sent to the API now always honors a user-configured `apiModelId`. For unrecognized values, capabilities are best-effort guessed by matching known model-family substrings (mirroring the existing `BedrockHandler.guessModelInfoFromId` heuristic) instead of defaulting to `anthropicDefaultModelId`'s info.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
"zoo-code": patch
3+
---
4+
5+
Fix LiteLLM provider cache key collision, credential priority, and model-selection fallback to non-existent default.
6+
7+
Two bugs are addressed:
8+
9+
1. **Cache key collision**: All URL-scoped providers (LiteLLM, Ollama, LM Studio, Poe, DeepSeek,
10+
Requesty) previously shared one cache entry keyed only on the provider name. Switching between
11+
profiles backed by different servers silently served the wrong model list and the stale list
12+
persisted across VS Code restarts via the disk cache. Fixed with a compound cache key:
13+
URL-scoped providers use `provider:baseUrl`; key-scoped providers (LiteLLM, Poe, Requesty)
14+
additionally include a short, irreversible discriminator derived from the API key
15+
(`provider:baseUrl:<discriminator>`) so that two different API keys on the same server never share
16+
a cache entry (relevant when the server enforces per-key model allowlists). Both the discriminator
17+
and the on-disk filename digest are derived via truncated PBKDF2 so neither can be reversed to
18+
identify the API key written to the cache filename. The `RouterProvider.getModel()` cold-start
19+
fallback is also corrected to pass the full options so it resolves the same compound key.
20+
21+
2. **Silent fallback to hardcoded default**: When the LiteLLM model list was empty (due to the
22+
collision above, a failed sync, or a transient error), `useSelectedModel` reset the configured
23+
model ID to `claude-3-7-sonnet-20250219` -- a model that typically does not exist on user
24+
LiteLLM servers. Four sub-fixes: preserve the configured model ID when the list is empty;
25+
invalidate the React Query router-models cache after a successful "Sync Models" click; pass the
26+
current LiteLLM credentials in the debounced `requestRouterModels` message; and correct the
27+
credential priority in `webviewMessageHandler.ts` so that message values (current unsaved field
28+
state) take precedence over stale saved config, matching the pattern already used for DeepSeek.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"zoo-code": patch
3+
---
4+
5+
Enhance the `apply_diff` tool description and parameter instructions to recommend `:start_line:` with exact syntax and emphasize copy-paste exact matching requirements, improving success rates for Gemini Flash and other smaller/faster models.

.github/workflows/cli-release.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ on:
1313
type: boolean
1414
default: false
1515

16+
# Least privilege: the release job escalates to contents: write via its own
17+
# job-level permissions block.
18+
permissions:
19+
contents: read
20+
1621
jobs:
1722
# Build CLI for each platform.
1823
build:

.github/workflows/code-qa.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,56 @@ on:
99
merge_group:
1010
types: [checks_requested]
1111

12+
# Least privilege: every job below escalates only where it needs to.
13+
permissions:
14+
contents: read
15+
1216
jobs:
17+
dependency-review:
18+
runs-on: ubuntu-latest
19+
# Only meaningful for PRs — validates the dependency diff of the pull
20+
# request against GitHub's advisory database before merge.
21+
if: github.event_name == 'pull_request'
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
25+
with:
26+
# This job never pushes — don't persist the GITHUB_TOKEN.
27+
persist-credentials: false
28+
- name: Dependency review
29+
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
30+
31+
invisible-chars:
32+
runs-on: ubuntu-latest
33+
# Reject invisible / homoglyph Unicode that GitHub's diff UI renders
34+
# invisibly and most editors hide. These compile fine, which is the
35+
# risk: identifier-splitting, string-literal injection, and the
36+
# "Trojan Source" bidi-override attack (U+202A-U+202E). Scanning raw
37+
# bytes catches them in strings, identifiers, and comments alike.
38+
steps:
39+
- name: Checkout code
40+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
41+
with:
42+
# This job never pushes — don't persist the GITHUB_TOKEN.
43+
persist-credentials: false
44+
- name: Reject invisible / homoglyph Unicode
45+
run: |
46+
# zero-width (U+200B-200F), word joiner (U+2060), BOM (U+FEFF),
47+
# bidi overrides (U+202A-202E), soft hyphen (U+00AD).
48+
# Covers source, release-adjacent executable scripts
49+
# (*.sh / *.cjs / *.cts / *.mts), and the executable shell
50+
# blocks inside GitHub workflow/action YAML.
51+
if grep -rnP '[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2060}\x{FEFF}\x{00AD}]' \
52+
--include='*.ts' --include='*.tsx' --include='*.js' --include='*.mjs' \
53+
--include='*.cjs' --include='*.cts' --include='*.mts' --include='*.sh' \
54+
--include='*.yml' --include='*.yaml' \
55+
--exclude-dir=node_modules --exclude-dir=dist --exclude-dir=out \
56+
--exclude-dir=coverage --exclude-dir=.turbo --exclude-dir=.vinxi \
57+
src webview-ui packages apps .github; then
58+
echo "::error::Found invisible or homoglyph Unicode characters (zero-width / bidi-override / BOM / soft hyphen)"
59+
exit 1
60+
fi
61+
1362
check-translations:
1463
runs-on: ubuntu-latest
1564
steps:

.github/workflows/codeql.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ on:
77
schedule:
88
- cron: '24 19 * * 3'
99

10+
# Least privilege: the analyze job escalates to security-events: write via its
11+
# own job-level permissions block.
12+
permissions:
13+
contents: read
14+
1015
jobs:
1116
analyze:
1217
name: Analyze (${{ matrix.language }})
@@ -47,7 +52,7 @@ jobs:
4752

4853
# Initializes the CodeQL tools for scanning.
4954
- name: Initialize CodeQL
50-
uses: github/codeql-action/init@dd903d2e4f5405488e5ef1422510ee31c8b32357 # v3
55+
uses: github/codeql-action/init@411c4c9a36b3fca4d674f06b6396b2c6d23522c6 # v3
5156
with:
5257
languages: ${{ matrix.language }}
5358
build-mode: ${{ matrix.build-mode }}
@@ -75,6 +80,6 @@ jobs:
7580
exit 1
7681
7782
- name: Perform CodeQL Analysis
78-
uses: github/codeql-action/analyze@dd903d2e4f5405488e5ef1422510ee31c8b32357 # v3
83+
uses: github/codeql-action/analyze@411c4c9a36b3fca4d674f06b6396b2c6d23522c6 # v3
7984
with:
8085
category: "/language:${{matrix.language}}"

.github/workflows/e2e.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ on:
77
merge_group:
88
types: [checks_requested]
99

10+
permissions:
11+
contents: read
12+
1013
jobs:
1114
e2e-mock:
1215
runs-on: ubuntu-latest
@@ -34,6 +37,22 @@ jobs:
3437
- name: Install xvfb
3538
if: github.event_name != 'pull_request' || steps.e2e-marker.outputs.cache-hit != 'true'
3639
run: sudo apt-get install -y xvfb
40+
41+
- name: Get VS Code version from package.json
42+
if: github.event_name != 'pull_request' || steps.e2e-marker.outputs.cache-hit != 'true'
43+
id: vscode-ver
44+
run: |
45+
VERSION=$(node -p 'require("./apps/vscode-e2e/package.json").devDependencies["@types/vscode"]')
46+
echo "version=$VERSION" >> $GITHUB_OUTPUT
47+
48+
- name: Cache VS Code test binary
49+
if: github.event_name != 'pull_request' || steps.e2e-marker.outputs.cache-hit != 'true'
50+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
51+
with:
52+
path: |
53+
apps/vscode-e2e/.vscode-test/
54+
key: vscode-test-${{ runner.os }}-${{ steps.vscode-ver.outputs.version }}-v1
55+
3756
- name: Run mocked E2E tests
3857
id: run-e2e
3958
# merge_group and workflow_dispatch always run; cache skip is pull_request only

0 commit comments

Comments
 (0)