Repository navigation
Conversation
|
Picked tnsardesai to review these related PRs (#491, kernel/kernel#5031): recent commits in |
tnsardesai
left a comment
There was a problem hiding this comment.
Correctness
- Blocking compatibility break — aborting a REPL call no longer stops a hung cell once SDKs key every request —
server/cmd/api/api/browser_repl.go:L669-L672- Problem: the keyed path runs
Executeoncontext.WithoutCancel, so disconnecting no longer kills the running cell. kernel/kernel#5031 turns on Stainless idempotency, which attaches a key to every SDK POST. So the "no key → disconnect kills the REPL" path this PR keeps is effectively gone for SDK users. A follow-upreset: truedoesn't help, because it waits on the sameadmissionchannel behind the running cell. - Impact: an agent or user that aborts a stuck cell (for example,
awaiton a promise that never resolves) and then resets or retries is blocked for up totimeout_sec(max 300s), and the VM stays awake. Today they get a fresh REPL right away. - Fix: give keyed calls a way to cancel. One option:
reset: true(or a dedicated cancel endpoint) cancels the in-flight keyed cell instead of queuing behindadmission. Another: keep the at-most-once guarantee but cancel the detached call once no caller has been waiting on the key for some grace period.
- Problem: the keyed path runs
|
Fixed in 00d6058 using the grace-period approach.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 00d6058. Configure here.
| } | ||
| } else { | ||
| delete(c.calls, key) | ||
| } |
There was a problem hiding this comment.
Abandoned calls consume idempotency keys
Medium Severity
After abandonGrace, cancel turns into a 200 in both handlers: Playwright maps admission or setup cancel to execution failed before any code runs, and REPL maps a mid-read cancel to a terminated 200. keep then stores that abort, so a later retry with the same key receives the cached failure instead of running again.
Reviewed by Cursor Bugbot for commit 00d6058. Configure here.


Summary
Playwright execute and the browser REPL can now be retried safely. Both endpoints accept an optional
Idempotency-Keyheader, and each key runs at most once.The Stainless SDKs retry on 408, 409, 429, 5xx, connection errors and client timeouts. The TS and Python SDKs default to a 60s timeout, and execute also defaults to
timeout_sec: 60. As a result, a single execute call could run the user's code up to three times, and the caller only ever saw a timeout error.Behavior
Compatibility
Declaring the header changes the generated client signatures.
ExecutePlaywrightCode*andExecuteBrowserRepl*now take a*Paramsargument. The e2e callers are updated, withnilparams. Downstream consumers need the same one-argument change when they pick this up. API side: kernel/kernel#5031.Testing
go vet ./...is clean.go test -racepasses for all non-e2e packages. The REPL tests run against real Node and esbuild.lib/devtoolsproxyfailed once on an unrelated temp-dir cleanup race with Chromium and passed 5 of 5 on re-run.Reviewed with sol-loop: 2 rounds (before the grace-period change from review) with openai-codex/gpt-6.1-sol on extra-high reasoning. Sol verdict: approved.