Skip to content

Commit a8bf706

Browse files
Merge branch 'main' into ollama_fetch_fix
2 parents eff47f7 + 367013f commit a8bf706

160 files changed

Lines changed: 5232 additions & 2118 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.

‎.github/workflows/label-pr-review-state.yml‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,28 @@ jobs:
153153
}),
154154
]);
155155
156+
// listForRef returns every check run ever recorded on the ref, including
157+
// stale superseded ones (e.g. a failed run later re-run green). Branch
158+
// protection and the PR UI only consider the latest run per check name, so
159+
// reduce to that before evaluating — otherwise a single stale failure makes
160+
// ciFailed true forever and state labels never come back. See issue #884.
161+
//
162+
// Unlike listReviews (which documents oldest-first order), listForRef's
163+
// ordering is unspecified, so we pick the latest by run.id — GitHub assigns
164+
// monotonically increasing IDs, and id is never null (a freshly re-queued
165+
// run can have started_at: null, which would lose a string comparison
166+
// against an older completed run's timestamp).
167+
const latestByName = new Map();
168+
for (const run of checkRuns) {
169+
const prev = latestByName.get(run.name);
170+
if (!prev || run.id > prev.id) {
171+
latestByName.set(run.name, run);
172+
}
173+
}
174+
156175
// Filter to required checks only (or all checks if rules unavailable).
157176
// Always exclude this workflow's own run to avoid self-referential loops.
158-
const relevantRuns = checkRuns.filter(run => {
177+
const relevantRuns = [...latestByName.values()].filter(run => {
159178
if (run.name === 'Reconcile PR review state labels') return false;
160179
return requiredCheckNames ? requiredCheckNames.has(run.name) : true;
161180
});
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Post weekly release reminder
2+
3+
# Requires repo secret DISCORD_RELEASE_WEBHOOK_URL — Discord webhook for the
4+
# release-reminders channel. The reminder job fails (noisily) if it is unset.
5+
6+
on:
7+
schedule:
8+
# Friday at 09:00 UTC
9+
- cron: "0 9 * * 5"
10+
workflow_dispatch:
11+
12+
permissions: {}
13+
14+
concurrency:
15+
group: release-reminder
16+
# A re-run produces an identical message, so cancel a stale/duplicate run
17+
# rather than risk posting twice.
18+
cancel-in-progress: true
19+
20+
jobs:
21+
remind:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Post release reminder to Discord
25+
env:
26+
DISCORD_RELEASE_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }}
27+
run: |
28+
set -euo pipefail
29+
owners=("Elliott" "Navad" "Toray")
30+
anchor_date="2026-07-17"
31+
seconds_since_anchor=$(($(date -u +%s) - $(date -u -d "$anchor_date" +%s)))
32+
weeks_since_anchor=$((seconds_since_anchor / 604800))
33+
owner="${owners[$((weeks_since_anchor % ${#owners[@]}))]}"
34+
35+
message=$(cat <<EOF
36+
**Weekly release reminder**
37+
38+
**${owner}** is on deck for this week's Zoo Code release.
39+
40+
1. Create the release branch and prepare the release with \`.roo/commands/release.md\`.
41+
2. Get the release PR approved.
42+
3. Tag the release branch to trigger the Marketplace publish workflow.
43+
4. Approve the deployment when the \`marketplace-production\` environment requests it.
44+
5. After publishing succeeds, add the release PR to the merge queue.
45+
46+
Avoid merging or rebasing the release branch before publishing, so the approved tag keeps the intended commit SHA.
47+
48+
More detail: https://discord.com/channels/1497384592494297201/1498024845945081999/1512914847124291667
49+
EOF
50+
)
51+
52+
payload=$(jq -n --arg content "$message" '{content: $content}')
53+
curl --fail-with-body --silent --show-error \
54+
--header 'Content-Type: application/json' \
55+
--data "$payload" \
56+
"$DISCORD_RELEASE_WEBHOOK_URL"
57+
58+
- name: Notify on failure
59+
if: failure()
60+
env:
61+
DISCORD_RELEASE_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }}
62+
run: |
63+
set -euo pipefail
64+
payload=$(jq -nc --arg content "⚠️ release-reminder workflow failed — see the Actions runs." '{content: $content}')
65+
curl --fail-with-body --silent --show-error \
66+
--header 'Content-Type: application/json' \
67+
--data "$payload" \
68+
"$DISCORD_RELEASE_WEBHOOK_URL" || true

‎CHANGELOG.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Zoo Code Changelog
22

3+
## [3.68.0]
4+
5+
### Minor Changes
6+
7+
- Add Friendli provider with GLM-5.2 support for another hosted way to use the latest GLM model (#722 by @Lee-Si-Yoon, PR #721 by @Lee-Si-Yoon)
8+
- Add native thinking/reasoning support for Ollama models to preserve reasoning output end-to-end (#831 by @navedmerchant, PR #832 by @navedmerchant)
9+
- Fix(anthropic): honor custom `apiModelId` selections instead of silently defaulting to `claude-sonnet-4-5` (#418 by @tatianadenel-devops, #843 by @grizmin, PR #842 by @grizmin)
10+
- Fix(ollama): correctly handle tool results and prevent premature context condensing (#847 by @navedmerchant, PR #848 by @navedmerchant)
11+
- Improve Anthropic Vertex Claude content block handling for more reliable responses (#788 by @daewoongoh, PR #789 by @daewoongoh)
12+
- Fix(task-lifecycle): preserve the parent-child link when a delegated subtask is interrupted (#560 by @edelauna, PR #787 by @edelauna)
13+
- Refactor: remove the deprecated `openai-error-handler` shim and use the shared `error-handler` directly (#766 by @daewoongoh, PR #767 by @daewoongoh)
14+
- Feat(nightly-publish): publish Open VSX pre-releases and skip nightly publish on release merges (#784 by @edelauna, PR #790 by @edelauna)
15+
- Fix(ci): don't skip fork-PR label reconciliation on scheduled and manual runs (PR #234 by @app/roomote)
16+
- Fix(label-pr-review-state): detect merge conflicts and label PRs with `has-conflicts` (PR #269 by @app/roomote)
17+
- Chore(deps): update the `github/codeql-action` digest to `411c4c9` (PR #803 by @app/renovate)
18+
- Chore(deps): update `@types/react` to `v18.3.31` (PR #805 by @app/renovate)
19+
- Chore(deps): update `axios` to `v1.18.1` (PR #806 by @app/renovate)
20+
- Chore: merge the v3.66.0 release preparation branch into `main` (PR #795 by @navedmerchant)
21+
322
## [3.66.0]
423

524
### Minor Changes

‎README.md‎

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,15 @@
5353
You can find a quick guide for migrating from Roo Code to Zoo Code in the [Roo→Zoo migration guide](https://docs.zoocode.dev/roo-to-zoo-migration). We plan to try and help users as they transition over, we have our [Reddit](https://www.reddit.com/r/ZooCode) and [Discord](https://discord.gg/VxfP4Vx3gX)
5454
for this exact support, so if you are having problems or if you have question, jump on and ask.
5555

56-
## What's New in v3.66.0
57-
58-
- **Claude Sonnet 5 support** — the latest Claude model is now available across Anthropic, Bedrock, and Vertex providers
59-
- **Semble v0.4.1 upgrade** — flattened result parsing and localized status messages
60-
- **Task-lifecycle status transition guard** — a new status transition guard and startup delegation reconciliation prevent invalid task state transitions
61-
- Fix: LiteLLM cache key collision and silent fallback to a non-existent default model
62-
- Fix: reliable auto context condensing for the VS Code Language Model API
63-
- Fix: ThinkingBudget now supports `xhigh` and all extended reasoning effort values
64-
- Fix: round-trip DeepSeek `reasoning_content` in thinking mode to prevent 400 errors
65-
- Fix: base64-encode Gemini `thoughtSignature` bypass token to fix the Vertex AI empty-response loop
66-
- Fix: provider cache reset after settings import
67-
- Fix: atomically serialize `reopenParentFromDelegation`
68-
- Fix: shell default profile name type guard
69-
- Security: dependency-review, invisible-char detection, and least-privilege workflow permissions
70-
- Upgrade `@anthropic-ai/sdk` to 0.104.1 and `@anthropic-ai/vertex-sdk` to 0.17.1
71-
- Dependency and tooling updates
56+
## What's New in v3.68.0
57+
58+
- **Friendli provider with GLM-5.2 support** — use the latest GLM model through Friendli.
59+
- **Native Ollama thinking/reasoning support** — preserve reasoning output end-to-end when you use Ollama models.
60+
- **Anthropic custom `apiModelId` fix** — custom Anthropic model IDs now stay selected instead of silently falling back to `claude-sonnet-4-5`.
61+
- Fix: Ollama provider tool result handling and premature context condensing.
62+
- Fix: preserve the parent-child task link when a delegated subtask is interrupted.
63+
- Improve Anthropic Vertex Claude content block handling for more reliable responses.
64+
- CI, nightly publishing, and dependency/tooling updates.
7265

7366
<details>
7467
<summary>🌐 Available languages</summary>

‎apps/cli/package.json‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@roo-code/core": "workspace:^",
2727
"@roo-code/types": "workspace:^",
2828
"@roo-code/vscode-shim": "workspace:^",
29-
"@trpc/client": "^11.8.1",
29+
"@trpc/client": "^11.18.0",
3030
"@vscode/ripgrep": "^1.15.9",
3131
"commander": "^12.1.0",
3232
"execa": "^9.5.2",
@@ -35,17 +35,18 @@
3535
"p-wait-for": "^5.0.2",
3636
"react": "^19.1.0",
3737
"superjson": "^2.2.6",
38-
"zustand": "^5.0.0"
38+
"zustand": "^5.0.14"
3939
},
4040
"devDependencies": {
4141
"@roo-code/config-eslint": "workspace:^",
42+
"@trpc/server": "^11.18.0",
4243
"@roo-code/config-typescript": "workspace:^",
4344
"@types/node": "20.19.43",
4445
"@types/react": "18.3.31",
4546
"@vitest/coverage-v8": "4.1.9",
4647
"ink-testing-library": "4.0.0",
4748
"rimraf": "6.0.1",
48-
"tsup": "8.5.0",
49+
"tsup": "8.5.1",
4950
"tsx": "4.22.4",
5051
"vitest": "4.1.9"
5152
}

‎apps/cli/scripts/build.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ create_tarball() {
173173

174174
# Find and copy ripgrep binary
175175
info "Looking for ripgrep binary..."
176-
RIPGREP_PATH=$(find "$REPO_ROOT/node_modules" -path "*/@vscode/ripgrep/bin/rg" -type f 2>/dev/null | head -1)
176+
RIPGREP_PATH=$(find "$REPO_ROOT/node_modules" -path "*/@vscode/ripgrep*/bin/rg" -type f 2>/dev/null | head -1)
177177
if [ -n "$RIPGREP_PATH" ] && [ -f "$RIPGREP_PATH" ]; then
178178
info "Found ripgrep at: $RIPGREP_PATH"
179179
mkdir -p "$RELEASE_DIR/node_modules/@vscode/ripgrep/bin"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"fixtures": [
3+
{
4+
"match": {
5+
"userMessage": "COLD_SHELL_INIT_E2E"
6+
},
7+
"response": {
8+
"toolCalls": [
9+
{
10+
"name": "execute_command",
11+
"arguments": "{\"command\":\"python3 -c \\\"\\nimport sys\\nprint('cold-init-ok', file=sys.stdout)\\nsys.exit(0)\\n\\\"\"}",
12+
"id": "call_cold_shell_init_001"
13+
}
14+
]
15+
}
16+
}
17+
]
18+
}

‎apps/vscode-e2e/fixtures/deepseek-v4.json‎

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,6 @@
1818
]
1919
}
2020
},
21-
{
22-
"match": {
23-
"model": "deepseek-v4-flash",
24-
"toolCallId": "call_dsv4_flash_on_read"
25-
},
26-
"response": {
27-
"toolCalls": [
28-
{
29-
"name": "attempt_completion",
30-
"arguments": "{\"result\":\"DEEPSEEK_V4_MARKER_deepseek_v4_flash_reasoning_on\"}",
31-
"id": "call_dsv4_flash_on_done"
32-
}
33-
]
34-
}
35-
},
3621
{
3722
"match": {
3823
"model": "deepseek-v4-flash",
@@ -49,21 +34,6 @@
4934
]
5035
}
5136
},
52-
{
53-
"match": {
54-
"model": "deepseek-v4-flash",
55-
"toolCallId": "call_dsv4_flash_off_read"
56-
},
57-
"response": {
58-
"toolCalls": [
59-
{
60-
"name": "attempt_completion",
61-
"arguments": "{\"result\":\"DEEPSEEK_V4_MARKER_deepseek_v4_flash_reasoning_off\"}",
62-
"id": "call_dsv4_flash_off_done"
63-
}
64-
]
65-
}
66-
},
6737
{
6838
"match": {
6939
"model": "deepseek-v4-pro",
@@ -82,21 +52,6 @@
8252
]
8353
}
8454
},
85-
{
86-
"match": {
87-
"model": "deepseek-v4-pro",
88-
"toolCallId": "call_dsv4_pro_on_read"
89-
},
90-
"response": {
91-
"toolCalls": [
92-
{
93-
"name": "attempt_completion",
94-
"arguments": "{\"result\":\"DEEPSEEK_V4_MARKER_deepseek_v4_pro_reasoning_on\"}",
95-
"id": "call_dsv4_pro_on_done"
96-
}
97-
]
98-
}
99-
},
10055
{
10156
"match": {
10257
"model": "deepseek-v4-pro",
@@ -112,21 +67,6 @@
11267
}
11368
]
11469
}
115-
},
116-
{
117-
"match": {
118-
"model": "deepseek-v4-pro",
119-
"toolCallId": "call_dsv4_pro_off_read"
120-
},
121-
"response": {
122-
"toolCalls": [
123-
{
124-
"name": "attempt_completion",
125-
"arguments": "{\"result\":\"DEEPSEEK_V4_MARKER_deepseek_v4_pro_reasoning_off\"}",
126-
"id": "call_dsv4_pro_off_done"
127-
}
128-
]
129-
}
13070
}
13171
]
13272
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"fixtures": [
3+
{
4+
"match": {
5+
"userMessage": "FAST_EXIT_SHELL_RACE_E2E"
6+
},
7+
"response": {
8+
"toolCalls": [
9+
{
10+
"name": "execute_command",
11+
"arguments": "{\"command\":\"python3 -c \\\"\\nimport sys\\nprint('boom', file=sys.stderr)\\nsys.exit(1)\\n\\\"\"}",
12+
"id": "call_fast_exit_shell_race_001"
13+
}
14+
]
15+
}
16+
}
17+
]
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"fixtures": [
3+
{
4+
"match": {
5+
"userMessage": "LONG_RUNNING_SILENT_COMMAND_E2E"
6+
},
7+
"response": {
8+
"toolCalls": [
9+
{
10+
"name": "execute_command",
11+
"arguments": "{\"command\":\"sleep 5\"}",
12+
"id": "call_long_running_silent_001"
13+
}
14+
]
15+
}
16+
}
17+
]
18+
}

0 commit comments

Comments
 (0)