@copilotkit/bot 0.0.1 → 0.0.2

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
@@ -44,6 +44,9 @@ await bot.start();
44
44
  `{ thread, message }`. (Routing is mention-preferred: if any mention
45
45
  handler is registered, all turns route to it; otherwise message handlers
46
46
  fire.)
47
+ - `onThreadStarted(handler)` — a conversation surface opened (e.g. the Slack
48
+ assistant pane); receives `{ thread, user? }`. Greet, set suggested prompts
49
+ or a title, or run the agent. Adapters without the concept never fire it.
47
50
  - `onInteraction<TValue>(id, handler)` — explicit escape-hatch handler for a
48
51
  known action id, bypassing the registry; `ctx.action.value` is typed `TValue`.
49
52
  - `onInterrupt<TPayload>(eventName, handler)` — handle a captured agent
@@ -80,6 +83,12 @@ interface Thread {
80
83
  }): Promise<MessageRef | undefined>;
81
84
  resume(value: unknown): Promise<MessageRef | undefined>;
82
85
  awaitChoice<T = unknown>(ui: Renderable): Promise<T>;
86
+ // Capability-gated (return { ok: false } on surfaces without support):
87
+ setSuggestedPrompts(
88
+ prompts: ReadonlyArray<{ title: string; message: string }>,
89
+ opts?: { title?: string },
90
+ ): Promise<{ ok: boolean; error?: string }>;
91
+ setTitle(title: string): Promise<{ ok: boolean; error?: string }>;
83
92
  }
