Commit Graph

379 Commits

Author SHA1 Message Date
Tyler Slaton 56615da485 ci: reduce release delay, fix flakey test, use devops bot token (#5644)
## Summary
- Mint a GitHub App token for the stable release workflow and reuse it
for PR creation and follow-up API calls
- Disable lefthook during automation commits so release PR generation
does not depend on local developer hooks
- Relax the CopilotChat perf regression test to assert correctness
without a hard 5s wall-clock check

## Testing
- Unit/UI test updated to allow longer async rendering while still
verifying 100 messages render successfully
- Not run (not requested)
2026-06-23 13:56:33 -07:00
Tyler Slaton 83b21df925 Stabilize release PR token and chat perf test 2026-06-23 13:51:35 -07:00
Mike Ryan 3e4c515252 fix: preserve legacy thread endpoint behavior 2026-06-23 12:10:01 -07:00
Mike Ryan 3452657416 fix: update thread capability test fixtures 2026-06-23 11:36:58 -07:00
Mike Ryan 0187ec250a fix: address thread capability review feedback 2026-06-23 11:33:48 -07:00
Mike Ryan d906171c26 fix: honor thread endpoint capabilities 2026-06-23 11:33:10 -07:00
Mike Ryan db09796809 fix: gate thread endpoints by runtime capability 2026-06-23 11:32:30 -07:00
Nathan 🔶 Tarbert 7d644f22fa fix: reject pending human-in-the-loop promise on run abort (#5554) 2026-06-22 18:04:50 -04:00
Austin Merrick 4c71ea1138 fix(core): allow clearing headers via setHeaders with null/undefined
setHeaders typed headers as Record<string, string>, so there was no
type-safe way to clear a header (e.g. Authorization on logout) — passing
an empty string left the header present with a blank value.

Widen the signature to Record<string, string | null | undefined> and drop
any entry whose value is null/undefined. setHeaders remains a full overwrite,
so clearing one header while keeping the rest is the spread pattern:
setHeaders({ ...copilotkit.headers, Authorization: null }). A shared
normalizeHeaders helper enforces the same string-only invariant at both
write paths (constructor and setHeaders).

Update the react-core AuthTokenSync skill example to show the logout/clear
path and warn that a header must not be managed via both the headers prop and
imperative setHeaders (the provider re-applies prop-derived headers as a full
overwrite when its inputs change). Also update the setHeaders reference
signature docs. Tests cover null/undefined stripping, empty-string
preservation, overwrite-not-merge semantics, single-header clear via spread,
subscriber notification, and propagation to local and remote
(ProxiedCopilotRuntimeAgent) agents.

Fixes #5535
2026-06-19 14:13:02 -07:00
Mike Ryan b094156537 chore: release monorepo v1.61.0 2026-06-18 15:00:19 -07:00
Maxim 8bba3e5535 test(react-core): assert missing-config warning is silent for self-managed agents
Strengthen the license-signal test so it pins that selfManagedAgents
satisfies hasLocalAgents — the Enterprise warning fires while the
separate "Missing required prop" missing-runtime warning does not.

Refs #5417
2026-06-18 22:54:19 +02:00
Maxim 7ece925f12 feat(react-core): warn when selfManagedAgents is used without a license key
selfManagedAgents is part of CopilotKit's Enterprise Intelligence
offering. Emit an advisory console.warn (in both development and
production) when it is supplied without a publicLicenseKey/publicApiKey,
so production usage is surfaced. The signal is client-side and not
enforced — rendering still proceeds — and agents__unsafe_dev_only
remains a free local-dev escape hatch.

Refs #5417
2026-06-18 22:45:22 +02:00
Maxim 0b690a0290 test(react-core): fix inaccurate console spy comment
The spy comment claimed console.error was "not blanket-silenced", but
the mock implementation does silence it. Correct the wording.

Refs #5417
2026-06-18 22:08:48 +02:00
Maxim 9abaefa7be test(react-core): make self-managed agents render assertions self-contained
Clear the console.error spy inside the render helper so each assertion
is independent, and split the combined runtimeUrl/publicApiKey case into
two tests so each renders a single provider tree.

Refs #5417
2026-06-18 21:59:10 +02:00
Maxim 186bb719df test(react-core): strengthen self-managed agents validation coverage
Add empty-map (selfManagedAgents={}) throw case and the pre-existing
runtimeUrl/publicApiKey happy paths so a future gate inversion is
caught, and assert valid configs surface no unexpected console errors
instead of blanket-silencing console.error.

Refs #5417
2026-06-18 21:52:56 +02:00
Maxim 9907519989 fix(react-core): honor selfManagedAgents in CopilotKit wrapper validation
The v1 <CopilotKit> wrapper's validateProps threw ConfigurationError
whenever neither runtimeUrl nor a public key was supplied, ignoring
self-managed agents. This rejected the documented self-managed-agent
setup even though the underlying v2 CopilotKitProvider accepts it.
Mirror the provider's hasLocalAgents gate so selfManagedAgents and
agents__unsafe_dev_only satisfy the check.

Closes #5417
2026-06-18 21:11:04 +02:00
David McKay 0098840d42 test(react-core): assert HITL attribution survives the status transition
Extend the unscoped-tool attribution test to verify toolCallId persists and
agentId stays undefined after the tool moves InProgress -> Executing, not just
at InProgress.
2026-06-18 10:58:47 -05:00
David McKay ca07dcad63 refactor(react-core): exhaustiveness check for HITL render fallback
Code-review follow-up. Replace the unreachable `as any` fallback branch with
a compile-time exhaustiveness check (const _: never = props): a newly-added
ToolCallStatus now becomes a type error that must get its own branch, rather
than silently rendering with respond=undefined. Also correct the prop-build
comment (name/description are overwritten with the registration values, not
'normalized'). No behavior change for the three live statuses.
2026-06-18 10:58:42 -05:00
David McKay b8f6856b48 fix(react-core): accurate HITL attribution docs + defensive render fallback
Addresses code-review findings on the HITL attribution change:
- Correct the render-prop JSDoc: agentId is the tool's STATIC registration
  scope (undefined for unscoped tools), not the runtime sub-agent; toolCallId
  is the key to correlate with runtime attribution (onToolExecutionStart /
  event stream). Removes the over-claim that agentId resumes 'the correct
  sub-agent'.
- Compare props.status against the ToolCallStatus enum instead of string
  literals (removes silent drift risk).
- Inject name/description/agentId in the otherwise-unreachable fallback branch
  so attribution is never silently dropped if a status is ever added; cast
  the narrowed-never props to a record so the spread typechecks.

Behavior-preserving for the three live statuses; e2e suite green (13/13).
2026-06-18 10:51:52 -05:00
David McKay 93d3d80d80 feat(react-core): expose toolCallId and agentId on human-in-the-loop render props
The HITL render callback received args/status/result but no attribution, so
a UI could not tell which run raised an interrupt — the blocker for rendering
and resuming human-in-the-loop stops that originate from a subagent.

- Add toolCallId (already delivered at runtime via the renderer props spread;
  this only surfaces it in the type) and agentId (sourced from the tool's own
  registration) to all three ReactHumanInTheLoop render-prop variants.
- Thread agentId through useHumanInTheLoop's enhanced props.
- e2e tests assert both reach the render props through the real CopilotChat
  pipeline, and that agentId is undefined for an unscoped tool.

No shared renderer-contract or dispatch changes; no runtime behavior change.
2026-06-18 10:42:30 -05:00
Mike Ryan 237a176fbf chore: release monorepo v1.60.2 (#5517)
## Release monorepo v1.60.2

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.60.2`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.60.2`
   - Creates git tag `monorepo/v1.60.2`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
2026-06-17 10:46:56 -07:00
davidmckayv 692e52244c chore: release monorepo v1.60.2 2026-06-17 16:59:44 +00:00
Tyler Slaton 8ec7d0d4e5 docs(shell-docs): restore enterprise intelligence product name 2026-06-17 09:16:29 -07:00
Tyler Slaton 449237af0c fix: rename premium docs to intelligence platform 2026-06-16 22:09:48 -07:00
Tyler Slaton 88588223af fix(react-core): add dark mode styling for default tool rendering (#5455)
## Summary
- Update the default tool-call renderer to use dark-theme-aware classes
for the card, header, status badge, and detail panels
- Add coverage for the dark theme styling path in unit tests
- Add a Storybook example that demonstrates the default tool renderer on
a dark CopilotKit surface

## Testing
- Added unit tests for the renderer’s dark-theme class output and
expanded details state
- Not run (not requested)
2026-06-16 10:04:54 -07:00
Jordan Ritter 7b80590f67 fix(react-core): await runAgent in useInterrupt::resolve
resolve() previously called copilotkit.runAgent(...) without await and
without return, so callers had no handle to sequence against the resume
run's settle. The harness DOM-settle check timed out for any consumer
awaiting the assistant confirmation bubble.

Changes:
- Make resolve async, return await copilotkit.runAgent(...) so callers
  receive a Promise that settles when the resume run settles.
- Update InterruptHandlerProps / InterruptRenderProps resolve return
  type from () => void to () => Promise<RunAgentResult>.
- Wrap runAgent in try/catch + setPendingEvent(null) + rethrow, so
  rejection clears the popup AND propagates to awaiting callers
  (mirrors onRunFailed handler symmetry; closes the case where
  runAgent rejects before any run-failed event fires, e.g. network
  error pre-RUN_STARTED).
- onRunFailed now also setPendingEvent(null) symmetric with
  onRunStartedEvent.
- Regression tests: RESUME-PATH asserts resolve() returns a Promise
  that settles 1:1 with runAgent; RESUME-PATH-REJECT asserts rejection
  propagates, popup clears, console.error logs.
2026-06-15 17:11:39 -07:00
Tyler Slaton bd2db6009a Add dark theme support to default tool renderer 2026-06-15 11:09:12 -07:00
jinhyuk9714 9639b8d4d6 fix(react-core): refresh thread headers on provider updates 2026-06-12 12:47:32 -05:00
Tyler Slaton 930e182d41 fix(react-core): stabilize pin-to-send scrolling (#5386)
## What does this PR do?

Fixes `pin-to-send` scrolling in the v2 chat view.

- Re-attaches the non-autoscroll scroll listener after the real scroll
element mounts by depending on `nonAutoScrollEl`, not the stable
`scrollRef` object.
- Lets the `usePinToSend` spacer adjust in both directions as content
below the pinned user message changes, so the user message stays
anchored after streaming finishes and layout height changes.
- Adds regression coverage for the scroll-to-bottom button and spacer
adjustment behavior.

## Related PRs and Issues

Fixes #5355

## Tests

- `corepack pnpm -C packages/react-core exec vitest run
src/v2/hooks/__tests__/use-pin-to-send.test.tsx
src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.tsx`
- `corepack pnpm exec oxfmt --check
packages/react-core/src/v2/components/chat/CopilotChatView.tsx
packages/react-core/src/v2/hooks/use-pin-to-send.ts
packages/react-core/src/v2/hooks/__tests__/use-pin-to-send.test.tsx
packages/react-core/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.tsx`
- `git diff --check`

Attempted:

- `corepack pnpm -C packages/react-core run check-types`
- This failed in the local workspace on existing/type-resolution issues
outside this diff, including `react-markdown` JSX namespace errors,
missing `@copilotkit/runtime-client-gql` declarations, and existing e2e
mock `AbstractAgent` private member mismatches.

## Checklist

- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [x] If the PR changes or adds functionality, I have updated the
relevant documentation (N/A: bug fix only, no API/docs change)
- [x] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
2026-06-12 10:34:38 -07:00
Austin Merrick 9275ec2ce0 fix(react-core): cover mermaid-block + sub/superscript streamdown styles 2026-06-12 09:49:45 -07:00
Tushar-Khandelwal-2004 f90c3dcfd7 fix(react-core): scope streamdown markdown styles 2026-06-12 09:49:44 -07:00
ranst91 02c3a8aef0 chore: release monorepo v1.60.1 2026-06-12 13:03:45 +00:00
Ran Shem Tov 7805a9a57b fix: update cpk to use latest agui core packages 2026-06-12 11:16:19 +02:00
Austin Merrick de9d46d1df docs(skills): migrate CopilotKit skills to the v2 API
Bring the agent skills in line with the shipped v2 API so their examples
install, compile, and connect. Extends #5345 (which migrated the
copilotkit-setup SKILL.md body) to the rest of the skills.

- Imports: drop the nonexistent @copilotkit/react and @copilotkit/agent
  packages and the bare @copilotkit/runtime/express subpath; use
  @copilotkit/react-core/v2 and @copilotkit/runtime/v2 (+ /v2/express),
  and createCopilotHonoHandler / createCopilotExpressHandler rather than
  the deprecated createCopilotEndpoint aliases.
- Provider: CopilotKit from @copilotkit/react-core/v2 with
  useSingleEndpoint={false} on multi-route setups (the v1-compat bridge
  defaults to single transport and would 404 a multi-route backend).
- Routes: v2 catch-all Hono handler exporting GET/POST/PATCH/DELETE via
  handle() from hono/vercel, replacing the v1
  copilotRuntimeNextJSAppRouterEndpoint + ExperimentalEmptyAdapter.
- Integrations: per-framework agent classes matched to the shipped
  examples (LangGraphAgent/LangGraphHttpAgent from @copilotkit/runtime/
  langgraph, CrewAIAgent, MastraAgent, LlamaIndexAgent, HttpAgent from
  @ag-ui/client; Agno via HttpAgent, not @ag-ui/agno).
- Hooks/props: correct useAgent, useThreads, useRenderTool, identifyUser,
  and the chat-component props (defaultOpen, onSubmitMessage, the headless
  CopilotChatView render prop).

Validated across review rounds and a build test against the published
@copilotkit/*@1.60.0 packages (tsc passes, every /v2 subpath resolves).
Regenerated the skills/runtime and skills/react-core mirrors.
2026-06-11 14:43:45 -07:00
MikeRyanDev a6e8000c94 chore: release monorepo v1.60.0 2026-06-11 16:27:00 +00:00
SeoyeonKim 8e440a9e7d fix(react-core): stabilize pin-to-send scrolling 2026-06-11 22:56:07 +09:00
Benjamin Taylor 8d68a95bc9 docs(packages): drop client license-key prop references; Angular no longer needs a key
Follow-up correction. The client publicLicenseKey/publicApiKey prop is the
header→cloud path and is NOT what activates the Intelligence runtime (that's
the server-side COPILOTKIT_LICENSE_TOKEN). So:

- Remove the `npx copilotkit@latest license` guidance from all client-prop
  contexts — that CLI yields the server-side license token, not the client
  prop value.
- Revert the client-prop docstrings (copilotkit-props, v2 CopilotKitProvider)
  to bare one-liners; drop the premium/"requires a license key" framing from
  the headless hook, react-ui observability docs, and runtime logging/onError
  JSDoc rather than reframing.
- Angular: remove all `licenseKey` mentions from the README — it is no longer
  a premium feature (the license watermark is disabled) and the key is not
  needed to function.

Server-side license-token documentation remains deferred to the example/runtime
setup pass (Bucket B).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 07:22:37 -05:00
Benjamin Taylor 8956c668bc docs(packages): retire Copilot Cloud framing in SDK doc references, point to the license key
Cloud is no longer promoted; the Intelligence license key is its replacement.
Scrub the old Copilot Cloud system from SDK JSDoc / doc-comments / console
messages / README prose so code references reflect how the license key is
obtained and used, mirroring examples/integrations/*:

- publicApiKey/publicLicenseKey docstrings (react-core props + v2 provider,
  vue legacy types, copilot-context) describe the CopilotKit public license
  key, acquired via `npx copilotkit@latest license` or the dashboard;
  publicApiKey framed as the legacy alias of publicLicenseKey.
- Premium-feature docs (headless hook, react-ui Chat/Popup/Sidebar
  observability, runtime logging/onError) drop "Copilot Cloud"/"requires a
  publicApiKey" wording and the publicApiKey examples in favor of the public
  license key + publicLicenseKey.
- console-styling messages and the angular README point at the license key
  and the `npx copilotkit@latest license` command.

Defunct features (guardrails_c, authConfig_c, useCopilotAuthenticatedAction_c)
keep their code but lose their JSDoc (marked @internal defunct).

Functional surfaces untouched: api.cloud.copilotkit.ai endpoint, the
X-CopilotCloud-Public-Api-Key header, prop names, gating logic, tests,
CHANGELOGs. Example-app migration (Bucket B) deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 07:22:37 -05:00
Mark Fogle c036a97efa fix(react-core): scope the A2UI catalog context to the runtime's a2ui agents (#5369) 2026-06-11 05:07:11 +00:00
Austin Merrick 0518414f0a docs(skills): recommend CopilotKit from /v2 everywhere and scrub CopilotCloud mentions
Follow-up to #5345 per review feedback:

- Propagate the provider change to all remaining skills: every example,
  props table, eval check, and prose mention now recommends CopilotKit
  imported from @copilotkit/react-core/v2 (the compatibility bridge and
  strict superset) instead of CopilotKitProvider. Migration docs in
  copilotkit-upgrade now point at the /v2 import path as the target and
  explicitly warn against migrating to CopilotKitProvider.
- Scrub CopilotCloud / Copilot Cloud / CopilotKit Cloud branding from
  skills, replacing it with CopilotKit Intelligence where the hosted
  platform is meant. Literal endpoint URLs and real identifiers like
  MissingPublicApiKeyError are unchanged.
- Fix react-core provider-setup.md which claimed publicApiKey was the
  canonical prop; publicLicenseKey is canonical and publicApiKey is a
  deprecated alias, matching #5345.
- Edits made in the packages/*/skills source dirs for the three mirrored
  skills, with skills/ regenerated via pnpm sync:plugin-skills (this also
  re-pins the plugin version fields to 1.59.5).
2026-06-09 13:53:55 -07:00
Ran Shem Tov e5d3963db6 fix(core): bump @ag-ui core packages to 0.0.56 and adapt runHttpRequest
Bump @ag-ui/core, @ag-ui/client, @ag-ui/encoder from 0.0.53 to 0.0.56
across all packages.

@ag-ui/client 0.0.56 changed runHttpRequest from (url, requestInit) to a
fetch-thunk signature (() => Promise<Response>). Update the single-route
and connect transport paths in ProxiedCopilotRuntimeAgent to wrap the
request in () => this.fetch(url, init), restoring the broken envelope
transports.

Add @ag-ui/core, client, encoder, proto to minimum-release-age-exclude
in .npmrc so the freshly published 0.0.56 (under the 24h release-age
gate) installs in CI.
2026-06-09 17:47:43 +02:00
lukasmoschitz 6756eac460 fix(react-core): render intelligence-indicator icon cross-browser (#5316)
## Problem

The "CopilotKit Intelligence" indicator's icon (spinner → checkmark)
rendered **blank in Safari and Firefox**. Its geometry was defined
through the CSS `d:` property, which is Blink-only (Chrome/Edge) — so in
any other engine the stylesheet-driven path drew nothing.

## Fix

- **Geometry in the `d` attribute, not CSS `d:`** — renders in every
browser.
- **Two overlaid paths instead of one morphing path.** A spinning
**arc** that fades out, and a **checkmark** that draws itself in via
`stroke-dashoffset`, upright. Cross-fading two static shapes is more
robust than path-morphing (the old `d:` morph was Chrome-only anyway).
- **Arc spins via `transform-box: fill-box; transform-origin: center`**
— the Safari-safe way to rotate an SVG sub-element about its center.
(`transform-box: view-box` is mis-resolved by WebKit and spins
off-center; a SMIL `<animateTransform>` fixes Safari but stalls for a
beat on first paint in Chrome — `fill-box` + `center` is correct and
instant in both.)
- **Spin isolated to the arc**, so the checkmark always renders upright
regardless of where the spin was when the turn finished, and the arc
keeps spinning as it fades (no abrupt stop / snap-back).
- **`pathLength="1"` on both paths** so dashes are expressed as plain
fractions — one consistent, self-documenting idiom for both shapes.
- **`prefers-reduced-motion` support** added: the arc doesn't spin and
the in-progress → finished states swap instantly.
- Both stale design docblocks rewritten to describe the actual
implementation.

## Scope

Two files — `IntelligenceIndicatorView.tsx` and `globals.css`. No
behavior/runtime changes; purely the indicator's presentation. The
settle choreography (glass chrome, hue shift, faux-italic label) is
unchanged.

## Testing

- `nx test react-core` — 24 intelligence-indicator tests pass (the suite
asserts DOM structure/behavior; cross-browser rendering itself isn't
observable in jsdom and was verified manually in Chrome + Safari).
- oxlint / oxfmt clean; type-check clean for the changed files.
- Manually verified in **Chrome and Safari**: icon renders, spins
centered, fades out mid-spin, checkmark draws in upright; no Chrome
startup stall, no Safari wobble.
2026-06-09 13:36:38 +02:00
Lukas Moschitz a22796a822 fix(react-core): render intelligence-indicator icon cross-browser
The icon geometry was defined via the Chrome-only CSS `d:` property, so
the spinner/checkmark rendered blank in Safari and Firefox. Move the
geometry into each path's `d` attribute and split the single morphing
path into two overlaid paths — a spinning arc that fades out and a
checkmark that draws itself in (stroke-dashoffset) upright.

Spin the arc with `transform-box: fill-box; transform-origin: center` so
it stays centered in WebKit (view-box is mis-resolved there; a SMIL
animateTransform stalls on first paint in Chrome). Both paths use
`pathLength="1"` so dashes read as fractions, and all motion is gated
behind `prefers-reduced-motion`.
2026-06-08 14:54:42 +02:00
Jordan Ritter 19f8ef89c8 fix(react-core): correct useCoAgent JSDoc link and stale run description 2026-06-06 16:09:52 -07:00
Benjamin Taylor 1c92a69f58 fix(links): point cloud.copilotkit.ai web links at the Intelligence dashboard
New users were still discovering cloud.copilotkit.ai through docs pages,
the README, example READMEs, and in-app banners/console messages. Replace
all user-facing web links with dashboard.operations.copilotkit.ai (the
destination the marketing-site CTAs already use). Functional API endpoints
(api.cloud.copilotkit.ai) are deliberately untouched since existing cloud
customers depend on them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:20:44 -05:00
contextablemark 9bfeb74bc9 chore: release monorepo v1.59.5 2026-06-05 05:21:08 +00:00
Mark 9fda7e634d Merge branch 'main' into mark/oss-162-a2ui-recovery-client-ux 2026-06-04 17:58:58 -07:00
Mark Fogle 943c1421fe fix(react-core): hold the A2UI loader until the surface can paint a card (OSS-162)
onReady fired after the first processMessages, but a data-bound list paints
nothing until its data model arrives — so at high stream latency the skeleton
dropped ~1s before the first card (blankness). Gate onReady on the surface
actually being renderable: for data-bound surfaces (components reference data via
`path`), wait for the first non-empty updateDataModel; static surfaces are
renderable from components alone. Latency-independent — fires exactly when the
first card can exist. Fallback timer bumped to 8s (backstop only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 00:57:43 +00:00
Mark Fogle 195de1fc6a fix(react-core): swap the A2UI loader on actual paint, not a fixed delay (OSS-162)
A fixed cross-over delay can't be right — the time from ops-arrive to first card
varies with stream latency, payload size, and machine speed. Instead, the surface
processor fires onReady the moment it has processed its first operations; the
renderer swaps one animation frame later. The timer is demoted to a 1.5s safety
fallback. Latency-independent true replacement, no magic number to tune.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 00:45:04 +00:00
Mark Fogle 5977a58836 fix(react-core): keep the A2UI surface mounted across the cross-over swap (OSS-162)
The prior cross-over returned a different tree shape once ready (top-level
`surfaces` vs the held wrapper), so React unmounted+remounted ReactSurfaceHost at
the swap — throwing away the offscreen-painted surface and reintroducing the gap
at the swap point. Keep ReactSurfaceHost in ONE stable position and only toggle
its wrapper styling (offscreen→in-flow) + the loader overlay, so the painted
surface is preserved. Also track the last pre-paint snapshot from content (not the
lagging operations state) so the paint snapshot can't clobber it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 23:43:12 +00:00