mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
codex/cloudplot-showcase-migration
15424 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
240ea8a575 | test(angular): verify inspector configuration before append | ||
|
|
32827246c0 | fix(react-core): defer inspector until after hydration | ||
|
|
a5e072301a | fix(inspector): restrict defaults to development builds | ||
|
|
3c44aa4640 | fix(react-core): assign inspector core explicitly | ||
|
|
fd4d06b089 | refactor: simplify default inspector integration | ||
|
|
90af71b401 | docs: document browser Inspector defaults | ||
|
|
4691946a8f | feat: enable the Inspector by default in browser frameworks | ||
|
|
72fcd1dabd |
docs(langgraph): fix inaccurate "Works the same for create_react_agent" comments (7 sites) (#6614)
Closes #6607. Verified against the pinned `langgraph_prebuilt` (1.1.0): `create_react_agent` has neither `middleware` nor `system_prompt` parameters, rejects `state_schema=CopilotKitState`, and is deprecated in favour of `langchain.agents.create_agent`. Readers following the comment hit an immediate `TypeError`. All 7 occurrences on `main` are updated (4 sites noted in the issue plus the 3 that landed with #5469): - `showcase/shell-docs/src/content/docs/integrations/langgraph/agent-app-context.mdx` (Python + TypeScript) - `showcase/shell-docs/src/content/docs/integrations/langgraph/frontend-tools.mdx` (Python + TypeScript) - `showcase/shell-docs/src/content/snippets/integrations/langgraph/frontend-tools.mdx` (Python + TypeScript) - `showcase/shell-docs/src/content/reference/hooks/useFrontendTool.mdx` (Python) Each comment is replaced with an accurate note (”`create_agent` supersedes the deprecated `create_react_agent`, which accepts neither `middleware=` nor `system_prompt=`”), and the TypeScript snippets now reference `createReactAgent` (camelCase) instead of the Python `create_react_agent` name — the second, smaller problem noted in the issue. |
||
|
|
ba4260ad66 |
feat(web-inspector): add Event Snippets and save-as-snippet (#6649)
Open Inspector Event Snippets on localhost. You can compile, save, and replay AG-UI events in chat. Chat shows a bookmark icon next to a tool call, an A2UI block, or generative UI. Click the icon to save that turn as a snippet. ## What does this PR do? This PR adds the Inspector Event Snippets pane. You can: - Compile a snippet from a recipe (tool-call, reasoning, text, activity, raw) - Save snippets in origin-scoped localStorage (`cpk:inspector:event-snippets`) - Import and export snippets from the pane header - Replay a snippet into live chat through Inspector-only Core inject Each Run remints `messageId`, `parentMessageId`, `toolCallId`, and `runId`. The second Run of the same snippet is a new turn. On localhost, chat shows a bookmark icon beside a tool call, A2UI block, or generative UI. The icon is absolutely positioned. It hangs to the right when there is room. Otherwise it hangs to the left. The card stays full chat width. The React demo adds `sayHello`, `getTime`, `addNumbers`, and a **Call 3 tools** suggestion. ## Related PRs and Issues - Linear [OSS-874](https://linear.app/copilotkit/issue/OSS-874/new-features-also-allow-users-to-emit-specific-events-from-the) ## 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 - [x] "Allow edits by maintainers" is checked (lets us help iterate on your PR directly — faster turnaround for everyone) ## Testing ### Commands run 1. Lefthook pre-commit ran `nx` targets `test`, `publint`, and `attw` for 27 affected projects. All passed. 2. I did not run `pnpm test:pr` (full repo). Lefthook ran the affected package matrix only. ### Manual test 1. Run `pnpm demo:react` from the repo root. 2. Open http://localhost:3000 3. Open Inspector and select Event Snippets. 4. In chat, click **Call 3 tools**. Confirm three tool cards at full chat width, with the bookmark hanging outside the card. 5. Click a bookmark, then click Run twice. Chat shows a second turn with new IDs. ### How this PR makes testing easy - `packages/web-inspector/src/lib/__tests__/event-snippets.test.ts` - `packages/core/src/__tests__/inspect-inject.test.ts` (covers two injects) - React demo: `examples/v2/react/demo/src/app/page.tsx` ## Linked issues Linear [OSS-874](https://linear.app/copilotkit/issue/OSS-874/new-features-also-allow-users-to-emit-specific-events-from-the) ## Risk / rollback - If ID remint is wrong, a second Run can no-op or duplicate a turn. - The save icon shows on localhost Inspector (or when `showDevConsole` is `true`). - Rollback: revert this PR. ## Public API change **Before** Angular has no Inspector service. ```ts // no CopilotInspector export from @copilotkit/angular ``` **After** ```ts import { CopilotInspector } from "@copilotkit/angular"; const inspector = inject(CopilotInspector); inspector.openInspector({ messageId: "msg-1", menu: "event-snippets", }); ``` React and Vue apps that already mount Inspector on localhost need no new caller code. Chat wires the bookmark through Inspector context. `@copilotkit/core` exports `ɵinjectInspectorEvents` for Inspector only. App code must not call it. There is no public Core emit API. |
||
|
|
bc0cea234a | docs: fix missing space in CONTRIBUTING heading | ||
|
|
78a751a887 | docs: use em dash in AG-UI protocol line in README | ||
|
|
198b226d94 | docs(showcase): narrow worker pin policy note | ||
|
|
e90a3dd938 | fix(showcase): preserve worker policy on railway pin | ||
|
|
c56f1d8a43 | fix(showcase): verify promoted deployment id before success | ||
|
|
c5a0f36efc | docs(showcase): document durable worker recycling | ||
|
|
a2344ece7f | fix(showcase): enforce worker policy in production operations | ||
|
|
92d3de79fb | fix(showcase): recycle harness workers with clean exits | ||
|
|
1351fa63d2 | fix(showcase): apply durable worker policy in staging | ||
|
|
dfa78fd231 |
fix(agentcore): ignore terraform provider caches under nested modules
The Terraform ignore rules were anchored to `infra-terraform/…`, which matches only the root provider cache. `terraform init` writes one next to every module, and the nested copies are the large ones: 834MB under infra-terraform/modules/backend/ was fully stageable, one `git add -A` from being committed. Switch the two cache patterns to unanchored `**/` forms, matching what this branch already did for the `venv/` layout. Verified with git check-ignore: the root cache, the nested cache and the nested lock file are all ignored now, tfstate and tfvars still are, and no tracked file (checked against modules/backend/locals.tf) is caught by the widened patterns. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f3dc78891b |
style(agentcore): apply oxfmt to the README table and tofu fmt to locals.tf
The Prerequisites table in examples/integrations/agentcore/README.md picked up a uv row whose URL is wider than the existing column padding, leaving the table unaligned against oxfmt (the repo formatter covers .md — see the lint-fix glob in lefthook.yml). Re-run oxfmt --write on that one file. locals.tf fails tofu fmt on a pre-existing misalignment in the Lambda source-path block that this branch did not introduce; since the file is already in this branch's diff, align it here so every changed .tf file passes tofu fmt -check. Scoped to locals.tf only — modules/backend/copilotkit_runtime.tf has the same class of debt but is out of this diff and is left alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
9cea7fde33 |
fix(agentcore): exclude local-only artifacts from the docker build context
`examples/integrations/agentcore/.dockerignore` covered only cdk.out, node_modules, __pycache__, *.pyc and the two venv layouts. Everything else a developer generates in this tree — the Terraform provider cache, tfstate, terraform.tfvars, config.yaml, docker/.env, generated aws-exports.json, the Vite build output, amplify-deploy.zip, egg-info — was uploaded to the daemon on every build. The context is this directory and three consumers share it: the Terraform local-exec build in infra-terraform/modules/backend/runtime.tf, infra-terraform/scripts/build-and-push-image.sh, and the CDK DockerImageAsset in infra-cdk/lib/backend-stack.ts. Scope of the harm: both agent Dockerfiles COPY explicit paths and never `COPY . .`, so none of this reached a published image layer — there is no credential leak. The cost is context transfer on every build, and CDK asset-hash churn: DockerImageAsset fingerprints the whole context, so an unrelated local file change re-tags and re-pushes the image. Measured with a throwaway `FROM alpine / COPY . /ctx` probe against a context carrying a realistic set of local-only files (871424 KB .terraform provider cache plus the rest): before: 165 files, 877112 KB in-image, 897.74 MB transferred in 20.7s after: 144 files, 2476 KB in-image, 11.26 kB transferred The 21 dropped paths are exactly the intended ones; nothing else disappeared and nothing was added. Both agent images then rebuilt clean with --no-cache for linux/arm64, and `import langgraph_agent` / `import strands_agent` each printed OK inside the resulting containers. All *.example templates survive. The file now reaches full parity with the sibling .gitignore, and adds **/.DS_Store (covered by the repo-root .gitignore). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
47c5510b49 |
chore(deps): update github actions (#6639)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/setup-java](https://redirect.github.com/actions/setup-java) | action | major | `v5.7.0` → `v6.0.0` | | [astral-sh/setup-uv](https://redirect.github.com/astral-sh/setup-uv) | action | patch | `v10.0.0` → `v10.0.1` | --- ### Release Notes <details> <summary>actions/setup-java (actions/setup-java)</summary> ### [`v6.0.0`](https://redirect.github.com/actions/setup-java/compare/v5.7.0...v6.0.0) [Compare Source](https://redirect.github.com/actions/setup-java/compare/v6.0.0...v6.0.0) ### [`v6`](https://redirect.github.com/actions/setup-java/compare/v5.7.0...v6.0.0) [Compare Source](https://redirect.github.com/actions/setup-java/compare/v5.7.0...v6.0.0) </details> <details> <summary>astral-sh/setup-uv (astral-sh/setup-uv)</summary> ### [`v10.0.1`](https://redirect.github.com/astral-sh/setup-uv/releases/tag/v10.0.1): 🌈 Tolerate transient manifest timeouts [Compare Source](https://redirect.github.com/astral-sh/setup-uv/compare/v10.0.0...v10.0.1) ##### Changes Thank you [@​arguile-](https://redirect.github.com/arguile-) for making this action more resilient. ##### 🐛 Bug fixes - Tolerate transient manifest timeouts [@​arguile-](https://redirect.github.com/arguile-) ([#​1016](https://redirect.github.com/astral-sh/setup-uv/issues/1016)) ##### 🧰 Maintenance - chore: update known checksums for 0.12.4 @​[github-actions\[bot\]](https://redirect.github.com/apps/github-actions) ([#​1017](https://redirect.github.com/astral-sh/setup-uv/issues/1017)) ##### 📚 Documentation - docs: update version references to v10.0.0 @​[github-actions\[bot\]](https://redirect.github.com/apps/github-actions) ([#​1014](https://redirect.github.com/astral-sh/setup-uv/issues/1014)) </details> --- ### Configuration 📅 **Schedule**: (in timezone America/Los_Angeles) - Branch creation - "before 9am every weekday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/CopilotKit/CopilotKit). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zNS40IiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> |
||
|
|
328ee3cb58 | Merge origin/main into feat/OSS-871-view-thread-in-app | ||
|
|
fddfcfe742 |
fix(agentcore): stop two .env.example entries parsing as their own comment text
|
||
|
|
2e2fbf2181 |
fix(agentcore): stop --local adopting an unidentified listener on port 8080
`3df7d6764a` hardened `start_local_agent` so a pre-existing listener on 8080
could not be mistaken for the child it just spawned. That hardening never ran.
`main()`'s `--local` branch probed the port first and, on a successful TCP
connect, printed "Agent already running on localhost:8080" and skipped
`start_local_agent` entirely - the function is called from exactly one place,
the `else` of that same probe. So in the one scenario the hardening existed for,
a stranger owning 8080, the hardened code was unreachable and the tester chatted
with the stranger under a success banner, exit 0.
A bare TCP accept only establishes that *some* process is listening. It cannot
establish that the process is this example's agent. The fix removes the check
that made that inference:
- `main()` no longer probes 8080 on the start path at all. Adopting a listener
is now opt-in via `--use-running-agent`, and even then it is announced as
unverified ("did not start it and cannot verify it is an agent") rather than
as "Agent already running". The flag errors out when nothing is listening, and
argparse rejects it without `--local` instead of silently ignoring it.
- The port check moved into `start_local_agent`, before the "Starting local
agent" banner, where it now REFUSES on an occupied port instead of spawning a
child that cannot bind. Because `main()` no longer duplicates the probe, this
is the only port check on the start path, so it is genuinely reachable from
the shipped CLI - which is precisely what the previous attempt was not.
- With the pre-spawn refusal in place, the loop's `not port_already_busy` guard
became a provably-constant conjunct and was folded away. The durable half of
the earlier hardening, polling the child for liveness BEFORE looking at the
port, is unchanged and still reachable.
Same-pattern audit of the file found one more instance: `run_chat` printed
"[Completed in Xs]" purely because `invoke_agent` returned, which it also does
after an HTTP error. `invoke_agent` now returns a bool and the line reports
"[Failed in Xs]" when the exchange did not succeed. The request payload and the
streaming decoder are deliberately untouched (deferred).
Verified by driving the real `main()` via importlib against a foreign HTTP
server bound to 127.0.0.1:8080:
- pre-fix, `--local`: "Agent already running on localhost:8080" then
"Agent: I am a STRANGER on 8080, not the agentcore agent", exit 0.
- post-fix, `--local`: "Port 8080 is already accepting connections" plus how to
proceed, exit 1, nothing spawned.
- post-fix, `--local --use-running-agent`: talks to it, labelled unverified.
- post-fix, `--local --use-running-agent` with nothing listening: exit 1.
- ordinary path (port free, child really binds 8080): "Agent started
successfully", byte-identical to pre-fix output.
- child exits 1 with no listener: still caught in ~1s, not 30s.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
98968b49c2 |
fix(web-inspector): address review on event snippets
- Raw recipe: the Events JSON input now calls requestUpdate, so Run and Save stop being permanently disabled. - Tool args recovery: one depth scan replaces the parse-every-prefix loop. Truncated args from a streaming tool call now fail at once, not after seconds of blocked main thread. - Chat bookmark: hidden while the tool arguments are incomplete, so a partial payload cannot be captured. - saveEventSnippet: React, Vue, and Angular wrap the body, so a compile or storage failure is reported instead of becoming an unhandled rejection. - Vue and Angular now gate the in-chat affordances on a dev build plus localhost, the same as React. showDevConsole: true on a staging URL no longer puts a bookmark into a production chat. |
||
|
|
11895f77d1 |
flag the Next.js-served origin the quickstarts' relative runtimeUrl assumes
Every framework quickstart sets runtimeUrl="/api/copilotkit". That resolves only because Next.js serves the app and the runtime from one origin, and nothing on the page said so -- so a reader on a client-only frontend followed a step that could not work for them. Annotate the provider step in all 13 quickstarts that carry it, pointing at the per-frontend guides that show a standalone runtime server and an absolute runtimeUrl. The callout deliberately uses no root-relative links. The Angular surface reuses these same integration quickstarts via resolveAngularDoc's fallback to frameworkContentSlug, and its link contract keeps readers inside /angular/**; linking three other frontends' pages both broke that contract and was wrong content for an Angular reader. aws-strands is left un-annotated while the Strands rejuvenation is underway. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
bf44b367b8 | chore(deps): update github actions | ||
|
|
8ae9e00a5e |
chore: rename Enterprise Intelligence product copy (#6652)
## Why Rename the product from **CopilotKit Enterprise Intelligence** to **CopilotKit Intelligence** across the open-source repo and docs site. This is a copy and asset change. It does not rename public APIs, routes, packages, environment variables, or compatibility keys. **Enterprise Intelligence** remains only where the text explicitly names the enterprise tier. ## What changed - Updated 220 tracked files across guides, reference docs, snippets, examples, skills, nav labels, page metadata, and generated framework records. - Updated user-facing package TSDoc and runtime warning text, with paired test changes. - Kept self-hosting and pricing copy explicit about Team, custom Enterprise plans, and the Enterprise Intelligence tier. - Fixed grammar and possessives created by the rename, including thread lifecycle, auth, agent runner, and registry copy. ## Image updates | Asset | Change | | --- | --- | | Channels architecture, light | Visible label now says **CopilotKit Intelligence** | | Channels architecture, dark | Visible label now says **CopilotKit Intelligence** | | Managed pricing | Product heading now says **COPILOTKIT INTELLIGENCE**; the **ENTERPRISE** tier label remains | All three PNGs remain Git LFS assets. ## Compatibility boundaries | Preserved | Reason | | --- | --- | | `/premium`, `/concepts/oss-vs-enterprise`, and existing docs routes | No redirect or SEO migration | | `/images/enterprise-intelligence/*` | Existing asset paths | | `enterprise-platform` registry key and `intelligence-platform` module paths | Internal compatibility identifiers | | Public exports, package names, environment variables, and API symbols | No public API change | | Existing `go.copilotkit.ai/enterprise-intelligence-platform` target | Link label changed; target stays compatible | ## Validation | Check | Result | | --- | --- | | `pnpm check:public-api-manifest` | Passed; manifest unchanged | | React core, runtime, and Vue tests, typechecks, builds, publint, and attw | Passed | | Showcase scripts | 2,519 tests passed | | Shell docs lint and typecheck | Passed | | Shell docs test suite | 437 tests passed | | Shell docs production build | Passed; 223 pages | | Hosted CI on the current PR head | All required checks passed | Residual searches found no old product name or malformed rename variants. The remaining old slugs and paths are the compatibility identifiers listed above. ## Related PRs - Intelligence product and CLI: https://github.com/CopilotKit/Intelligence/pull/925 - Website: https://github.com/CopilotKit/website/pull/535 |
||
|
|
6f3638c446 |
document Copilot Runtime hosting for React SPAs
A React single-page app is the one frontend the docs could not get to a working runtime. Every framework quickstart hosts the runtime in a Next.js route handler and uses a relative runtimeUrl of /api/copilotkit, which only resolves because Next.js serves the app and the runtime from one origin. A Vite or CRA app has neither a server nor a shared origin, so that step had nowhere to land. Add a React SPA page covering only that difference: a standalone Node runtime server, the absolute runtimeUrl it requires, and cors: true -- which is off by default on createCopilotNodeListener, unlike the Express and Hono adapters. Everything else links back to the root React docs rather than restating them. Registering react-spa in the frontend registry is what makes /react-spa resolve; route resolution is gated on isFrontendId, so an unregistered page 404s. Vue and React Native are the precedent: registered, single-page, no namespaced subtree. The existing registry-driven guard in frontend-options already covers the new page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3df7d6764a |
fix(agentcore): stop a foreign listener on 8080 masking a dead agent child
The startup wait loop in start_local_agent checked the port before polling the child, so any process already listening on 8080 satisfied the port check on the very first iteration. The function printed "Agent started successfully" and returned while the real child was dying, and the caller then chatted with the impostor - the exact failure the fail-fast poll() was added to surface. Two changes, because reordering alone is not enough: on the first iteration a doomed child has not exited yet, so a pre-existing listener would still be mistaken for it. - poll() now runs before the port check, so an already-exited child is always reported with its exit code instead of being masked. - Port ownership is snapshotted before the spawn (check_port_available() returns True when the port is OCCUPIED, despite its name). When 8080 was already busy, an open port is no longer accepted as proof this child is serving; the child that cannot bind will exit and be reported with its real exit code, and the timeout message names the port conflict. Fully attributing a listener to a specific child would need a readiness signal from the agent itself (identity endpoint or handshake); refusing to trust a pre-existing listener is the smaller change that keeps the reported outcome truthful. Verified by driving the real function via importlib with a shimmed child: - foreign listener on 8080 + child exits 1: was "Agent started successfully" (returned a process that was dead 0.5s later), now "Agent exited with code 1 before port 8080 opened" and exit 1. - port free + child really binds 8080: still "Agent started successfully" and the live process is returned. - port free + child exits 1: still caught in ~1s, no 30s timeout burn. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
25b4fecbc5 |
docs(agentcore): converge the one uv/deploy contract across the files that state it
The AgentCore example states its Python-tooling and deploy contract in six places — two READMEs, four script self-docs, terraform.tfvars.example, the Terraform variable descriptions and .gitignore. There is only one contract, but each of the last three review rounds corrected a single copy of it, so the copies drifted apart and now contradict each other. This pass reconciles all of them against measured behaviour instead of patching one more surface. What the contract actually is, verified by running each command: - test-agent.py imports boto3/requests/colorama, so it runs under uv with no --project flag. `uv run` resolves the script path against the shell's cwd, not the project root, so `--project ..` is redundant, not required: both forms load infra-terraform/scripts/test-agent.py and both reach the same `FileNotFoundError: 'terraform'`. The script's Usage block claimed the flag was needed; it no longer does. - deploy-frontend.py (Terraform) is standard-library only with a 3.8 floor, so uv is optional. `uv run --no-project` and plain `python3` stop identically at "terraform is not installed". Its "Requires: uv" line said otherwise. - That same script cannot succeed at all. It requires a Terraform output named feedback_api_url; no root or module outputs.tf declares one (only an SSM parameter of that name). Fed the exact output set that outputs.tf does declare, it exits 1 at "Missing required Terraform outputs: feedback_api_url" before any build or upload. The README documented it as the working path for a Terraform deployment; it now says what happens and points at infra-cdk. Repairing the script or declaring the output is tracked separately. - agents/ holds two uv projects plus agents/utils/, which both Dockerfiles COPY in and which has no pyproject.toml or lockfile. "Each agent is its own uv project" overstated the guarantee. - docker mode needs Docker running but no separate build step: the apply's docker_build_push provisioner builds and pushes ARM64 before the runtime resource, which depends_on it. tfvars.example prescribed apply -> build script -> apply, contradicting the build script's own header. - .gitignore covered .venv/ but not venv/, the third and last surface of a guard .dockerignore and the Terraform image-hash filter already cover. A real UV_PROJECT_ENVIRONMENT=venv sync produced 2329 committable files (30MB); it is now ignored, matching the other two. Also corrected while auditing every command, path, prerequisite and tool version in the same tree: the frontend is Vite, not Next.js; the CDK tester reads config.yaml at the example root, not infra-cdk/config.yaml; the CDK frontend deployer's floor is 3.8, not 3.11, and its usage hint named a path that does not resolve from the example root; build-and-push-image.sh resolves region from AWS_REGION/AWS_DEFAULT_REGION/aws-config with no us-east-1 fallback; up.sh overwrites the STACK_NAME and MEMORY_ID that .env.example told you to fill in; and backend_pattern's "available patterns" listed two agents this example does not ship. Deliberately untouched, tracked elsewhere: the missing docs/ directory and its links, "Node.js 18+", the duplicated `cd infra-cdk` teardown, the Memory-and-Gateway-only claim, the undeclared aws_region variable (still the one remaining README/tfvars.example disagreement), the absent teardown section, the duplicate deploy-frontend.sh, and every code-behaviour defect in the scripts. Verified: py_compile on all four touched Python files, bash -n on all five shell scripts, and every documented command run from the directory its text names. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e5c902aeea | fix: align docs auth labels with product name | ||
|
|
db88826432 | chore: rename Enterprise Intelligence product copy | ||
|
|
efd71cf8e1 |
style(web-inspector): name the failure on the launcher itself (#6656)
## What does this PR do? Stacked on top of #6646. That change gives the launcher a red dot when the app's wiring is broken; this one makes the launcher **say what broke**, once per outage, and then go quiet again. The beat fires as it does today. Immediately afterwards the launcher opens sideways into a short pill carrying the failure's name, holds long enough to be read, and closes back to the plain mark with its dot. Nothing remains behind: the dot keeps carrying the state, the pill carries only the moment. ### Why a pill at all Two reasons, and the second is the ticket's origin. A dot says *something* is wrong without saying *what*, so a connection failure and a refused thread list — two problems you would check in completely different places — look identical from outside. And the report this work started from was a user looking at her own application and asking whether the button used to look different, because she could not tell what it was. A 36-pixel mark with a 6-pixel dot on it is not self-explaining. Once per outage, the launcher now names both the problem and itself. ### The gesture Four phases in series, each a named constant in one place: beat 1500ms, open 250ms, hold 2500ms, close 250ms. The whole gesture occupies the **existing single pending-beat slot** for its full duration, so this introduces no new scheduling concept — the third deferral reason already read "another beat is running", and a gesture is a longer beat. An announcement beat falling inside that window is deferred exactly as any of the other three reasons would defer it. If the failure resolves mid-gesture the pill closes early; the beat is left to finish, because a beat asserts nothing. ### The reveal is a clip, not a resize The pill is laid out at full width and revealed by animating a **rounded** rectangular clip. Nothing is scaled and nothing is resized. That matters because of a contract this component already carried: **no property that forces a layout on every frame**. Animating width fails it — the browser recomputes layout sixty times a second on someone else's page. A clip does not: the geometry is constant and only the visible region changes. The contract is therefore **restated rather than broken** — it was never "only opacity and transform", that was the accurate list at the time; the rule is the layout guarantee, and a rectangular clip satisfies it. The test that guards it now resolves to `["clip-path", "opacity", "transform"]`. The `round` component is not cosmetic. Without it the revealing edge is a straight vertical line sweeping sideways, which reads as a wipe across a stationary pill. With it the edge is the capsule's own cap travelling outward, which reads as the launcher opening. Two alternatives were built side by side and rejected. Animating width produces an end state indistinguishable from the clip and gives up the guarantee for nothing. Scaling horizontally squashes the mark itself — not merely the rounded ends, as first assumed — so the logo would need counter-scaling too, at which point the dot and the halo become ellipses. ### Where it opens, and where it does not The launcher is always anchored to the top-right corner, so the natural direction is leftwards. But it is draggable and its position persists, and it can be dragged to within a margin of the left edge — where a leftward pill needs far more room than exists, permanently, for that reader. So the direction is chosen from available room at the start of the gesture: left if it fits, otherwise right, and if neither side has room **no pill opens at all**. The dot and the beat still fire, so the signal is intact and only the label is lost. Constraining where the reader may drag the control to protect our animation was considered and rejected: the page is theirs. ### Padding is derived, not literal The text side of the padding is `size / 2` — the capsule's radius. Padding is measured from the bounding box, but the first half-height of that side is the rounded cap, so a literal `14px` put the words *inside* the curve. And the launcher size is itself a `clamp()` on the viewport, so no literal could have been right at every size. Half the size lands the text exactly where the cap ends and the straight edge begins. A test asserts the expression rather than the value, so a later "simplification" back to a literal fails. ### One surface, one edge The launcher's surface and edge are now two custom properties declared once on the wrapper and resolved by both the button and the pill. Before this, the button carried literals in a brand-override block and the pill carried its own — exactly the arrangement where someone changes one side and forgets the other. The pill's red-tinted border is gone. It read as a second object sitting behind the mark rather than as the launcher opening. The surface moves from near-black to a dark grey, which softens the edge against a white page from 20.5:1 to 16.5:1 — still far above any legibility threshold, and the dot's separating ring follows the same token automatically. The launcher's own ring and shadow are deliberately **not** suppressed while the pill is open. The alternative was looked at and rejected: an outline that vanishes reads as something being hidden, not as something growing. The consequence — the mark's outline stays visible inside the open pill — is accepted. ### Two lines, and a click that means something The label is a heading and a subline: the failure's name over `Open Inspector for details`. It stays exactly as tall as the launcher; the type is 12px over 10.5px and there is still room above and below. The subline is an instruction, so the pill **takes pointer events while it is on screen** and a click opens the Inspector exactly as pressing the launcher does — the same open source, so the telemetry catalogue does not change. It is deliberately **not focusable**: the launcher is already a focusable control for the same action, and a second tab stop for one action would be a regression. The subline is the one string in this feature that exists nowhere else in the product; the heading is word-identical to what the panel says. That exception is deliberate and recorded at the constant. ### Accessibility A polite live region speaks the failure once per outage, on the same rising edge as the beat and the pill, so "once per outage" needs no separate rule. It speaks the **failure class only** — an instruction delivered through an announcement is not something a screen-reader user can act on, and it would double the spoken length. Reduced motion shows the pill with the same words and the same reading time, without animating it. The halo is held statically, as it already was. ### Known limitation, carried over A runtime that dies **mid-session** is out of reach. The handshake runs once on connect and nothing re-probes, and a transport-level run failure is reported through the run channel without touching the connection state. Measured two ways; filed as **OSS-904**, to be fixed in core so that every reader benefits and this feature needs no change of its own. ## Tests `packages/web-inspector` goes to **564** tests across 26 files. New coverage: the two-line content per source, the shared subline, the height and typography contract, the derived padding on both directions, the rounded reveal on both stops of both keyframes, click-opens-Inspector, click landing on the right view per source, click ending the gesture, phase-gated clickability, the absence of a second tab stop, the shared surface and edge tokens, and the spoken sentence excluding the instruction. Two guards are worth calling out because they exist to fail a plausible future edit: the padding test asserts the **expression**, not the value; and the token test asserts the **sharing**, not the colour. ## Notes for the reviewer Every visual decision here came from building the variants side by side in a browser and choosing by eye, not from reasoning about CSS. Where an earlier assumption turned out wrong — the wipe was a missing `round`, not a technique problem; the padding was measured from the box, not flush — the correction is in the commit body. To see it: run the v2 React demo, leave the panel closed, and from the console point the core at a dead route with `document.querySelector('cpk-web-inspector').core.setRuntimeUrl('/api/nope')`. Two seconds later the dot appears, then the beat, then the pill. Click it and the panel opens on Home. Heal with the original URL. Watch it in a **focused** window — an unfocused tab defers the gesture by design. ## Related PRs and Issues - Stacked on #6646 - Refs OSS-903 - OSS-904 — the core-side follow-up for the mid-session limitation ## 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 - [x] "Allow edits by maintainers" is checked |
||
|
|
0943c5196e |
fix(runtime): make published declarations resolvable for consumers (#6674)
Closes the remaining half of OSS-899. PR #6644 removed the `require("reflect-metadata")` banner from the published `.d.cts` files, taking a bare strict-mode `import { CopilotRuntime }` from 81 errors to 10. This takes it to **1**, and that one is not ours. ## Result Measured by overlaying the built `dist` onto a real consumer install of 1.69.0 and typechecking a bare import under `strict` + `skipLibCheck: false`: | entry point | before | after | | -- | --: | --: | | `@copilotkit/runtime` | 10 | **1** | | `/v2` | 1 | **1** | | `/v2/express` | 1 | **1** | | `/v2/hono` | 1 | **1** | | `/v2/node` | 1 | **1** | | `/langgraph` | 7 | **6** | The single remaining error on every entry point is the same one, and it is in a third-party package — see "Not fixed here" below. ## The gate `scripts/validate-dts-imports.ts` is the companion to `validate-dts-ambient.ts`. That one checks the *shape* of published declarations; this one checks what they *reach for*, against a single invariant: > Every module a published `.d.ts` imports must be resolvable by someone who > installed this package and nothing else. It flags devDependencies, optional peers, dependencies whose types live in a devDependency `@types/*`, relative imports of JS-only bundler chunks, and an explicit ban on `graphql-yoga`. It started red on 18 violations and is now clean on all 175 declaration files. Wired into the existing `check-dts` target, so it runs in `check:packages` and `static_quality.yml`. It caught two problems the typecheck probe missed, because they happened to hoist in that particular install: `@whatwg-node/server` and `@langchain/langgraph-sdk`. ## The fixes - **`graphql-yoga` (5× TS2416)** — `GraphQLContext` was `YogaInitialContext & {...}`. That one reference pulled the Yoga barrel into every consumer program, and with it `lru-cache@10`, whose `implements Map` clause is what actually errors. Declared locally instead; structurally identical, so a real Yoga context still satisfies it. Nothing in this package serves GraphQL any more — every v1 integration entry point delegates to the v2 Hono endpoint. - **`@copilotkit/channels` (1× TS7016)** — a devDependency and a pure re-export of `channels-core`, so tsdown inlined its prebuilt declarations plus a rolldown helper chunk that ships JavaScript only. Types now come from `channels-core`, which is a real dependency and stays external. - **`cors` / `express` (1× TS7016)** — public declarations use their types, but both `@types` packages were devDependencies. Promoted to dependencies. - **`@anthropic-ai/sdk` / `groq-sdk` (2× TS2307)** — optional peers named in exported signatures. Params and getters now use `SdkClientLike`, a structural type a real client satisfies; the SDK types stay at the two call sites that need them, inside function bodies where they are never emitted. - **`@langchain/langgraph-sdk`** — was deep-importing `dist/types.messages`, an internal file of an optional peer. Now derived from the base class signature in `@ag-ui/langgraph`, a real dependency. - **`@whatwg-node/server`** — an `export type {}` workaround for microsoft/TypeScript#42873 whose own comment said it was waiting on TypeScript 5.5. We are on 5.9.2 and it typechecks without it. ## Not fixed here **1× TS2694** — `@copilotkit/license-verifier@0.5.0` references zod's `core` namespace, which only exists in zod v4; this package pins `zod ^3.23.3`. It is an external package (0.5.0 is the latest published), so the fix is either a license-verifier release or migrating this package to zod v4. Both are larger than this PR and deserve their own ticket. Also unchanged: the 6 remaining `/langgraph` errors, all inside `@ag-ui/langgraph`, `@langchain/core`, and `@langchain/langgraph-sdk`. The `TS2416` on `run` is present identically in pristine 1.69.0 — it is downstream of `@ag-ui/langgraph`'s own unresolvable deep imports, not something this branch introduced. ## Reviewer note The `SdkClientLike` swap narrows `adapter.anthropic` and `adapter.groq` for anyone reaching past `baseURL` and `apiKey`. Both adapters are v1-deprecated, and the alternative is a type error for every consumer who does not install those optional peers — but it is a public-surface change and worth a second opinion. ## Verification - `nx test runtime` — 2078 tests, 144 files, all passing - `nx build runtime` + `npm run check-dts` — both validators clean on 175 files - `tsc --noEmit` on the package — clean 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
105ac3cfb9 |
fix(core): keep exactly one tool result per tool call across message snapshots (#6294)
# fix(core): keep exactly one tool result per tool call across message snapshots ## Summary When an agent emits a MESSAGES_SNAPSHOT, AG-UI merges it by message id and can drop a tool message that TOOL_CALL_RESULT created. The next turn then sends an assistant tool call without its paired result, which providers reject. This PR records observed tool results for the current input and repairs history through AG-UI's returned-messages mutation channel. It keeps one tool message per toolCallId and composes with current main's first-seen message provenance. ## Root cause @ag-ui/client applies events against its own cloned messages array. TOOL_CALL_RESULT creates a tool message and inserts it after its assistant owner. A later MESSAGES_SNAPSHOT is a replace-by-id merge, so a missing tool entry can remove that result. packages/core had no record of the result event, so there was nothing to restore it from. ## What changed - StateManager records one ToolCallResultEvent per toolCallId on the current RunAgentInput. Events keep flowing through AG-UI's normal path. - At RUN_FINISHED, RUN_ERROR, and onRunFailed, reconciliation returns a fresh message array only when a repair is needed. AG-UI applies it through its normal mutation chain. - Pending results are released at each finished server-run boundary and at finalization, so a later server run under one input cannot resurrect a result removed by its snapshot. - The "Forwarded to client" sentinel classifier now lives in one internal module used by StateManager and run-handler.ts. ## The reconciliation rule toolCallId is the decisive identity: - No assistant owner for the call: do nothing. - A real tool message already exists for the call under any message id: keep one result and remove duplicate same-call representations. - Only placeholders exist: promote one to the canonical result and drop the rest. - Nothing exists: insert the result after its assistant owner and its contiguous tool messages. ## On the LangGraph duplicate LangGraph can represent one result with different streamed and checkpoint message ids. The regression fixture keeps the streamed result before the snapshot and places both representations in the snapshot. The final history and next-turn input contain one result for that toolCallId. Two tool messages for one toolCallId are one malformed history class. Keying reconciliation by toolCallId makes that duplicate unrepresentable while preserving normal event delivery. ## What this does not do - No direct agent.messages mutation, setMessages from a subscriber, or stopPropagation. AG-UI remains the owner of message application, ordering, and publication. - Reconciliation does not infer or rewrite run identity. Current main's event-derived run identity and first-seen snapshot provenance remain intact. - No message-to-run association is performed inside reconciliation. - No public API change, export, version bump, or changeset. ## Relationship to #3884 Related to #3884, but not marked as closing it. The event sequence in that issue has no MESSAGES_SNAPSHOT, and it already produces a correct turn-2 history on current main. Snapshot-dropped results are a real bug worth fixing independently, while the reporter's case still needs a raw event trace. ## Test plan All cases drive CopilotKitCore.runAgent() against real AbstractAgent subclasses. - Two-turn reproduction: a snapshot omits the result, and the next turn receives exactly one result. - LangGraph shape: differing message ids under one toolCallId produce one surviving tool message in real event-before-snapshot order. - Repeated server runs under one input do not resurrect a result removed by a later snapshot. - Terminal mutation, normal result propagation, duplicate results, placeholders, ownerless results, ordering, RUN_ERROR, local failure, and run ownership remain covered. - The focused core tests pass 32/32. Core typecheck, build, formatting, lint, and diff checks pass. CI checkboxes remain for GitHub. |
||
|
|
aa91d059ef |
test(web-inspector): cover the Learning error source, and quiet its lint
The `memory` latch shipped with no test at all, and the one test that mentions it still explained the old behaviour: "the Memory store is never even subscribed from here". That is no longer true -- opening the view does subscribe it -- so the test passed while teaching the wrong thing. The comment now says what actually holds: without an Intelligence context the store never fetches, so there is nothing to fail. Three tests: a refused load names itself and lands on Learning, a refused load arms nothing while the view has never been opened, and a resolved one clears itself. The middle one is the important one -- it is the constraint that makes `memory` an unread event rather than a state the launcher could mirror from a cold start. The harness needed two things. `intelligence` is now settable, because the view is a locked teaser without it and the latch is unreachable. And the memory store stub replaces its state rather than mutating it: the store's selectors memoize on the state they were handed, so an in-place edit reports the stale value forever and looks exactly like a signal that never fires. Also hoists the selector-escape pattern so `no-control-regex` can be suppressed on it with a reason -- the control range is the point, since an attribute selector escapes those too. Lint returns to its 5359 baseline. |
||
|
|
1d1a319b1f |
docs(web-inspector): record why the wiring latch arms without a window
Arming used to wait 2000ms so a blip produced neither dot nor beat. The window is gone and that is deliberate, but nothing said so, and the tests now assert immediate arming as the contract -- so the next reader would find no trace of the trade-off, only the behaviour. What the note holds: `threads` can flap and plays a whole gesture for a blip, bounded by the single pending-beat slot to one gesture per gesture length; `connection` cannot flap on its own because nothing retries the handshake; and the `connecting` branch already covers the retry case if a fix for the mid-session gap adds polling. Mirrored on OSS-904, which is where such a fix would land. |
||
|
|
e8cbd61ec9 |
docs(integrations): wire quickstart runtimes to Intelligence (closes OSS-932) (#6671)
## What does this PR do?
Twelve integration quickstarts opened by telling the reader to create a
free account and get a license key, then — seven steps later — showed a
runtime constructed like this:
```ts
const runtime = new CopilotRuntime({
agents: { ... },
runner: new InMemoryAgentRunner(),
});
```
`runner` and `intelligence` are mutually exclusive by construction
(`CopilotSseRuntimeOptions` declares `intelligence?: undefined`), so the
key provisioned in step 1 could not be consumed. Threads read "locked",
and nothing on the page indicated a choice had been made. Worse, **none
of the twelve pages ever named `INTELLIGENCE_API_KEY`** — after step 1
the key was never mentioned again.
Each page now:
1. Constructs the runtime with `intelligence: new
CopilotKitIntelligence({ apiKey: process.env.INTELLIGENCE_API_KEY! })`
and `identifyUser`.
2. Names `INTELLIGENCE_API_KEY` in a `.env.local` fence at the point the
route reads it.
3. Links `/premium/connect-your-runtime` — a good page that had **zero**
inbound links from any quickstart — from a callout that also documents
the in-memory opt-out.
The in-memory runner stays available and is labelled as the opt-out. It
was already the default (`super(options, options.runner ?? new
InMemoryAgentRunner())`), so passing it explicitly only ever added the
steer.
Also adds the required `name` field to the `identifyUser` snippets in
`connect-your-runtime.mdx` and the runtime skill's `agent-runners.md`.
Both omitted it, so copying either was a type error:
```
Property 'name' is missing in type '{ id: string; }' but required in type 'CopilotRuntimeUser'
```
### Scope
Not "every page mentioning `InMemoryAgentRunner`" — that is 37 files,
and most are legitimate (`backend/agent-runner.mdx` is *about* runners;
an AgentCore host is a Lambda and cannot host the Intelligence socket at
all). The scope is **pages that provision a license key and then show a
runtime that cannot consume it**, which partitions those 37 cleanly into
12 in-scope and 25 untouched.
Note that includes `docs/agent-spec/quickstart.mdx`, which is
byte-identical to `docs/integrations/agent-spec/quickstart.mdx`. Both
are fixed here; retiring the duplication is filed separately.
## Verification
Nine of the twelve runtime fences are `doctest="component"` gated, so
they are really compiled in CI against a pinned
`@copilotkit/runtime@1.68.3`. The new constructor was proven there
before being applied to twelve files.
- Extracted the docs tree with `scripts/doc-tests/extract.ts` → 16
snippets. **All 15 `component` snippets typecheck clean**, covering 9 of
the 12 edited pages plus 6 untouched pages (so it also rules out
collateral damage).
- Confirmed the gate can go red: removing `name` from an edited snippet
reproduces exactly the error above, so the pass above is meaningful.
- The 3 ungated fences (mastra ×1, langgraph ×2) were typechecked by
hand, since CI will not.
- `src/lib/__tests__/intelligence-wiring-docs.test.ts` passes 3/3. That
suite guards this defect class, and **this change brings these pages
into its coverage for the first time — 8 → 20 pages**, because a page
only enters the suite once it actually configures `intelligence`.
- `pnpm check:intelligence-env-names` passes. `pnpm check:plugin-skills`
initially failed (`packages/runtime/skills/**` is mirrored to
`skills/**`); synced, both copies included.
## Related PRs and Issues
- Closes OSS-932
- Part of the OSS-923 split, alongside OSS-933 (runtime silently drops
`runner` alongside `intelligence`)
- OSS-935 — the byte-identical agent-spec duplication
- OSS-936 — the Mastra fence's `getLocalAgents({ mastra })` does not
compile against `@ag-ui/mastra@1.1.2`. **Pre-existing on
`origin/main`**, reproduced on the unmodified snippet, not addressed
here
Worth noting for reviewers: the Mastra runtime fence cannot be
doctest-gated as written (it imports the `@/mastra` path alias, which
does not resolve in the extracted directory), and `@ag-ui/mastra` is in
no `doctest.json`. It is the least-verified page in the set on two
independent axes, and it accumulated two unrelated defects. That may
explain why only the Mastra evaluation cell surfaced this.
## Checklist
- [x] I have read the Contribution Guide
- [x] If the PR changes or adds functionality, I have updated the
relevant documentation
- [x] "Allow edits by maintainers" is checked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||
|
|
7ed7194077 |
docs(agentcore): reconcile deploy-frontend self-doc with the Terraform README
Two concurrent fixes landed different answers for the same command. The README fix measured that this script's import closure is standard-library only and that `--no-project` runs it without creating an example-root virtualenv; the self-documentation fix independently settled on `--project ..`, which also works but syncs 13 packages the script never imports. Take the README's form in both places. The point of the finding was that the two must not disagree, so leaving them on different invocations would have reproduced the defect. Verified: `--help` renders the new epilog, and the command strings in infra-terraform/README.md and scripts/deploy-frontend.py are now identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
54ed0464ac |
docs(agentcore): stop the uv comment claiming the runtime env vars
The comment "Configure UV for container environment" sat above a six-variable
ENV block, but only three of those are uv settings. The other three are read by
completely unrelated consumers, and the comment silently claimed them:
UV_COMPILE_BYTECODE / UV_LINK_MODE / UV_NO_CACHE uv (confirmed via `uv help
sync`, which lists all three as `[env: ...]` on uv 0.9.30)
DOCKER_CONTAINER=1 bedrock_agentcore runtime
OTEL_PYTHON_LOG_CORRELATION=true opentelemetry logging
instrumentation
PYTHONUNBUFFERED=1 the CPython interpreter
DOCKER_CONTAINER is the dangerous one. In the installed tree it has two
consumers, not one:
.venv/lib/python3.13/site-packages/bedrock_agentcore/runtime/app.py:402
if os.path.exists("/.dockerenv") or os.environ.get("DOCKER_CONTAINER"):
host = "0.0.0.0" # nosec B104 - Docker needs this to expose the port
else:
host = "127.0.0.1"
.venv/lib/python3.13/site-packages/bedrock_agentcore/identity/auth.py:163
if os.getenv("DOCKER_CONTAINER") == "1":
raise ValueError("Workload access token has not been set. ...")
(Line numbers are from the langgraph image, bedrock-agentcore 1.0.6. The strands
image pins 1.2.0, where the same two checks live at app.py:450 and auth.py:284.)
Both agents reach that first path: each builds a BedrockAgentCoreApp and calls
app.run().
The hazard: a reader who trusts the header and prunes "uv config" they don't
recognise unbinds the agent from 0.0.0.0, and nothing tells them. The bind check
is an `or` against /.dockerenv, which plain `docker run` creates -- so a local
smoke test still passes. AgentCore's managed runtime has no /.dockerenv, so the
breakage appears only once deployed. The HEALTHCHECK cannot catch it either: it
reaches the server over localhost from inside the container, which a
127.0.0.1-bound server answers happily.
Split the block into three ENV instructions, each under a comment describing
what actually reads those variables, so no variable's purpose is misattributed.
Two more instances of the same pattern, fixed in both files:
- "Create non-root user" also covered the USER line beneath it, which switches
to that user rather than creating it.
- The strands file said "Copy agent code and shared utilities" above three
COPYs, one of which is tools/. Now matches its langgraph twin.
This is comment-only. No environment variable, value, or ordering changed.
Verification, both images built for linux/arm64 from context
examples/integrations/agentcore:
- `docker run --rm --platform linux/arm64 -e GATEWAY_CREDENTIAL_PROVIDER_NAME=dummy
-e AWS_DEFAULT_REGION=us-east-1 <tag> sh -c 'env | sort'` before vs after is
identical for both agents (modulo the per-container HOSTNAME).
- `docker inspect -f '{{range .Config.Env}}...'` before vs after is identical
for both agents including ordering, so the baked config is unchanged, not
merely equivalent at runtime.
- The DOCKER_CONTAINER claim was reproduced against the real code path with
/.dockerenv masked and uvicorn.run stubbed: set -> host 0.0.0.0, unset ->
host 127.0.0.1.
- The HEALTHCHECK command was run against a 127.0.0.1-bound server inside the
container and passed, confirming the failure mode is silent.
- The two Dockerfiles are byte-identical modulo the agent name.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
484db5c8df |
fix(agentcore): finish the patterns->agents rename in the build script's error path
The `patterns/` -> `agents/` rename in build-and-push-image.sh landed on the
Dockerfile path, the `ls` target and the "Available agents:" label, but left
the `||` fallback on the same `ls` saying "No patterns found". When the agent
directory is missing entirely, the user saw a header and a body that named two
different directories:
Available agents:
No patterns found
Now both say "agents".
Deliberately NOT renamed, because they are established interface names rather
than directory vocabulary:
- the `-p, --pattern` CLI flag, its `case` arm, its help text in both the
header comment and usage(), and the `PATTERN` variable it populates;
- the "Pattern:" line in the config banner, which echoes that flag's value;
- the `backend_pattern` Terraform variable this flag mirrors, which is
declared in variables.tf and consumed across modules/backend.
Verified by running, not reading:
- `bash -n` clean before and after.
- Drove the real script to the missing-Dockerfile branch with a nonexistent
`-p does-not-exist`, an explicit `-s`/`-r`, and a local stub `aws` on PATH
that answers `sts get-caller-identity` with a dummy account id. No AWS API
was contacted and no real credentials were used.
- To fire the `||` arm itself, ran the same script from a copied tree with no
`agents/` directory. Before: "Available agents:" / " No patterns found".
After: "Available agents:" / " No agents found".
- Re-ran against the real repo tree, where `ls` succeeds and lists
langgraph-single-agent and strands-single-agent, confirming the success
path is unaffected.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
baa747eb4a |
docs(agentcore): migrate deploy-frontend.py self-documentation to uv
The Terraform frontend deploy script still told the reader to run `python scripts/deploy-frontend.py`, in both its module docstring Usage block and its argparse epilog. That contradicted two things the example had already moved on from: - infra-terraform/README.md documents `uv run --project .. scripts/deploy-frontend.py`, and - the sibling infra-terraform/scripts/test-agent.py had already had its usage text migrated to `uv run --project .. scripts/test-agent.py`. The whole agentcore example moved to uv; this one file's self-documentation did not. Aligned it with the README and the sibling rather than inventing a third convention. Also corrected the stale prerequisite line, which is the same bug pattern. It named "Python 3.8+" and no uv. Walking the full import closure confirms this script imports only the standard library (argparse, atexit, json, os, re, shutil, subprocess, sys, time, pathlib, typing) -- it pulls in none of the example-root deps and does not import scripts/utils.py -- so the "no external dependencies" fact is preserved in the new wording. But the documented invocation now goes through the example-root pyproject.toml, whose tooling project pins `requires-python >= 3.12`, so advertising a 3.8 floor for the documented command was wrong. The in-file `sys.version_info < (3, 8)` guard is left alone as the direct-interpreter safety net. Verified by running, not reading, from examples/integrations/agentcore/ infra-terraform: - `uv run --project .. scripts/deploy-frontend.py --help` renders the new epilog. - `uv run --project .. scripts/deploy-frontend.py` reaches the script and stops at "terraform is not installed" (the prerequisite loop). - With a no-op terraform stub on PATH and every AWS credential source removed, it gets past prerequisites and stops at "AWS credentials not configured or invalid". No AWS API was called -- credential lookup failed locally. No real credentials were used at any point. - `python3 -m py_compile` on the file passes. Confirmed empirically that `--project ..` does not change the working directory, so the relative `scripts/...` path in the new text resolves from infra-terraform/; the interpreter uv provisions is 3.13.2, which satisfies the >= 3.12 floor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
f69990b437 |
docs(agentcore): fix false uv dependency claims in Terraform README
The infra-terraform README justified `uv run --project .. scripts/deploy-frontend.py` with "The Python dependencies live in the example-root pyproject.toml". Both halves of that were wrong, and the command did needless work. What was false: 1. `infra-terraform/scripts/deploy-frontend.py` has no third-party dependencies. Its full import closure is argparse, atexit, json, os, re, shutil, subprocess, sys, time, pathlib and typing — all standard library, and it imports no local module. It never touches boto3/requests/PyYAML/colorama from the example-root `pyproject.toml`. 2. `--project ..` was not what made the root project reachable. `uv` already discovers `examples/integrations/agentcore/pyproject.toml` by walking up from `infra-terraform/` (it is the only pyproject.toml on that walk-up path), so the flag was redundant even for scripts that do need those packages. What it did add was a forced sync of the example-root `.venv` — 13 packages — before a script that imports none of them. The documented invocation is now `uv run --no-project scripts/deploy-frontend.py`, with plain `python3 scripts/deploy-frontend.py` noted as equally fine. The sibling `scripts/test-agent.py` genuinely differs — it imports boto3, requests and colorama — so it is documented separately as plain `uv run` (no `--no-project`, and no `--project ..` either), and the README now says so rather than making the two scripts falsely uniform. Verified by running, from `infra-terraform/`, with no AWS API calls: - `uv run --project .. scripts/deploy-frontend.py --help` (old form) printed "Creating virtual environment at: .../agentcore/.venv" and "Installed 13 packages", then ran .../agentcore/infra-terraform/scripts/deploy-frontend.py. - `uv run scripts/deploy-frontend.py --help` (no flag) produced the identical venv creation, the identical 13-package install and the identical resolved script path, confirming `--project ..` is a no-op for discovery. - `uv run --no-project scripts/deploy-frontend.py --help` (new form) resolved the same absolute script path and left no `.venv` at the example root at all. - `python3 scripts/deploy-frontend.py --help` likewise ran clean with no sync. - `uv run --no-project` on `scripts/test-agent.py` fails at `test-agent.py line 36, in <module> import boto3` (ModuleNotFoundError), while plain `uv run` syncs the 13 root packages and resolves its imports — which is why the two scripts are documented differently. Resolved script paths were captured with a runpy probe run under the very same `uv run` invocation form, using a non-`__main__` run name so module-level imports execute but `main()` does not. Audited the rest of the file for the same class of checkable-and-false claim. The remaining assertions hold: `amplify_app_id` and `amplify_staging_bucket` are real outputs in `outputs.tf`; the example-root `scripts/deploy-frontend.py` does use `aws cloudformation describe-stacks` and does take a stack name via `sys.argv[1]`; `stack_name_base` and `backend_pattern` are declared in `variables.tf`; and `--pattern` does override the `backend_pattern` value parsed from `terraform.tfvars`. Separately-tracked gaps (undeclared `aws_region`, missing `admin_user_email`, absent teardown section, undocumented `build-and-push-image.sh` and duplicate `scripts/deploy-frontend.sh`) are left untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6db61abbc8 |
fix(agentcore): exclude non-dotted venv/ from the docker build context
`.dockerignore` excluded `**/.venv/` only, while its counterpart —
`venv_path_regex = "(^|/)\.?venv/"` in
infra-terraform/modules/backend/runtime.tf — deliberately covers BOTH
`.venv/` and `venv/`, the layout `uv sync` produces under a non-default
`UV_PROJECT_ENVIRONMENT=venv`. The two halves of the same guard disagreed,
and the comment above that local justified itself by claiming
`.dockerignore` already excluded the tree — which was false for `venv/`.
Consequence: with `UV_PROJECT_ENVIRONMENT=venv`, the virtualenv tree
entered the docker build context that feeds both Terraform's
`docker build` and the CDK `DockerImageAsset` hash in
infra-cdk/lib/backend-stack.ts, while Terraform's own content hash
ignored it. Compose Watch (docker/docker-compose.yml `agent` service,
context `..`) inherits the same rules.
Auditing the rest of the file surfaced the same
narrower-than-what-it-guards pattern in the CDK output rules:
`cdk.out*/` and `infra-cdk/cdk.out*/` are path-anchored, so a `cdk.out`
directory anywhere else was not excluded. Replaced both with
`**/cdk.out*/`. The path-anchored `infra-cdk/node_modules/` and
`frontend/node_modules/` lines were already subsumed by the
`**/node_modules/` line below them and were dropped for the same reason.
Deliberately NOT touched here (separate tracked finding): `.terraform/`,
`docker/.env`, `config.yaml`, `terraform.tfvars`, `*.tfstate`,
`aws-exports.json`, `.git/`, `frontend/dist`.
Verified by measurement, not by reading. Marker files were planted in
`venv/`, `.venv/`, `cdk.out/`, `cdk.out-lg/`, `infra-cdk/cdk.out/`,
`frontend/cdk.out/`, three `node_modules/` locations and
`__pycache__/`, at root, agent-package and deep-nested depths. A
throwaway `FROM busybox / COPY . /ctx` image then listed the real build
context.
before: 148 files in context, 5 of them leaked —
agents/langgraph-single-agent/venv/CTXPROBE.txt
agents/langgraph-single-agent/venv/CTXPROBE_mod.py
agents/strands-single-agent/venv/lib/python3.13/site-packages/pkg/CTXPROBE.txt
frontend/cdk.out/CTXPROBE.txt
venv/CTXPROBE.txt
after: 143 files in context, zero leaked; `comm` over the two
listings shows those 5 paths as the only difference and no
project file dropped.
`**/.venv/` still works after the edit: the root and agent-package
`.venv` markers are absent from both listings, and the after-listing
contains no `.venv/`, `venv/`, `node_modules`, `cdk.out`, `__pycache__`
or `*.pyc` path at all. The `**/` prefix was confirmed to match zero
path segments (root-level `.venv/` was excluded by `**/.venv/` before
the change), which is what makes `**/cdk.out*/` a strict superset of
the two anchored rules it replaces. All scratch directories were
removed; `git status` is clean apart from this commit.
The runtime.tf comment was re-worded to name both patterns so it is
true again; the filter logic itself is unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
0771fb98dc |
docs: fix Anthropic thinking snippets to adaptive thinking (#6606)
## What & why Every Anthropic extended-thinking snippet in the docs was stale, and the AI SDK one was outright broken. Surfaced by @hejtmii in #2191, who pointed out the deprecated `{ type: "enabled", budgetTokens: 10000 }` form. Investigating it turned up two further defects he didn't mention. Three distinct problems: 1. **The AI SDK snippet never enabled thinking at all.** It passed the options as a second argument to `anthropic(...)`, but `AnthropicProvider` declares `(modelId: AnthropicMessagesModelId): LanguageModelV3` — one parameter. Provider options belong in `providerOptions.anthropic` on `streamText`. This was a hard TypeScript error, so anyone copying it got a compile failure, and the shape was silently ignored by the provider. 2. **The TanStack snippet used a model id and a key name the adapter no longer accepts.** `claude-sonnet-4` is not in `@tanstack/ai-anthropic`'s model union, and that package spells the field `budget_tokens`, not `budgetTokens`. 3. **All five sites used the deprecated thinking form.** To be precise about blast radius: these snippets pinned Sonnet 4 / 4.5, where `{ type: "enabled", budgetTokens }` is still accepted, so they were not returning 400s as written. The form is deprecated from Claude 4.6 and rejected outright on 4.7+, so the cost was teaching a pattern that breaks the moment a reader bumps the model — which is exactly what a docs reader does. ## Changes - `providerOptions.anthropic` for the AI SDK snippet, with `thinking: { type: "adaptive" }` + `effort`. - `thinking: { type: "adaptive", display: "summarized" }` for the TanStack snippet. - `advanced-configuration.mdx` modernized (it was already structurally correct — just the deprecated shape). - Models pinned to `claude-sonnet-4-6` across all three files. - New callout on the reasoning-visibility trap (see below). - Cross-link from the custom-agent reasoning section to the BuiltInAgent `providerOptions` page — #2191's reporter went looking for a BuiltInAgent thinking example and didn't find the one that exists. ### Why `claude-sonnet-4-6` and not a newer model This is deliberate, not staleness. From Opus 4.7 onward (including Sonnet 5 and Opus 5) Anthropic defaults thinking `display` to `"omitted"`, and `@ai-sdk/anthropic@3.0.49` exposes no `display` option (its only `display*` fields are computer-use tool params). On a newer model these snippets would emit `REASONING_*` events carrying **no text** — silently defeating the purpose of a page about reasoning. Sonnet 4.6 defaults to `"summarized"`. The added callout documents the trade-off so a future model bump is a conscious choice. ## Testing No runtime code changed, so verification is that the new snippets compile against the real installed providers and the old ones do not. Typechecked with the repo's own `@ai-sdk/anthropic@3.0.49`, and `@tanstack/ai-anthropic@0.16.9` installed fresh. **AI SDK — new form passes:** ``` $ npx tsc --noEmit --skipLibCheck --strict ... __snippet_check.ts EXIT=0 ``` **AI SDK — old form fails (mutation check, confirms the defect was real):** ``` $ npx tsc --noEmit --skipLibCheck --strict ... __snippet_check_old.ts __snippet_check_old.ts(7,41): error TS2554: Expected 1 arguments, but got 2. ``` **TanStack — new form passes, old form fails:** ``` ===== NEW ===== (no output) ===== OLD ===== old.ts(6,28): error TS2345: Argument of type '"claude-sonnet-4"' is not assignable to parameter of type '"claude-fable-5" | "claude-haiku-4-5" | "claude-opus-4-1" | "claude-opus-4-5" | "claude-opus-4-6" | "claude-opus-4-7" | "claude-opus-4-8" | "claude-opus-5" | "claude-opus-5-fast" | "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-sonnet-5"'. old.ts(8,33): error TS2322: Type '"enabled"' is not assignable to type '"adaptive" | "disabled"'. ``` Wire-shape confirmed by reading the provider's compiled request builder: `thinking: { type: "adaptive" }` is forwarded as-is, and `effort` is emitted as `output_config: { effort }` — the correct modern location. `effort` values were checked against each provider's own union (`@ai-sdk/anthropic` has no `xhigh`; `claude-sonnet-4-6` in TanStack resolves to `AnthropicAdaptiveThinkingOptions`, which has no `effort`, so none is shown there). MDX integrity checked: `Tabs`/`Tab`/`Callout` tags and code fences all balance in every edited file. Link target verified — `integrations/built-in-agent/meta.json` sets `"root": true`, which strips that prefix, so `/advanced-configuration` is the correct absolute URL (matching how `server-tools.mdx` and the section index already link to it). Also confirmed no `budgetTokens`/`budget_tokens` occurrences remain anywhere under `showcase/shell-docs/src/content/` except the explanatory comment. ## Scope Docs only. Three things deliberately **not** included: 1. **`BuiltInAgent`'s `ModelString` union still lists only pre-4.6 Anthropic models.** It is an open union (`| (string & {})`), so the new snippets typecheck without touching it, but refreshing that list is a separate code change. 2. **`showcase/integrations/claude-sdk-typescript/src/agent_server.ts:1125` still sends `thinking: { type: "enabled", budget_tokens: 2048 }`.** That cell defaults to `claude-sonnet-4-6`, where the form is deprecated-but-functional, so it works today and would only break if `CLAUDE_MODEL` were pointed at 4.7+. It is app code under `showcase/` with its own rules, so it belongs in its own PR. 3. **The rest of #2191.** Replaying `thinking`/`signature` blocks on follow-up turns is a genuine runtime gap — `convertMessagesToVercelAISDKMessages` has no `reasoning`-role branch, and the signature never leaves the runtime — and needs its own PR. Leaving #2191 open. Refs #2191 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
cbe6a81ff4 |
fix(runtime): keep optional peer SDK types off the published surface
@anthropic-ai/sdk and groq-sdk are optional peers, so a consumer who never uses
those adapters does not install them -- yet both were named in exported
signatures, which is a TS2307 on a bare `import { CopilotRuntime }`. The
LangGraph agent had a third case, and a worse one: it deep-imported
@langchain/langgraph-sdk/dist/types.messages, an internal file of an optional
peer.
The adapter params and getters now use SdkClientLike, a structural type a real
Anthropic or Groq instance satisfies. The SDK types stay for the two call sites
that need them, inside function bodies where they are never emitted. The
LangGraph message type is derived from the base class signature in
@ag-ui/langgraph, which is a real dependency.
Narrows adapter.anthropic and adapter.groq for anyone reaching past baseURL and
apiKey. Both adapters are v1-deprecated and the alternative is a type error for
every consumer.
|
||
|
|
1d9f19713a |
fix(runtime): ship the @types packages our public declarations depend on
dist/v2/runtime/endpoints/express.d.cts imports types from `cors` and `express`. Neither ships its own declarations, and both @types packages were devDependencies, so whether a consumer resolved them came down to whether something else in their tree happened to hoist them. Moving them to dependencies makes the published types self-contained. |
||
|
|
3755a227d5 |
fix(runtime): drop the obsolete @whatwg-node/server type workaround
`export type {} from "@whatwg-node/server"` worked around microsoft/TypeScript#42873
and its own comment says it was waiting on the TypeScript 5.5 stable release.
The repo is on 5.9.2 and typechecks without it.
It was reaching a devDependency, so it emitted an import of a module consumers
never install.
|