84
93
  ```
85
94
 
@@ -158,8 +167,9 @@ pass it as `actionStore` to make actions survive restarts.
158
167
 
159
168
  To target a new surface, implement `PlatformAdapter` from this package. The
160
169
  engine drives ingress through the `IngressSink` you receive in `start(sink)`
161
- (`sink.onTurn(IncomingTurn)` / `sink.onInteraction(InteractionEvent)`) and
162
- egress through your `post` / `update` / `stream` / `delete` (which receive
170
+ (`sink.onTurn(IncomingTurn)` / `sink.onInteraction(InteractionEvent)` /
171
+ `sink.onCommand(IncomingCommand)` / `sink.onThreadStarted(IncomingThreadStart)`)
172
+ and egress through your `post` / `update` / `stream` / `delete` (which receive
163
173
  `BotNode[]` to translate to a native payload via `render`). You also provide
164
174
  `createRunRenderer(target)` (an AG-UI `RunRenderer`: the subscriber to stream
165
175
  into, plus accessors for captured tool calls and interrupts that the run-loop
@@ -168,7 +178,10 @@ reads after each `runAgent`), `decodeInteraction(raw)` (native event → opaque
168
178
  (`getOrCreate` → `AgentSession`), and the surface `capabilities` /
169
179
  `ackDeadlineMs`. Optional capability methods like `getMessages(target)` and
170
180
  `postFile(target, args)` back the matching `thread` methods when the surface
171
- supports them. Slash commands are also capability-gated: an adapter forwards
181
+ supports them likewise `setSuggestedPrompts(target, prompts, opts?)` and
182
+ `setThreadTitle(target, title)` back `thread.setSuggestedPrompts` /
183
+ `thread.setTitle`, and `sink.onThreadStarted(...)` emits the "conversation
184
+ opened" lifecycle event. Slash commands are also capability-gated: an adapter forwards
172
185
  invocations via `sink.onCommand(IncomingCommand)`, and may implement
173
186
  `registerCommands(specs)` to publish the bot's declared commands up front
174
187
  (e.g. Discord's application-command API); adapters that omit it are skipped.
@@ -176,9 +189,10 @@ See `@copilotkit/bot-slack` for a complete implementation.
176
189
 
177
190
  ## Exports
178
191
 
179
- `createBot`, `Bot`, `CreateBotOptions`, `BotHandler`; `Thread`; the
180
- `PlatformAdapter` boundary types (`RunRenderer`, `IngressSink`,
181
- `IncomingTurn`, `InteractionEvent`, `IncomingCommand`, `SurfaceCapabilities`,
192
+ `createBot`, `Bot`, `CreateBotOptions`, `BotHandler`, `ThreadStartHandler`;
193
+ `Thread`; the `PlatformAdapter` boundary types (`RunRenderer`, `IngressSink`,
194
+ `IncomingTurn`, `InteractionEvent`, `IncomingCommand`, `IncomingThreadStart`,
195
+ `SurfaceCapabilities`,
182
196
  `ReplyTarget`, `ConversationStore`, `AgentSession`, `CapturedToolCall`,
183
197
  `CapturedInterrupt`, `UserQuery`); `ActionStore` / `InMemoryActionStore` /
184
198
  `ActionSnapshot` / `ActionRegistry` / `ActionExpiredError`; `BotTool` /
@@ -1,14 +1,19 @@
1
1
  import type { PlatformAdapter } from "./platform-adapter.js";
2
- import { type ActionStore } from "./action-store.js";
3
- import { type BotTool, type ContextEntry } from "./tools.js";
4
- import { type BotCommand, type CommandContext } from "./commands.js";
2
+ import type { ActionStore } from "./action-store.js";
3
+ import type { BotTool, ContextEntry } from "./tools.js";
4
+ import type { BotCommand, CommandContext } from "./commands.js";
5
5
  import { Thread } from "./thread.js";
6
6
  import type { AbstractAgent } from "@ag-ui/client";
7
- import type { InteractionContext, IncomingMessage } from "@copilotkit/bot-ui";
7
+ import type { InteractionContext, IncomingMessage, PlatformUser } from "@copilotkit/bot-ui";
8
8
  export type BotHandler = (ctx: {
9
9
  thread: Thread;
10
10
  message: IncomingMessage;
11
11
  }) => void | Promise<void>;
12
+ /** Handler for a "conversation opened" lifecycle event (e.g. the Slack assistant pane). */
13
+ export type ThreadStartHandler = (ctx: {
14
+ thread: Thread;
15
+ user?: PlatformUser;
16
+ }) => void | Promise<void>;
12
17
  export interface CreateBotOptions {
13
18
  adapters: PlatformAdapter[];
14
19
  agent?: AbstractAgent | ((threadId: string) => AbstractAgent);
@@ -21,6 +26,12 @@ export interface CreateBotOptions {
21
26
  export interface Bot {
22
27
  onMention(h: BotHandler): void;
23
28
  onMessage(h: BotHandler): void;
29
+ /**
30
+ * A conversation surface opened (e.g. the Slack assistant pane). Greet, set
31
+ * suggested prompts, set a title, or run the agent. Adapters without the
32
+ * concept never fire this.
33
+ */
34
+ onThreadStarted(h: ThreadStartHandler): void;
24
35
  /** Handle clicks on a specific action `id`. `ctx.action.value` is typed as `TValue`. */
25
36
  onInteraction<TValue = unknown>(id: string, h: (ctx: InteractionContext<TValue>) => void | Promise<void>): void;
26
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"create-bot.d.ts","sourceRoot":"","sources":["../src/create-bot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAmB,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,CAAC;CAC1B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC,CAAC;IAC9D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,GAAG;IAClB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,wFAAwF;IACxF,aAAa,CAAC,MAAM,GAAG,OAAO,EAC5B,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC3D,IAAI,CAAC;IACR;;;;OAIG;IACH,WAAW,CAAC,QAAQ,GAAG,OAAO,EAC5B,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACvE,IAAI,CAAC;IACR,8DAA8D;IAC9D,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,kDAAkD;IAClD,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACrD,IAAI,CAAC;IACR,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,GAAG,CA6MrD"}
1
+ {"version":3,"file":"create-bot.d.ts","sourceRoot":"","sources":["../src/create-bot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EAMhB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,CAAC;CAC1B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3B,2FAA2F;AAC3F,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE3B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,aAAa,CAAC,CAAC;IAC9D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,GAAG;IAClB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B;;;;OAIG;IACH,eAAe,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC7C,wFAAwF;IACxF,aAAa,CAAC,MAAM,GAAG,OAAO,EAC5B,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC3D,IAAI,CAAC;IACR;;;;OAIG;IACH,WAAW,CAAC,QAAQ,GAAG,OAAO,EAC5B,SAAS,EAAE,MAAM,EACjB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACvE,IAAI,CAAC;IACR,8DAA8D;IAC9D,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,kDAAkD;IAClD,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACrD,IAAI,CAAC;IACR,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,GAAG,CA6NrD"}
@@ -1,7 +1,7 @@
1
1
  import { ActionRegistry, ActionExpiredError } from "./action-registry.js";
2
2
  import { InMemoryActionStore } from "./action-store.js";
3
- import { toAgentToolDescriptors, parseToolArgs, } from "./tools.js";
4
- import { normalizeCommandName, toCommandSpec, } from "./commands.js";
3
+ import { toAgentToolDescriptors, parseToolArgs } from "./tools.js";
4
+ import { normalizeCommandName, toCommandSpec } from "./commands.js";
5
5
  import { Thread } from "./thread.js";
6
6
  export function createBot(opts) {
7
7
  const registry = new ActionRegistry({
@@ -23,6 +23,7 @@ export function createBot(opts) {
23
23
  const context = opts.context ?? [];
24
24
  const mentionHandlers = [];
25
25
  const messageHandlers = [];
26
+ const threadStartedHandlers = [];
26
27
  const interactionHandlers = new Map();
27
28
  const interruptHandlers = new Map();
28
29
  const commandHandlers = new Map();
@@ -125,6 +126,14 @@ export function createBot(opts) {
125
126
  };
126
127
  await command.handler(ctx);
127
128
  },
129
+ async onThreadStarted(evt) {
130
+ // The adapter has already applied its static defaults (greeting /
131
+ // prompts) before emitting this, so handlers layer on top and never
132
+ // race. Zero handlers → no-op.
133
+ const thread = makeThread(adapter, evt.replyTarget, evt.conversationKey);
134
+ for (const h of threadStartedHandlers)
135
+ await h({ thread, user: evt.user });
136
+ },
128
137
  };
129
138
  }
130
139
  return {
@@ -134,6 +143,9 @@ export function createBot(opts) {
134
143
  onMessage(h) {
135
144
  messageHandlers.push(h);
136
145
  },
146
+ onThreadStarted(h) {
147
+ threadStartedHandlers.push(h);
148
+ },
137
149
  onInteraction(id, h) {
138
150
  interactionHandlers.set(id, h);
139
151
  },
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { createBot } from "./create-bot.js";
2
- export type { Bot, CreateBotOptions, BotHandler } from "./create-bot.js";
2
+ export type { Bot, CreateBotOptions, BotHandler, ThreadStartHandler, } from "./create-bot.js";
3
3
  export { Thread } from "./thread.js";
4
4
  export type { ThreadDeps } from "./thread.js";
5
- export type { PlatformAdapter, RunRenderer, IngressSink, IncomingTurn, InteractionEvent, IncomingCommand, SurfaceCapabilities, ReplyTarget, ConversationStore, AgentSession, CapturedToolCall, CapturedInterrupt, UserQuery, NativePayload, } from "./platform-adapter.js";
5
+ export type { PlatformAdapter, RunRenderer, IngressSink, IncomingTurn, InteractionEvent, IncomingCommand, IncomingThreadStart, SurfaceCapabilities, ReplyTarget, ConversationStore, AgentSession, CapturedToolCall, CapturedInterrupt, UserQuery, NativePayload, } from "./platform-adapter.js";
6
6
  export { defineBotCommand, normalizeCommandName, toCommandSpec, } from "./commands.js";
7
7
  export type { BotCommand, CommandContext, CommandSpec } from "./commands.js";
8
8
  export { InMemoryActionStore } from "./action-store.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,YAAY,EACV,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EACV,GAAG,EACH,gBAAgB,EAChB,UAAU,EACV,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,YAAY,EACV,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,aAAa,GACd,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EACL,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD,cAAc,oBAAoB,CAAC"}
@@ -11,6 +11,10 @@ export interface SurfaceCapabilities {
11
11
  supportsReactions: boolean;
12
12
  supportsStreaming: boolean;
13
13
  maxBlocksPerMessage?: number;
14
+ /** Pinned prompt chips on a conversation surface (Slack assistant pane). */
15
+ supportsSuggestedPrompts?: boolean;
16
+ /** Nameable conversations (Slack assistant-thread titles). */
17
+ supportsThreadTitle?: boolean;
14
18
  [k: string]: unknown;
15
19
  }
16
20
  export interface CapturedToolCall {
@@ -59,11 +63,23 @@ export interface IncomingCommand {
59
63
  user?: PlatformUser;
60
64
  platform: string;
61
65
  }
66
+ /**
67
+ * A "conversation opened" lifecycle event (Slack: `assistant_thread_started`).
68
+ * Adapters without the concept never emit it.
69
+ */
70
+ export interface IncomingThreadStart {
71
+ conversationKey: string;
72
+ replyTarget: ReplyTarget;
73
+ user?: PlatformUser;
74
+ platform: string;
75
+ }
62
76
  export interface IngressSink {
63
77
  onTurn(turn: IncomingTurn): void | Promise<void>;
64
78
  onInteraction(evt: InteractionEvent): void | Promise<void>;
65
79
  /** A slash command fired. Routed to the matching `bot.onCommand` handler (ignored if none). */
66
80
  onCommand(cmd: IncomingCommand): void | Promise<void>;
81
+ /** A conversation surface opened. Adapters without the concept never call it. */
82
+ onThreadStarted(evt: IncomingThreadStart): void | Promise<void>;
67
83
  }
68
84
  export interface UserQuery {
69
85
  query: string;
@@ -121,5 +137,29 @@ export interface PlatformAdapter {
121
137
  * commands at all simply omit it and command handlers never fire there.
122
138
  */
123
139
  registerCommands?(commands: readonly CommandSpec[]): void | Promise<void>;
140
+ /**
141
+ * Optional: pin suggested prompts on a conversation surface (backs the
142
+ * capability-gated `Thread.setSuggestedPrompts`). Adapters without the
143
+ * concept omit this, and `Thread.setSuggestedPrompts` returns
144
+ * `{ ok: false, error }` without throwing.
145
+ */
146
+ setSuggestedPrompts?(target: ReplyTarget, prompts: ReadonlyArray<{
147
+ title: string;
148
+ message: string;
149
+ }>, opts?: {
150
+ title?: string;
151
+ }): Promise<{
152
+ ok: boolean;
153
+ error?: string;
154
+ }>;
155
+ /**
156
+ * Optional: set the conversation's display title (backs `Thread.setTitle`).
157
+ * Adapters without the concept omit this, and `Thread.setTitle` returns
158
+ * `{ ok: false, error }` without throwing.
159
+ */
160
+ setThreadTitle?(target: ReplyTarget, title: string): Promise<{
161
+ ok: boolean;
162
+ error?: string;
163
+ }>;
124
164
  }
125
165
  //# sourceMappingURL=platform-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"platform-adapter.d.ts","sourceRoot":"","sources":["../src/platform-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platform-adapter.d.ts","sourceRoot":"","sources":["../src/platform-adapter.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ describe("FakeAdapter", () => {
10
10
  },
11
11
  onInteraction: () => { },
12
12
  onCommand: () => { },
13
+ onThreadStarted: () => { },
13
14
  });
14
15
  a.emitTurn({ userText: "hi" });
15
16
  expect(got).toBe("hi");
@@ -25,6 +26,7 @@ describe("FakeAdapter", () => {
25
26
  id = e.id;
26
27
  },
27
28
  onCommand: () => { },
29
+ onThreadStarted: () => { },
28
30
  });
29
31
  a.emitInteraction({ id: "ck:abc" });
30
32
  expect(id).toBe("ck:abc");
@@ -1,5 +1,5 @@
1
1
  import type { BotNode, MessageRef, PlatformUser, ThreadMessage } from "@copilotkit/bot-ui";
2
- import type { PlatformAdapter, SurfaceCapabilities, IngressSink, IncomingTurn, InteractionEvent, IncomingCommand, RunRenderer, ReplyTarget, NativePayload, UserQuery, ConversationStore } from "../platform-adapter.js";
2
+ import type { PlatformAdapter, SurfaceCapabilities, IngressSink, IncomingTurn, IncomingThreadStart, InteractionEvent, IncomingCommand, RunRenderer, ReplyTarget, NativePayload, UserQuery, ConversationStore } from "../platform-adapter.js";
3
3
  import type { CommandSpec } from "../commands.js";
4
4
  /** A RunRenderer whose subscriber captures tool-call-end and custom (interrupt) events — used by run-loop tests. */
5
5
  export declare function makeFakeRunRenderer(): RunRenderer;
@@ -7,6 +7,15 @@ export declare class FakeAdapter implements PlatformAdapter {
7
7
  readonly platform = "fake";
8
8
  readonly capabilities: SurfaceCapabilities;
9
9
  readonly ackDeadlineMs = 3000;
10
+ /**
11
+ * @param fakeOpts.paneMethods When `false`, the optional
12
+ * `setSuggestedPrompts`/`setThreadTitle` methods are omitted (and the
13
+ * matching capability flags cleared) so tests can exercise the
14
+ * capability-gated `{ ok: false }` path. Defaults to present.
15
+ */
16
+ constructor(fakeOpts?: {
17
+ paneMethods?: boolean;
18
+ });
10
19
  readonly conversationStore: ConversationStore;
11
20
  posted: BotNode[][];
12
21
  updated: {
@@ -32,7 +41,26 @@ export declare class FakeAdapter implements PlatformAdapter {
32
41
  decodeInteraction(raw: unknown): InteractionEvent | undefined;
33
42
  lookupUser(_q: UserQuery): Promise<PlatformUser | undefined>;
34
43
  getMessages(_target: ReplyTarget): Promise<ThreadMessage[]>;
44
+ /** Suggested-prompt calls recorded by the capability-gated method (when present). */
45
+ suggestedPromptsCalls: {
46
+ target: ReplyTarget;
47
+ prompts: ReadonlyArray<{
48
+ title: string;
49
+ message: string;
50
+ }>;
51
+ opts?: {
52
+ title?: string;
53
+ };
54
+ }[];
55
+ setSuggestedPrompts?: PlatformAdapter["setSuggestedPrompts"];
56
+ /** Thread-title calls recorded by the capability-gated method (when present). */
57
+ threadTitleCalls: {
58
+ target: ReplyTarget;
59
+ title: string;
60
+ }[];
61
+ setThreadTitle?: PlatformAdapter["setThreadTitle"];
35
62
  emitTurn(partial: Partial<IncomingTurn>): void;
63
+ emitThreadStarted(partial?: Partial<IncomingThreadStart>): Promise<void> | void;
36
64
  emitInteraction(partial: Partial<InteractionEvent>): void;
37
65
  emitCommand(partial: Partial<IncomingCommand> & {
38
66
  command: string;
@@ -1 +1 @@
1
- {"version":3,"file":"fake-adapter.d.ts","sourceRoot":"","sources":["../../src/testing/fake-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,UAAU,EACV,YAAY,EACZ,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EAGX,WAAW,EACX,aAAa,EACb,SAAS,EACT,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,oHAAoH;AACpH,wBAAgB,mBAAmB,IAAI,WAAW,CAyBjD;AAED,qBAAa,WAAY,YAAW,eAAe;IACjD,QAAQ,CAAC,QAAQ,UAAU;IAC3B,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAKxC;IACF,QAAQ,CAAC,aAAa,QAAQ;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAI3C;IAEF,MAAM,EAAE,OAAO,EAAE,EAAE,CAAM;IACzB,OAAO,EAAE;QAAE,GAAG,EAAE,UAAU,CAAC;QAAC,EAAE,EAAE,OAAO,EAAE,CAAA;KAAE,EAAE,CAAM;IACnD,gBAAgB,EAAE,gBAAgB,EAAE,CAAM;IAC1C,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,4DAA4D;IAC5D,QAAQ,EAAE,aAAa,EAAE,CAAM;IAC/B,wDAAwD;IACxD,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAK;IAEd,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAGvC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,aAAa;IAG9B,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9D,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAGrD,MAAM,CACV,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC,UAAU,CAAC;IAMhB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAE7C,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW;IAKpD,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS;IAGvD,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAG5D,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAKjE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAS9C,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAUzD,WAAW,CACT,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GACtD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAUvB,gGAAgG;IAChG,kBAAkB,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC5C,gBAAgB,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI;CAGzD"}
1
+ {"version":3,"file":"fake-adapter.d.ts","sourceRoot":"","sources":["../../src/testing/fake-adapter.ts"],"names":[],"mappings":"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"}
@@ -28,13 +28,35 @@ export function makeFakeRunRenderer() {
28
28
  }
29
29
  export class FakeAdapter {
30
30
  platform = "fake";
31
- capabilities = {
32
- supportsModals: false,
33
- supportsTyping: false,
34
- supportsReactions: false,
35
- supportsStreaming: true,
36
- };
31
+ capabilities;
37
32
  ackDeadlineMs = 3000;
33
+ /**
34
+ * @param fakeOpts.paneMethods When `false`, the optional
35
+ * `setSuggestedPrompts`/`setThreadTitle` methods are omitted (and the
36
+ * matching capability flags cleared) so tests can exercise the
37
+ * capability-gated `{ ok: false }` path. Defaults to present.
38
+ */
39
+ constructor(fakeOpts = {}) {
40
+ const paneMethods = fakeOpts.paneMethods !== false;
41
+ this.capabilities = {
42
+ supportsModals: false,
43
+ supportsTyping: false,
44
+ supportsReactions: false,
45
+ supportsStreaming: true,
46
+ supportsSuggestedPrompts: paneMethods,
47
+ supportsThreadTitle: paneMethods,
48
+ };
49
+ if (paneMethods) {
50
+ this.setSuggestedPrompts = async (target, prompts, opts) => {
51
+ this.suggestedPromptsCalls.push({ target, prompts, opts });
52
+ return { ok: true };
53
+ };
54
+ this.setThreadTitle = async (target, title) => {
55
+ this.threadTitleCalls.push({ target, title });
56
+ return { ok: true };
57
+ };
58
+ }
59
+ }
38
60
  conversationStore = {
39
61
  async getOrCreate(conversationKey, _replyTarget, makeAgent) {
40
62
  return { agent: makeAgent(conversationKey) };
@@ -86,6 +108,12 @@ export class FakeAdapter {
86
108
  async getMessages(_target) {
87
109
  return this.messages;
88
110
  }
111
+ /** Suggested-prompt calls recorded by the capability-gated method (when present). */
112
+ suggestedPromptsCalls = [];
113
+ setSuggestedPrompts;
114
+ /** Thread-title calls recorded by the capability-gated method (when present). */
115
+ threadTitleCalls = [];
116
+ setThreadTitle;
89
117
  // --- test helpers ---
90
118
  emitTurn(partial) {
91
119
  void this.sink?.onTurn({
@@ -96,6 +124,14 @@ export class FakeAdapter {
96
124
  ...partial,
97
125
  });
98
126
  }
127
+ emitThreadStarted(partial) {
128
+ return this.sink?.onThreadStarted({
129
+ conversationKey: "c",
130
+ replyTarget: {},
131
+ platform: "fake",
132
+ ...partial,
133
+ });
134
+ }
99
135
  emitInteraction(partial) {
100
136
  const evt = {
101
137
  id: "",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=thread-capabilities.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-capabilities.test.d.ts","sourceRoot":"","sources":["../src/thread-capabilities.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { createBot } from "./create-bot.js";
3
+ import { FakeAdapter } from "./testing/fake-adapter.js";
4
+ describe("onThreadStarted routing", () => {
5
+ it("invokes registered handlers with the thread and user", async () => {
6
+ const fake = new FakeAdapter();
7
+ const bot = createBot({ adapters: [fake] });
8
+ const seen = [];
9
+ bot.onThreadStarted(({ thread, user }) => {
10
+ seen.push({ user: user?.id, platform: thread.platform });
11
+ });
12
+ await bot.start();
13
+ await fake.emitThreadStarted({ user: { id: "U1", name: "Ada" } });
14
+ expect(seen).toEqual([{ user: "U1", platform: "fake" }]);
15
+ });
16
+ it("invokes every registered handler in order", async () => {
17
+ const fake = new FakeAdapter();
18
+ const bot = createBot({ adapters: [fake] });
19
+ const order = [];
20
+ bot.onThreadStarted(() => {
21
+ order.push(1);
22
+ });
23
+ bot.onThreadStarted(() => {
24
+ order.push(2);
25
+ });
26
+ await bot.start();
27
+ await fake.emitThreadStarted();
28
+ expect(order).toEqual([1, 2]);
29
+ });
30
+ it("is a no-op when no handler is registered", async () => {
31
+ const fake = new FakeAdapter();
32
+ const bot = createBot({ adapters: [fake] });
33
+ await bot.start();
34
+ // Should not throw.
35
+ await expect(Promise.resolve(fake.emitThreadStarted())).resolves.toBeUndefined();
36
+ });
37
+ });
38
+ describe("Thread.setSuggestedPrompts / setTitle capability gating", () => {
39
+ it("delegates to the adapter when supported", async () => {
40
+ const fake = new FakeAdapter();
41
+ const bot = createBot({ adapters: [fake] });
42
+ const results = [];
43
+ bot.onThreadStarted(async ({ thread }) => {
44
+ results.push(await thread.setSuggestedPrompts([{ title: "Triage", message: "Triage my issues" }], { title: "Try" }));
45
+ results.push(await thread.setTitle("My conversation"));
46
+ });
47
+ await bot.start();
48
+ await fake.emitThreadStarted({ replyTarget: { channel: "D1" } });
49
+ expect(results).toEqual([{ ok: true }, { ok: true }]);
50
+ expect(fake.suggestedPromptsCalls).toHaveLength(1);
51
+ expect(fake.suggestedPromptsCalls[0]).toMatchObject({
52
+ target: { channel: "D1" },
53
+ prompts: [{ title: "Triage", message: "Triage my issues" }],
54
+ opts: { title: "Try" },
55
+ });
56
+ expect(fake.threadTitleCalls).toEqual([
57
+ { target: { channel: "D1" }, title: "My conversation" },
58
+ ]);
59
+ });
60
+ it("returns { ok: false } without throwing when unsupported", async () => {
61
+ const fake = new FakeAdapter({ paneMethods: false });
62
+ const bot = createBot({ adapters: [fake] });
63
+ const results = [];
64
+ bot.onThreadStarted(async ({ thread }) => {
65
+ results.push(await thread.setSuggestedPrompts([]));
66
+ results.push(await thread.setTitle("nope"));
67
+ });
68
+ await bot.start();
69
+ await fake.emitThreadStarted();
70
+ expect(results[0].ok).toBe(false);
71
+ expect(results[0].error).toMatch(/does not support suggested prompts/);
72
+ expect(results[1].ok).toBe(false);
73
+ expect(results[1].error).toMatch(/does not support thread titles/);
74
+ expect(fake.suggestedPromptsCalls).toHaveLength(0);
75
+ expect(fake.threadTitleCalls).toHaveLength(0);
76
+ });
77
+ });
package/dist/thread.d.ts CHANGED
@@ -38,6 +38,21 @@ export declare class Thread implements ThreadInterface {
38
38
  fileId?: string;
39
39
  error?: string;
40
40
  }>;
41
+ /** Pin suggested prompts (returns `{ ok: false }` on surfaces without support). */
42
+ setSuggestedPrompts(prompts: ReadonlyArray<{
43
+ title: string;
44
+ message: string;
45
+ }>, opts?: {
46
+ title?: string;
47
+ }): Promise<{
48
+ ok: boolean;
49
+ error?: string;
50
+ }>;
51
+ /** Name this conversation (returns `{ ok: false }` on surfaces without support). */
52
+ setTitle(title: string): Promise<{
53
+ ok: boolean;
54
+ error?: string;
55
+ }>;
41
56
  /** Read the conversation's messages (returns `[]` when the adapter can't read history). */
42
57
  getMessages(): Promise<ThreadMessage[]>;
43
58
  /** Resolve a platform user by free-form query (returns `undefined` when unsupported). */
@@ -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
@@ -39,6 +39,28 @@ export class Thread {
39
39
  }
40
40
  return adapter.postFile(this.deps.replyTarget, args);
41
41
  }
42
+ /** Pin suggested prompts (returns `{ ok: false }` on surfaces without support). */
43
+ async setSuggestedPrompts(prompts, opts) {
44
+ const adapter = this.deps.adapter;
45
+ if (!adapter.setSuggestedPrompts) {
46
+ return {
47
+ ok: false,
48
+ error: `${this.platform} does not support suggested prompts`,
49
+ };
50
+ }
51
+ return adapter.setSuggestedPrompts(this.deps.replyTarget, prompts, opts);
52
+ }
53
+ /** Name this conversation (returns `{ ok: false }` on surfaces without support). */
54
+ async setTitle(title) {
55
+ const adapter = this.deps.adapter;
56
+ if (!adapter.setThreadTitle) {
57
+ return {
58
+ ok: false,
59
+ error: `${this.platform} does not support thread titles`,
60
+ };
61
+ }
62
+ return adapter.setThreadTitle(this.deps.replyTarget, title);
63
+ }
42
64
  /** Read the conversation's messages (returns `[]` when the adapter can't read history). */
43
65
  async getMessages() {
44
66
  return (await this.deps.adapter.getMessages?.(this.deps.replyTarget)) ?? [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/bot",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Platform-agnostic JSX bot engine for CopilotKit (createBot, Thread, PlatformAdapter, ActionStore).",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -35,12 +35,12 @@
35
35
  "dist"
36
36
  ],
37
37
  "dependencies": {
38
- "@ag-ui/client": "0.0.53",
39
- "@ag-ui/core": "0.0.53",
38
+ "@ag-ui/client": "0.0.57",
39
+ "@ag-ui/core": "0.0.57",
40
40
  "zod-to-json-schema": "^3.24.1",
41
- "@copilotkit/bot-ui": "~0.0.1",
42
- "@copilotkit/shared": "^1.59.5",
43
- "@copilotkit/core": "^1.59.5"
41
+ "@copilotkit/bot-ui": "~0.0.2",
42
+ "@copilotkit/shared": "^1.60.1",
43
+ "@copilotkit/core": "^1.60.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^22.10.0",