Repository navigation
build(deps-dev): Bump react and @types/react - #652
dependabot[bot] wants to merge 1 commit into
Conversation
Bumps [react](https://github.com/react/react/tree/HEAD/packages/react) and [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react). These dependencies needed to be updated together. Updates `react` from 19.2.7 to 19.2.8 - [Release notes](https://github.com/react/react/releases) - [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/react/react/commits/v19.2.8/packages/react) Updates `@types/react` from 19.2.17 to 19.2.18 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: react dependency-version: 19.2.8 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: "@types/react" dependency-version: 19.2.18 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Lands #652 on this branch. React refuses to render when `react` and `react-dom` are not the exact same version, so the matching react-dom bump from #607 rides along: #652 on its own failed 15 component test files with `Incompatible React versions`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014GcYCCtSc5VGD6YCoxsrsY
|
Landed on the Note for whoever picks this up next: this bump is not green on its own. React refuses to render when |
|
OK, I won't notify you again about this release, but will get in touch when a new version is available. You can also ignore all major, minor, or patch releases for a dependency by adding an If you change your mind, just re-open this PR and I'll resolve any conflicts on it. |
Applied while red-teaming the pull-based Evaluator v2 worker against a live stack (agenteye #652 / failproofai #758). All five reproduced live and are covered by tests/test_evaluator_review_fixes.py; the full evaluator suite (153 tests) still passes. - authoring._bounded: reject C0 control characters and DEL in bounded result text (reasoning/summary/description/display_value/unit/label), matching the server's check_bounded. The SDK previously validated only byte length, so a result quoting transcript text with a NUL or ANSI escape was accepted locally then rejected by the server with a NON-RETRYABLE 422 — a successful eval was silently lost and its assignment dead-lettered. TAB/LF/CR are kept. - authoring.EvalResult.result_items: carry the eval's `reasoning` on the PRIMARY result (result_key == eval_key) for metric- and assertion-kind evals, not only on a score item. A non-score eval previously dropped its reasoning entirely. - runtime._execute_run_in_slot: always bound an evaluation by wall clock. A LOCAL (customer-authored) eval declaring no timeout_seconds ran with NO timeout — a hung await or unbounded judge call wedged the worker slot and held the lease forever. Falls back to DEFAULT_EVAL_TIMEOUT_SECONDS (300s, the contract's per-eval default); managed evals keep their tighter in-sandbox cap. - runtime._execute_run_in_slot: log the full traceback LOCALLY when a customer eval raises. The wire error stays scrubbed to the exception type (it can quote transcript data), but the pod now records the real exception so an author can debug their own eval instead of seeing only "evaluation raised HTTPError". - source._OBJECT_REPR: scope the output-boundary guard to the " at 0x..." repr tail and drop the bare "0x"+hex alternative, which false-rejected legitimate result text (a hex colour like 0xFFFFFF, a digest, an address the agent logged) as an embedded object repr. The tail still catches a '<'-stripped repr. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The server returns error code `insufficient_permissions` (HTTP 403) when a worker key lacks `evaluations:run` (server worker_auth.rs), but that code was absent from the frozen ERROR_SPECS on both sides and from both contract.json fixtures. Add it (403, non-retryable) to the SDK's ERROR_SPECS and the SDK fixture; the mirroring server-side entry lands in agenteye #652. Keeps the two contract.json fixtures byte-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…oo-large transcripts Follow-up review fixes (agenteye #652 / failproofai #758), all covered by tests/test_evaluator_review_fixes.py; evaluator suite (145 tests) green. - _heartbeat now beats IMMEDIATELY before its first sleep. The pre-plan condition phase can consume most of the claim-time lease, and the server only renews a planned assignment's lease on heartbeat — so sleeping a full interval before the first beat let the lease expire after the runs had started and cancelled every one. (Server-side: the plan handler also extends the lease.) - process_assignment tolerates an idempotent replay whose run set diverges from this attempt's plan. On reclaim the server re-serves the FIRST attempt's runs, which are authoritative — even one this attempt's condition would have skipped. The status-equality check is skipped on replay, and a replayed run absent from this attempt's selection is reconstructed from the assignment's descriptors instead of raising and dead-lettering an assignment that could never converge. - process_assignment catches transcript_too_large at the transcript fetch and returns cleanly (logging + a metric) instead of propagating. No runs are planned yet, the error is non-retryable, and re-raising wedged the poll loop and burned the whole retry budget — reproduced live, where a 28.6 MiB session froze the pod. The server terminalizes the assignment as too_large. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ed pods, fork+exec sandbox, review hardening (#758) * docs(sdk): clarify evaluator v2 boundary * feat(sdk): add evaluator v2 worker runtime * fix(evaluator): resume only unfinished replayed runs * feat(sdk): run hosted evaluator definitions * fix(evaluator): harden managed source sandbox and contain poison definitions An adversarial review of the server-authored `execution_mode='python'` evaluations (which run in the shared managed pod) found the AST sandbox escapable several ways: `str.format`/`format_map` C-level field traversal, generator/frame introspection (`gi_frame.f_globals`) that reached the eval globals and could poison a process-shared namespace across evaluations, and `type.mro()` type-object reach — none of which start with `_`, so the dunder guard never saw them. Replace the attribute denylist with a **default-deny allowlist** (the transcript data surface plus pure string/collection methods), give each eval **fresh per-call globals** so nothing persists between evaluations, and reject any result whose text embeds a runtime object repr (`<... at 0x...>`, the heap-pointer/ASLR disclosure that falls out of any bound method's repr) at the output boundary. Drop `enumerate` and bare generator expressions — both were gratuitous pointer-repr sources. Also compile managed source lazily inside the per-run executor, so a definition the sandbox rejects dead-letters as one bounded `failed`/`eval_error` run instead of crashing the assignment and being reclaimed until its attempt budget is spent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * feat(evaluator): normal short polling instead of long-poll in the worker The v2 worker long-polled the claim endpoint (wait_seconds, server held the request open up to 25s), which ties up a server request handler per idle worker and does not match the normal-polling cadence of our other cloud surfaces. The worker now polls normally: claim returns immediately, and on an empty claim the worker sleeps the server-advertised poll_interval_seconds (from the register response, default 10s) before polling again. Wire changes (mirrored with the server): ClaimRequest drops wait_seconds and MAX_CLAIM_WAIT_SECONDS is removed; RegisterResponse gains poll_interval_seconds, which the worker adopts like heartbeat_interval_seconds and rejects if non-positive. WorkerConfig drops claim_wait_seconds and the request_timeout_seconds > claim_wait_seconds constraint. Contract fixture updated in lockstep with the agenteye copy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * fix(evaluator): sandbox managed source in a killable process (hermes SEC-001) Managed (server-authored) evaluations ran in an in-process ThreadPoolExecutor with an asyncio.wait_for timeout that only cancelled the awaiter — Python cannot kill the running thread, so `sum(range(10**20))` kept burning CPU well past the timeout and tied up the sole worker slot; conditions ran with no timeout at all. Run managed conditions/evaluators in a forked child with hard RLIMIT_CPU + RLIMIT_AS + a parent-side wall-clock SIGKILL, killed on timeout before capacity is released. The kernel enforces the limits on a separate process the parent can terminate outright — the one thing a thread cannot do. Only the result crosses back, as a small pickle, with the child's exception semantics preserved. `resource` is imported at module level (never in the child) and the child does only eval->pickle->write->_exit, so the fork holds no lock another thread owns. Defense in depth at compile: reject `**` with a large/non-constant exponent and cap AST size. A managed condition the sandbox rejects now dead-letters as condition_error instead of raising out of the plan loop. Also require execution_mode on the wire (F2): a falsy/missing value was silently coerced to `local`, running a `python` definition down the customer path. Only server-authored source is isolated; customer evaluators run their own trusted code in-process. New tests cover the compute/condition bombs, the AST bounds, the fork result round-trip, and the execution_mode rejection. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * fix(evaluator): fail closed when the fork sandbox is unavailable (hermes SEC-001) The non-POSIX fallback in _run_killable ran managed source directly (`return fn(session)`), so on a platform without os.fork an allowed-but-expensive expression like `sum(range(10**20))` got NO CPU/memory/wall-clock enforcement and could hold a worker slot indefinitely. Refuse instead: raise EvaluationSandboxUnavailable rather than execute server-authored source without a killable boundary. The managed worker only ships on Linux (fork present), so this never trips in production; it closes the "no fork => no sandbox => run it anyway" gap. New test simulates a fork-less platform and asserts managed eval + condition both fail closed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * fix(evaluator): fork+exec the sandbox + clamp the timeout (hermes SEC-001) Two SEC-001 problems in the fork-based sandbox: 1. os.fork() DEADLOCKS the worker. The managed worker is multi-threaded (asyncio loop, executor pool, writer daemon, health server); forking it and running Python in the child hangs on a lock another thread held at fork. Reproduced in the container: the worker registered, forked on its first managed eval, and hung (health down, no progress). Unit tests missed it because they fork from a single-threaded context. Replace fork-and-run-Python with fork+EXEC: a fresh `python -m failproofai_sdk.evaluator._sandbox_runner` process reads the (kind, source, transcript-wire, limits) tuple, installs RLIMIT_CPU + RLIMIT_AS on itself, evaluates, and returns the pickled result; the parent bounds wall-clock with subprocess timeout + kill. exec clears the inherited lock state, so it is safe from a multi-threaded process. Verified under real background-thread churn: normal eval works, compute + condition bombs are killed at budget, no hang. 2. The server-provided per-definition timeout had no upper bound, so a large timeout_seconds removed the execution bound. Clamp the effective CPU/wall budget to MAX_SANDBOX_TIMEOUT_SECONDS (60s). Fails closed (EvaluationSandboxUnavailable) if the sandbox cannot be spawned or the transcript is not serializable. Tests now use a real SessionTranscript (it must cross the process boundary via to_wire). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * fix(evaluator): bound the sandbox result on both sides (hermes SEC-001) The parent read the sandbox child's entire stdout and pickle.loads'd it, so a permitted expression building a huge result (metrics={str(x):1 for x in range(100000)}) could OOM the worker despite the child RLIMIT. Bound it on both sides: the child now validates the result (result_items / the 25-result limit) and refuses to serialize anything over SANDBOX_MAX_RESULT_BYTES (1 MiB) before it crosses; the parent reads via a temp-file-in / Popen with a capped, timed stdout read and kills the child on overflow or timeout. Input moves to a temp file (the transcript can be large; feeding a big stdin while bounding stdout invites a pipe deadlock). eval_key is threaded to the sandbox so the child can enforce the 25-item limit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * fix(evaluator): bound aggregate sandbox memory (hermes SEC-001) A 2 GiB per-sandbox limit did not bound the host: max_concurrency up to 32 could run 32 sandboxes at once (~64 GiB), and a permitted expression can allocate memory before returning a valid result (`([0]*200000000, EvalResult(...))[1]`). Lower the per-sandbox address space to 512 MiB (generous for a <=25 MiB transcript, rejects the ~1.6 GiB allocation) AND cap concurrent sandbox processes with a semaphore, so the aggregate (~2 GiB) is bounded independent of the worker's claim concurrency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * Harden evaluator v2 sandbox; fix condition selection and error mirror - COR-001: managed (python) applicability now follows the server's condition_source, never a colliding local condition with the same (eval_key, eval_version). Condition selection branches on execution_mode, mirroring the evaluator branch below it. - API-001: recognize the server's `incomplete_plan` terminal error — added to the ERROR_SPECS mirror and the shared contract.json fixture (byte-identical with the server). - Adversarial-audit (SEC): close a heap-address disclosure bypass. The output-boundary `<obj at 0xADDR>` guard was anchored on `<`, so an allow-listed str(x).replace("<","") / f-string / % kept the live address while stripping the match. The defense moves to compile time: a bound method (the only reachable value with a pointer repr — transcript and result types are frozen, pointer-free dataclasses) may only be CALLED, never referenced as a bare value, so no reachable value carries a pointer repr through str()/f-string/%. The output-boundary scan is kept and broadened (no leading `<`) as defense in depth. Regression tests cover the colliding-key condition, the three bypass payloads, and that legitimate called-method/data-attribute stringification still works. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * Count sandbox-slot wait against the execution timeout (hermes SEC-001) `_run_sandboxed` acquired the MAX_CONCURRENT_SANDBOXES slot with an unbounded wait and only started its wall-clock deadline afterward. The runtime runs this in a thread and `asyncio.wait_for` cancels only the awaiter, so a run queued behind busy slots could — after its caller was already reported timed out — still acquire a slot and launch a sandbox; 28 threads could pile up behind 4 long sandboxes and starve the worker (conditions have no runtime-level wait at all). One wall-clock deadline now covers BOTH the slot wait and execution: the slot is acquired with the remaining budget, and on timeout (or a slot acquired exactly at the deadline) the run raises EvaluationTimeout without spawning a child. Regression test: more concurrent compute bombs than slots all resolve within ~one budget, not N serialized budgets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * fix(evaluator): report why source was rejected; scrub the sandbox child's env Found reviewing #758 alongside agenteye#652 as one system, with a real server, a managed worker and two customer-hosted workers running. Surface the reason a server-authored definition was rejected Every failure collapsed to "evaluation raised <TypeName>", so a hosted definition that can never run reported only "evaluation raised UnsafeEvaluatorSource" — on every session, forever, with nothing telling the author what was wrong. It matters because the server accepts any source that passes its size and key checks: it does not (and in Rust cannot cheaply) validate the sandbox's single-expression grammar, so a definition that is structurally unrunnable is published with 201 Created and then fails silently per-session. Observed exactly that end to end: a perfectly ordinary multi-statement evaluator was accepted by the API and failed every session with no diagnosis. UnsafeEvaluatorSource now reports its detail ("evaluator_source must be one expression"), bounded to MAX_ERROR_MESSAGE_BYTES. Deliberately narrower than the generic handler, which still reports the type name only: UnsafeEvaluatorSource is raised by our own validator BEFORE any customer source executes and its message describes the source's shape, so it carries no transcript content — whereas an arbitrary eval exception can quote the transcript it was reading into a field that is persisted and displayed. Ordered before `except Exception` so it is reachable (it subclasses ValueError). Scrub the sandbox child's environment subprocess.Popen inherited os.environ, so the sandbox executing untrusted server-authored source ran with FAILPROOFAI_EVALUATOR_TOKEN in its environment — on the FailproofAI-managed pod, the cross-tenant credential the whole fleet authenticates with. The AST allowlist and empty __builtins__ stop a managed expression from reaching os.environ today, so this is defence in depth rather than a live escape: it means a future gap in those restrictions cannot be escalated into credential theft. Only what the interpreter needs is forwarded, PYTHONPATH included — without it the child cannot import the sandbox runner at all. Verified: 148 evaluator tests pass. The sandbox itself held under direct attack — open()/eval()/globals() die as NameError on empty builtins, dunder and introspection attributes are refused at compile time, and a 10**9-element allocation bomb was contained as a per-eval MemoryError in 497ms with no host memory movement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(evaluator): give the condition compute bomb a margin that survives a fast interpreter `test_condition_compute_bomb_is_also_bounded` failed on CI under Python 3.14 after the previous commit, while passing locally — the signature of a machine-speed coin flip rather than a real regression. The cause is the bomb's size, not the sandbox. The test asserts that a CPU-bound condition cannot finish inside its budget, but used `sum(range(10**8))` against a 1-second budget: ~1.35 CPU-seconds measured on 3.14, a 1.35x margin. On a fast enough runner the sum simply completes and nothing times out. 3.14 is the version that fails first because it is the fastest — 1.35s against 3.13's 1.44s here. Its evaluator twin one function above already uses `10**9` (~13x margin) for the same 1-second budget, so the condition variant was carrying a bomb ten times smaller for no stated reason. Matching it restores the margin and costs no wall-clock: the sandbox kills the child at its budget either way, so a bigger bomb only widens the gap between "killed" and "could have finished". The test still completes in ~1.06s. This changes a test rather than the code because the code is correct — the property under test (a CPU bomb in a condition is stopped by the sandbox budget) is unchanged and now actually verified rather than raced. The threshold was the defect. Also records this PR's two SDK fixes in the changelog section they belong to. Verified with CI's own command on the version that failed: `uv sync --locked --extra dev --python 3.14 && uv run pytest tests/ -q` — 961 passed, 9 skipped, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fp-cloud-cli: mirror the new evaluations:run permission Adds `evaluations:run` to ALL_PERMISSIONS (in the server's declared order, after evaluations:trigger). It is a normal key-assignable grant — the credential a customer evaluator pod authenticates with — so `fp keys create --permission evaluations:run` and `fp users` accept it, it lands in the admin preset, and it stays out of read-only/standard. Mirrors server auth.rs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * sdk(evaluator): fail closed when kernel resource limits are unavailable SEC-001 (hermes review): on a platform without the stdlib `resource` module (e.g. Windows), the sandbox child's `_install_limits` no-ops, so a permitted expression could allocate unbounded memory in each managed-worker child before the parent's wall-clock kill lands — the advertised RLIMIT_AS cap is never imposed. `_run_sandboxed` now refuses with `EvaluationSandboxUnavailable` BEFORE spawning any child when `_resource` is unavailable, rather than run server-authored source unbounded. Regression test verifies no child is started. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * sdk(evaluator): bound the condition phase by the lease; make sync-eval thread leaks observable Two hermes advisories on the v2 worker runtime. Pre-plan condition phase vs the lease. Conditions were evaluated serially with no lease awareness before the plan was created, and a managed condition may run its full sandbox budget — so a few near-budget conditions could burn the whole assignment lease before the plan request, and the server then fences the plan as lease_lost and reclaims the assignment in a loop instead of recording a result. The lease cannot be renewed before the plan (the server only extends a lease for a planned assignment with running runs), so the worker now bounds the phase to the lease: each condition is capped to the time remaining before a plan-submission margin (using assignment.lease_expires_at when it is in the future, else the negotiated lease duration measured from now, which keeps the bound from firing spuriously on a replayed/stale deadline in tests or under clock skew), and once that budget is gone the remaining conditions are skipped as `lease_exhausted` rather than run. Local conditions, which previously ran with no timeout at all, are bounded the same way. The complete fix — renewing the lease during the condition phase — needs a server-side pre-plan heartbeat and is tracked separately. Timed-out synchronous evaluators. A synchronous evaluator that overruns its timeout runs in the executor thread and cannot be cancelled (CPython cannot interrupt a running thread), so its thread is orphaned; with the pool sized to the concurrency limit, one orphan on a single-slot worker silently stopped all further local evaluation. The eval executor now carries headroom over the semaphore so an orphaned thread does not immediately starve live capacity — the semaphore stays the true concurrency bound — and each orphan increments `sync_evaluations_orphaned` and logs a warning naming the evaluator so a hung one is findable. This is a finite cushion, not a cure for a permanently-blocked evaluator; the CHANGELOG points authors at async or managed evaluators for long or untrusted work. Tests: sync-timeout orphan counting + executor headroom; lease-exhausted conditions are skipped without running; lease-phase deadline honors a future lease and falls back to the duration for a stale one; condition budget caps by both remaining lease and per-definition timeout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * sdk(evaluator): let a managed comprehension read session on Python 3.10 (hermes COR-001) The sandbox eval passed `session` in the eval locals mapping (eval(code, fresh_globals, {"session": session})). A list/set/dict comprehension runs in its own scope and resolves a free name like `session` from GLOBALS, so on CPython 3.10/3.11 — supported versions — an allowed source such as `all([session.event_count > 0 for i in range(1)])` raised NameError. `session` now goes in the fresh per-call globals mapping and both the condition and evaluator eval paths use empty locals, so a comprehension resolves it while per-call isolation is preserved. Verified on 3.10 (reproduced the NameError without the fix) and passing 3.10–3.14. Regression test: test_comprehension_body_can_read_session. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018v4UWTsTpQaxMGdt7sJVtW * chore(security): time-box the nltk advisory that has no fix OSV turned red on GHSA-8mgp-746c-j5xp (nltk 3.10.3, CVSS 8.3), surfaced 2026-09-03 against a branch that neither introduced it nor can resolve it — the surface-late case `osv-scanner.toml` documents. nltk is transitive via llama-index-core and appears only in `sdk/python/uv.lock`, the dev/test lockfile that pins every extra so CI can exercise the adapters. The SDK's runtime dependency list is empty and the `llamaindex` extra is imported lazily, so nltk reaches no shipped code path. OSV reports "0 vulnerabilities can be fixed" with an empty FIXED VERSION; there is nothing to bump to, and the only alternative is dropping the extra and its adapter tests. `[[IgnoredVulns]]`, not `PackageOverrides`, so any OTHER advisory against nltk still blocks — including a fixable one, which is the signal worth keeping. Dated to match the chromadb entries so the whole list is re-reviewed in one pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014WXCEX4M9pjMUaM3vM237L * sdk(evaluator): fix five worker-runtime defects found in review Applied while red-teaming the pull-based Evaluator v2 worker against a live stack (agenteye #652 / failproofai #758). All five reproduced live and are covered by tests/test_evaluator_review_fixes.py; the full evaluator suite (153 tests) still passes. - authoring._bounded: reject C0 control characters and DEL in bounded result text (reasoning/summary/description/display_value/unit/label), matching the server's check_bounded. The SDK previously validated only byte length, so a result quoting transcript text with a NUL or ANSI escape was accepted locally then rejected by the server with a NON-RETRYABLE 422 — a successful eval was silently lost and its assignment dead-lettered. TAB/LF/CR are kept. - authoring.EvalResult.result_items: carry the eval's `reasoning` on the PRIMARY result (result_key == eval_key) for metric- and assertion-kind evals, not only on a score item. A non-score eval previously dropped its reasoning entirely. - runtime._execute_run_in_slot: always bound an evaluation by wall clock. A LOCAL (customer-authored) eval declaring no timeout_seconds ran with NO timeout — a hung await or unbounded judge call wedged the worker slot and held the lease forever. Falls back to DEFAULT_EVAL_TIMEOUT_SECONDS (300s, the contract's per-eval default); managed evals keep their tighter in-sandbox cap. - runtime._execute_run_in_slot: log the full traceback LOCALLY when a customer eval raises. The wire error stays scrubbed to the exception type (it can quote transcript data), but the pod now records the real exception so an author can debug their own eval instead of seeing only "evaluation raised HTTPError". - source._OBJECT_REPR: scope the output-boundary guard to the " at 0x..." repr tail and drop the bare "0x"+hex alternative, which false-rejected legitimate result text (a hex colour like 0xFFFFFF, a digest, an address the agent logged) as an embedded object repr. The tail still catches a '<'-stripped repr. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * sdk(evaluator): register insufficient_permissions in the error contract The server returns error code `insufficient_permissions` (HTTP 403) when a worker key lacks `evaluations:run` (server worker_auth.rs), but that code was absent from the frozen ERROR_SPECS on both sides and from both contract.json fixtures. Add it (403, non-retryable) to the SDK's ERROR_SPECS and the SDK fixture; the mirroring server-side entry lands in agenteye #652. Keeps the two contract.json fixtures byte-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * sdk(evaluator): harden the run loop against lease loss, replay, and too-large transcripts Follow-up review fixes (agenteye #652 / failproofai #758), all covered by tests/test_evaluator_review_fixes.py; evaluator suite (145 tests) green. - _heartbeat now beats IMMEDIATELY before its first sleep. The pre-plan condition phase can consume most of the claim-time lease, and the server only renews a planned assignment's lease on heartbeat — so sleeping a full interval before the first beat let the lease expire after the runs had started and cancelled every one. (Server-side: the plan handler also extends the lease.) - process_assignment tolerates an idempotent replay whose run set diverges from this attempt's plan. On reclaim the server re-serves the FIRST attempt's runs, which are authoritative — even one this attempt's condition would have skipped. The status-equality check is skipped on replay, and a replayed run absent from this attempt's selection is reconstructed from the assignment's descriptors instead of raising and dead-lettering an assignment that could never converge. - process_assignment catches transcript_too_large at the transcript fetch and returns cleanly (logging + a metric) instead of propagating. No runs are planned yet, the error is non-retryable, and re-raising wedged the poll loop and burned the whole retry budget — reproduced live, where a 28.6 MiB session froze the pod. The server terminalizes the assignment as too_large. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: chhhee10 <chetanraghuvanshi85@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Bumps react and @types/react. These dependencies needed to be updated together.
Updates
reactfrom 19.2.7 to 19.2.8Release notes
Sourced from react's releases.
Commits
1dd4ecb[FlightReply] Performance improvements when decoding (#37087)b0d2fdb[19.2.x] Update required references to GitHub repo (#36753)Updates
@types/reactfrom 19.2.17 to 19.2.18Commits
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)