@copilotkit/channels-core 0.6.0 → 0.6.2-canary.1785779327

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -189,6 +189,43 @@ methods (e.g. `thread.getMessages()`, `thread.lookupUser(query)`,
189
189
  A `ContextEntry` is `{ description: string; value: string }` — knowledge
190
190
  folded into the agent's system context on each `runAgent`.
191
191
 
192
+ ## Agent-rendered components
193
+
194
+ `defineChannelComponent` turns a server-rendered JSX function into an agent
195
+ tool. Its Standard Schema validates tool args before `render` runs. The render
196
+ context supplies the source `platform` and the run's `AbortSignal`.
197
+
198
+ ```tsx
199
+ import { createChannel, defineChannelComponent } from "@copilotkit/channels";
200
+ import { z } from "zod";
201
+
202
+ const Approval = defineChannelComponent({
203
+ name: "show_approval",
204
+ description: "Post an approval request.",
205
+ parameters: z.object({ title: z.string() }),
206
+ render: ({ title }, { platform, signal }) => (
207
+ <Card title={`${title} (${platform})`}>
208
+ <Button key="approve" value="approve" onClick={approve}>
209
+ Approve
210
+ </Button>
211
+ </Card>
212
+ ),
213
+ });
214
+
215
+ const channel = createChannel({
216
+ name: "approvals",
217
+ components: [Approval],
218
+ });
219
+ ```
220
+
221
+ When the agent calls `show_approval`, Channels posts the rendered message as a
222
+ separate provider message and returns a short tool acknowledgement. The agent
223
+ run then continues. Interactive nodes in a component definition need stable,
224
+ unique JSX keys. Channels stores those keys with the source platform and action
225
+ value, so a click or reaction can recover the same handler after a restart.
226
+ Legacy `components: { Name: Component }` registrations still use positional
227
+ recovery for old snapshots.
228
+
192
229
  ## ActionStore
193
230
 
194
231
  Inline JSX handlers are bound by content. Each interactive node gets a
@@ -1,4 +1,5 @@
1
- import type { ChannelNode, InteractionContext, ComponentFn, Renderable, MessageReactionHandler } from "@copilotkit/channels-ui";
1
+ import type { ChannelNode, InteractionContext, Renderable, MessageReactionHandler } from "@copilotkit/channels-ui";
2
+ import type { ChannelComponentRenderContext } from "./channel-component.js";
2
3
  import type { ActionContinuationContext, ActionContinuationBinding, ActionContinuationSnapshot, ActionStore } from "./action-store.js";
3
4
  export declare class ActionExpiredError extends Error {
4
5
  readonly code = "channel_action_expired";
@@ -31,6 +32,7 @@ export declare class ActionRegistry {
31
32
  component: string;
32
33
  props: Record<string, unknown>;
33
34
  conversationKey: string;
35
+ platform?: string;
34
36
  }): Promise<void>;
35
37
  /**
36
38
  * Resolve the `onReaction` handler for `messageId`: the hot cache first, then
@@ -39,10 +41,22 @@ export declare class ActionRegistry {
39
41
  * handler whose closure can't be re-derived after a restart.
40
42
  */
41
43
  resolveMessageReaction(messageId: string): Promise<MessageReactionHandler | undefined>;
42
- registerComponent(name: string, fn: ComponentFn): void;
44
+ registerComponent(name: string, fn: (props: Record<string, unknown>, context: ChannelComponentRenderContext) => Renderable | Promise<Renderable>, options?: {
45
+ requireKeys?: boolean;
46
+ }): void;
43
47
  clearHotCache(): void;
44
- bindTree(componentName: string, props: Record<string, unknown>, conversationKey: string, continuation?: ActionContinuationContext): Promise<ChannelNode[]>;
45
- bindRenderable(ui: Renderable, conversationKey: string, continuation?: ActionContinuationContext): Promise<{
48
+ bindTree(componentName: string, props: Record<string, unknown>, conversationKey: string, continuation?: ActionContinuationContext, renderContext?: ChannelComponentRenderContext): Promise<ChannelNode[]>;
49
+ /** Bind a named component and detach its root reaction for message routing. */
50
+ bindRegisteredRenderable(componentName: string, props: Record<string, unknown>, conversationKey: string, continuation: ActionContinuationContext | undefined, renderContext: ChannelComponentRenderContext): Promise<{
51
+ root: ChannelNode[];
52
+ onReaction?: MessageReactionHandler;
53
+ reactionComponent?: {
54
+ component: string;
55
+ props: Record<string, unknown>;
56
+ platform: string;
57
+ };
58
+ }>;
59
+ bindRenderable(ui: Renderable, conversationKey: string, continuation?: ActionContinuationContext, renderContext?: ChannelComponentRenderContext): Promise<{
46
60
  root: ChannelNode[];
47
61
  onReaction?: MessageReactionHandler;
48
62
  /**
@@ -53,9 +67,14 @@ export declare class ActionRegistry {
53
67
  reactionComponent?: {
54
68
  component: string;
55
69
  props: Record<string, unknown>;
70
+ platform: string;
56
71
  };
57
72
  }>;
58
73
  private walk;
74
+ /** Traverse children and provider-native named slots through one path model. */
75
+ private walkValue;
76
+ /** Bind one node reached through a singular provider-native slot. */
77
+ private walkNode;
59
78
  /**
60
79
  * Run the click handler for `id` and return the clicked element's `value`
61
80
  * (so callers can resolve a HITL `awaitChoice` waiter even when the platform
@@ -1 +1 @@
1
- {"version":3,"file":"action-registry.d.ts","sourceRoot":"","sources":["../src/action-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EACzB,0BAA0B,EAC1B,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,4BAA4B;gBAE7B,EAAE,EAAE,MAAM;CAIvB;AAED,mFAAmF;AACnF,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,IAAI,mCAAmC;;CAMjD;AAcD,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,UAAU,CAAkC;IAKpD,OAAO,CAAC,GAAG,CAGP;IAIJ,OAAO,CAAC,gBAAgB,CAA6C;IAErE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;gBAE1B,IAAI,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IAK9D,oFAAoF;IACpF,uBAAuB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,sBAAsB,GAC9B,IAAI;IAIP;;;;;OAKG;IACG,sBAAsB,CAC1B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,eAAe,EAAE,MAAM,CAAC;KACzB,GACA,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;OAKG;IACG,sBAAsB,CAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;IAa9C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI;IAItD,aAAa,IAAI,IAAI;IAMf,QAAQ,CACZ,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,yBAAyB,GACvC,OAAO,CAAC,WAAW,EAAE,CAAC;IAqBnB,cAAc,CAClB,EAAE,EAAE,UAAU,EACd,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,yBAAyB,GACvC,OAAO,CAAC;QACT,IAAI,EAAE,WAAW,EAAE,CAAC;QACpB,UAAU,CAAC,EAAE,sBAAsB,CAAC;QACpC;;;;WAIG;QACH,iBAAiB,CAAC,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC;KAC3E,CAAC;YA4BY,IAAI;IAsDlB;;;;;OAKG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BrE,0EAA0E;IACpE,eAAe,CACnB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,0BAA0B,CAAC;IAOtC,mEAAmE;IAC7D,iBAAiB,CACrB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,0BAA0B,CAAC;CASvC"}
1
+ {"version":3,"file":"action-registry.d.ts","sourceRoot":"","sources":["../src/action-registry.ts"],"names":[],"mappings":"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"}
@@ -54,6 +54,7 @@ export class ActionRegistry {
54
54
  props: snap.props,
55
55
  path: [],
56
56
  conversationKey: snap.conversationKey,
57
+ platform: snap.platform,
57
58
  });
58
59
  }
59
60
  /**
@@ -69,26 +70,52 @@ export class ActionRegistry {
69
70
  const snap = await this.store.get(reactionKey(messageId));
70
71
  if (!snap?.component)
71
72
  return undefined;
72
- const fn = this.components.get(snap.component);
73
- if (!fn)
73
+ const registered = this.components.get(snap.component);
74
+ if (!registered)
74
75
  return undefined;
75
- const root = renderToIR(fn(snap.props));
76
+ const root = renderToIR(await registered.render(snap.props, {
77
+ platform: (snap.platform ??
78
+ "slack"),
79
+ signal: new AbortController().signal,
80
+ }));
76
81
  return takeMessageReaction(root);
77
82
  }
78
- registerComponent(name, fn) {
79
- this.components.set(name, fn);
83
+ registerComponent(name, fn, options = {}) {
84
+ this.components.set(name, {
85
+ render: fn,
86
+ requireKeys: options.requireKeys ?? false,
87
+ });
80
88
  }
81
89
  clearHotCache() {
82
90
  this.hot.clear();
83
91
  }
84
92
  // Renders the named component, binds all event-prop handlers in the tree
85
93
  // (mint id, hot-cache + ActionStore snapshot, rewrite prop to { id }), returns the bound IR.
86
- async bindTree(componentName, props, conversationKey, continuation) {
87
- const fn = this.components.get(componentName);
88
- const root = renderToIR((fn ? fn(props) : props));
89
- await this.walk(root, [], componentName, props, conversationKey, continuation);
94
+ async bindTree(componentName, props, conversationKey, continuation, renderContext = {
95
+ platform: "slack",
96
+ signal: new AbortController().signal,
97
+ }) {
98
+ const registered = this.components.get(componentName);
99
+ const rendered = registered
100
+ ? await registered.render(props, renderContext)
101
+ : props;
102
+ const root = renderToIR(rendered);
103
+ const interactiveKeys = new Set();
104
+ await this.walk(root, [], componentName, props, conversationKey, continuation, registered?.requireKeys ?? false, renderContext.platform, interactiveKeys);
90
105
  return root;
91
106
  }
107
+ /** Bind a named component and detach its root reaction for message routing. */
108
+ async bindRegisteredRenderable(componentName, props, conversationKey, continuation, renderContext) {
109
+ const root = await this.bindTree(componentName, props, conversationKey, continuation, renderContext);
110
+ const onReaction = takeMessageReaction(root);
111
+ return {
112
+ root,
113
+ onReaction,
114
+ reactionComponent: onReaction
115
+ ? { component: componentName, props, platform: renderContext.platform }
116
+ : undefined,
117
+ };
118
+ }
92
119
  // Binds an arbitrary Renderable for posting. If `ui` is a component element
93
120
  // (`{ type: fn, props }`), it is registered + bound by name (cold-path
94
121
  // re-render supported). Otherwise the IR is bound inline with `component:""`,
@@ -96,7 +123,10 @@ export class ActionRegistry {
96
123
  // degradation for inline handlers that can't be re-derived). A top-level
97
124
  // `<Message onReaction>` handler is pulled off the IR (so it never reaches the
98
125
  // adapter) and returned for the caller to associate with the posted message.
99
- async bindRenderable(ui, conversationKey, continuation) {
126
+ async bindRenderable(ui, conversationKey, continuation, renderContext = {
127
+ platform: "slack",
128
+ signal: new AbortController().signal,
129
+ }) {
100
130
  let root;
101
131
  let component;
102
132
  let props;
@@ -104,31 +134,50 @@ export class ActionRegistry {
104
134
  const fn = ui.type;
105
135
  component = fn.name || "anonymous";
106
136
  props = (ui.props ?? {});
107
- this.registerComponent(component, fn);
108
- root = await this.bindTree(component, props, conversationKey, continuation);
137
+ this.registerComponent(component, (componentProps) => fn(componentProps));
138
+ root = await this.bindTree(component, props, conversationKey, continuation, {
139
+ platform: renderContext.platform,
140
+ signal: renderContext.signal,
141
+ });
109
142
  }
110
143
  else {
111
144
  root = renderToIR(ui);
112
- await this.walk(root, [], "", undefined, conversationKey, continuation);
145
+ await this.walk(root, [], "", undefined, conversationKey, continuation, false, renderContext.platform, new Set());
113
146
  }
114
147
  const onReaction = takeMessageReaction(root);
115
148
  return {
116
149
  root,
117
150
  onReaction,
118
- reactionComponent: onReaction && component && props ? { component, props } : undefined,
151
+ reactionComponent: onReaction && component && props
152
+ ? { component, props, platform: renderContext.platform }
153
+ : undefined,
119
154
  };
120
155
  }
121
- async walk(nodes, base, comp, props, conv, continuation) {
156
+ async walk(nodes, base, comp, props, conv, continuation, requireKeys, platform, interactiveKeys, exactPath) {
122
157
  for (let i = 0; i < nodes.length; i++) {
123
158
  const node = nodes[i];
124
- const path = [...base, i];
159
+ const path = exactPath ?? [...base, i];
160
+ const eventProps = EVENT_PROPS.filter((eventProp) => typeof node.props[eventProp] === "function");
161
+ if (requireKeys && eventProps.length > 0) {
162
+ if (node.key === undefined ||
163
+ (typeof node.key === "string" && node.key.trim().length === 0)) {
164
+ throw new Error(`${formatComponentPath(comp, path)}.${eventProps[0]} requires a non-empty JSX key`);
165
+ }
166
+ if (interactiveKeys.has(node.key)) {
167
+ throw new Error(`duplicate interactive JSX key "${node.key}"`);
168
+ }
169
+ interactiveKeys.add(node.key);
170
+ }
125
171
  for (const ep of EVENT_PROPS) {
126
172
  const handler = node.props[ep];
127
173
  if (typeof handler === "function") {
128
174
  const fullPath = [...path, ep];
175
+ const locator = requireKeys && node.key !== undefined
176
+ ? { key: node.key, eventProp: ep }
177
+ : undefined;
129
178
  const id = continuation
130
179
  ? `ck:${globalThis.crypto.randomUUID()}`
131
- : mintId(comp, fullPath, props);
180
+ : mintId(comp, locator ? [locator.key, locator.eventProp] : fullPath, props);
132
181
  this.hot.set(id, {
133
182
  handler: handler,
134
183
  value: node.props.value,
@@ -138,6 +187,9 @@ export class ActionRegistry {
138
187
  component: comp,
139
188
  props,
140
189
  path: fullPath,
190
+ ...(locator ? { locator } : {}),
191
+ platform,
192
+ actionValue: node.props.value,
141
193
  conversationKey: conv,
142
194
  boundArgs: isBound(handler) ? getBoundArgs(handler) : undefined,
143
195
  ...(continuation
@@ -147,12 +199,29 @@ export class ActionRegistry {
147
199
  node.props[ep] = { id };
148
200
  }
149
201
  }
150
- const children = node.props.children;
151
- if (Array.isArray(children)) {
152
- await this.walk(children, [...path, "children"], comp, props, conv, continuation);
202
+ for (const [propName, propValue] of Object.entries(node.props)) {
203
+ if (EVENT_PROPS.includes(propName))
204
+ continue;
205
+ await this.walkValue(propValue, [...path, propName], comp, props, conv, continuation, requireKeys, platform, interactiveKeys);
153
206
  }
154
207
  }
155
208
  }
209
+ /** Traverse children and provider-native named slots through one path model. */
210
+ async walkValue(value, path, comp, props, conv, continuation, requireKeys, platform, interactiveKeys) {
211
+ if (isChannelNode(value)) {
212
+ await this.walkNode(value, path, comp, props, conv, continuation, requireKeys, platform, interactiveKeys);
213
+ return;
214
+ }
215
+ if (!Array.isArray(value))
216
+ return;
217
+ for (let index = 0; index < value.length; index++) {
218
+ await this.walkValue(value[index], [...path, index], comp, props, conv, continuation, requireKeys, platform, interactiveKeys);
219
+ }
220
+ }
221
+ /** Bind one node reached through a singular provider-native slot. */
222
+ async walkNode(node, path, comp, props, conv, continuation, requireKeys, platform, interactiveKeys) {
223
+ await this.walk([node], [], comp, props, conv, continuation, requireKeys, platform, interactiveKeys, path);
224
+ }
156
225
  /**
157
226
  * Run the click handler for `id` and return the clicked element's `value`
158
227
  * (so callers can resolve a HITL `awaitChoice` waiter even when the platform
@@ -175,16 +244,26 @@ export class ActionRegistry {
175
244
  const snap = await this.store.get(id);
176
245
  if (!snap || !snap.component)
177
246
  throw new ActionExpiredError(id);
178
- const fn = this.components.get(snap.component);
179
- if (!fn)
247
+ const registered = this.components.get(snap.component);
248
+ if (!registered)
180
249
  throw new ActionExpiredError(id);
181
- const tree = renderToIR(fn(snap.props));
182
- handler = pluck(tree, snap.path);
183
- value = pluckValue(tree, snap.path);
250
+ const tree = renderToIR(await registered.render(snap.props, {
251
+ platform: (snap.platform ??
252
+ ctx.platform),
253
+ signal: new AbortController().signal,
254
+ }));
255
+ handler = snap.locator
256
+ ? findHandlerByLocator(tree, snap.locator)
257
+ : pluck(tree, snap.path);
258
+ value = snap.locator ? snap.actionValue : pluckValue(tree, snap.path);
184
259
  if (!handler)
185
260
  throw new ActionExpiredError(id);
186
261
  }
187
- await handler({ ...ctx, action: { ...ctx.action, id } });
262
+ const actionValue = value === undefined ? ctx.action.value : value;
263
+ await handler({
264
+ ...ctx,
265
+ action: { ...ctx.action, id, value: actionValue },
266
+ });
188
267
  return value;
189
268
  }
190
269
  /** Read and validate one continuation capability without consuming it. */
@@ -219,6 +298,40 @@ function assertContinuationBinding(actual, actionId, expected) {
219
298
  throw new ActionContinuationMismatchError();
220
299
  }
221
300
  }
301
+ function isChannelNode(value) {
302
+ return (typeof value === "object" &&
303
+ value !== null &&
304
+ "type" in value &&
305
+ "props" in value &&
306
+ typeof value.props === "object" &&
307
+ value.props !== null);
308
+ }
309
+ function formatComponentPath(component, path) {
310
+ return path.reduce((result, segment) => typeof segment === "number"
311
+ ? `${result}[${segment}]`
312
+ : `${result}.${segment}`, component);
313
+ }
314
+ function findHandlerByLocator(tree, locator) {
315
+ const matches = [];
316
+ const visit = (value) => {
317
+ if (Array.isArray(value)) {
318
+ for (const item of value)
319
+ visit(item);
320
+ return;
321
+ }
322
+ if (!isChannelNode(value))
323
+ return;
324
+ if (value.key === locator.key) {
325
+ const handler = value.props[locator.eventProp];
326
+ if (typeof handler === "function")
327
+ matches.push(handler);
328
+ }
329
+ for (const propValue of Object.values(value.props))
330
+ visit(propValue);
331
+ };
332
+ visit(tree);
333
+ return matches.length === 1 ? matches[0] : undefined;
334
+ }
222
335
  /** Store key for a message's durable reaction snapshot (distinct from minted action ids). */
223
336
  function reactionKey(messageId) {
224
337
  return `reaction:${messageId}`;
@@ -22,6 +22,12 @@ export interface ActionSnapshot {
22
22
  component?: string;
23
23
  props?: unknown;
24
24
  path: (string | number)[];
25
+ locator?: {
26
+ key: string | number;
27
+ eventProp: "onClick" | "onSelect" | "onSubmit";
28
+ };
29
+ platform?: string;
30
+ actionValue?: unknown;
25
31
  boundArgs?: unknown;
26
32
  conversationKey: string;
27
33
  continuation?: ActionContinuationSnapshot;
@@ -1 +1 @@
1
- {"version":3,"file":"action-store.d.ts","sourceRoot":"","sources":["../src/action-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE9E,iEAAiE;AACjE,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,2BAA2B,CAAC;CACxC;AAED,+EAA+E;AAC/E,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,yBAAyB,EACzB,aAAa,GAAG,iBAAiB,GAAG,UAAU,CAC/C,CAAC;AAEF,8EAA8E;AAC9E,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,0BAA0B,CAAC;CAC3C;AACD,iHAAiH;AACjH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACrD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AACD,iHAAiH;AACjH,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,GAAG,CAAmE;IACxE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IASpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAGjC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;CAU/D"}
1
+ {"version":3,"file":"action-store.d.ts","sourceRoot":"","sources":["../src/action-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE9E,iEAAiE;AACjE,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,2BAA2B,CAAC;CACxC;AAED,+EAA+E;AAC/E,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,yBAAyB,EACzB,aAAa,GAAG,iBAAiB,GAAG,UAAU,CAC/C,CAAC;AAEF,8EAA8E;AAC9E,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE;QACR,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;QACrB,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;KAChD,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,0BAA0B,CAAC;CAC3C;AACD,iHAAiH;AACjH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACrD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AACD,iHAAiH;AACjH,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,GAAG,CAAmE;IACxE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IASpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAGjC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;CAU/D"}
@@ -0,0 +1,18 @@
1
+ import type { Renderable } from "@copilotkit/channels-ui";
2
+ import type { InferSchemaOutput, ObjectSchema } from "./standard-schema.js";
3
+ export type ChannelComponentPlatform = "slack" | "teams" | "discord" | "telegram" | "whatsapp";
4
+ export interface ChannelComponentRenderContext {
5
+ platform: ChannelComponentPlatform;
6
+ signal: AbortSignal;
7
+ }
8
+ export interface ChannelComponentDefinition<Schema extends ObjectSchema = ObjectSchema> {
9
+ name: string;
10
+ description: string;
11
+ parameters: Schema;
12
+ render(props: InferSchemaOutput<Schema>, context: ChannelComponentRenderContext): Renderable | Promise<Renderable>;
13
+ }
14
+ /** Define an agent-rendered Channel component with schema-inferred props. */
15
+ export declare function defineChannelComponent<Schema extends ObjectSchema>(component: ChannelComponentDefinition<Schema>): ChannelComponentDefinition<Schema>;
16
+ /** Distinguish component-tool descriptors from legacy JSX component functions. */
17
+ export declare function isChannelComponentDefinition(value: unknown): value is ChannelComponentDefinition;
18
+ //# sourceMappingURL=channel-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-component.d.ts","sourceRoot":"","sources":["../src/channel-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE5E,MAAM,MAAM,wBAAwB,GAChC,OAAO,GACP,OAAO,GACP,SAAS,GACT,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,wBAAwB,CAAC;IACnC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B,CACzC,MAAM,SAAS,YAAY,GAAG,YAAY;IAE1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CACJ,KAAK,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAChC,OAAO,EAAE,6BAA6B,GACrC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACrC;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,MAAM,SAAS,YAAY,EAChE,SAAS,EAAE,0BAA0B,CAAC,MAAM,CAAC,GAC5C,0BAA0B,CAAC,MAAM,CAAC,CAEpC;AAED,kFAAkF;AAClF,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,0BAA0B,CAWrC"}
@@ -0,0 +1,13 @@
1
+ /** Define an agent-rendered Channel component with schema-inferred props. */
2
+ export function defineChannelComponent(component) {
3
+ return component;
4
+ }
5
+ /** Distinguish component-tool descriptors from legacy JSX component functions. */
6
+ export function isChannelComponentDefinition(value) {
7
+ return (typeof value === "object" &&
8
+ value !== null &&
9
+ typeof value.name === "string" &&
10
+ typeof value.description === "string" &&
11
+ typeof value.render === "function" &&
12
+ typeof value.parameters?.["~standard"] === "object");
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=channel-component.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-component.test.d.ts","sourceRoot":"","sources":["../src/channel-component.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,120 @@
1
+ import { Section } from "@copilotkit/channels-ui";
2
+ import { z } from "zod";
3
+ import { expect, test, vi } from "vitest";
4
+ import { createChannel } from "./create-channel.js";
5
+ import { defineChannelComponent } from "./channel-component.js";
6
+ import { FakeAdapter } from "./testing/fake-adapter.js";
7
+ import { FakeAgent } from "./testing/fake-agent.js";
8
+ function setup(args) {
9
+ const adapter = new FakeAdapter({ platform: "intelligence" });
10
+ let iterations = 0;
11
+ const agent = new FakeAgent([
12
+ (subscriber) => {
13
+ iterations += 1;
14
+ subscriber.onToolCallEndEvent?.({
15
+ event: { toolCallId: "component-call-1" },
16
+ toolCallName: args.component.name,
17
+ toolCallArgs: args.toolArgs ?? {},
18
+ });
19
+ },
20
+ () => {
21
+ iterations += 1;
22
+ },
23
+ ]);
24
+ const channel = createChannel({
25
+ identifyUser: "platform",
26
+ adapters: [adapter],
27
+ agent: () => agent,
28
+ components: [args.component],
29
+ });
30
+ channel.onMessage(async ({ thread }) => {
31
+ await thread.runAgent();
32
+ });
33
+ return {
34
+ adapter,
35
+ channel,
36
+ iterations: () => iterations,
37
+ async run() {
38
+ await channel.ɵruntime.start();
39
+ await adapter.getSink().onTurn({
40
+ conversationKey: "conversation-1",
41
+ replyTarget: {},
42
+ userText: "show the order",
43
+ platform: args.platform ?? "slack",
44
+ });
45
+ },
46
+ };
47
+ }
48
+ test("a channel component validates args, renders asynchronously, and posts through the thread", async () => {
49
+ const render = vi.fn(async (props, context) => {
50
+ await Promise.resolve();
51
+ return Section({
52
+ children: `${context.platform}:${props.orderId}:${context.signal.aborted}`,
53
+ });
54
+ });
55
+ const component = defineChannelComponent({
56
+ name: "show_order",
57
+ description: "Show one order",
58
+ parameters: z.object({ orderId: z.string() }),
59
+ render,
60
+ });
61
+ const harness = setup({
62
+ component,
63
+ platform: "teams",
64
+ toolArgs: { orderId: "order-42" },
65
+ });
66
+ await harness.run();
67
+ expect(render).toHaveBeenCalledWith({ orderId: "order-42" }, { platform: "teams", signal: expect.any(AbortSignal) });
68
+ expect(harness.adapter.posted).toEqual([
69
+ [
70
+ {
71
+ type: "section",
72
+ props: {
73
+ children: [
74
+ {
75
+ type: "text",
76
+ props: { value: "teams:order-42:false" },
77
+ },
78
+ ],
79
+ },
80
+ },
81
+ ],
82
+ ]);
83
+ expect(harness.iterations()).toBe(2);
84
+ });
85
+ test("invalid component arguments do not render or post", async () => {
86
+ const render = vi.fn(() => Section({ children: "should not render" }));
87
+ const component = defineChannelComponent({
88
+ name: "show_order",
89
+ description: "Show one order",
90
+ parameters: z.object({ orderId: z.string() }),
91
+ render,
92
+ });
93
+ const harness = setup({ component, toolArgs: { orderId: 42 } });
94
+ await harness.run();
95
+ expect(render).not.toHaveBeenCalled();
96
+ expect(harness.adapter.posted).toEqual([]);
97
+ expect(harness.iterations()).toBe(2);
98
+ });
99
+ test("channel start rejects component and tool name collisions", async () => {
100
+ const component = defineChannelComponent({
101
+ name: "show_order",
102
+ description: "Show one order",
103
+ parameters: z.object({}),
104
+ render: () => Section({ children: "order" }),
105
+ });
106
+ const channel = createChannel({
107
+ identifyUser: "platform",
108
+ adapters: [new FakeAdapter()],
109
+ components: [component],
110
+ tools: [
111
+ {
112
+ name: "show_order",
113
+ description: "Conflicting tool",
114
+ parameters: z.object({}),
115
+ handler: () => "conflict",
116
+ },
117
+ ],
118
+ });
119
+ await expect(channel.ɵruntime.start()).rejects.toThrow('duplicate channel tool or component name "show_order"');
120
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=component-reaction-recovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-reaction-recovery.test.d.ts","sourceRoot":"","sources":["../src/component-reaction-recovery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { expect, test } from "vitest";
2
+ import { Message } from "@copilotkit/channels-ui";
3
+ import { ActionRegistry } from "./action-registry.js";
4
+ import { InMemoryActionStore } from "./action-store.js";
5
+ const reactionHandler = () => undefined;
6
+ test("registered component reactions recover with their source platform", async () => {
7
+ const store = new InMemoryActionStore();
8
+ const renderPlatforms = [];
9
+ const register = (registry) => {
10
+ registry.registerComponent("deployment", (_props, context) => {
11
+ renderPlatforms.push(context.platform);
12
+ return Message({ children: "done", onReaction: reactionHandler });
13
+ });
14
+ };
15
+ const first = new ActionRegistry({ store });
16
+ register(first);
17
+ const bound = await first.bindRegisteredRenderable("deployment", {}, "conversation-1", undefined, { platform: "teams", signal: new AbortController().signal });
18
+ expect(bound.onReaction).toBe(reactionHandler);
19
+ await first.persistMessageReaction("message-1", {
20
+ component: "deployment",
21
+ props: {},
22
+ conversationKey: "conversation-1",
23
+ platform: "teams",
24
+ });
25
+ const restarted = new ActionRegistry({ store });
26
+ register(restarted);
27
+ expect(await restarted.resolveMessageReaction("message-1")).toBe(reactionHandler);
28
+ expect(renderPlatforms).toEqual(["teams", "teams"]);
29
+ });
@@ -10,6 +10,7 @@ import { Transcripts } from "./transcripts.js";
10
10
  import type { TranscriptsConfig } from "./transcripts.js";
11
11
  import type { ChannelIdentifyUser } from "./identity.js";
12
12
  import type { StandardSchemaV1, InferSchemaOutput } from "./standard-schema.js";
13
+ import type { ChannelComponentDefinition } from "./channel-component.js";
13
14
  export type LockConflictDecision = "drop" | "force";
14
15
  /**
15
16
  * How overlapping turns on the same `conversationKey` are handled.
@@ -43,7 +44,8 @@ export type ChannelConcurrency = "parallel" | "serial" | "drop";
43
44
  *
44
45
  * Fails loud on all three ways cloning can fail to isolate: a missing `clone()`,
45
46
  * a `clone()` that hands back the same object, and a `clone()` that silently
46
- * drops subclass state (see {@link assertCloneKeptOwnFields}).
47
+ * drops subclass state (see {@link warnOnCloneDroppedOwnFields}, which reports
48
+ * rather than refuses).
47
49
  */
48
50
  export declare function isolateAgentInstance(prototype: AbstractAgent, threadId: string): AbstractAgent;
49
51
  /**
@@ -62,6 +64,7 @@ export declare function resolveChannelConcurrency(cfg: {
62
64
  * with the props persisted in the store, so the specific shape isn't needed here.
63
65
  */
64
66
  export type ChannelComponent = (props: never) => ReturnType<ComponentFn>;
67
+ export type ChannelComponentRegistration = ChannelComponent | ChannelComponentDefinition;
65
68
  export type ChannelHandler<TState = unknown> = (ctx: {
66
69
  thread: StatefulThread<TState>;
67
70
  message: ChannelMessage;
@@ -237,12 +240,11 @@ export interface CreateChannelOptions<TStateSchema extends StandardSchemaV1 | un
237
240
  tools?: ChannelTool[];
238
241
  context?: ContextEntry[];
239
242
  /**
240
- * Named JSX components used in interactive messages. Registering them here
241
- * lets the channel re-render and re-fire their handlers after a restart (durable
242
- * actions); without registration, a click on a message posted before the
243
- * restart degrades to "action expired".
243
+ * Agent-rendered component definitions or legacy named JSX components.
244
+ * Definitions become tools. Both forms let the channel recover keyed handlers
245
+ * after a restart when the configured store is durable.
244
246
  */
245
- components?: ChannelComponent[];
247
+ components?: ChannelComponentRegistration[] | Record<string, ChannelComponent>;
246
248
  /** Slash commands. Forwarded to adapters that support them; ignored elsewhere. */
247
249
  commands?: ChannelCommand[];
248
250
  /** Persistence, per-thread state schema, transcripts, and lock/dedup tuning. */
@@ -1 +1 @@
1
- {"version":3,"file":"create-channel.d.ts","sourceRoot":"","sources":["../src/create-channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-channel.d.ts","sourceRoot":"","sources":["../src/create-channel.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { sanitizeAgentEventStream } from "./sanitize-agent-events.js";
8
8
  import { normalizeEmoji, toCanonicalEmoji, renderToIR, } from "@copilotkit/channels-ui";
9
9
  import { Transcripts } from "./transcripts.js";
10
10
  import { resolveChannelUser } from "./identity.js";
11
+ import { isChannelComponentDefinition } from "./channel-component.js";
11
12
  import { ChannelTelemetry } from "./telemetry/channel-telemetry.js";
12
13
  import { errorClass, normalizePlatform } from "./telemetry/sanitize-error.js";
13
14
  import { createRequire } from "node:module";
@@ -58,7 +59,8 @@ function isEmojiPlatform(platform) {
58
59
  *
59
60
  * Fails loud on all three ways cloning can fail to isolate: a missing `clone()`,
60
61
  * a `clone()` that hands back the same object, and a `clone()` that silently
61
- * drops subclass state (see {@link assertCloneKeptOwnFields}).
62
+ * drops subclass state (see {@link warnOnCloneDroppedOwnFields}, which reports
63
+ * rather than refuses).
62
64
  */
63
65
  export function isolateAgentInstance(prototype, threadId) {
64
66
  if (typeof prototype.clone !== "function") {
@@ -70,7 +72,7 @@ export function isolateAgentInstance(prototype, threadId) {
70
72
  if (cloned == null || cloned === prototype) {
71
73
  throw new Error("createChannel: agent.clone() must return a distinct instance for concurrent turns");
72
74
  }
73
- assertCloneKeptOwnFields(prototype, cloned);
75
+ warnOnCloneDroppedOwnFields(prototype, cloned);
74
76
  cloned.threadId = threadId;
75
77
  // `clone()` copies `isRunning` from the source, and a source that has already
76
78
  // run can be mid-run at the moment it is cloned. A fresh turn is not.
@@ -90,7 +92,7 @@ export function isolateAgentInstance(prototype, threadId) {
90
92
  return cloned;
91
93
  }
92
94
  /**
93
- * Fail loud when `clone()` silently drops subclass state.
95
+ * Report but do not refuse — a `clone()` that drops subclass state.
94
96
  *
95
97
  * `AbstractAgent.prototype.clone()` copies a fixed field list, so a subclass
96
98
  * that declares its own fields (an auth client, config, a cache) gets them back
@@ -98,27 +100,49 @@ export function isolateAgentInstance(prototype, threadId) {
98
100
  * exists and returns a correctly-typed instance, nothing else surfaces it. The
99
101
  * agent just runs gutted.
100
102
  *
101
- * Comparing own enumerable keys catches exactly that and stays quiet for the
102
- * agents that do override `clone()` (`HttpAgent`, `LangGraphAgent`,
103
- * `BuiltInAgent`, `IntelligenceAgent`). Symbol-keyed and non-enumerable fields
104
- * are not covered.
103
+ * This used to throw. It no longer does, because whether a dropped field matters
104
+ * depends on what the field HOLDS, and from here the two cases are
105
+ * indistinguishable:
106
+ *
107
+ * - **Config** (`orchestrationAgentUrl`, an auth client) is read during the run
108
+ * and never rewritten, so losing it does gut the agent.
109
+ * - **Per-run scratch state** is re-initialized at the start of every run, so
110
+ * losing it changes nothing. `LangGraphAgent`'s `emittedToolCallStartIds` and
111
+ * `eventsStreamActive` are exactly this: both are reset when a run binds its
112
+ * subscriber, before anything reads them.
113
+ *
114
+ * Throwing on the second case took a Channel that works and refused every turn
115
+ * — while the identical clone happens on every ordinary runtime request
116
+ * (`agent-utils.ts` clones per request) with no ill effect at all, which is why
117
+ * it had never been noticed outside Channels. A warning keeps the signal for the
118
+ * config case without failing the harmless one.
119
+ *
120
+ * Deliberately NOT done: copying the dropped fields onto the clone. That would
121
+ * share one mutable object across concurrent turns, which is the exact hazard
122
+ * this isolation exists to prevent.
123
+ *
124
+ * Comparing own enumerable keys stays quiet for the agents that override
125
+ * `clone()` fully (`HttpAgent`, `BuiltInAgent`, `IntelligenceAgent`).
126
+ * Symbol-keyed and non-enumerable fields are not covered.
105
127
  *
106
128
  * Own *functions* are deliberately exempt. Assigning a method on the instance is
107
129
  * how spies and instrumentation wrap an agent, and losing that wrapper leaves
108
130
  * the class's prototype method intact — the clone still behaves correctly, it
109
131
  * just isn't wrapped. Only dropped state leaves an agent genuinely gutted.
110
132
  */
111
- function assertCloneKeptOwnFields(prototype, cloned) {
133
+ function warnOnCloneDroppedOwnFields(prototype, cloned) {
112
134
  const source = prototype;
113
135
  const dropped = Object.keys(prototype).filter((key) => typeof source[key] !== "function" &&
114
136
  !Object.prototype.hasOwnProperty.call(cloned, key));
115
137
  if (dropped.length === 0)
116
138
  return;
117
139
  const name = prototype.constructor?.name ?? "the configured agent";
118
- throw new Error(`createChannel: ${name}.clone() dropped ${dropped.join(", ")}. ` +
140
+ console.warn(`createChannel: ${name}.clone() dropped ${dropped.join(", ")}. ` +
119
141
  "Every turn runs on a clone, and AbstractAgent's clone() only copies its " +
120
- `own fixed field list, so those fields would read as undefined. Override ` +
121
- `clone() on ${name} to copy them (HttpAgent.clone() is the reference).`);
142
+ "own fixed field list, so those fields read as undefined on the clone. " +
143
+ "That is harmless for state a run re-initializes, and gutting for anything " +
144
+ `read as configuration — override clone() on ${name} to carry them if it is ` +
145
+ "the latter (HttpAgent.clone() is the reference).");
122
146
  }
123
147
  /**
124
148
  * Resolve effective turn concurrency from `store.concurrency` and legacy
@@ -256,8 +280,59 @@ export function createChannel(opts) {
256
280
  return run;
257
281
  }
258
282
  const toolMap = new Map();
259
- for (const t of opts.tools ?? [])
260
- toolMap.set(t.name, t);
283
+ let componentConfigurationError;
284
+ for (const tool of opts.tools ?? []) {
285
+ if (toolMap.has(tool.name)) {
286
+ componentConfigurationError = new Error(`duplicate channel tool or component name "${tool.name}"`);
287
+ continue;
288
+ }
289
+ toolMap.set(tool.name, tool);
290
+ }
291
+ const componentEntries = [];
292
+ const configuredComponents = Array.isArray(opts.components)
293
+ ? opts.components.map((component) => ({
294
+ name: component.name,
295
+ component,
296
+ }))
297
+ : Object.entries(opts.components ?? {}).map(([name, component]) => ({
298
+ name,
299
+ component,
300
+ }));
301
+ const componentNames = new Set();
302
+ for (const { name, component } of configuredComponents) {
303
+ if (!name)
304
+ continue;
305
+ if (componentNames.has(name) || toolMap.has(name)) {
306
+ componentConfigurationError = new Error(`duplicate channel tool or component name "${name}"`);
307
+ continue;
308
+ }
309
+ componentNames.add(name);
310
+ if (isChannelComponentDefinition(component)) {
311
+ componentEntries.push({
312
+ name,
313
+ requireKeys: true,
314
+ render: (props, renderContext) => component.render(props, renderContext),
315
+ });
316
+ toolMap.set(name, {
317
+ name,
318
+ description: component.description,
319
+ parameters: component.parameters,
320
+ async handler(args, toolContext) {
321
+ await toolContext.thread.postRegisteredComponent(name, args, {
322
+ platform: toolContext.platform,
323
+ signal: toolContext.signal ?? new AbortController().signal,
324
+ });
325
+ return `Rendered component "${name}".`;
326
+ },
327
+ });
328
+ continue;
329
+ }
330
+ componentEntries.push({
331
+ name,
332
+ requireKeys: false,
333
+ render: (props) => component(props),
334
+ });
335
+ }
261
336
  const context = opts.context ?? [];
262
337
  const mentionHandlers = [];
263
338
  const messageHandlers = [];
@@ -681,6 +756,8 @@ export function createChannel(opts) {
681
756
  // and real adapters would connect/port-bind twice.
682
757
  if (started)
683
758
  return;
759
+ if (componentConfigurationError)
760
+ throw componentConfigurationError;
684
761
  if (adapters.some((adapter) => adapter.capabilities.supportsMessageEvents) &&
685
762
  mentionHandlers.length === 0 &&
686
763
  messageHandlers.length === 0) {
@@ -706,20 +783,22 @@ export function createChannel(opts) {
706
783
  retentionMs: cfg.actionRetentionMs ?? 7 * 24 * 60 * 60 * 1000,
707
784
  });
708
785
  registry = registryInstance;
709
- for (const c of opts.components ?? []) {
710
- if (!c.name) {
786
+ for (const component of componentEntries) {
787
+ if (!component.name) {
711
788
  console.warn("[channel] createChannel: skipping anonymous component — give it a name to enable durable actions after restart.");
712
789
  continue;
713
790
  }
714
- registryInstance.registerComponent(c.name, c);
791
+ registryInstance.registerComponent(component.name, component.render, {
792
+ requireKeys: component.requireKeys,
793
+ });
715
794
  }
716
795
  toolDescriptors = toAgentToolDescriptors([...toolMap.values()]);
717
796
  tel.capture("oss.channel.configured", {
718
797
  platforms: adapters.map((a) => normalizePlatform(a.platform)),
719
798
  adapterCount: adapters.length,
720
799
  store: storeKind(backend),
721
- hasComponents: (opts.components?.length ?? 0) > 0,
722
- componentsCount: opts.components?.length ?? 0,
800
+ hasComponents: componentEntries.length > 0,
801
+ componentsCount: componentEntries.length,
723
802
  toolsCount: toolMap.size,
724
803
  commandsCount: commandHandlers.size,
725
804
  contextCount: context.length,
@@ -985,8 +985,9 @@ describe("createChannel", () => {
985
985
  // Nothing ever runs on the configured object, so it stays pristine.
986
986
  expect(shared.messages).toEqual([]);
987
987
  });
988
- it("agent whose clone() drops subclass state fails loud", async () => {
988
+ it("agent whose clone() drops subclass state warns and still runs the turn", async () => {
989
989
  const state = new MemoryStore();
990
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => undefined);
990
991
  // Inherits `FakeAgent.clone()`, which builds a plain `FakeAgent` and so
991
992
  // cannot carry this field — the same shape as a subclass inheriting
992
993
  // `AbstractAgent.prototype.clone()`, which copies a fixed field list.
@@ -1006,13 +1007,46 @@ describe("createChannel", () => {
1006
1007
  });
1007
1008
  await channel.ɵruntime.start();
1008
1009
  const sink = fake.getSink();
1010
+ // Reports it, and does not refuse the turn: whether a dropped field matters
1011
+ // depends on what it holds, and this cannot tell config from per-run state.
1009
1012
  await expect(sink.onTurn({
1010
1013
  conversationKey: "c1",
1011
1014
  replyTarget: {},
1012
1015
  userText: "hi",
1013
1016
  platform: "fake",
1014
1017
  eventId: "E1",
1015
- })).rejects.toThrow(/StatefulAgent\.clone\(\) dropped authClient/);
1018
+ })).resolves.not.toThrow();
1019
+ expect(warn).toHaveBeenCalledWith(expect.stringMatching(/StatefulAgent\.clone\(\) dropped authClient/));
1020
+ warn.mockRestore();
1021
+ });
1022
+ it("the dropped-state warning names every field, once per turn", async () => {
1023
+ const state = new MemoryStore();
1024
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => undefined);
1025
+ class TwoFieldAgent extends FakeAgent {
1026
+ authClient = { token: "secret" };
1027
+ cache = new Map();
1028
+ }
1029
+ const fake = new FakeAdapter();
1030
+ const channel = createChannel({
1031
+ identifyUser: "platform",
1032
+ adapters: [fake],
1033
+ agent: () => new TwoFieldAgent(),
1034
+ store: { adapter: state },
1035
+ });
1036
+ channel.onMention(async ({ thread }) => {
1037
+ await thread.runAgent({ prompt: "hi" });
1038
+ });
1039
+ await channel.ɵruntime.start();
1040
+ await fake.getSink().onTurn({
1041
+ conversationKey: "c1",
1042
+ replyTarget: {},
1043
+ userText: "hi",
1044
+ platform: "fake",
1045
+ eventId: "E1",
1046
+ });
1047
+ expect(warn).toHaveBeenCalledTimes(1);
1048
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining("authClient, cache"));
1049
+ warn.mockRestore();
1016
1050
  });
1017
1051
  it("does not fail loud when clone() drops an instance-patched method", async () => {
1018
1052
  const state = new MemoryStore();
package/dist/index.d.ts CHANGED
@@ -2,7 +2,9 @@ export { createChannel } from "./create-channel.js";
2
2
  export { isolateAgentInstance, resolveChannelConcurrency, } from "./create-channel.js";
3
3
  export { sanitizeAgentEventStream } from "./sanitize-agent-events.js";
4
4
  export { HttpAgent } from "@ag-ui/client";
5
- export type { Channel, CreateChannelOptions, ReplyContinuationOptions, ChannelHandler, WelcomeHandler, ThreadStartHandler, ReactionEvent, ReactionHandler, ModalSubmitEvent, ModalSubmitHandler, ModalCloseEvent, ModalCloseHandler, StoreConfig, LockConflictDecision, ChannelConcurrency, StatefulThread, ChannelComponent, } from "./create-channel.js";
5
+ export type { Channel, CreateChannelOptions, ReplyContinuationOptions, ChannelHandler, WelcomeHandler, ThreadStartHandler, ReactionEvent, ReactionHandler, ModalSubmitEvent, ModalSubmitHandler, ModalCloseEvent, ModalCloseHandler, StoreConfig, LockConflictDecision, ChannelConcurrency, StatefulThread, ChannelComponent, ChannelComponentRegistration, } from "./create-channel.js";
6
+ export { defineChannelComponent } from "./channel-component.js";
7
+ export type { ChannelComponentDefinition, ChannelComponentPlatform, ChannelComponentRenderContext, } from "./channel-component.js";
6
8
  export { ChannelIdentityResolutionError, ChannelIdentityResultError, resolveChannelUser, } from "./identity.js";
7
9
  export type { ChannelConversation, ChannelEvent, ChannelIdentifyUser, ChannelIdentityContext, ChannelInstallation, ChannelTenant, IngressIdentityContext, } from "./identity.js";
8
10
  export { Thread } from "./thread.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ export { sanitizeAgentEventStream } from "./sanitize-agent-events.js";
8
8
  // The usual `agent` for a Channel is an AG-UI agent over HTTP. Re-exported so
9
9
  // wiring one up needs no second import (any `AbstractAgent` still works).
10
10
  export { HttpAgent } from "@ag-ui/client";
11
+ export { defineChannelComponent } from "./channel-component.js";
11
12
  export { ChannelIdentityResolutionError, ChannelIdentityResultError, resolveChannelUser, } from "./identity.js";
12
13
  // Thread
13
14
  export { Thread } from "./thread.js";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=keyed-action-recovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyed-action-recovery.test.d.ts","sourceRoot":"","sources":["../src/keyed-action-recovery.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,121 @@
1
+ import { jsx as _jsx } from "@copilotkit/channels-core/jsx-runtime";
2
+ import { createNativeNode } from "@copilotkit/channels-ui";
3
+ import { expect, test, vi } from "vitest";
4
+ import { ActionRegistry } from "./action-registry.js";
5
+ import { InMemoryActionStore } from "./action-store.js";
6
+ function SlackButton(props) {
7
+ return createNativeNode("slack", "element", "button", props);
8
+ }
9
+ async function unusedChoice() {
10
+ throw new Error("awaitChoice is not used by this fixture");
11
+ }
12
+ async function emptyState() {
13
+ return undefined;
14
+ }
15
+ function interactionContext(id) {
16
+ const thread = {
17
+ platform: "slack",
18
+ post: async () => ({ id: "message-1" }),
19
+ update: async (ref) => ref,
20
+ delete: async () => undefined,
21
+ awaitChoice: unusedChoice,
22
+ runAgent: async () => undefined,
23
+ resume: async () => undefined,
24
+ stream: async () => ({ id: "message-1" }),
25
+ postFile: async () => ({ ok: true, fileId: "file-1" }),
26
+ getMessages: async () => [],
27
+ lookupUser: async () => undefined,
28
+ setSuggestedPrompts: async () => ({ ok: true }),
29
+ setTitle: async () => ({ ok: true }),
30
+ react: async () => ({ ok: true }),
31
+ unreact: async () => ({ ok: true }),
32
+ postEphemeral: async () => null,
33
+ subscribe: async () => undefined,
34
+ unsubscribe: async () => undefined,
35
+ isSubscribed: async () => false,
36
+ setState: async () => undefined,
37
+ state: emptyState,
38
+ };
39
+ const actor = { id: "user-1", kind: "human" };
40
+ return {
41
+ thread,
42
+ message: {
43
+ text: "",
44
+ user: null,
45
+ actor,
46
+ ref: { id: "message-1" },
47
+ platform: "slack",
48
+ },
49
+ action: { id, value: { decision: "provider-mutated" } },
50
+ values: {},
51
+ user: null,
52
+ actor,
53
+ platform: "slack",
54
+ };
55
+ }
56
+ function actionId(tree, key) {
57
+ const elements = tree[0]?.props.elements;
58
+ if (!Array.isArray(elements)) {
59
+ throw new Error("expected native action elements");
60
+ }
61
+ const node = elements.find((candidate) => typeof candidate === "object" &&
62
+ candidate !== null &&
63
+ "key" in candidate &&
64
+ candidate.key === key);
65
+ if (!node || typeof node !== "object" || !("props" in node)) {
66
+ throw new Error(`expected action with key ${key}`);
67
+ }
68
+ const handler = node.props.onClick;
69
+ if (typeof handler !== "object" ||
70
+ handler === null ||
71
+ !("id" in handler) ||
72
+ typeof handler.id !== "string") {
73
+ throw new Error(`expected bound action with key ${key}`);
74
+ }
75
+ return handler.id;
76
+ }
77
+ test("cold recovery finds the same keyed handler after async sibling reorder", async () => {
78
+ const store = new InMemoryActionStore();
79
+ const handled = vi.fn();
80
+ let reordered = false;
81
+ const render = async () => {
82
+ await Promise.resolve();
83
+ const approve = (_jsx(SlackButton, { text: "Approve", value: { decision: reordered ? "changed" : "approve" }, onClick: (context) => handled("approve", context.action.value) }, "approve-order"));
84
+ const reject = (_jsx(SlackButton, { text: "Reject", value: { decision: "reject" }, onClick: (context) => handled("reject", context.action.value) }, "reject-order"));
85
+ const unrelated = (_jsx(SlackButton, { text: "Inspect", value: { decision: "inspect" }, onClick: (context) => handled("inspect", context.action.value) }, "inspect-order"));
86
+ return createNativeNode("slack", "block", "actions", {
87
+ elements: reordered ? [unrelated, reject, approve] : [approve, reject],
88
+ });
89
+ };
90
+ const first = new ActionRegistry({ store });
91
+ first.registerComponent("order_actions", render, { requireKeys: true });
92
+ const tree = await first.bindTree("order_actions", {}, "conversation-1", undefined, { platform: "slack", signal: new AbortController().signal });
93
+ const id = actionId(tree, "approve-order");
94
+ reordered = true;
95
+ const restarted = new ActionRegistry({ store });
96
+ restarted.registerComponent("order_actions", render, {
97
+ requireKeys: true,
98
+ });
99
+ const value = await restarted.dispatch(id, interactionContext(id));
100
+ expect(value).toEqual({ decision: "approve" });
101
+ expect(handled).toHaveBeenCalledOnce();
102
+ expect(handled).toHaveBeenCalledWith("approve", { decision: "approve" });
103
+ });
104
+ test("component tools reject a handler without a stable JSX key", async () => {
105
+ const registry = new ActionRegistry({ store: new InMemoryActionStore() });
106
+ registry.registerComponent("missing_key", () => createNativeNode("slack", "element", "button", {
107
+ text: "Approve",
108
+ onClick: () => undefined,
109
+ }), { requireKeys: true });
110
+ await expect(registry.bindTree("missing_key", {}, "conversation-1")).rejects.toThrow("missing_key[0].onClick requires a non-empty JSX key");
111
+ });
112
+ test("component tools reject duplicate interactive keys", async () => {
113
+ const registry = new ActionRegistry({ store: new InMemoryActionStore() });
114
+ registry.registerComponent("duplicate_key", () => createNativeNode("slack", "block", "actions", {
115
+ elements: [
116
+ _jsx(SlackButton, { text: "Approve", value: { decision: "approve" }, onClick: () => undefined }, "decision"),
117
+ _jsx(SlackButton, { text: "Reject", value: { decision: "reject" }, onClick: () => undefined }, "decision"),
118
+ ],
119
+ }), { requireKeys: true });
120
+ await expect(registry.bindTree("duplicate_key", {}, "conversation-1")).rejects.toThrow('duplicate interactive JSX key "decision"');
121
+ });
package/dist/thread.d.ts CHANGED
@@ -7,6 +7,7 @@ import type { AbstractAgent } from "@ag-ui/client";
7
7
  import type { StateStore } from "./state/state-store.js";
8
8
  import type { StandardSchemaV1 } from "./standard-schema.js";
9
9
  import type { MemoryGrant } from "./memory.js";
10
+ import type { ChannelComponentRenderContext } from "./channel-component.js";
10
11
  /** A Channel run requested Memory without an attached Intelligence backend. */
11
12
  export declare class ChannelMemoryUnavailableError extends Error {
12
13
  readonly code = "channel_memory_unavailable";
@@ -98,6 +99,8 @@ export declare class Thread implements ThreadInterface {
98
99
  */
99
100
  private bindReaction;
100
101
  post(ui: Renderable): Promise<MessageRef>;
102
+ /** @internal Post a registered component through the normal bind and adapter path. */
103
+ postRegisteredComponent(componentName: string, props: Record<string, unknown>, renderContext: ChannelComponentRenderContext): Promise<MessageRef>;
101
104
  update(ref: MessageRef, ui: Renderable): Promise<MessageRef>;
102
105
  delete(ref: MessageRef): Promise<void>;
103
106
  stream(src: string | AsyncIterable<string>): Promise<MessageRef>;
@@ -1 +1 @@
1
- {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../src/thread.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../src/thread.ts"],"names":[],"mappings":"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"}
package/dist/thread.js CHANGED
@@ -64,7 +64,10 @@ export class Thread {
64
64
  this.store = deps.state;
65
65
  }
66
66
  async bindForPost(ui) {
67
- return this.deps.registry.bindRenderable(ui, this.deps.conversationKey, this.activeContinuation);
67
+ return this.deps.registry.bindRenderable(ui, this.deps.conversationKey, this.activeContinuation, {
68
+ platform: this.platform,
69
+ signal: new AbortController().signal,
70
+ });
68
71
  }
69
72
  trackOperation(operation) {
70
73
  if (!this.deps.adapter.trackThreadOperation) {
@@ -107,6 +110,15 @@ export class Thread {
107
110
  return ref;
108
111
  });
109
112
  }
113
+ /** @internal Post a registered component through the normal bind and adapter path. */
114
+ postRegisteredComponent(componentName, props, renderContext) {
115
+ return this.trackOperation(async () => {
116
+ const bound = await this.deps.registry.bindRegisteredRenderable(componentName, props, this.deps.conversationKey, this.activeContinuation, renderContext);
117
+ const ref = await this.deps.adapter.post(this.deps.replyTarget, bound.root);
118
+ await this.bindReaction(ref.id, bound);
119
+ return ref;
120
+ });
121
+ }
110
122
  update(ref, ui) {
111
123
  return this.trackOperation(async () => {
112
124
  const bound = await this.bindForPost(ui);
@@ -478,6 +490,7 @@ export class Thread {
478
490
  message: this.deps.message,
479
491
  user: this.deps.user,
480
492
  actor: this.deps.actor,
493
+ signal: session.agent.abortController?.signal ?? new AbortController().signal,
481
494
  platform: this.platform,
482
495
  }),
483
496
  handleInterrupt: async (interrupt) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/channels-core",
3
- "version": "0.6.0",
3
+ "version": "0.6.2-canary.1785779327",
4
4
  "description": "Platform-agnostic JSX channel engine for CopilotKit (createChannel, Thread, PlatformAdapter, ActionStore).",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -50,10 +50,10 @@
50
50
  "dependencies": {
51
51
  "@ag-ui/client": "0.0.57",
52
52
  "@ag-ui/core": "0.0.57",
53
- "zod-to-json-schema": "^3.24.1",
54
- "@copilotkit/core": "^1.64.2",
55
- "@copilotkit/shared": "^1.64.2",
56
- "@copilotkit/channels-ui": "~0.6.0"
53
+ "@copilotkit/channels-ui": "0.6.2-canary.1785779327",
54
+ "@copilotkit/core": "1.65.1-canary.1785779327",
55
+ "@copilotkit/shared": "1.65.1-canary.1785779327",
56
+ "zod-to-json-schema": "^3.24.1"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/node": "^22.10.0",