@copilotkit/learning

中文文档
1.86.0发布于 2026/11/11MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 92.2万

Capture clicks, page changes, and network metadata in the browser as AG-UI CUSTOM events

原始使用文档
文档目录3 节
  1. Authenticated Trajectories
  2. React
  3. Custom batch sinks

@copilotkit/learning

Capture page context, navigation, clicks, form edits, network requests, and developer events as AG-UI CUSTOM events. Use the authenticated Core integration to send events to CopilotKit Intelligence.

Capture retains raw URLs, query strings, hashes, page titles, referrers, element text, attributes, and live control values by default. Network events include browser-visible request and response headers and body snapshots. Each body snapshot has a 4 KiB limit and an explicit status for incomplete or unavailable content. Only passwords and credentials are replaced with [redacted], in the browser:

  • Values of password fields: type="password", fields that had it earlier in the session (show-password toggles), fields with a credential key as name, and autocomplete current-password, new-password, or one-time-code.
  • Values typed into password fields, wherever they appear in body snapshots, URLs, or element attributes (the last 20 values of 4 or more characters, kept in memory until stop, also when input capture is off).
  • Values of credential keys such as password, secret, api_key, access_token, authorization, cookie, jwt, or token in JSON, URL-encoded, and FormData bodies, key: value text, query strings, hashes, and element attributes, including inside JSON strings nested up to four levels deep. Booleans and null stay.
  • Element attributes named like credentials (data-api-key, data-token).
  • Values of headers whose name is a credential key (authorization, cookie, x-api-key, x-csrf-token, …), plus x-amz-security-token, private-token, and x-token.
  • URL user names and passwords (https://user:pass@host), which are removed anywhere in captured text.

Redaction runs on the first 16 KiB of a body, before the 4 KiB limit applies. Everything else is captured raw. Binary bodies, hand-built multipart text, XML, single-quoted objects, percent-encoded JSON inside form values, OAuth code= values, path tokens, and passwords shorter than 4 characters are not redacted. See Captured data for the matching rules and limits.

Use capture, beforeSend, ignoreUrls, and data-copilotkit-ignore for your app's exclusions. The deprecated routes option no longer masks or transforms paths.

Click events also include target.label, a short, cleaned name of the clicked control. Automatic Learning shows this name to the model. It comes from the first of aria-labelledby, aria-label, the caption of a submit, button, reset, or image input, title (controls only), and the text of a control named by its content: buttons, links with href, summary, and roles such as tab, menuitem, or option. Images inside a control count with their alt, aria-label, or <title>, and a clicked icon without its own name takes the name of the control around it. Control text is not used when it looks like separate fields, as cards do: longer than 80 characters, containing headings, lists, tables, fields, or more than one paragraph, or split across two divs that hold text, directly or through inline elements, or three text-carrying siblings. ARIA autocomplete suggestions, and anything inside them, get no label from any source: aria-labelledby, aria-label, title, and text are all ignored, and aria-labelledby elsewhere that points into a suggestion list gives no name. Use data-copilotkit-action to name a suggestion. Containers, editable content, text slotted into web components, and the <label> of a native checkbox or radio button (use aria-label or data-copilotkit-action there) never contribute their text; script, style, template, and hidden content is skipped. Invisible characters are removed, passwords and credentials become [redacted], URLs [url], emails [email], and JWT or other token-like strings [redacted]. Other names are cut at 80 characters with …, and label is omitted when no name remains. Raw text, attributes, and values are unchanged. data-copilotkit-action gives a control an explicit name in target.action. To exclude a control or a suggestion list without ARIA roles, add data-copilotkit-ignore, or remove the label in beforeSend:

beforeSend: (event) => {
  if (event.name === "click") delete (event.value.target as { label?: string }).label;
  return event;
},

See Click labels for the full rules.

Text edits are combined per field and recorded after a 300 ms pause. Committing or leaving the field, pressing Enter outside input-method composition, clicking, navigating, emitting a developer event, or stopping capture records the pending edit first. Paired input and change notifications for the same edit produce one record; a later user edit can record the same value again. Checkbox and select changes remain immediate. See Form edit timing for composition and delivery behavior.

Authenticated Trajectories

Use Core to connect capture to CopilotKit Intelligence. This experimental integration targets the join and batch APIs in Intelligence #1569.

import { CopilotKitCore } from "@copilotkit/core";

const copilotkit = new CopilotKitCore({
  runtimeUrl: "/api/copilotkit",
  runtimeTransport: "single",
  learning: {
    onError: ({ code }) => console.warn("Trajectory capture:", code),
  },
});

const result = await copilotkit.startTrajectory();
if (result.status === "started") {
  copilotkit.emitTrajectoryEvent("deal.approved", { dealId: "deal-1" });
}

// Stop on consent withdrawal or when capture is no longer needed.
copilotkit.stopTrajectory();

An omitted trajectoryId generates a UUID. Start succeeds after Runtime authentication and the Phoenix channel join. The Runtime resolves the user on the server. Browser-supplied identity and container IDs are ignored. Setting learningContainerIds in browser capture configuration produces a warning; that option applies only to custom sinks.

To assign authenticated capture to an existing Learning Space, configure the Runtime on the server:

const intelligence = new CopilotKitIntelligence({
  apiKey: process.env.CPK_INTELLIGENCE_API_KEY!,
  getTrajectoryLearningContainerIds: ({ trajectoryId, user }) => {
    // Use the verified application user to choose existing Spaces.
    return ["expense-review"];
  },
});

The selector accepts synchronous or asynchronous results. Return [] to request no new assignments explicitly. Return null or undefined to omit assignments from the connect request. Each connect adds memberships; none of these results removes existing memberships, and a membership removed in Intelligence stays removed. Keep the result stable across reconnects. The selector needs no agent run or Thread, and a linked Thread's Space does not add the Trajectory. The browser chooses the Trajectory ID; the user comes from the Runtime. Intelligence validates that the selected Spaces belong to the API key's project.

Assignment problems never stop capture. If a selected Space does not exist, the Runtime logs a warning with the Trajectory and Space IDs and connects without any assignments, including the Spaces that exist. The selector has a five-second deadline and receives an optional second AbortSignal argument for cancelling its work when the request ends or the deadline expires. A callback error, invalid result, or deadline expiry logs a server error, and the Trajectory connects without assignments. Processing assigned events requires an Intelligence backend with Trajectory inputs enabled for Automatic Learning.

Capture includes page context, navigation, clicks, form edits, network requests, and developer events. Paths remain unchanged. When Runtime starts an agent run, Core sends thread.linked with the run's threadId, once for each Thread. Runtime creates the Thread before the run starts, so Intelligence can store the link. Click Thread context and agent events are deferred for this connection path.

Core sends Phoenix events messages with { events, dropped }. It flushes after two seconds, at 50 events, or before the batch exceeds 64 KiB. Each event must fit within 16 KiB, including sequence metadata. Sizes use serialized UTF-8 JSON. The Gateway replies with { highestSeq, accepted, rejected }. This receipt confirms Redis acceptance, not a Postgres commit. Postgres projection follows asynchronously. The receipt does not identify individual rejected events.

Developer events accept any JSON value. Core adds seq to object values. It wraps scalars, arrays, null, and objects that already contain seq as { data: value, seq }, preserving the developer's data.

Sequence numbers increase for the lifetime of a Core instance, including reconnects and stop/start. They start from the Core instance's creation time in microseconds, not 0, so a new Core instance that reuses a Trajectory ID after a page reload continues above the earlier seqs. The Gateway stores each seq once per Trajectory and acknowledges a repeat as accepted, so a new Core instance can still lose events as duplicates if it starts the same ID before the earlier one's seqs run past its own start, roughly when it starts within (seqs used by the earlier instance ÷ 1000) milliseconds. Prefer a new Trajectory UUID for each Core instance when you do not need to continue one.

Capture pauses while disconnected. Reconnect requests fresh credentials. Developer events emitted during recovery count toward dropped; their content is not buffered. Core keeps one batch awaiting a receipt and one bounded queue; it does not resend failed batches. Known client losses are reported through dropped. Server rejections are already counted by the Gateway. A missing receipt reports PERSISTENCE_UNKNOWN through onError, because the server may have saved the batch. An unauthorized or trajectory_mismatch reply stops capture and reconnect attempts.

Stop cancels pending starts and reconnects. It attempts one final queued batch if no receipt is pending, then disconnects without waiting. Stop is not a guarantee that the last batch was saved. A batch still awaiting its receipt reports PERSISTENCE_UNKNOWN, including during a normal stop.

If a start or an established capture ends with an error and no onError is set, Core logs a console warning with the error code and a setup hint, such as a missing runtimeUrl, a Runtime without intelligence, or a missing identifyUser. Each outcome warns once per Core instance. Server error messages are never shown in the browser. Setting onError replaces the warning. Stops and recoverable connection loss do not warn.

React

Capture needs a Runtime configured with intelligence and identifyUser, and a project with Trajectories enabled. Then turn capture on in the provider:

<CopilotKitProvider runtimeUrl="/api/copilotkit" learning>
  {children}
</CopilotKitProvider>

learning turns capture on. For options, pass an object, such as learning={{ onError }}. learning={false} or removing the prop turns capture off, which suits a consent switch: learning={hasConsent}.

Capture starts after mount. Without learning.trajectoryId, the provider generates the Trajectory ID. The ID stays the same across rerenders, React StrictMode effect replays, reconnects, and option changes. Turning capture off and on again starts a new Trajectory with a new ID. Unmounting the provider stops capture. Read the active ID from copilotkit.trajectoryId, or subscribe with onTrajectoryChanged.

Set learning.trajectoryId to use your own ID instead.

To decide yourself when capture starts, set autoStart: false. The provider configures capture and waits for your app to call copilotkit.startTrajectory():

<CopilotKitProvider
  runtimeUrl="/api/copilotkit"
  learning={{ autoStart: false }}
>
  {children}
</CopilotKitProvider>

With autoStart: false, the provider ignores learning.trajectoryId and logs a console warning. Pass the ID to startTrajectory({ trajectoryId }) instead.

Earlier versions waited for startTrajectory() when the object had no trajectoryId, for example learning={{ onError }}. Those objects now start capture after mount. Add autoStart: false to keep the manual start.

Custom batch sinks

The original createCollector API supports an experimental self-hosted custom batch sink with the same browser capture defaults. It does not authenticate or connect to the Gateway.

import { createCollector, httpSink } from "@copilotkit/learning";

const collector = createCollector({
  sink: httpSink("/api/learning-events"),
});

collector.start({ trajectoryId: crypto.randomUUID() });

With the custom-sink integration, pass learning to CopilotKitProvider instead. Core adds Thread context and emits agent and tool events. Agent message text is included in full unless capture.agentText is false. These additions belong to the custom-sink integration, not standalone browser capture.

Event sequence numbers increase for the lifetime of the collector or Core instance, including across stop/start cycles.

Docs: https://docs.copilotkit.ai/intelligence/capture-interactions

版本与发布记录

@copilotkit/learning 共发布 52 个版本,首次发布于 2026/10/03;过去 12 个月发布了 52 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.86.0latest2026/11/11今天
2.0.0-rc.40next2026/11/11今天
2.0.0-rc.392026/11/10今天
2.0.0-rc.382026/11/10今天
2.0.0-rc.372026/11/091 天前
2.0.0-rc.362026/11/064 天前

其他发布通道:canary → 1.84.2-canary.openbot-intel-fixes,next → 2.0.0-rc.40。

关于 @copilotkit/learning 的常见问题

@copilotkit/learning 是什么?

Capture clicks, page changes, and network metadata in the browser as AG-UI CUSTOM events

如何安装 @copilotkit/learning?

在项目目录运行 npm install @copilotkit/learning,或使用 pnpm add / yarn add / bun add。

@copilotkit/learning 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@copilotkit/learning 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@copilotkit/learning 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@copilotkit/learning 可以商用吗?

@copilotkit/learning 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@copilotkit/learning 的下载量有多少?

根据 npm 官方下载统计,@copilotkit/learning 在 2026/10/11 – 2026/11/09 这 30 天内被下载 921,611 次,日均约 30,720 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@copilotkit/learning 还在维护吗?

最新版本 1.86.0 发布于 2026/11/11(今天);至今共发布 52 个版本,其中过去 12 个月发布了 52 个;首次发布于 2026/10/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。