Commit Graph

147 Commits

Author SHA1 Message Date
Alem Tuzlak 42d3c92fbd chore: merge origin/main into tyler/default-browser-inspector 2026-08-27 12:09:27 +02:00
tylerslaton 9629e930d1 chore: release monorepo v1.69.2 2026-08-26 00:18:42 +00:00
Tyler Slaton b3b339f544 Revert "feat(web-inspector): add Event Snippets and save-as-snippet (#6649)"
This reverts commit ba4260ad66, reversing
changes made to 47c5510b49.
2026-08-26 02:11:19 +02:00
MikeRyanDev 6053e4e262 chore: release monorepo v1.69.1 2026-08-25 18:50:37 +00:00
Alem Tuzlak 5391c4886b feat(web-inspector): add view thread in your app (#6562)
## What does this PR do?

Lets a developer open a saved Inspector thread in the live official
chat.

- New header action: **View in your app**
- Official React and Vue chat switch to that thread
- A pinned `threadId` does not block the switch
- **Stop viewing** or an app thread change restores the previous thread
- Example threads have no action
- Production builds hide the action
- Same agent only. No matching official chat shows an error in the
Inspector

Core owns a two-way EventClient bridge
(`@tanstack/devtools-event-client`). The root import is a no-op in
production.

Docs: Inspector guide, section **View a thread in your app**.

## Related PRs and Issues

-
https://linear.app/copilotkit/issue/OSS-871/new-features-add-a-new-view-thread-in-your-app-feature

## 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
2026-08-25 13:52:52 +02:00
Tyler Slaton b53fa8f1ea refactor(inspector): consolidate framework integration 2026-08-25 11:25:08 +02:00
Tyler Slaton 0748627929 docs(inspector): remove obsolete configuration guidance 2026-08-25 11:25:08 +02:00
Tyler Slaton 39d5598f0e fix(inspector): simplify framework lifecycle mounts 2026-08-25 11:25:07 +02:00
Tyler Slaton a5e072301a fix(inspector): restrict defaults to development builds 2026-08-25 11:25:06 +02:00
Tyler Slaton fd4d06b089 refactor: simplify default inspector integration 2026-08-25 11:25:05 +02:00
Tyler Slaton 4691946a8f feat: enable the Inspector by default in browser frameworks 2026-08-25 11:25:04 +02:00
Alem Tuzlak 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.
2026-08-25 09:39:37 +02:00
Alem Tuzlak 328ee3cb58 Merge origin/main into feat/OSS-871-view-thread-in-app 2026-08-24 19:58:19 +02:00
Alem Tuzlak 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.
2026-08-24 19:10:06 +02:00
Mike Ryan db88826432 chore: rename Enterprise Intelligence product copy 2026-08-24 09:38:15 -07:00
Alem Tuzlak 4bd576d4ea Merge branch 'main' into alem/oss-874-inspector-event-snippets 2026-08-24 15:48:38 +02:00
MikeRyanDev 71977ddfce chore: release monorepo v1.69.0 2026-08-21 18:09:45 +00:00
Alem Tuzlak 76c8e23a0b feat(web-inspector): add Event Snippets and save-as-snippet
Developers can compile, save, and replay AG-UI events from Inspector.

Localhost chat can save a live turn as a snippet.
2026-08-21 19:39:18 +02:00
Alem Tuzlak 3b4f9b7662 test: stabilize slow package import checks
Give the React dist-context and Vue SSR import-safety tests enough time on slower CI runners.
2026-08-20 19:17:27 -07:00
Tyler Slaton 7180a14dcb Merge main into Inspector docs quickstart callouts 2026-08-20 18:15:00 -07:00
Ben Taylor d30983f406 refactor(vue): make tool-call memoization lint-valid (#5932)
## What does this PR do?

Makes the existing Vue tool-call memoization lint-valid without changing
rendering behavior.

The existing `v-memo` placement on the fallback renderer inside the
tool-call loop violates the `vue/valid-v-memo` placement constraint.
This refactor introduces a Vue-valid component boundary while preserving
the optimization contract:

- Named `#tool-call-<toolName>` and generic `#tool-call` consumer slots
remain reactive.
- Only the registered fallback renderer remains memoized.
- The fallback memo boundary matches the React counterpart's
renderer-level optimization.

The focused tests act as behavior-preservation and regression guards for
slot updates and fallback rerender prevention.

## Related PRs and Issues

- None.

## Verification

- `CI=1 pnpm exec nx run @copilotkit/vue:test -- --run
src/v2/components/chat/__tests__/CopilotChatToolCallsView.test.ts
--reporter=dot` — 14/14 passed.
- `CI=1 pnpm exec nx run @copilotkit/vue:check-types` — passed.
- `CI=1 pnpm exec nx run @copilotkit/vue:build` — passed.
- Direct ESLint from `packages/vue` on all touched source/test files —
passed.
- `git diff --check upstream/main...HEAD` — passed.
- `CI=1 pnpm exec nx run @copilotkit/vue:lint` remains blocked by 172
pre-existing errors in unrelated files; no package-wide lint cleanup is
included.
- The broad commit-hook suite encountered an unrelated SSR timeout; the
final tree was not changed afterward.

Coverage preserves generic and named slot updates, unchanged fallback
rerender prevention, tool-name changes, agent-specific renderer
selection, status/result behavior, and renderer precedence.

## Scope and exclusions

This is limited to the Vue tool-call rendering boundary, its parity
note, and focused tests. It does not change React behavior, package-wide
lint errors, attachment work, or unrelated rendering paths.

## Checklist

- [x] Contribution guide and package instructions reviewed.
- [x] Relevant Vue parity documentation updated.
- [x] Allow edits by maintainers is enabled.
2026-08-20 14:11:46 -05:00
BenTaylorDev aa3fb29dce chore: release monorepo v1.68.3 2026-08-20 10:27:07 -07:00
contextablemark b0233c4eb0 chore: release monorepo v1.68.2 2026-08-20 02:19:06 +00:00
Tyler Slaton 4b2586bd90 fix(web-inspector): load saved threads in active chats 2026-08-19 15:34:03 -07:00
github-actions[bot] ac22a414ef style: auto-fix formatting 2026-08-19 12:05:07 +00:00
Alem Tuzlak 06cef9e659 feat(web-inspector): add view thread in your app
Let the Inspector load a saved thread into the official React or Vue chat. Core owns a two-way EventClient bridge. Official chat configuration applies an in-memory override that wins over a pinned threadId. Production builds hide the action.
2026-08-19 13:50:39 +02:00
tylerslaton 1f9b60b231 chore: release monorepo v1.68.1 2026-08-14 21:05:45 +00:00
tylerslaton e6864b6bdd chore: release monorepo v1.68.0 2026-08-14 20:11:31 +00:00
Ben Taylor 3a80c2696e feat(vue): mirror React's useAgent thread scoping, remove thread cloning (#6234)
## Problem

Vue's `useAgent` implemented per-thread agent **cloning** — a mechanism
React never had. Passing a `threadId` silently handed you a copy of the
agent:

```ts
useAgent({ agentId: "assistant", threadId: "thread-1" })  // → a clone, keyed (agent, threadId)
```

The clones lived in a module-level `WeakMap` (`globalThreadCloneMap`),
so:

- Nothing tied a clone's lifetime to the scope that created it — they
were never released.
- Components had to *look up* which copy was live.
`CopilotChatMessageView` called `getThreadClone(registryAgent,
config.threadId) ?? registryAgent` just to find the agent actually being
rendered.
- `getThreadClone` / `globalThreadCloneMap` were exported from the
module purely so components could do that lookup.

Meanwhile React grew an explicit contract for the same use case in
#6141: a private *proxied* agent, registered under a local `agentId` and
routed to a `runtimeAgentId`.

## Change

Deletes cloning entirely and ports React #6141's contract to Vue.

`cloneForThread`, `getOrCreateThreadClone`, `getThreadClone` and
`globalThreadCloneMap` are gone — zero references remain, including in
prose.

`UseAgentProps` becomes a base plus a two-branch union, with the same
all-or-nothing rule React now enforces:

```ts
useAgent()                                       // shared registry agent
useAgent({ agentId })                            // shared registry agent
useAgent({ agentId, runtimeAgentId, threadId })  // private proxied agent
```

Every partial set — `{ agentId, threadId }`, `{ agentId, runtimeAgentId
}`, `{ runtimeAgentId, threadId }` — is a compile error, backed by the
same three runtime guards with the same messages for callers TypeScript
doesn't reach.

### Parity with #6141

| | React (#6141) | Vue (this PR) |
|---|---|---|
| scoped branch | `agentId` / `threadId` / `runtimeAgentId`, all
required `string` | same, as `MaybeRefOrGetter<string>` |
| unscoped branch | `agentId?: string`, `threadId?: undefined`,
`runtimeAgentId?: undefined` | identical |
| runtime guards | 3 | same 3, same messages |
| thread resolution | prop → chat config, gated on `hasExplicitThreadId`
| identical |
| proxy registration | balanced effect on core + both ids | same deps |

## Two Vue-specific details

Both are load-bearing and were found by tests failing, not by
inspection:

**The pin watcher's first source is `() => agent.value`, not `agent`.**
Vue sets `forceTrigger` when any array watch source is a shallow ref, so
passing the ref directly re-ran the pin on *every* `triggerRef(agent)` —
i.e. every streamed message — re-pinning the inherited thread over one
`CopilotChat` had deliberately set for the chat it renders. Two existing
suites cover this (`uses the explicit agentId and threadId over
inherited configuration`). React has no equivalent hazard because effect
deps compare by identity.

**`CopilotChat` assigns `agent.threadId` inside its `/connect`
watcher**, not a separate one. `CopilotKitCore.connectAgent` reads that
field *synchronously* (`run-handler.ts`) to decide whether a restore is
fresh, so a later assignment lets `/connect` address the previous thread
— skipping the messages/state reset and re-stamping its restore key with
the stale id. Same placement as React's `CopilotChat`.

`CopilotChatMessageView` now resolves the registry agent directly
instead of consulting the clone map, and reads `copilotkit.agents` so it
recomputes when the registry changes.

## What callers see

**One agent per `agentId`** — the model React has always had. Thread
isolation is now explicit instead of implicit: ask for it and you get a
real, separately-registered agent rather than a copy that appears out of
nowhere.

```ts
// before — silently produced a copy of the "assistant" agent
useAgent({ agentId: "assistant", threadId: "thread-1" })

// now — an explicit private agent of your own, routed to "assistant"
useAgent({ agentId: "chat-1", runtimeAgentId: "assistant", threadId: "thread-1" })
```

Nothing in this repo needed updating: `CopilotChat`, `use-capabilities`,
`use-interrupt` and all six example apps already used `{ agentId }`.
`<CopilotChat agentId threadId>` is unchanged for consumers.

## Tests

`use-agent-thread-isolation.test.ts` (433 lines) covered clone semantics
that no longer exist; it's replaced by
`use-agent-thread-pinning.test.ts`, which pins the new invariants — one
instance per `agentId` never a copy, config-thread pinning gated on
explicitness, and all three all-or-nothing guards.

Four component suites used `getThreadClone` purely as a lookup to find
the agent under test and now read from the registry.

`MockMCPProxyAgent` recorded `addMessage` **only inside its `clone()`
override**, so those assertions were passing only because cloning
existed. The recording moves onto the class. `clone()` itself is left
intact everywhere — `CopilotKitCore`'s `SuggestionEngine` still clones
agents (`packages/core/src/core/suggestion-engine.ts`), so removing
those overrides would have planted a latent trap.

## Deliberately not included

Found while reviewing this area, real, but out of scope — each wants its
own change:

- `useAgent`'s header watcher **replaces** `agent.headers` instead of
calling `copilotkit.applyHeadersToAgent()`, dropping per-agent
construction-time headers. Regresses #5635 in Vue; React does this
correctly.
- `credentials` never reach a provisional agent.
- No `onAgentsChanged` subscription anywhere in `packages/vue`, so `()
=> copilotkit.value.agents` as a watch source never re-evaluates on
registry change.
- `/connect` is skipped for a plain `HttpAgent` — the `hasCustomConnect`
prototype comparison matches every real agent. Vue-only, no React
equivalent.
- `CopilotThreadsDrawer.ssr.test.ts` is a latent flake (5s timeout on a
dynamic import; passes in isolation).
2026-08-13 11:43:33 -05:00
tylerslaton 10d8f43829 chore: release monorepo v1.67.1 2026-08-10 20:28:46 +00:00
onsclom 48312f4d65 chore: release monorepo v1.67.0 2026-08-10 18:32:14 +00:00
tylerslaton b40602e698 chore: release monorepo v1.66.4 2026-08-07 01:25:14 +00:00
tylerslaton cfc5cfe727 chore: release monorepo v1.66.3 2026-08-07 00:31:47 +00:00
tylerslaton 53b772552f chore: release monorepo v1.66.2 2026-08-04 21:57:57 +00:00
tylerslaton c69f7e96a5 chore: release monorepo v1.66.1 2026-08-04 14:59:52 +00:00
tylerslaton a87b77a991 chore: release monorepo v1.66.0 2026-08-03 20:14:52 +00:00
Mark 36f2972150 fix(a2ui-renderer): bump @a2ui/web_core to 0.10.4 for the openUrl XSS advisory
GHSA-72qq-p3r5-f7wq (CVSS 9.3). web_core <= 0.10.1 passed an agent-supplied
`openUrl` argument straight to `window.open()` with no scheme allowlist, so a
Button whose `functionCall` named a `javascript:` URI executed arbitrary script
in the host origin when a user clicked it. The Basic Catalog is the default, so
no non-default configuration was required to be exposed.

We pinned 0.9.0 exactly, as a runtime dependency of two published packages
(@copilotkit/a2ui-renderer, @copilotkit/vue) and transitively of
@copilotkit/react-core and @copilotkit/angular, so downstream users could not
upgrade out of it on their own. 0.10.4 keeps the ./v0_9 and
./v0_9/basic_catalog entrypoints we import; the only symbol dropped from v0_9
is FrameworkSignal, which we never referenced.

Add regression tests over both renderers that reach the sink independently
(React and Lit). They assert that javascript: and data: URIs never reach
window.open, that https URLs still open with noopener,noreferrer, and that a
blocked scheme leaves the surface mounted rather than escaping into the click
handler. Verified they fail against 0.9.0 and pass against 0.10.4.
2026-08-03 18:43:00 +00:00
BenTaylorDev 6988d5d8e2 chore: release monorepo v1.65.0 2026-08-02 22:43:24 +00:00
tylerslaton 33b1312795 chore: release monorepo v1.64.2 2026-07-31 20:10:27 +00:00
Markus Ecker 2d7f188b29 feat(vue): mirror React's useAgent thread scoping, remove thread cloning
Ports PR #6141's React contract to Vue and deletes the per-thread cloning Vue
used instead.

Cloning is gone: cloneForThread, getOrCreateThreadClone, getThreadClone and the
module-level globalThreadCloneMap. Those clones were reachable only through a
WeakMap, components had to look them up to find the agent actually in use, and
nothing tied a clone's lifetime to the scope that created it.

In its place, the same two-shape contract React now has:

  useAgent()                                       // shared registry agent
  useAgent({ agentId })                            // shared registry agent
  useAgent({ agentId, runtimeAgentId, threadId })  // private proxied agent

UseAgentProps becomes a base plus a two-branch union, so every partial set —
{ agentId, threadId }, { agentId, runtimeAgentId }, { runtimeAgentId, threadId }
— is a compile error, with the same three runtime guards and the same messages as
React for callers TypeScript doesn't reach. Vue's branches take
MaybeRefOrGetter where React takes plain values; the shapes are otherwise
identical.

Thread resolution mirrors React exactly: an explicit `threadId` prop wins,
otherwise the chat configuration's thread gated on `hasExplicitThreadId`, so a
ThreadsProvider-minted placeholder UUID never overwrites the agent's own.

Two Vue-specific details, both load-bearing:

- The pin watcher's first source is `() => agent.value`, not `agent`. Vue sets
  `forceTrigger` when any array watch source is a shallow ref, which would re-run
  the pin on every `triggerRef(agent)` — i.e. every streamed message — and re-pin
  the inherited thread over one CopilotChat had deliberately set for the chat it
  renders. Two suites cover this ("uses the explicit agentId and threadId over
  inherited configuration").
- CopilotChat assigns `agent.threadId` inside its /connect watcher rather than a
  separate one, because CopilotKitCore.connectAgent reads that field
  synchronously to decide whether a restore is fresh; a later assignment would
  let /connect address the previous thread. React does the same, in the same
  place.

CopilotChatMessageView resolves the registry agent directly instead of consulting
the clone map, and reads `copilotkit.agents` so it recomputes when the registry
changes.

Tests: use-agent-thread-isolation.test.ts covered clone semantics that no longer
exist; use-agent-thread-pinning.test.ts replaces it with the new invariants —
one instance per agentId, config-thread pinning gated on explicitness, and all
three all-or-nothing guards. Four component suites used getThreadClone purely as
a lookup and now read from the registry. MockMCPProxyAgent recorded addMessage
only inside its clone() override, so those assertions passed only because
cloning existed; the recording moves onto the class. clone() itself is left
intact everywhere, since CopilotKitCore's SuggestionEngine still clones agents
(packages/core/src/core/suggestion-engine.ts).

Call-site enumeration: cloneForThread and getOrCreateThreadClone were
module-private, zero references. getThreadClone and globalThreadCloneMap were
used by CopilotChatMessageView (rewritten) and 4 test files (retargeted); zero
remain, including in prose. useAgent's other callers, use-capabilities and
use-interrupt, pass `{ agentId }` only and match the unscoped branch unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 16:40:31 +02:00
Alem Tuzlak 9d8916a9d9 fix(showcase): settle mcp-apps D5/D6 on the full iframe cascade
The `completeOnMount` gate added in d70d48a561 named the `mcp-app-iframe`
testid, which only Angular's `copilot-mcp-apps-widget` declared. react-core
and vue build the sandbox iframe imperatively with no testid, so every
React/Vue integration timed the turn out at 30s with
`reason=surface-missing` and never reached `assertIframePresent` — whose
`iframe[sandbox]` fallback would have passed. D5 + D6 `mcp-apps` went red on
all 18 integrations that support the feature (first_failure_at 2026-07-28
23:03Z) while the demos rendered correctly by hand.

Fixed on both sides of the contract:

- react-core and vue now set `data-testid="mcp-app-iframe"` and a `title` on
  the host-created iframe, matching Angular. Pinned by a test in each package.
- `completeOnMount` accepts CSS `selectors` alongside `testIds`, so the probe
  settles on the same cascade its module doc and assertion already use
  (`[data-testid="mcp-app-iframe"], iframe[sandbox]`). A comma-joined entry is
  one conjunctive surface whose branches `querySelectorAll` unions, so the
  delta/`minNewMounts` semantics are unchanged and `testIds` is now sugar for
  the equivalent selector. This half greens the fleet on the next sweep
  without waiting for a package release, since the integrations pin
  @copilotkit/react-core 1.61.2.

A spec naming no surface now throws instead of burning the turn budget and
reporting a misleading `surface-missing`.

Verified against live staging: after clicking the pill, the old gate matched
0 elements and the cascade matched 1 (the sandboxed iframe was there all
along). Also recorded in showcase/GOTCHAS.md.
2026-07-29 12:34:38 +02:00
tylerslaton 028a5adc9d chore: release monorepo v1.64.1 2026-07-28 17:48:23 -07:00
tylerslaton 17564afd2b chore: release monorepo v1.64.0 2026-07-28 02:40:43 +00:00
MikeRyanDev 69861f13df chore: release monorepo v1.63.2 2026-07-23 16:15:51 +00:00
enekesabel d0288d96d8 fix(vue): refresh forwarded tool-call slots on membership changes 2026-07-21 09:32:37 +02:00
Ben Taylor 7fb0abf60e fix(vue): keep attachment sources structuredClone-safe (#5933)
## What does this PR do?

Fixes a Vue `DataCloneError` that occurred when uploaded attachment
sources crossed the `structuredClone` boundary in core. Vue’s deep
`ref()` conversion wrapped nested attachment sources in reactive
proxies; `useAttachments` now keeps the attachment container shallow
with `shallowRef()`, preserving externally supplied sources as raw
cloneable values before they reach AG-UI/core payloads.

The change is intentionally Vue-only: core and React are untouched
because the defect is caused by Vue’s reactivity behavior at the
framework boundary. Focused regressions cover both the attachment hook
and `CopilotChat` submission path, including non-reactivity and
successful `structuredClone` behavior.

## Related PRs and Issues

- [CopilotKit issue
#3](https://github.com/enekesabel/CopilotKit/issues/3)

## Verification

- `pnpm nx run @copilotkit/vue:check-types` — passed.
- `pnpm nx run @copilotkit/vue:test --
src/v2/hooks/__tests__/use-attachments.test.ts
src/v2/components/chat/__tests__/CopilotChat.attachments.test.ts` —
passed, 18 tests in 2 files.
- `pnpm nx run @copilotkit/vue:build` — passed.
- Pre-commit package gate (`test-and-check-packages`) — passed: 1073
tests, publint, and attw.
- `pnpm nx run @copilotkit/vue:lint` — remains blocked by 171
pre-existing errors across unrelated Vue files; no lint errors were
introduced in the changed files.
- `git diff --check upstream/main...HEAD` — passed.

## Scope and exclusions

- Changed files are limited to
`packages/vue/src/v2/hooks/use-attachments.ts`, its focused hook and
`CopilotChat` tests, and the related `packages/vue/PARITY.md` and
`packages/vue/AGENTS.md` guidance.
- No core, React, workflow, or package-wide lint cleanup is included.
- The `PARITY.md` change removes accidental table-format churn and
retains only the meaningful attachment parity note.

## Checklist

- [x] I have read the [Contribution
Guide](https://github.com/CopilotKit/CopilotKit/blob/main/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)
2026-07-20 11:43:28 -05:00
tylerslaton a7459f4fb2 chore: release monorepo v1.63.1 2026-07-16 18:23:58 +00:00
tylerslaton 6c354037fc chore: release monorepo v1.63.0 2026-07-15 22:18:07 +00:00
enekesabel 4f29932ca8 fix(vue): keep attachment sources structuredClone-safe 2026-07-13 11:35:07 +02:00
enekesabel b9f74f9d03 refactor(vue): make tool-call memoization lint-valid 2026-07-13 11:35:01 +02:00