feat(sdk): add process surface with handles, log replay and reconnect - #191
Open
MDzaja wants to merge 5 commits into
Open
feat(sdk): add process surface with handles, log replay and reconnect#191MDzaja wants to merge 5 commits into
MDzaja wants to merge 5 commits into
Conversation
Signed-off-by: MDzaja <mirkodzaja0@gmail.com>
Vidoc security reviewCaution Fix before merge — 11 findings (1 critical, 10 high). 10 other findings non-blocking.
Non-blocking (10) — review when convenient
Reviewed 303 changed files. Each finding has an inline comment explaining the risk and the fix. Full analysis → 💬 Have questions? Tag @vidoc in a comment and I'll answer. |
- replace deprecated NewDaytonaValidationError with NewDaytonaError and apply De Morgan simplification in the process surface (staticcheck) - add license headers to the golden test helpers and the run-output test - skip golden test collection when DAYTONA_API_KEY is absent so the unit lane no longer fails at collection (and no longer cascades into sdk-go:build/sdk-java:test via nx bail) - apply black formatting drift in stub signatures and unicode escapes Signed-off-by: MDzaja <mirkodzaja0@gmail.com>
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
TypeScript: omit empty argv and blank shellCommand from requests, validate terminal dims and finite timeouts, browser-safe base64 decoding, reject non-UTF-8 stdin instead of corrupting it, document SIGTERM kill default, add timedOut to ProcessRunResult, cancel losing deadline timers, error on log page-cap exhaustion, reject keepLogs=none without callbacks. Python: enforce wait_timeout_ms on silent SSE streams (sync read timeout, async wait_for), deadline-aware PTY wait with bounded result resolution, initialize connection state for attached terminals, resolve results on unexpected websocket failures. Go: unknown SSE events error instead of ending streams, int32 range validation for dims and timeouts, interpreter cleanup on canceled contexts, error on page-cap exhaustion. Java: preserve callback exceptions with addSuppressed cleanup, zero wait timeout now times out immediately (TS/Ruby convention; OkHttp treats 0 as unbounded), throw on page-cap exhaustion. Ruby: correct start() kwarg docs to the real option names, honor the timed_out terminal reason, wrap transport errors as ConnectionError, and decode malformed UTF-8 with replacement instead of starving callbacks. Output truncation on retention eviction is now documented on every SDK's collection path (retained suffix + firstAvailableCursor recovery). Signed-off-by: MDzaja <mirkodzaja0@gmail.com>
There was a problem hiding this comment.
All reported issues were addressed across 44 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
- TypeScript: cursor-stall guard in log collection (Java parity), absent frame data decodes as empty bytes, cancellation-safe SSE test fixture, timedOut no longer conflates a wait timeout with an own-timeout kill - Python: mark PTY handles disconnected before result resolution on reader failure, retryable timed-out wait probes, truthful run() recovery docs (watchdog stream interruption verified impossible with httpx and documented) - Ruby: impossible UTF-8 prefixes (overlong/out-of-range) are replaced immediately instead of buffered until EOF, pinning Python codec parity - Go: page-cap exhaustion test no longer performs 10k real round trips Signed-off-by: MDzaja <mirkodzaja0@gmail.com>
…T_FAILED Signed-off-by: MDzaja <mirkodzaja0@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a process management surface to all five SDKs (TypeScript, Python, Go, Java, Ruby): start background processes, stream and replay their output, reconnect from any client, and manage their lifecycle. Requires an updated daemon; all existing SDK methods are unchanged and keep working against older daemons.
New API
Process client (
sandbox.process):start(options)→ProcessHandle— background process you supervise yourself. Logs are retained after exit untilcleanup().run(options)→ collected result — one-shot: waits for exit and returns stdout/stderr + exit metadata (optionalonStdout/onStderrstreaming callbacks,waitTimeoutMswith partial results). Output is retained briefly after exit.get(id)/connect(id)— attach to any process by id, running or finished, from any client. This is the reconnect story: persist the sandbox id + process id, reconnect later, replay everything.list(filter)— server-side listing of processes (state/kind/name/session filters), including ones started by other clients.exec(...)— alias ofexecuteCommand.ProcessHandle:logs(cursor-paged replay withtruncatedHead/CURSOR_EXPIREDrecovery),streamLogs(replay-then-live),stdin/stdinEof,kill,resize,wait,output,cleanup,attachTerminal(interactive PTY socket forkind: 'pty'processes).Code interpreter ergonomics: scoped contexts that always clean up —
withContext(fn)(TS/Java/Go) and context managers/blocks (with sandbox.code_interpreter.context() as ctx:in Python,code_interpreter.context { |ctx| }in Ruby).Correctness details
get/listresponses from older daemons are normalized into the standardSessionmodel — return types are unchanged from the previous release.startvsrunandwaitvsoutput.Compatibility
main).Testing
test:golden) pass for TypeScript and Python: 40/40 and 50/50.Summary by cubic
Adds a reconnectable process surface across all SDKs so callers can start/run processes, replay or stream logs, send stdin, and supervise via handles. Previously processes were fire‑and‑forget via exec/code_run; now clients can reconnect by id, enforce deadlines, and collect UTF‑8‑safe output, with updated error mapping and spec sync.
sandbox.process.start/run/get/connect/list(with filters).execremains (aliased for consistency). TypeScript addsProcessClient/ProcessHandle/ProcessTransport; OpenAPI/toolbox spec regenerated and SDKs updated, including newPROCESS_START_FAILEDmapping.logs(cursor‑paged),streamLogs(replay‑then‑live withCURSOR_EXPIREDrecovery),stdin/stdinEof,kill(signal with optional escalation),resize,wait/output,cleanup, andattachTerminalforkind: 'pty'. Streams decode incrementally for UTF‑8 correctness; collection fails fast on page‑budget exhaustion and documents retained‑suffix behavior.withContextin TypeScript/Java/Go; context managers/blocks in Python/Ruby).argv/blankshellCommand; reject non‑UTF‑8stdin; browser‑safe base64; guard against cursor stalls; absent frame data decodes as empty;ProcessRunResult.timedOutonly reflects a wait‑deadline miss; cancel losing deadlines; rejectkeepLogs: 'none'without streaming callbacks.wait_timeout_mson quiet SSE runs; PTY waits honor remaining budget and resolve results on reader failure; attached terminals initialize connection state; retryable probes for timed‑out waits; docs clarifyrun()recovery.waitTimeoutMstimeouts immediately; keep callback exceptions andaddSuppressedcleanup failures; page‑cap exhaustion errors.start()kwarg docs; honortimed_outterminal reason; wrap transport errors as connection errors; replace malformed/impossible UTF‑8 prefixes immediately.CURSOR_EXPIRED, stdin closed/unavailable, terminal errors, name conflicts, unsupported operation,PROCESS_START_FAILED); SDK docs added for process APIs; TypeScript/Python golden contract suites gated byDAYTONA_API_KEY; CI lint/staticcheck/license fixes.Compatibility & rollout
CURSOR_EXPIRED, resume from the first available cursor reported by the daemon.Written for commit 0ddc922. Summary will update on new commits.