chat 4.27.0 → 4.28.1

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.
@@ -354,7 +354,8 @@ function Button(options) {
354
354
  style: options.style,
355
355
  value: options.value,
356
356
  disabled: options.disabled,
357
- actionType: options.actionType
357
+ actionType: options.actionType,
358
+ callbackUrl: options.callbackUrl
358
359
  };
359
360
  }
360
361
  function LinkButton(options) {
@@ -607,6 +608,7 @@ function Modal(options) {
607
608
  return {
608
609
  type: "modal",
609
610
  callbackId: options.callbackId,
611
+ callbackUrl: options.callbackUrl,
610
612
  title: options.title,
611
613
  submitLabel: options.submitLabel,
612
614
  closeLabel: options.closeLabel,
@@ -881,6 +883,7 @@ function resolveJSXElement(element) {
881
883
  style: props.style,
882
884
  value: props.value,
883
885
  actionType: props.actionType,
886
+ callbackUrl: props.callbackUrl,
884
887
  disabled: props.disabled
885
888
  });
886
889
  }
@@ -929,6 +932,7 @@ function resolveJSXElement(element) {
929
932
  }
930
933
  return Modal({
931
934
  callbackId: props.callbackId,
935
+ callbackUrl: props.callbackUrl,
932
936
  title: props.title,
933
937
  submitLabel: props.submitLabel,
934
938
  closeLabel: props.closeLabel,
package/dist/index.d.ts CHANGED
@@ -1,27 +1,30 @@
1
1
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
2
2
  import { Root, List, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, Paragraph, Strong, TableCell, Table as Table$1, TableRow, Text } from 'mdast';
3
3
  export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Table as MdastTable, Nodes, Paragraph, Root, Strong, TableCell, TableRow, Text } from 'mdast';
4
- import { C as ChatElement, a as CardElement, M as ModalElement, S as SelectOptionElement, b as CardChild, A as ActionsComponent, B as ButtonComponent, c as CardComponent, d as cardChildToFallbackText$1, e as CardLinkComponent, T as TextComponent, D as DividerComponent, F as FieldComponent, f as FieldsComponent, g as fromReactElement$1, I as ImageComponent, i as isCardElement$1, h as isJSX$1, L as LinkButtonComponent, j as SectionComponent, k as Table$2, t as toCardElement$1, l as toModalElement$1, m as fromReactModalElement$1, n as isModalElement$1, E as ExternalSelectComponent, o as ModalComponent, R as RadioSelectComponent, p as SelectComponent, q as SelectOptionComponent, r as TextInputComponent } from './jsx-runtime-Co9uV6l7.js';
5
- export { s as ActionsElement, u as ButtonElement, v as ButtonOptions, X as ButtonProps, w as ButtonStyle, Y as CardJSXElement, Z as CardJSXProps, _ as CardLinkProps, x as CardOptions, $ as CardProps, a0 as ContainerProps, y as DividerElement, a1 as DividerProps, ab as ExternalSelectElement, ac as ExternalSelectOptions, a2 as ExternalSelectProps, z as FieldElement, a3 as FieldProps, G as FieldsElement, H as ImageElement, a4 as ImageProps, J as LinkButtonElement, K as LinkButtonOptions, a5 as LinkButtonProps, N as LinkElement, ad as ModalChild, ae as ModalOptions, a6 as ModalProps, af as RadioSelectElement, ag as RadioSelectOptions, O as SectionElement, ah as SelectElement, a7 as SelectOptionProps, ai as SelectOptions, a8 as SelectProps, P as TableAlignment, Q as TableElement, U as TableOptions, V as TextElement, aj as TextInputElement, ak as TextInputOptions, a9 as TextInputProps, aa as TextProps, W as TextStyle } from './jsx-runtime-Co9uV6l7.js';
4
+ import { C as ChatElement, a as CardElement, M as ModalElement, S as SelectOptionElement, b as CardChild, A as ActionsComponent, B as ButtonComponent, c as CardComponent, d as cardChildToFallbackText$1, e as CardLinkComponent, T as TextComponent, D as DividerComponent, F as FieldComponent, f as FieldsComponent, g as fromReactElement$1, I as ImageComponent, i as isCardElement$1, h as isJSX$1, L as LinkButtonComponent, j as SectionComponent, k as Table$2, t as toCardElement$1, l as toModalElement$1, m as fromReactModalElement$1, n as isModalElement$1, E as ExternalSelectComponent, o as ModalComponent, R as RadioSelectComponent, p as SelectComponent, q as SelectOptionComponent, r as TextInputComponent } from './jsx-runtime-DxGwoLu2.js';
5
+ export { s as ActionsElement, u as ButtonElement, v as ButtonOptions, X as ButtonProps, w as ButtonStyle, Y as CardJSXElement, Z as CardJSXProps, _ as CardLinkProps, x as CardOptions, $ as CardProps, a0 as ContainerProps, y as DividerElement, a1 as DividerProps, ab as ExternalSelectElement, ac as ExternalSelectOptions, a2 as ExternalSelectProps, z as FieldElement, a3 as FieldProps, G as FieldsElement, H as ImageElement, a4 as ImageProps, J as LinkButtonElement, K as LinkButtonOptions, a5 as LinkButtonProps, N as LinkElement, ad as ModalChild, ae as ModalOptions, a6 as ModalProps, af as RadioSelectElement, ag as RadioSelectOptions, O as SectionElement, ah as SelectElement, a7 as SelectOptionProps, ai as SelectOptions, a8 as SelectProps, P as TableAlignment, Q as TableElement, U as TableOptions, V as TextElement, aj as TextInputElement, ak as TextInputOptions, a9 as TextInputProps, aa as TextProps, W as TextStyle } from './jsx-runtime-DxGwoLu2.js';
6
6
 
7
- interface MessageHistoryConfig {
7
+ interface ThreadHistoryConfig {
8
8
  /** Maximum messages to keep per thread (default: 100) */
9
9
  maxMessages?: number;
10
10
  /** TTL for cached history in milliseconds (default: 7 days) */
11
11
  ttlMs?: number;
12
12
  }
13
13
  /**
14
- * Persistent message history cache backed by the StateAdapter.
14
+ * Persistent per-thread history cache backed by the StateAdapter.
15
15
  *
16
- * Used by adapters that lack server-side message history APIs (e.g., WhatsApp, Telegram).
17
- * Messages are atomically appended via `state.appendToList()`, which is safe
18
- * without holding a thread lock.
16
+ * Used by adapters that lack server-side message history APIs (e.g. WhatsApp,
17
+ * Telegram). Messages are atomically appended via `state.appendToList()`,
18
+ * which is safe without holding a thread lock.
19
+ *
20
+ * Distinct from the cross-platform per-user {@link TranscriptsApi} (see
21
+ * `transcripts.ts`) — this cache is keyed by thread, not user.
19
22
  */
20
- declare class MessageHistoryCache {
23
+ declare class ThreadHistoryCache {
21
24
  private readonly state;
22
25
  private readonly maxMessages;
23
26
  private readonly ttlMs;
24
- constructor(state: StateAdapter, config?: MessageHistoryConfig);
27
+ constructor(state: StateAdapter, config?: ThreadHistoryConfig);
25
28
  /**
26
29
  * Atomically append a message to the history for a thread.
27
30
  * Trims to maxMessages (keeps newest) and refreshes TTL.
@@ -54,8 +57,8 @@ interface ChannelImplConfigWithAdapter {
54
57
  channelVisibility?: ChannelVisibility;
55
58
  id: string;
56
59
  isDM?: boolean;
57
- messageHistory?: MessageHistoryCache;
58
60
  stateAdapter: StateAdapter;
61
+ threadHistory?: ThreadHistoryCache;
59
62
  }
60
63
  /**
61
64
  * Config for creating a ChannelImpl with lazy adapter resolution.
@@ -75,7 +78,7 @@ declare class ChannelImpl<TState = Record<string, unknown>> implements Channel<T
75
78
  private readonly _adapterName?;
76
79
  private _stateAdapterInstance?;
77
80
  private _name;
78
- private readonly _messageHistory?;
81
+ private readonly _threadHistory?;
79
82
  constructor(config: ChannelImplConfig);
80
83
  get adapter(): Adapter;
81
84
  private get _stateAdapter();
@@ -103,6 +106,7 @@ declare class ChannelImpl<TState = Record<string, unknown>> implements Channel<T
103
106
  schedule(message: AdapterPostableMessage | ChatElement, options: {
104
107
  postAt: Date;
105
108
  }): Promise<ScheduledMessage>;
109
+ private processCallbackUrls;
106
110
  startTyping(status?: string): Promise<void>;
107
111
  mentionUser(userId: string): string;
108
112
  toJSON(): SerializedChannel;
@@ -206,9 +210,9 @@ interface ThreadImplConfigWithAdapter {
206
210
  isDM?: boolean;
207
211
  isSubscribedContext?: boolean;
208
212
  logger?: Logger;
209
- messageHistory?: MessageHistoryCache;
210
213
  stateAdapter: StateAdapter;
211
214
  streamingUpdateIntervalMs?: number;
215
+ threadHistory?: ThreadHistoryCache;
212
216
  }
213
217
  /**
214
218
  * Config for creating a ThreadImpl with lazy adapter resolution.
@@ -249,8 +253,8 @@ declare class ThreadImpl<TState = Record<string, unknown>> implements Thread<TSt
249
253
  private readonly _fallbackStreamingPlaceholderText;
250
254
  /** Cached channel instance */
251
255
  private _channel?;
252
- /** Message history cache (set only for adapters with persistMessageHistory) */
253
- private readonly _messageHistory?;
256
+ /** Thread history cache (set only for adapters with persistThreadHistory) */
257
+ private readonly _threadHistory?;
254
258
  private readonly _logger?;
255
259
  constructor(config: ThreadImplConfig);
256
260
  /**
@@ -296,13 +300,14 @@ declare class ThreadImpl<TState = Record<string, unknown>> implements Thread<TSt
296
300
  post(message: string | AdapterPostableMessage | AsyncIterable<string> | ChatElement): Promise<SentMessage>;
297
301
  private handlePostableObject;
298
302
  postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
303
+ private processCallbackUrls;
299
304
  schedule(message: AdapterPostableMessage | ChatElement, options: {
300
305
  postAt: Date;
301
306
  }): Promise<ScheduledMessage>;
302
307
  /**
303
308
  * Handle streaming from an AsyncIterable.
304
309
  * Normalizes the stream (supports both textStream and fullStream from AI SDK),
305
- * then uses adapter's native streaming if available, otherwise falls back to post+edit.
310
+ * then uses the adapter's stream implementation if available, otherwise falls back to post+edit.
306
311
  */
307
312
  private handleStream;
308
313
  /**
@@ -512,6 +517,14 @@ interface ChatConfig<TAdapters extends Record<string, Adapter> = Record<string,
512
517
  * wait until some real text has been streamed before creating the message.
513
518
  */
514
519
  fallbackStreamingPlaceholderText?: string | null;
520
+ /**
521
+ * Resolves a stable cross-platform user key from inbound messages.
522
+ *
523
+ * Required when `transcripts` is configured. Called once per inbound
524
+ * message during dispatch; the result is attached to the Message
525
+ * instance as `message.userKey` for handlers to use.
526
+ */
527
+ identity?: IdentityResolver;
515
528
  /**
516
529
  * Lock scope determines which messages contend for the same lock.
517
530
  *
@@ -529,13 +542,12 @@ interface ChatConfig<TAdapters extends Record<string, Adapter> = Record<string,
529
542
  */
530
543
  logger?: Logger | LogLevel;
531
544
  /**
532
- * Configuration for persistent message history.
533
- * Only used by adapters that set `persistMessageHistory: true`.
545
+ * @deprecated Renamed to {@link ChatConfig.threadHistory}. Both fields are
546
+ * read for backwards compatibility; `threadHistory` takes precedence when
547
+ * both are set.
534
548
  */
535
549
  messageHistory?: {
536
- /** Maximum messages to store per thread (default: 100) */
537
550
  maxMessages?: number;
538
- /** TTL for cached history in milliseconds (default: 7 days) */
539
551
  ttlMs?: number;
540
552
  };
541
553
  /**
@@ -559,6 +571,28 @@ interface ChatConfig<TAdapters extends Record<string, Adapter> = Record<string,
559
571
  * Defaults to 500ms. Lower values provide smoother updates but may hit rate limits.
560
572
  */
561
573
  streamingUpdateIntervalMs?: number;
574
+ /**
575
+ * Configuration for persistent per-thread message history backfill.
576
+ *
577
+ * Only used by adapters that set `persistThreadHistory: true` (e.g.
578
+ * Telegram, WhatsApp). Distinct from `transcripts` (the cross-platform
579
+ * per-user Transcripts API).
580
+ */
581
+ threadHistory?: {
582
+ /** Maximum messages to store per thread (default: 100) */
583
+ maxMessages?: number;
584
+ /** TTL for cached history in milliseconds (default: 7 days) */
585
+ ttlMs?: number;
586
+ };
587
+ /**
588
+ * Cross-platform per-user message persistence.
589
+ *
590
+ * When set, `chat.transcripts` is available for append/list/count/delete
591
+ * keyed by a resolved cross-platform user key.
592
+ *
593
+ * Requires `identity` to also be set; the constructor throws otherwise.
594
+ */
595
+ transcripts?: TranscriptsConfig;
562
596
  /** Default bot username across all adapters */
563
597
  userName: string;
564
598
  }
@@ -681,6 +715,7 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
681
715
  * ```
682
716
  */
683
717
  fetchMessages(threadId: string, options?: FetchOptions): Promise<FetchResult<TRawMessage>>;
718
+ fetchSubject?(raw: TRawMessage): Promise<MessageSubject | null>;
684
719
  /** Fetch thread metadata */
685
720
  fetchThread(threadId: string): Promise<ThreadInfo>;
686
721
  /**
@@ -759,10 +794,17 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
759
794
  /** Parse platform message format to normalized format */
760
795
  parseMessage(raw: TRawMessage): Message<TRawMessage>;
761
796
  /**
762
- * When true, the SDK persists message history in the state adapter for this platform.
763
- * Use this for platforms that lack server-side message history APIs (e.g., WhatsApp, Telegram).
797
+ * @deprecated Renamed to {@link Adapter.persistThreadHistory}. Both flags
798
+ * are read for backwards compatibility; either being `true` enables
799
+ * persistence.
764
800
  */
765
801
  readonly persistMessageHistory?: boolean;
802
+ /**
803
+ * When true, the SDK persists per-thread message history in the state
804
+ * adapter for this platform. Use for platforms that lack server-side
805
+ * message history APIs (e.g. WhatsApp, Telegram).
806
+ */
807
+ readonly persistThreadHistory?: boolean;
766
808
  /**
767
809
  * Post a message to channel top-level (not in a thread).
768
810
  */
@@ -916,7 +958,7 @@ interface ChatInstance {
916
958
  * @param message - Either a parsed message, or a factory function for lazy async parsing
917
959
  * @param options - Webhook options including waitUntil
918
960
  */
919
- processMessage(adapter: Adapter, threadId: string, message: Message | (() => Promise<Message>), options?: WebhookOptions): void;
961
+ processMessage(adapter: Adapter, threadId: string, message: Message | (() => Promise<Message>), options?: WebhookOptions): Promise<void>;
920
962
  /**
921
963
  * Process a modal close event from an adapter.
922
964
  *
@@ -959,6 +1001,12 @@ interface ChatInstance {
959
1001
  adapter: Adapter;
960
1002
  channelId: string;
961
1003
  }, options: WebhookOptions | undefined): void;
1004
+ /**
1005
+ * Cross-platform per-user transcript store. Throws on access when
1006
+ * `transcripts` is not configured on the Chat instance — callers should
1007
+ * check `ChatConfig.transcripts` if they need a no-throw guard.
1008
+ */
1009
+ readonly transcripts: TranscriptsApi;
962
1010
  }
963
1011
  /** Lock scope determines which messages contend for the same lock. */
964
1012
  type LockScope = "thread" | "channel";
@@ -1390,6 +1438,24 @@ interface Thread<TState = Record<string, unknown>, TRawMessage = unknown> extend
1390
1438
  unsubscribe(): Promise<void>;
1391
1439
  }
1392
1440
 
1441
+ interface MessageSubject {
1442
+ assignee?: {
1443
+ id: string;
1444
+ name: string;
1445
+ };
1446
+ author?: {
1447
+ id: string;
1448
+ name: string;
1449
+ };
1450
+ description?: string;
1451
+ id: string;
1452
+ labels?: string[];
1453
+ raw: unknown;
1454
+ status?: string;
1455
+ title?: string;
1456
+ type: string;
1457
+ url?: string;
1458
+ }
1393
1459
  interface ThreadInfo {
1394
1460
  channelId: string;
1395
1461
  channelName?: string;
@@ -1519,7 +1585,7 @@ interface MessageMetadata {
1519
1585
  /** When the message was last edited */
1520
1586
  editedAt?: Date;
1521
1587
  }
1522
- interface SentMessage<TRawMessage = unknown> extends Message<TRawMessage> {
1588
+ interface SentMessage<TRawMessage = unknown> extends Omit<Message<TRawMessage>, "subject"> {
1523
1589
  /** Add a reaction to this message */
1524
1590
  addReaction(emoji: EmojiValue | string): Promise<void>;
1525
1591
  /** Delete this message */
@@ -1596,14 +1662,14 @@ type PostableMessage = AdapterPostableMessage | AsyncIterable<string | StreamChu
1596
1662
  /**
1597
1663
  * Duck-typed stream event compatible with AI SDK's `fullStream`.
1598
1664
  * - `text-delta` events are extracted as text output.
1599
- * - `step-finish` events trigger paragraph separators between steps.
1665
+ * - `finish-step` events trigger paragraph separators between steps.
1600
1666
  * - All other event types (tool-call, tool-result, etc.) are silently skipped.
1601
1667
  */
1602
1668
  type StreamEvent = {
1603
1669
  textDelta: string;
1604
1670
  type: "text-delta";
1605
1671
  } | {
1606
- type: "step-finish";
1672
+ type: "finish-step";
1607
1673
  } | {
1608
1674
  type: string;
1609
1675
  };
@@ -2189,6 +2255,141 @@ interface MemberJoinedChannelEvent {
2189
2255
  userId: string;
2190
2256
  }
2191
2257
  type MemberJoinedChannelHandler = (event: MemberJoinedChannelEvent) => void | Promise<void>;
2258
+ /**
2259
+ * Resolves a stable, cross-platform user key from an inbound message context.
2260
+ *
2261
+ * Return `null` to skip persistence for this event (unknown user, system
2262
+ * message, or the bot itself). The SDK fails loudly rather than silently
2263
+ * falling back to a platform-specific ID.
2264
+ */
2265
+ type IdentityResolver = (context: IdentityContext) => string | null | Promise<string | null>;
2266
+ interface IdentityContext {
2267
+ /** Adapter name (e.g. "slack", "discord"). */
2268
+ adapter: string;
2269
+ author: Author;
2270
+ message: Message;
2271
+ }
2272
+ /**
2273
+ * Role tag on a stored message.
2274
+ *
2275
+ * - `user`: produced by the resolved end-user
2276
+ * - `assistant`: produced by this bot
2277
+ * - `system`: SDK-injected marker (handoff, summary). Adapters never produce it.
2278
+ */
2279
+ type TranscriptRole = "user" | "assistant" | "system";
2280
+ interface TranscriptEntry {
2281
+ /** mdast AST. Only present when `transcripts.storeFormatted` is true. */
2282
+ formatted?: FormattedContent;
2283
+ /**
2284
+ * UUID assigned by the SDK at append time. Opaque — not lexicographically
2285
+ * sortable. Entries are returned by `list()` in append order (the underlying
2286
+ * list semantics of `state.appendToList`); use `timestamp` to reason about
2287
+ * ordering across stores.
2288
+ */
2289
+ id: string;
2290
+ /** Originating adapter name. */
2291
+ platform: string;
2292
+ /** Platform-native message ID, when known. */
2293
+ platformMessageId?: string;
2294
+ role: TranscriptRole;
2295
+ /** Plain-text body — canonical field for prompt building. */
2296
+ text: string;
2297
+ /** Originating thread ID. */
2298
+ threadId: string;
2299
+ /** ms-since-epoch, set at append time on the SDK side. */
2300
+ timestamp: number;
2301
+ /** Cross-platform user key from the IdentityResolver. */
2302
+ userKey: string;
2303
+ }
2304
+ /** Duration shorthand: e.g. `"7d"`, `"30m"`, `"2h"`, `"45s"`. */
2305
+ type DurationString = `${number}${"s" | "m" | "h" | "d"}`;
2306
+ interface TranscriptsConfig {
2307
+ /** Hard cap; older messages evicted on append. Default 200. */
2308
+ maxPerUser?: number;
2309
+ /**
2310
+ * Default retention applied as the list TTL. Refreshed on every append
2311
+ * (matches `appendToList` semantics). Omit for no expiry.
2312
+ */
2313
+ retention?: number | DurationString;
2314
+ /** Persist `formatted` (mdast). Default false to keep storage small. */
2315
+ storeFormatted?: boolean;
2316
+ }
2317
+ /**
2318
+ * Input shape for appending a non-Message (e.g. an assistant reply you
2319
+ * just posted via `thread.post()`).
2320
+ */
2321
+ interface AppendInput {
2322
+ formatted?: FormattedContent;
2323
+ platformMessageId?: string;
2324
+ role: TranscriptRole;
2325
+ text: string;
2326
+ }
2327
+ interface AppendOptions {
2328
+ /**
2329
+ * Required when appending an `AppendInput` (assistant/system role) — the
2330
+ * SDK has no Message instance from which to read the resolved key.
2331
+ *
2332
+ * Ignored when appending a Message; the Message's own `userKey` is used.
2333
+ */
2334
+ userKey?: string;
2335
+ }
2336
+ interface ListQuery {
2337
+ /** Newest N kept (still returned in chronological order). Default 50. */
2338
+ limit?: number;
2339
+ /** Filter to a subset of adapter names. */
2340
+ platforms?: string[];
2341
+ /** Filter to specific roles. Default: all. */
2342
+ roles?: TranscriptRole[];
2343
+ /** Filter to a single thread. */
2344
+ threadId?: string;
2345
+ userKey: string;
2346
+ }
2347
+ /**
2348
+ * Target for {@link TranscriptsApi.delete}. Wipes every stored message under
2349
+ * the given user key.
2350
+ */
2351
+ interface DeleteTarget {
2352
+ userKey: string;
2353
+ }
2354
+ /** Query shape for {@link TranscriptsApi.count}. */
2355
+ interface CountQuery {
2356
+ userKey: string;
2357
+ }
2358
+ /**
2359
+ * Cross-platform per-user message store.
2360
+ *
2361
+ * Distinct from the existing per-thread `threadHistory` config (which exists
2362
+ * to backfill thread context for adapters that lack server-side history APIs).
2363
+ * The Transcripts API is keyed by a resolved cross-platform user key and is
2364
+ * intended for transcript-style use cases (LLM context building, audit).
2365
+ */
2366
+ interface TranscriptsApi {
2367
+ /**
2368
+ * Persist a Message (or AppendInput) under the user key.
2369
+ *
2370
+ * - For Message: `userKey` is read from the Message instance (set by the
2371
+ * SDK during inbound dispatch via the configured IdentityResolver).
2372
+ * No-op if the Message has no `userKey` (resolver returned null).
2373
+ * - For AppendInput: `options.userKey` is required.
2374
+ */
2375
+ append<TState = Record<string, unknown>, TRawMessage = unknown>(thread: Postable<TState, TRawMessage>, message: Message | AppendInput, options?: AppendOptions): Promise<TranscriptEntry | null>;
2376
+ /** Total stored count for a user key. */
2377
+ count(query: CountQuery): Promise<number>;
2378
+ /** GDPR / DSR delete — wipes every stored message under the user key. */
2379
+ delete(target: DeleteTarget): Promise<{
2380
+ deleted: number;
2381
+ }>;
2382
+ /**
2383
+ * Returns the most recent entries in chronological order (oldest first),
2384
+ * capped at `query.limit` (default 50).
2385
+ *
2386
+ * Pagination is intentionally not supported — the store keeps at most
2387
+ * `transcripts.maxPerUser` entries per user. To widen the window, raise
2388
+ * `maxPerUser`; to fetch a different slice, narrow with `threadId` /
2389
+ * `platforms` / `roles`.
2390
+ */
2391
+ list(query: ListQuery): Promise<TranscriptEntry[]>;
2392
+ }
2192
2393
 
2193
2394
  /**
2194
2395
  * Message class with serialization support for workflow engines.
@@ -2321,8 +2522,20 @@ declare class Message<TRawMessage = unknown> {
2321
2522
  * ```
2322
2523
  */
2323
2524
  isMention?: boolean;
2525
+ /**
2526
+ * Cross-platform user key for this message's author.
2527
+ *
2528
+ * Set by the Chat SDK before passing the message to handlers, when
2529
+ * `ChatConfig.identity` is configured. `undefined` if no resolver is
2530
+ * configured; `undefined` (i.e. absent) when the resolver returned null.
2531
+ *
2532
+ * Used by the Transcripts API to look up / append per-user transcripts.
2533
+ */
2534
+ userKey?: string;
2324
2535
  /** Links found in the message */
2325
2536
  links: LinkPreview[];
2537
+ private _subjectPromise?;
2538
+ get subject(): Promise<MessageSubject | null>;
2326
2539
  constructor(data: MessageData<TRawMessage>);
2327
2540
  /**
2328
2541
  * Serialize the message to a plain JSON object.
@@ -2486,6 +2699,14 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
2486
2699
  * ```
2487
2700
  */
2488
2701
  registerSingleton(): this;
2702
+ /**
2703
+ * Cross-platform per-user transcript store.
2704
+ *
2705
+ * Available only when `transcripts` is configured on the Chat instance
2706
+ * (and an `identity` resolver is set). Throws on access otherwise so
2707
+ * callers fail loudly rather than silently no-op'ing.
2708
+ */
2709
+ get transcripts(): TranscriptsApi;
2489
2710
  /**
2490
2711
  * Get the registered singleton Chat instance.
2491
2712
  * Throws if no singleton has been registered.
@@ -2503,7 +2724,9 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
2503
2724
  private readonly _fallbackStreamingPlaceholderText;
2504
2725
  private readonly _dedupeTtlMs;
2505
2726
  private readonly _onLockConflict;
2506
- private readonly _messageHistory;
2727
+ private readonly _threadHistory;
2728
+ private readonly _identity;
2729
+ private readonly _transcripts;
2507
2730
  private readonly _concurrencyStrategy;
2508
2731
  private readonly _concurrencyConfig;
2509
2732
  private readonly _concurrentSlots;
@@ -2811,7 +3034,7 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
2811
3034
  * Handles waitUntil registration and error catching internally.
2812
3035
  * Adapters should call this instead of handleIncomingMessage directly.
2813
3036
  */
2814
- processMessage(adapter: Adapter, threadId: string, messageOrFactory: Message | (() => Promise<Message>), options?: WebhookOptions): void;
3037
+ processMessage(adapter: Adapter, threadId: string, messageOrFactory: Message | (() => Promise<Message>), options?: WebhookOptions): Promise<void>;
2815
3038
  /**
2816
3039
  * Process an incoming reaction event from an adapter.
2817
3040
  * Handles waitUntil registration and error catching internally.
@@ -2827,7 +3050,7 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
2827
3050
  adapter: Adapter;
2828
3051
  }, options: WebhookOptions | undefined): Promise<void>;
2829
3052
  processOptionsLoad(event: OptionsLoadEvent, _options?: WebhookOptions): Promise<OptionsLoadResult | undefined>;
2830
- processModalSubmit(event: Omit<ModalSubmitEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, _options?: WebhookOptions): Promise<ModalResponse | undefined>;
3053
+ processModalSubmit(event: Omit<ModalSubmitEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, options?: WebhookOptions): Promise<ModalResponse | undefined>;
2831
3054
  processModalClose(event: Omit<ModalCloseEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, options?: WebhookOptions): void;
2832
3055
  /**
2833
3056
  * Process an incoming slash command from an adapter.
@@ -3042,6 +3265,21 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
3042
3265
  */
3043
3266
  declare function fromFullStream(stream: AsyncIterable<unknown>): AsyncIterable<string | StreamChunk>;
3044
3267
 
3268
+ /**
3269
+ * @deprecated Renamed — import from `./thread-history` instead.
3270
+ *
3271
+ * This module is preserved for backwards compatibility and re-exports the
3272
+ * new names under the old identifiers. New code should use `ThreadHistoryCache`
3273
+ * and `ThreadHistoryConfig` directly.
3274
+ */
3275
+
3276
+ /** @deprecated Use `ThreadHistoryConfig` from `./thread-history` instead. */
3277
+ type MessageHistoryConfig = ThreadHistoryConfig;
3278
+ /** @deprecated Use `ThreadHistoryCache` from `./thread-history` instead. */
3279
+ declare const MessageHistoryCache: typeof ThreadHistoryCache;
3280
+ /** @deprecated Use `ThreadHistoryCache` from `./thread-history` instead. */
3281
+ type MessageHistoryCache = ThreadHistoryCache;
3282
+
3045
3283
  /**
3046
3284
  * Standalone JSON reviver for Chat SDK objects.
3047
3285
  *
@@ -3128,7 +3366,7 @@ interface StreamingPlanOptions {
3128
3366
  groupTasks?: "plan" | "timeline";
3129
3367
  /**
3130
3368
  * Minimum interval between updates in ms (default: 500).
3131
- * Used for fallback mode (post+edit on adapters without native streaming).
3369
+ * Used by post+edit streaming paths.
3132
3370
  */
3133
3371
  updateIntervalMs?: number;
3134
3372
  }
@@ -3250,7 +3488,7 @@ declare const defaultEmojiResolver: EmojiResolver;
3250
3488
  * // Returns: "Thanks! 👍"
3251
3489
  * ```
3252
3490
  */
3253
- declare function convertEmojiPlaceholders(text: string, platform: "slack" | "gchat" | "teams" | "discord" | "github" | "linear" | "whatsapp", resolver?: EmojiResolver): string;
3491
+ declare function convertEmojiPlaceholders(text: string, platform: "slack" | "gchat" | "teams" | "discord" | "messenger" | "github" | "linear" | "whatsapp", resolver?: EmojiResolver): string;
3254
3492
  /** Base emoji object with well-known emoji as EmojiValue singletons */
3255
3493
  type BaseEmojiHelper = {
3256
3494
  [K in WellKnownEmoji]: EmojiValue;
@@ -3610,4 +3848,4 @@ declare const Select: SelectComponent;
3610
3848
  declare const SelectOption: SelectOptionComponent;
3611
3849
  declare const TextInput: TextInputComponent;
3612
3850
 
3613
- export { type ActionEvent, type ActionHandler, Actions, ActionsComponent, type Adapter, type AdapterPostableMessage, type AddTaskOptions, type AiAssistantMessage, type AiFilePart, type AiImagePart, type AiMessage, type AiMessagePart, type AiTextPart, type AiUserMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, ButtonComponent, Card, CardChild, CardComponent, CardElement, CardLink, CardLinkComponent, CardText, type Channel, ChannelImpl, type ChannelInfo, type ChannelVisibility, Chat, type ChatConfig, ChatElement, ChatError, type ChatInstance, type CompletePlanOptions, type ConcurrencyConfig, type ConcurrencyStrategy, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, type DirectMessageHandler, Divider, DividerComponent, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, ExternalSelect, ExternalSelectComponent, type FetchDirection, type FetchOptions, type FetchResult, Field, FieldComponent, Fields, FieldsComponent, type FileUpload, type FormatConverter, type FormattedContent, Image, ImageComponent, LinkButton, LinkButtonComponent, type LinkPreview, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LockScope, type LockScopeContext, type LogLevel, type Logger, type MarkdownConverter, type MarkdownTextChunk, type MemberJoinedChannelEvent, type MemberJoinedChannelHandler, type MentionHandler, Message, type MessageContext, type MessageData, type MessageHandler, MessageHistoryCache, type MessageHistoryConfig, type MessageMetadata, Modal, type ModalClearResponse, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalComponent, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type OptionsLoadEvent, type OptionsLoadGroup, type OptionsLoadHandler, type OptionsLoadResult, Plan, type PlanContent, type PlanModel, type PlanModelTask, type PlanTask, type PlanTaskStatus, type PlanUpdateChunk, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableObject, type PostableObjectContext, type PostableRaw, type QueueEntry, RadioSelect, RadioSelectComponent, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, type ScheduledMessage, Section, SectionComponent, Select, SelectComponent, SelectOption, SelectOptionComponent, SelectOptionElement, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StartPlanOptions, type StateAdapter, type StreamChunk, type StreamEvent, type StreamOptions, StreamingMarkdownRenderer, StreamingPlan, type StreamingPlanData, type StreamingPlanOptions, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, Table, type TaskUpdateChunk, TextComponent, TextInput, TextInputComponent, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type UpdateTaskInput, type UserInfo, type WebhookOptions, type WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromFullStream, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isPostableObject, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, reviver, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toAiMessages, toCardElement, toModalElement, toPlainText, walkAst };
3851
+ export { type ActionEvent, type ActionHandler, Actions, ActionsComponent, type Adapter, type AdapterPostableMessage, type AddTaskOptions, type AiAssistantMessage, type AiFilePart, type AiImagePart, type AiMessage, type AiMessagePart, type AiTextPart, type AiUserMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AppendInput, type AppendOptions, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, ButtonComponent, Card, CardChild, CardComponent, CardElement, CardLink, CardLinkComponent, CardText, type Channel, ChannelImpl, type ChannelInfo, type ChannelVisibility, Chat, type ChatConfig, ChatElement, ChatError, type ChatInstance, type CompletePlanOptions, type ConcurrencyConfig, type ConcurrencyStrategy, ConsoleLogger, type CountQuery, type CustomEmojiMap, DEFAULT_EMOJI_MAP, type DeleteTarget, type DirectMessageHandler, Divider, DividerComponent, type DurationString, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, ExternalSelect, ExternalSelectComponent, type FetchDirection, type FetchOptions, type FetchResult, Field, FieldComponent, Fields, FieldsComponent, type FileUpload, type FormatConverter, type FormattedContent, type IdentityContext, type IdentityResolver, Image, ImageComponent, LinkButton, LinkButtonComponent, type LinkPreview, type ListQuery, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LockScope, type LockScopeContext, type LogLevel, type Logger, type MarkdownConverter, type MarkdownTextChunk, type MemberJoinedChannelEvent, type MemberJoinedChannelHandler, type MentionHandler, Message, type MessageContext, type MessageData, type MessageHandler, MessageHistoryCache, type MessageHistoryConfig, type MessageMetadata, type MessageSubject, Modal, type ModalClearResponse, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalComponent, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type OptionsLoadEvent, type OptionsLoadGroup, type OptionsLoadHandler, type OptionsLoadResult, Plan, type PlanContent, type PlanModel, type PlanModelTask, type PlanTask, type PlanTaskStatus, type PlanUpdateChunk, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableObject, type PostableObjectContext, type PostableRaw, type QueueEntry, RadioSelect, RadioSelectComponent, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, type ScheduledMessage, Section, SectionComponent, Select, SelectComponent, SelectOption, SelectOptionComponent, SelectOptionElement, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StartPlanOptions, type StateAdapter, type StreamChunk, type StreamEvent, type StreamOptions, StreamingMarkdownRenderer, StreamingPlan, type StreamingPlanData, type StreamingPlanOptions, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, Table, type TaskUpdateChunk, TextComponent, TextInput, TextInputComponent, type Thread, ThreadHistoryCache, type ThreadHistoryConfig, ThreadImpl, type ThreadInfo, type ThreadSummary, type TranscriptEntry, type TranscriptRole, type TranscriptsApi, type TranscriptsConfig, type UpdateTaskInput, type UserInfo, type WebhookOptions, type WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromFullStream, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isPostableObject, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, reviver, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toAiMessages, toCardElement, toModalElement, toPlainText, walkAst };