-
Notifications
You must be signed in to change notification settings - Fork 0
Comparing changes
Open a pull request
base repository: levelcodeai/levelcode
base: 7fd4786
head repository: levelcodeai/levelcode
compare: faa8eb5
- 9 commits
- 9 files changed
- 2 contributors
Commits on Jul 24, 2026
-
ci: move release actions off the deprecated Node 20 runtime
Every release run logs a Node 20 deprecation warning per step, and closes with: "The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/cache@v4, actions/checkout@v4, actions/setup-node@v4, actions/upload-artifact@v4." Nothing is broken — GitHub is shimming them onto Node 24 — but the shim is temporary, so pin majors that target node24 natively: checkout v4 -> v7 setup-node v4 -> v7 cache v4 -> v6 upload-artifact v4 -> v7 download-artifact v4 -> v8 Node 24 actions require Actions Runner >= 2.327.1; the hosted images run 2.335.1 (per the v0.9.2 build log) and self-update, so nothing to do there. The majors were picked against how this workflow actually uses them, and each one's breaking change was checked rather than assumed: · setup-node v6 limits automatic caching to npm — this workflow never sets setup-node's `cache:` input (npm caching is the explicit actions/cache step), so it's a no-op here. · checkout v7 blocks fork checkouts for pull_request_target / workflow_run — neither is a trigger (tag push + workflow_dispatch). · upload-artifact v7's unzipped "direct uploads" are opt-in via `archive:`; the default still zips, so the .app.zip round-trip is unchanged. · download-artifact v8 now ERRORS on a digest mismatch instead of warning. Kept deliberately: a corrupted app bundle must not reach a release we then sign and notarize. A spurious failure is recoverable by re-running the job. Verified every input this workflow passes is still declared in the new majors (notably download-artifact's `merge-multiple`, which the draft-release job depends on), that all five now report `using: node24`, and that the YAML still parses with both matrix arches and triggers intact.Configuration menu - View commit details
-
Copy full SHA for 0866bee - Browse repository at this point
Copy the full SHA 0866beeView commit details
Commits on Jul 25, 2026
-
Merge pull request #40 from levelcodeai/fix/actions-node24
ci: move release actions off the deprecated Node 20 runtime
Configuration menu - View commit details
-
Copy full SHA for 7ba72f1 - Browse repository at this point
Copy the full SHA 7ba72f1View commit details -
feat(ai): offer Claude Opus 5 on OpenRouter (BYOK) + 1M-context caps
Gateway (LevelCode Cloud) users get Opus 5 from the server roster with no editor release — that side is thin.ly. This is the BYOK half: the OpenRouter picker, the local caps table, and the sketch cost meter. - providers/index.js — a picker row for `anthropic/claude-opus-5`. Placed second, under the flagship, since it is the frontier pick most people reach for. - providers/catalog.js — an explicit CAPS row, for the same reason Kimi K3 has one: the `claude-` heuristic reports 200K, so a 1M window would drive the in-run context meter to cry "full" at a fifth of the real budget. - sketch/pricing.js — Opus 5 ties Opus 4.8's $5/$25, which the `claude-opus` family fallback already produced. The FAST variant does NOT: it is $10/$50, and the fallback was quietly pricing it at half. Both are pinned now, so the meter is honest whichever slug a BYOK user types. - sketch.js — MODEL_TIERS openrouter.powerful moves 4.8 → 5. Same price, newer model. It also fixes a latent wart: the old id was never in the OpenRouter registry, so a per-node model override naming it failed validation and silently fell back. Revert this one line if you'd rather pin the tier to 4.8. Prices/context confirmed against the OpenRouter models API (2026-07-24): $5/M in · $25/M out · $0.50/M cached · 1M ctx (fast variant: $10/$50). Verified at runtime, not just in tests: the row renders in the picker, caps resolve to 1,000,000, tools/vision on, and isAnthropicFamily matches so explicit prompt-cache breakpoints are sent. Full gate green (24 suites).
Configuration menu - View commit details
-
Copy full SHA for ea9407e - Browse repository at this point
Copy the full SHA ea9407eView commit details -
fix(ai): Opus 4.8 is 1M on OpenRouter — split the caps row by route
The CAPS row for Opus 4.8 said 200K, so the in-run context meter warned "full" at a fifth of the real budget for anyone on the OpenRouter/gateway route. Every OpenRouter endpoint for that model (Anthropic first-party, Bedrock, Azure, Google) advertises 1M/128K. Fixed under the OpenRouter slug ONLY, and deliberately not under the bare id: 'claude-opus-4-8' → 200000 direct Anthropic provider 'anthropic/claude-opus-4-8' → 1000000 OpenRouter / gateway Those are two different routes sharing one key today, and I can only vouch for one of them. This extension sends no `anthropic-beta` header on the native path, so I have not confirmed the long window is reachable there — and overstating it would be the worse failure, telling the user they have room the API will refuse. Exact-id lookup beats basename, so the rows coexist and each route reports its own truth. If the native path does support 1M unheadered, the bare row is a one-line follow-up. Tests pin both sides of the split plus the unlisted-Claude heuristic default. Full gate green (24 suites).
Configuration menu - View commit details
-
Copy full SHA for a4777a8 - Browse repository at this point
Copy the full SHA a4777a8View commit details -
Merge pull request #42 from levelcodeai/feat/opus-5-openrouter
feat(ai): Claude Opus 5 on OpenRouter (BYOK) + correct the Opus 1M context windows
Configuration menu - View commit details
-
Copy full SHA for 8ac0aef - Browse repository at this point
Copy the full SHA 8ac0aefView commit details -
fix(ai): refresh an expired token when loading the Cloud model roster
On a fresh open of LevelCode, a paid plan's model picker showed only TWO models (the free engine + the flagship) instead of the full roster — no Opus 4.8, no Kimi K3, and none of the "×credits · ctx · turns left" detail or "coming soon" rows. That is the OFFLINE fallback branch of pickCloudModel, reached whenever fetchCloudRoster returns no models. Cause: fetchCloudRoster returned null on ANY non-OK response and, unlike the profile fetch (webHandoffUrl) and the agent loop, did NOT refresh the token on a 401. Access tokens are short-lived, so the FIRST roster request after a fresh open is made with last session's expired token → 401 → null → 2-model fallback. The account WEB page looked correct because it authenticates differently and refreshes. Fix, mirroring the proven webHandoffUrl retry: - On 401, refreshCloudToken() once and retry with the fresh token. - Gate on the stored TOKEN, not the cloudSignedIn flag — the flag can still be false mid-activation while a valid token exists, which was a second path to the same degraded menu. - On a genuinely transient failure, return the last-known-good roster (cloudRoster) instead of collapsing to the 2-model fallback; the menu just omits the credits/turns detail it can't recompute offline. Not unit-tested — this is vscode-requiring host glue with no pure seam to extract; it is verified by reading and by matching webHandoffUrl's battle-tested pattern (now the second of two 401-refresh call sites). I could not reproduce the live 401 without a running, signed-in editor, so this fixes the identified code path rather than an observed repro. Full gate: 24 suites, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for f4278bb - Browse repository at this point
Copy the full SHA f4278bbView commit details -
fix(ai): correct the cache comment; guard the refreshed token (PR #43 …
…review) 1. The comment claimed "credits/turns aren't cached", but cloudRoster = data.models caches the per-model fields including turns_left, so the cached-roster fallback CAN show a slightly stale "≈ turns left". Only the account-level credit BALANCE is genuinely not carried (the "$X credits left" header is omitted until the next good fetch). Comment now says exactly that. 2. After refreshCloudToken() succeeds, the refreshed secret was used unchecked — if it came back falsy the retry would send `Authorization: Bearer null`, noise that masks the real 401. Now the retry only fires when the refreshed token is truthy; otherwise it falls through to the cached-roster path. Comment-and-guard only, no behaviour change on the happy path. Full gate: 24 suites, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for ef99a8f - Browse repository at this point
Copy the full SHA ef99a8fView commit details -
fix(ai): fall back to the cached roster unless data.models is a real …
…array (PR #43 review) The retry returned `data || cached()`, so any truthy JSON that lacked a valid `models` array — a 200 with an error object, a partial response, a schema drift — was returned as-is. pickCloudModel then sees "no models" and collapses to the 2-model fallback even though cloudRoster still holds a good list, defeating the whole point of the cache. Now a payload only counts as a roster when data.models is an array; otherwise it returns cached(). Also fixes the mirror case where a 200 arrives but json() failed (data null) — same fall-through to the cache. Full gate: 24 suites, 0 failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 367dc64 - Browse repository at this point
Copy the full SHA 367dc64View commit details -
Merge pull request #43 from levelcodeai/fix/cloud-roster-token-refresh
fix(ai): refresh an expired token when loading the Cloud model roster
Configuration menu - View commit details
-
Copy full SHA for faa8eb5 - Browse repository at this point
Copy the full SHA faa8eb5View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 7fd4786...faa8eb5