experimental-ash 0.24.0 → 0.24.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/CHANGELOG.md +19 -0
- package/dist/src/chunks/authored-module-loader-DcCfCiBm.js +4 -0
- package/dist/src/chunks/client-DLHAGI2g.js +4 -0
- package/dist/src/chunks/dev-authored-source-watcher-CBID_Dwh.js +1 -0
- package/dist/src/chunks/{errors-DsO9xmQL.js → errors-HYWjHxV6.js} +1 -1
- package/dist/src/chunks/{gray-matter-BxS7ZG-J.js → gray-matter-D-9jHwOT.js} +4 -4
- package/dist/src/chunks/host-zBy9FyyX.js +70 -0
- package/dist/src/chunks/{jsdist-M7JFZoA4.js → jsdist-BkeWZ7EZ.js} +61 -61
- package/dist/src/chunks/package-HUaeub_D.js +1 -0
- package/dist/src/chunks/paths-CebY5GCi.js +89 -0
- package/dist/src/chunks/{picocolors-Bq-tZK9u.js → picocolors-aAkqW4On.js} +1 -1
- package/dist/src/chunks/token-D98SQdvs.js +1 -0
- package/dist/src/chunks/{url-BVRhVE2O.js → url-JdCGA634.js} +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/dev/environment.d.ts +16 -2
- package/dist/src/cli/dev/environment.js +1 -1
- package/dist/src/cli/dev/input-requests.js +1 -1
- package/dist/src/cli/dev/repl.js +3 -3
- package/dist/src/cli/dev/url.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/cli/ui/output.js +1 -1
- package/dist/src/client/index.d.ts +1 -0
- package/dist/src/client/index.js +1 -0
- package/dist/src/compiled/.vendor-stamp.json +7 -6
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/google/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
- package/dist/src/compiled/@chat-adapter/slack/_slack-web-api.d.ts +7 -0
- package/dist/src/compiled/@chat-adapter/slack/index.d.ts +418 -109
- package/dist/src/compiled/@chat-adapter/slack/index.js +31 -27
- package/dist/src/compiled/@chat-adapter/slack/package.json +1 -1
- package/dist/src/compiled/@chat-adapter/state-memory/index.d.ts +8 -2
- package/dist/src/compiled/@chat-adapter/state-memory/index.js +1 -1
- package/dist/src/compiled/@chat-adapter/state-memory/package.json +1 -1
- package/dist/src/compiled/@opentelemetry/api/index.js +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +19 -17
- package/dist/src/compiled/@vercel/sandbox/package.json +1 -1
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime.js +22 -22
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/_chunks/node/auth-ZhCJAHxl.js +2 -0
- package/dist/src/compiled/_chunks/node/{dist-BdWHjlRQ.js → dist-BQYUcBqu.js} +31 -31
- package/dist/src/compiled/_chunks/node/{chunk-Dd2tEFlW.js → dist-BdTs18CF.js} +1 -1
- package/dist/src/compiled/_chunks/node/retry-DkR2H1Y0.js +1 -0
- package/dist/src/compiled/_chunks/node/token-CoIbMZkq.js +1 -0
- package/dist/src/compiled/_chunks/node/{version-BMyZn3Y2.js → version-D4IYmfaS.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/coerce-BhzIW-Hm.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{compat-CIROS3w4.js → compat-DcEvieoj.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{core-DOVmxHH8.js → core-XWIi7wKc.js} +3 -3
- package/dist/src/compiled/_chunks/workflow/{dist-C7wPwOI9.js → dist-DO14ZaQj.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{dist-CpUQh3NH.js → dist-DZZY3Zyp.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-DOMbNs-S.js +51 -0
- package/dist/src/compiled/_chunks/workflow/{schemas-DFZoEyCn.js → schemas-DmgDnhW3.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/sleep-CRjce49s.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{src-ClRYdO4-.js → src-B54rYDvB.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/symbols-D8paKc8P.js +9 -0
- package/dist/src/compiled/_chunks/workflow/{token-CsNmv7KW.js → token-D9z1dMB6.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{token-j5Cl4rrs.js → token-DV7rQw_t.js} +1 -1
- package/dist/src/compiled/chat/index.d.ts +6 -3143
- package/dist/src/compiled/chat/index.js +1 -1
- package/dist/src/compiled/chat/{jsx-runtime-DxGwoLu2.d.ts → jsx-runtime-CFq1K_Ve.d.ts} +1 -1
- package/dist/src/compiled/chat/package.json +1 -1
- package/dist/src/compiled/jose/index.js +2 -2
- package/dist/src/compiled/jsonc-parser/LICENSE.md +21 -0
- package/dist/src/compiled/jsonc-parser/index.d.ts +13 -0
- package/dist/src/compiled/jsonc-parser/index.js +15 -0
- package/dist/src/compiled/jsonc-parser/package.json +7 -0
- package/dist/src/compiled/just-bash/index.js +773 -773
- package/dist/src/compiled/just-bash/package.json +1 -1
- package/dist/src/compiled/turndown/index.js +1 -1
- package/dist/src/compiled/zod/index.js +1 -1
- package/dist/src/compiled/zod-validation-error/index.js +1 -1
- package/dist/src/compiler/manifest.d.ts +36 -3
- package/dist/src/compiler/manifest.js +5 -1
- package/dist/src/compiler/module-map.js +8 -0
- package/dist/src/compiler/normalize-manifest.js +1 -0
- package/dist/src/compiler/normalize-subagent.d.ts +3 -2
- package/dist/src/compiler/normalize-subagent.js +112 -3
- package/dist/src/compiler/remote-agent-node.d.ts +20 -0
- package/dist/src/compiler/remote-agent-node.js +19 -0
- package/dist/src/discover/discover-subagent.js +35 -2
- package/dist/src/discover/grammar.d.ts +1 -0
- package/dist/src/discover/grammar.js +5 -0
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/evals/loaders/yaml.js +1 -1
- package/dist/src/evals/runner/discover.js +1 -1
- package/dist/src/evals/runner/execute-suite.js +1 -1
- package/dist/src/evals/runner/reporters/console.js +1 -1
- package/dist/src/evals/scorers/autoevals-client.js +1 -1
- package/dist/src/evals/scorers/autoevals.js +1 -1
- package/dist/src/evals/scorers/json.js +1 -1
- package/dist/src/evals/scorers/run.js +1 -1
- package/dist/src/evals/scorers/sql.js +1 -1
- package/dist/src/evals/scorers/text.js +1 -1
- package/dist/src/execution/connection-auth-steps.js +2 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-asset-import-plugin.d.ts +5 -0
- package/dist/src/internal/authored-asset-import-plugin.js +141 -0
- package/dist/src/internal/authored-module-bundle.d.ts +4 -0
- package/dist/src/internal/authored-module-bundle.js +19 -0
- package/dist/src/internal/authored-module-loader.d.ts +6 -0
- package/dist/src/internal/authored-module-loader.js +114 -125
- package/dist/src/internal/authored-package-tsconfig-paths.d.ts +9 -0
- package/dist/src/internal/authored-package-tsconfig-paths.js +209 -0
- package/dist/src/internal/nitro/host/channel-routes.d.ts +9 -2
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +12 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +19 -3
- package/dist/src/internal/nitro/host/schedule-task-routes.d.ts +7 -3
- package/dist/src/internal/nitro/host/start-development-server.js +2 -0
- package/dist/src/internal/workflow-bundle/builder-support.js +1 -33
- package/dist/src/public/agents/auth.d.ts +30 -0
- package/dist/src/public/agents/auth.js +37 -0
- package/dist/src/public/definitions/remote-agent.d.ts +25 -0
- package/dist/src/public/definitions/remote-agent.js +11 -0
- package/dist/src/public/index.d.ts +1 -0
- package/dist/src/public/index.js +1 -0
- package/dist/src/public/next/index.d.ts +4 -4
- package/dist/src/public/next/index.js +16 -25
- package/dist/src/runtime/connections/mcp-client.js +3 -2
- package/dist/src/runtime/connections/types.d.ts +24 -0
- package/dist/src/runtime/resolve-agent-graph.js +57 -0
- package/dist/src/runtime/sessions/turn.d.ts +17 -5
- package/dist/src/runtime/subagents/registry.d.ts +6 -6
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/runtime/types.d.ts +20 -0
- package/package.json +22 -17
- package/dist/src/chunks/authored-module-loader-XcFLnl49.js +0 -2
- package/dist/src/chunks/client-nshDsWNF.js +0 -4
- package/dist/src/chunks/dev-authored-source-watcher-B4PaZGUr.js +0 -7
- package/dist/src/chunks/host-DsW72Q-w.js +0 -65
- package/dist/src/chunks/package-DmsQgn4v.js +0 -1
- package/dist/src/chunks/paths-OknjaYR8.js +0 -89
- package/dist/src/chunks/prewarm-B4YblQ5m.js +0 -6
- package/dist/src/chunks/token-DtoyQZy2.js +0 -1
- package/dist/src/chunks/token-util-CHjOk3A7.js +0 -1
- package/dist/src/compiled/_chunks/node/auth-vbe4XEEK.js +0 -2
- package/dist/src/compiled/_chunks/node/dist-DMSq2ehP.js +0 -1
- package/dist/src/compiled/_chunks/node/retry-BOcy5BbJ.js +0 -1
- package/dist/src/compiled/_chunks/node/token-D-BTJHoU.js +0 -1
- package/dist/src/compiled/_chunks/workflow/coerce-Dh0wa7P9.js +0 -1
- package/dist/src/compiled/_chunks/workflow/context-errors-Bbvvp-li.js +0 -6
- package/dist/src/compiled/_chunks/workflow/dist-C_oiE-l7.js +0 -40
- package/dist/src/compiled/_chunks/workflow/resume-hook-C3VWUPii.js +0 -12
- package/dist/src/compiled/_chunks/workflow/sleep-QTkC1VFe.js +0 -1
- package/dist/src/compiled/_chunks/workflow/symbols-QezhMuLg.js +0 -4
- package/dist/src/compiled/chat/_workflow-serde.d.ts +0 -5
- /package/dist/src/chunks/{chunk-8L7ocgPr.js → chunk-DSjMdhoD.js} +0 -0
- /package/dist/src/chunks/{guards-CjJ3lmju.js → guards-26p6sOw3.js} +0 -0
- /package/dist/src/chunks/{input-requests-BsBi7_5K.js → input-requests-DJiy6dG9.js} +0 -0
- /package/dist/src/chunks/{runtime-model-BWu6M_hq.js → runtime-model-Dh0Nz64z.js} +0 -0
- /package/dist/src/chunks/{types-MZUhN0Zy.js → types-DDA2QUED.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{chunk-DHhdAPOb.js → chunk-DSjMdhoD.js} +0 -0
|
@@ -1,375 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { P as PostableObject, A as Adapter, a as PostableObjectContext, S as StreamChunk, T as ThreadHistoryCache, b as ThreadHistoryConfig, c as StreamEvent, E as EmojiMapConfig, d as EmojiValue, W as WellKnownEmoji, e as EmojiFormats, C as CustomEmojiMap, f as AdapterPostableMessage } from './chat-D9UYaaNO.js';
|
|
2
|
+
export { y as ActionEvent, z as ActionHandler, g as AiAssistantMessage, h as AiFilePart, i as AiImagePart, j as AiMessage, k as AiMessagePart, l as AiTextPart, m as AiUserMessage, F as AppHomeOpenedEvent, G as AppHomeOpenedHandler, B as AppendInput, D as AppendOptions, H as AssistantContextChangedEvent, I as AssistantContextChangedHandler, J as AssistantThreadStartedEvent, K as AssistantThreadStartedHandler, L as Attachment, N as Author, O as Channel, o as ChannelImpl, Q as ChannelInfo, R as ChannelVisibility, r as Chat, U as ChatConfig, V as ChatInstance, X as ConcurrencyConfig, Y as ConcurrencyStrategy, b6 as ConsoleLogger, Z as CountQuery, _ as DeleteTarget, $ as DirectMessageHandler, a0 as DurationString, a1 as Emoji, a2 as EphemeralMessage, a3 as FetchDirection, a4 as FetchOptions, a5 as FetchResult, a6 as FileUpload, a7 as FormattedContent, a8 as IdentityContext, a9 as IdentityResolver, aa as LinkPreview, ab as ListQuery, ac as ListThreadsOptions, ad as ListThreadsResult, ae as Lock, af as LockScope, ag as LockScopeContext, ai as LogLevel, ah as Logger, aj as MarkdownTextChunk, ak as MemberJoinedChannelEvent, al as MemberJoinedChannelHandler, am as MentionHandler, M as Message, an as MessageContext, s as MessageData, ao as MessageHandler, ap as MessageMetadata, aq as MessageSubject, ar as ModalClearResponse, as as ModalCloseEvent, at as ModalCloseHandler, au as ModalCloseResponse, av as ModalErrorsResponse, aw as ModalPushResponse, ax as ModalResponse, ay as ModalSubmitEvent, az as ModalSubmitHandler, aA as ModalUpdateResponse, aB as OptionsLoadEvent, aC as OptionsLoadGroup, aD as OptionsLoadHandler, aE as OptionsLoadResult, aF as PlanUpdateChunk, aM as PostEphemeralOptions, aG as Postable, aH as PostableAst, aI as PostableCard, aJ as PostableMarkdown, aK as PostableMessage, aL as PostableRaw, aN as QueueEntry, aO as RawMessage, aP as ReactionEvent, aQ as ReactionHandler, aR as ScheduledMessage, aS as SentMessage, q as SerializedChannel, u as SerializedMessage, w as SerializedThread, aT as SlashCommandEvent, aU as SlashCommandHandler, aV as StateAdapter, aW as StreamOptions, aX as SubscribedMessageHandler, b7 as THREAD_STATE_TTL_MS, aY as TaskUpdateChunk, aZ as Thread, x as ThreadImpl, a_ as ThreadInfo, a$ as ThreadSummary, n as ToAiMessagesOptions, b0 as TranscriptEntry, b1 as TranscriptRole, b2 as TranscriptsApi, b3 as TranscriptsConfig, b4 as UserInfo, b5 as WebhookOptions, p as deriveChannelId, v as isPostableObject, t as toAiMessages } from './chat-D9UYaaNO.js';
|
|
2
3
|
import { Root, List, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, Paragraph, Strong, TableCell, Table as Table$1, TableRow, Text } from './_mdast.js';
|
|
3
4
|
export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Table as MdastTable, Nodes, Paragraph, Root, Strong, TableCell, TableRow, Text } from './_mdast.js';
|
|
4
|
-
import { C as
|
|
5
|
-
export {
|
|
6
|
-
|
|
7
|
-
interface ThreadHistoryConfig {
|
|
8
|
-
/** Maximum messages to keep per thread (default: 100) */
|
|
9
|
-
maxMessages?: number;
|
|
10
|
-
/** TTL for cached history in milliseconds (default: 7 days) */
|
|
11
|
-
ttlMs?: number;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Persistent per-thread history cache backed by the StateAdapter.
|
|
15
|
-
*
|
|
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.
|
|
22
|
-
*/
|
|
23
|
-
declare class ThreadHistoryCache {
|
|
24
|
-
private readonly state;
|
|
25
|
-
private readonly maxMessages;
|
|
26
|
-
private readonly ttlMs;
|
|
27
|
-
constructor(state: StateAdapter, config?: ThreadHistoryConfig);
|
|
28
|
-
/**
|
|
29
|
-
* Atomically append a message to the history for a thread.
|
|
30
|
-
* Trims to maxMessages (keeps newest) and refreshes TTL.
|
|
31
|
-
*/
|
|
32
|
-
append(threadId: string, message: Message): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Get messages for a thread in chronological order (oldest first).
|
|
35
|
-
*
|
|
36
|
-
* @param threadId - The thread ID
|
|
37
|
-
* @param limit - Optional limit on number of messages to return (returns newest N)
|
|
38
|
-
*/
|
|
39
|
-
getMessages(threadId: string, limit?: number): Promise<Message[]>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Serialized channel data for passing to external systems (e.g., workflow engines).
|
|
44
|
-
*/
|
|
45
|
-
interface SerializedChannel {
|
|
46
|
-
_type: "chat:Channel";
|
|
47
|
-
adapterName: string;
|
|
48
|
-
channelVisibility?: ChannelVisibility;
|
|
49
|
-
id: string;
|
|
50
|
-
isDM: boolean;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Config for creating a ChannelImpl with explicit adapter/state instances.
|
|
54
|
-
*/
|
|
55
|
-
interface ChannelImplConfigWithAdapter {
|
|
56
|
-
adapter: Adapter;
|
|
57
|
-
channelVisibility?: ChannelVisibility;
|
|
58
|
-
id: string;
|
|
59
|
-
isDM?: boolean;
|
|
60
|
-
stateAdapter: StateAdapter;
|
|
61
|
-
threadHistory?: ThreadHistoryCache;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Config for creating a ChannelImpl with lazy adapter resolution.
|
|
65
|
-
*/
|
|
66
|
-
interface ChannelImplConfigLazy {
|
|
67
|
-
adapterName: string;
|
|
68
|
-
channelVisibility?: ChannelVisibility;
|
|
69
|
-
id: string;
|
|
70
|
-
isDM?: boolean;
|
|
71
|
-
}
|
|
72
|
-
type ChannelImplConfig = ChannelImplConfigWithAdapter | ChannelImplConfigLazy;
|
|
73
|
-
declare class ChannelImpl<TState = Record<string, unknown>> implements Channel<TState> {
|
|
74
|
-
readonly id: string;
|
|
75
|
-
readonly isDM: boolean;
|
|
76
|
-
readonly channelVisibility: ChannelVisibility;
|
|
77
|
-
private _adapter?;
|
|
78
|
-
private readonly _adapterName?;
|
|
79
|
-
private _stateAdapterInstance?;
|
|
80
|
-
private _name;
|
|
81
|
-
private readonly _threadHistory?;
|
|
82
|
-
constructor(config: ChannelImplConfig);
|
|
83
|
-
get adapter(): Adapter;
|
|
84
|
-
private get _stateAdapter();
|
|
85
|
-
get name(): string | null;
|
|
86
|
-
get state(): Promise<TState | null>;
|
|
87
|
-
setState(newState: Partial<TState>, options?: {
|
|
88
|
-
replace?: boolean;
|
|
89
|
-
}): Promise<void>;
|
|
90
|
-
/**
|
|
91
|
-
* Iterate messages newest first (backward from most recent).
|
|
92
|
-
* Uses adapter.fetchChannelMessages if available, otherwise falls back
|
|
93
|
-
* to adapter.fetchMessages with the channel ID.
|
|
94
|
-
*/
|
|
95
|
-
get messages(): AsyncIterable<Message>;
|
|
96
|
-
/**
|
|
97
|
-
* Iterate threads in this channel, most recently active first.
|
|
98
|
-
*/
|
|
99
|
-
threads(): AsyncIterable<ThreadSummary>;
|
|
100
|
-
fetchMetadata(): Promise<ChannelInfo>;
|
|
101
|
-
post<T extends PostableObject>(message: T): Promise<T>;
|
|
102
|
-
post(message: string | AdapterPostableMessage | AsyncIterable<string> | ChatElement): Promise<SentMessage>;
|
|
103
|
-
private handlePostableObject;
|
|
104
|
-
private postSingleMessage;
|
|
105
|
-
postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
|
|
106
|
-
schedule(message: AdapterPostableMessage | ChatElement, options: {
|
|
107
|
-
postAt: Date;
|
|
108
|
-
}): Promise<ScheduledMessage>;
|
|
109
|
-
private processCallbackUrls;
|
|
110
|
-
startTyping(status?: string): Promise<void>;
|
|
111
|
-
mentionUser(userId: string): string;
|
|
112
|
-
toJSON(): SerializedChannel;
|
|
113
|
-
static fromJSON<TState = Record<string, unknown>>(json: SerializedChannel, adapter?: Adapter): ChannelImpl<TState>;
|
|
114
|
-
static [WORKFLOW_SERIALIZE](instance: ChannelImpl): SerializedChannel;
|
|
115
|
-
static [WORKFLOW_DESERIALIZE](data: SerializedChannel): ChannelImpl;
|
|
116
|
-
private createSentMessage;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Derive the channel ID from a thread ID.
|
|
120
|
-
*/
|
|
121
|
-
declare function deriveChannelId(adapter: Adapter, threadId: string): string;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Logger types and implementations for chat-sdk
|
|
125
|
-
*/
|
|
126
|
-
type LogLevel = "debug" | "info" | "warn" | "error" | "silent";
|
|
127
|
-
interface Logger {
|
|
128
|
-
/** Create a sub-logger with a prefix */
|
|
129
|
-
child(prefix: string): Logger;
|
|
130
|
-
debug(message: string, ...args: unknown[]): void;
|
|
131
|
-
error(message: string, ...args: unknown[]): void;
|
|
132
|
-
info(message: string, ...args: unknown[]): void;
|
|
133
|
-
warn(message: string, ...args: unknown[]): void;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Default console logger implementation.
|
|
137
|
-
*/
|
|
138
|
-
declare class ConsoleLogger implements Logger {
|
|
139
|
-
private readonly prefix;
|
|
140
|
-
private readonly level;
|
|
141
|
-
constructor(level?: LogLevel, prefix?: string);
|
|
142
|
-
private shouldLog;
|
|
143
|
-
child(prefix: string): Logger;
|
|
144
|
-
debug(message: string, ...args: unknown[]): void;
|
|
145
|
-
info(message: string, ...args: unknown[]): void;
|
|
146
|
-
warn(message: string, ...args: unknown[]): void;
|
|
147
|
-
error(message: string, ...args: unknown[]): void;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Context provided to a PostableObject after it has been posted.
|
|
152
|
-
*/
|
|
153
|
-
interface PostableObjectContext {
|
|
154
|
-
adapter: Adapter;
|
|
155
|
-
logger?: Logger;
|
|
156
|
-
messageId: string;
|
|
157
|
-
threadId: string;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Base interface for objects that can be posted to threads/channels.
|
|
161
|
-
* Examples: Plan, Poll, etc.
|
|
162
|
-
*
|
|
163
|
-
* @template TData - The data type returned by getPostData()
|
|
164
|
-
*/
|
|
165
|
-
interface PostableObject<TData = unknown> {
|
|
166
|
-
/** Symbol identifying this as a postable object */
|
|
167
|
-
readonly $$typeof: symbol;
|
|
168
|
-
/**
|
|
169
|
-
* Get a fallback text representation for adapters that don't support this object type.
|
|
170
|
-
* This should return a human-readable string representation.
|
|
171
|
-
*/
|
|
172
|
-
getFallbackText(): string;
|
|
173
|
-
/** Get the data to send to the adapter */
|
|
174
|
-
getPostData(): TData;
|
|
175
|
-
/** Check if the adapter supports this object type */
|
|
176
|
-
isSupported(adapter: Adapter): boolean;
|
|
177
|
-
/** The kind of object - used by adapters to dispatch */
|
|
178
|
-
readonly kind: string;
|
|
179
|
-
/** Called after successful posting to bind the object to the thread */
|
|
180
|
-
onPosted(context: PostableObjectContext): void;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Type guard to check if a value is a PostableObject.
|
|
184
|
-
*/
|
|
185
|
-
declare function isPostableObject(value: unknown): value is PostableObject;
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Serialized thread data for passing to external systems (e.g., workflow engines).
|
|
189
|
-
*/
|
|
190
|
-
interface SerializedThread {
|
|
191
|
-
_type: "chat:Thread";
|
|
192
|
-
adapterName: string;
|
|
193
|
-
channelId: string;
|
|
194
|
-
channelVisibility?: ChannelVisibility;
|
|
195
|
-
currentMessage?: SerializedMessage;
|
|
196
|
-
id: string;
|
|
197
|
-
isDM: boolean;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Config for creating a ThreadImpl with explicit adapter/state instances.
|
|
201
|
-
*/
|
|
202
|
-
interface ThreadImplConfigWithAdapter {
|
|
203
|
-
adapter: Adapter;
|
|
204
|
-
channelId: string;
|
|
205
|
-
channelVisibility?: ChannelVisibility;
|
|
206
|
-
currentMessage?: Message;
|
|
207
|
-
fallbackStreamingPlaceholderText?: string | null;
|
|
208
|
-
id: string;
|
|
209
|
-
initialMessage?: Message;
|
|
210
|
-
isDM?: boolean;
|
|
211
|
-
isSubscribedContext?: boolean;
|
|
212
|
-
logger?: Logger;
|
|
213
|
-
stateAdapter: StateAdapter;
|
|
214
|
-
streamingUpdateIntervalMs?: number;
|
|
215
|
-
threadHistory?: ThreadHistoryCache;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Config for creating a ThreadImpl with lazy adapter resolution.
|
|
219
|
-
* The adapter will be looked up from the Chat singleton on first access.
|
|
220
|
-
*/
|
|
221
|
-
interface ThreadImplConfigLazy {
|
|
222
|
-
adapterName: string;
|
|
223
|
-
channelId: string;
|
|
224
|
-
channelVisibility?: ChannelVisibility;
|
|
225
|
-
currentMessage?: Message;
|
|
226
|
-
fallbackStreamingPlaceholderText?: string | null;
|
|
227
|
-
id: string;
|
|
228
|
-
initialMessage?: Message;
|
|
229
|
-
isDM?: boolean;
|
|
230
|
-
isSubscribedContext?: boolean;
|
|
231
|
-
logger?: Logger;
|
|
232
|
-
streamingUpdateIntervalMs?: number;
|
|
233
|
-
}
|
|
234
|
-
type ThreadImplConfig = ThreadImplConfigWithAdapter | ThreadImplConfigLazy;
|
|
235
|
-
declare class ThreadImpl<TState = Record<string, unknown>> implements Thread<TState> {
|
|
236
|
-
readonly id: string;
|
|
237
|
-
readonly channelId: string;
|
|
238
|
-
readonly isDM: boolean;
|
|
239
|
-
readonly channelVisibility: ChannelVisibility;
|
|
240
|
-
/** Direct adapter instance (if provided) */
|
|
241
|
-
private _adapter?;
|
|
242
|
-
/** Adapter name for lazy resolution */
|
|
243
|
-
private readonly _adapterName?;
|
|
244
|
-
/** Direct state adapter instance (if provided) */
|
|
245
|
-
private _stateAdapterInstance?;
|
|
246
|
-
private _recentMessages;
|
|
247
|
-
private readonly _isSubscribedContext;
|
|
248
|
-
/** Current message context for streaming - provides userId/teamId */
|
|
249
|
-
private readonly _currentMessage?;
|
|
250
|
-
/** Update interval for fallback streaming */
|
|
251
|
-
private readonly _streamingUpdateIntervalMs;
|
|
252
|
-
/** Placeholder text for fallback streaming (post + edit) */
|
|
253
|
-
private readonly _fallbackStreamingPlaceholderText;
|
|
254
|
-
/** Cached channel instance */
|
|
255
|
-
private _channel?;
|
|
256
|
-
/** Thread history cache (set only for adapters with persistThreadHistory) */
|
|
257
|
-
private readonly _threadHistory?;
|
|
258
|
-
private readonly _logger?;
|
|
259
|
-
constructor(config: ThreadImplConfig);
|
|
260
|
-
/**
|
|
261
|
-
* Get the adapter for this thread.
|
|
262
|
-
* If created with lazy config, resolves from Chat singleton on first access.
|
|
263
|
-
*/
|
|
264
|
-
get adapter(): Adapter;
|
|
265
|
-
/**
|
|
266
|
-
* Get the state adapter for this thread.
|
|
267
|
-
* If created with lazy config, resolves from Chat singleton on first access.
|
|
268
|
-
*/
|
|
269
|
-
private get _stateAdapter();
|
|
270
|
-
get recentMessages(): Message[];
|
|
271
|
-
set recentMessages(messages: Message[]);
|
|
272
|
-
/**
|
|
273
|
-
* Get the current thread state.
|
|
274
|
-
* Returns null if no state has been set.
|
|
275
|
-
*/
|
|
276
|
-
get state(): Promise<TState | null>;
|
|
277
|
-
/**
|
|
278
|
-
* Set the thread state. Merges with existing state by default.
|
|
279
|
-
* State is persisted for 30 days.
|
|
280
|
-
*/
|
|
281
|
-
setState(newState: Partial<TState>, options?: {
|
|
282
|
-
replace?: boolean;
|
|
283
|
-
}): Promise<void>;
|
|
284
|
-
/**
|
|
285
|
-
* Get the Channel containing this thread.
|
|
286
|
-
* Lazy-created and cached.
|
|
287
|
-
*/
|
|
288
|
-
get channel(): Channel<TState>;
|
|
289
|
-
/**
|
|
290
|
-
* Iterate messages newest first (backward from most recent).
|
|
291
|
-
* Auto-paginates lazily.
|
|
292
|
-
*/
|
|
293
|
-
get messages(): AsyncIterable<Message>;
|
|
294
|
-
get allMessages(): AsyncIterable<Message>;
|
|
295
|
-
getParticipants(): Promise<Author[]>;
|
|
296
|
-
isSubscribed(): Promise<boolean>;
|
|
297
|
-
subscribe(): Promise<void>;
|
|
298
|
-
unsubscribe(): Promise<void>;
|
|
299
|
-
post<T extends PostableObject>(message: T): Promise<T>;
|
|
300
|
-
post(message: string | AdapterPostableMessage | AsyncIterable<string> | ChatElement): Promise<SentMessage>;
|
|
301
|
-
private handlePostableObject;
|
|
302
|
-
postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
|
|
303
|
-
private processCallbackUrls;
|
|
304
|
-
schedule(message: AdapterPostableMessage | ChatElement, options: {
|
|
305
|
-
postAt: Date;
|
|
306
|
-
}): Promise<ScheduledMessage>;
|
|
307
|
-
/**
|
|
308
|
-
* Handle streaming from an AsyncIterable.
|
|
309
|
-
* Normalizes the stream (supports both textStream and fullStream from AI SDK),
|
|
310
|
-
* then uses the adapter's stream implementation if available, otherwise falls back to post+edit.
|
|
311
|
-
*/
|
|
312
|
-
private handleStream;
|
|
313
|
-
/**
|
|
314
|
-
* Slack payloads carry the workspace ID in a few different shapes depending on
|
|
315
|
-
* the webhook type:
|
|
316
|
-
* - Message events: `team_id` or `team` as a string
|
|
317
|
-
* - `block_actions` payloads: `team.id` (object), with `user.team_id` as a fallback
|
|
318
|
-
*/
|
|
319
|
-
private extractSlackRecipientTeamId;
|
|
320
|
-
startTyping(status?: string): Promise<void>;
|
|
321
|
-
/**
|
|
322
|
-
* Fallback streaming implementation using post + edit.
|
|
323
|
-
* Used when adapter doesn't support native streaming.
|
|
324
|
-
* Uses recursive setTimeout to send updates every intervalMs (default 500ms).
|
|
325
|
-
* Schedules next update only after current edit completes to avoid overwhelming slow services.
|
|
326
|
-
*/
|
|
327
|
-
private fallbackStream;
|
|
328
|
-
refresh(): Promise<void>;
|
|
329
|
-
mentionUser(userId: string): string;
|
|
330
|
-
/**
|
|
331
|
-
* Serialize the thread to a plain JSON object.
|
|
332
|
-
* Use this to pass thread data to external systems like workflow engines.
|
|
333
|
-
*
|
|
334
|
-
* @example
|
|
335
|
-
* ```typescript
|
|
336
|
-
* // Pass to a workflow
|
|
337
|
-
* await workflow.start("my-workflow", {
|
|
338
|
-
* thread: thread.toJSON(),
|
|
339
|
-
* message: serializeMessage(message),
|
|
340
|
-
* });
|
|
341
|
-
* ```
|
|
342
|
-
*/
|
|
343
|
-
toJSON(): SerializedThread;
|
|
344
|
-
/**
|
|
345
|
-
* Reconstruct a Thread from serialized JSON data.
|
|
346
|
-
*
|
|
347
|
-
* Reconstructs a ThreadImpl from serialized data.
|
|
348
|
-
* Uses lazy resolution from Chat.getSingleton() for adapter and state.
|
|
349
|
-
*
|
|
350
|
-
* @param json - Serialized thread data
|
|
351
|
-
* @requires Call `chat.registerSingleton()` before deserializing threads
|
|
352
|
-
*
|
|
353
|
-
* @example
|
|
354
|
-
* ```typescript
|
|
355
|
-
* const thread = ThreadImpl.fromJSON(serializedThread);
|
|
356
|
-
* ```
|
|
357
|
-
*/
|
|
358
|
-
static fromJSON<TState = Record<string, unknown>>(json: SerializedThread, adapter?: Adapter): ThreadImpl<TState>;
|
|
359
|
-
/**
|
|
360
|
-
* Serialize a ThreadImpl instance for @workflow/serde.
|
|
361
|
-
* This static method is automatically called by workflow serialization.
|
|
362
|
-
*/
|
|
363
|
-
static [WORKFLOW_SERIALIZE](instance: ThreadImpl): SerializedThread;
|
|
364
|
-
/**
|
|
365
|
-
* Deserialize a ThreadImpl from @workflow/serde.
|
|
366
|
-
* Uses lazy adapter resolution from Chat.getSingleton().
|
|
367
|
-
* Requires chat.registerSingleton() to have been called.
|
|
368
|
-
*/
|
|
369
|
-
static [WORKFLOW_DESERIALIZE](data: SerializedThread): ThreadImpl;
|
|
370
|
-
private createSentMessage;
|
|
371
|
-
createSentMessageFromMessage(message: Message): SentMessage;
|
|
372
|
-
}
|
|
5
|
+
import { C as CardElement, a as CardChild, A as ActionsComponent, B as ButtonComponent, b as CardComponent, c as cardChildToFallbackText$1, d as CardLinkComponent, T as TextComponent, D as DividerComponent, F as FieldComponent, e as FieldsComponent, f as fromReactElement$1, I as ImageComponent, i as isCardElement$1, g as isJSX$1, L as LinkButtonComponent, S as SectionComponent, h as Table$2, t as toCardElement$1, j as toModalElement$1, k as fromReactModalElement$1, l as isModalElement$1, E as ExternalSelectComponent, M as ModalComponent, R as RadioSelectComponent, m as SelectComponent, n as SelectOptionComponent, o as TextInputComponent } from './jsx-runtime-CFq1K_Ve.js';
|
|
6
|
+
export { p as ActionsElement, q as ButtonElement, r as ButtonOptions, U as ButtonProps, s as ButtonStyle, V as CardJSXElement, W as CardJSXProps, X as CardLinkProps, u as CardOptions, Y as CardProps, Z as ChatElement, _ as ContainerProps, v as DividerElement, $ as DividerProps, a9 as ExternalSelectElement, aa as ExternalSelectOptions, a0 as ExternalSelectProps, w as FieldElement, a1 as FieldProps, x as FieldsElement, y as ImageElement, a2 as ImageProps, z as LinkButtonElement, G as LinkButtonOptions, a3 as LinkButtonProps, H as LinkElement, ab as ModalChild, ac as ModalElement, ad as ModalOptions, a4 as ModalProps, ae as RadioSelectElement, af as RadioSelectOptions, J as SectionElement, ag as SelectElement, ah as SelectOptionElement, a5 as SelectOptionProps, ai as SelectOptions, a6 as SelectProps, K as TableAlignment, N as TableElement, O as TableOptions, P as TextElement, aj as TextInputElement, ak as TextInputOptions, a7 as TextInputProps, a8 as TextProps, Q as TextStyle } from './jsx-runtime-CFq1K_Ve.js';
|
|
7
|
+
import '@workflow/serde';
|
|
373
8
|
|
|
374
9
|
/**
|
|
375
10
|
* Error types for chat-sdk
|
|
@@ -472,2778 +107,6 @@ declare class Plan implements PostableObject<PlanModel> {
|
|
|
472
107
|
private enqueueEdit;
|
|
473
108
|
}
|
|
474
109
|
|
|
475
|
-
/**
|
|
476
|
-
* Represents the visibility scope of a channel.
|
|
477
|
-
*
|
|
478
|
-
* - `private`: Channel is only visible to invited members (e.g., private Slack channels)
|
|
479
|
-
* - `workspace`: Channel is visible to all workspace members (e.g., public Slack channels)
|
|
480
|
-
* - `external`: Channel is shared with external organizations (e.g., Slack Connect)
|
|
481
|
-
* - `unknown`: Visibility cannot be determined
|
|
482
|
-
*/
|
|
483
|
-
type ChannelVisibility = "private" | "workspace" | "external" | "unknown";
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Chat configuration with type-safe adapter inference.
|
|
487
|
-
* @template TAdapters - Record of adapter name to adapter instance
|
|
488
|
-
*/
|
|
489
|
-
interface ChatConfig<TAdapters extends Record<string, Adapter> = Record<string, Adapter>> {
|
|
490
|
-
/** Map of adapter name to adapter instance */
|
|
491
|
-
adapters: TAdapters;
|
|
492
|
-
/**
|
|
493
|
-
* How to handle messages that arrive while a handler is already
|
|
494
|
-
* processing on the same thread.
|
|
495
|
-
*
|
|
496
|
-
* - `'drop'` (default) — discard the message (throw `LockError`)
|
|
497
|
-
* - `'queue'` — queue the message; when the current handler finishes,
|
|
498
|
-
* process only the latest queued message with `context.skipped` containing
|
|
499
|
-
* all intermediate messages
|
|
500
|
-
* - `'debounce'` — all messages start/reset a debounce timer; only the
|
|
501
|
-
* final message in a burst is processed
|
|
502
|
-
* - `'concurrent'` — no locking; all messages processed in parallel
|
|
503
|
-
* - `ConcurrencyConfig` — fine-grained control over strategy and parameters
|
|
504
|
-
*/
|
|
505
|
-
concurrency?: ConcurrencyStrategy | ConcurrencyConfig;
|
|
506
|
-
/**
|
|
507
|
-
* TTL for message deduplication entries in milliseconds.
|
|
508
|
-
* Defaults to 300000 (5 minutes). Increase if your webhook cold starts
|
|
509
|
-
* cause platform retries that arrive after the default TTL expires.
|
|
510
|
-
*/
|
|
511
|
-
dedupeTtlMs?: number;
|
|
512
|
-
/**
|
|
513
|
-
* Placeholder text for fallback streaming (post + edit) adapters.
|
|
514
|
-
* Defaults to `"..."`.
|
|
515
|
-
*
|
|
516
|
-
* Set to `null` to avoid posting an initial placeholder message and instead
|
|
517
|
-
* wait until some real text has been streamed before creating the message.
|
|
518
|
-
*/
|
|
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;
|
|
528
|
-
/**
|
|
529
|
-
* Lock scope determines which messages contend for the same lock.
|
|
530
|
-
*
|
|
531
|
-
* - `'thread'`: lock per threadId (default for most adapters)
|
|
532
|
-
* - `'channel'`: lock per channelId (default for WhatsApp, Telegram)
|
|
533
|
-
* - function: resolve scope dynamically per message (async supported)
|
|
534
|
-
*
|
|
535
|
-
* When not set, falls back to the adapter's `lockScope` property,
|
|
536
|
-
* then to `'thread'`.
|
|
537
|
-
*/
|
|
538
|
-
lockScope?: LockScope | ((context: LockScopeContext) => LockScope | Promise<LockScope>);
|
|
539
|
-
/**
|
|
540
|
-
* Logger instance or log level.
|
|
541
|
-
* Pass "silent" to disable all logging.
|
|
542
|
-
*/
|
|
543
|
-
logger?: Logger | LogLevel;
|
|
544
|
-
/**
|
|
545
|
-
* @deprecated Renamed to {@link ChatConfig.threadHistory}. Both fields are
|
|
546
|
-
* read for backwards compatibility; `threadHistory` takes precedence when
|
|
547
|
-
* both are set.
|
|
548
|
-
*/
|
|
549
|
-
messageHistory?: {
|
|
550
|
-
maxMessages?: number;
|
|
551
|
-
ttlMs?: number;
|
|
552
|
-
};
|
|
553
|
-
/**
|
|
554
|
-
* @deprecated Use `concurrency` instead.
|
|
555
|
-
*
|
|
556
|
-
* Behavior when a thread lock cannot be acquired (another handler is processing).
|
|
557
|
-
* - `'drop'` (default) — throw `LockError`, preserving current behavior
|
|
558
|
-
* - `'force'` — force-release the existing lock and re-acquire
|
|
559
|
-
* - callback — custom logic receiving `(threadId, message)`, return `'force'` or `'drop'`
|
|
560
|
-
*
|
|
561
|
-
* When `'force'` is used, the previous handler continues executing — only the lock
|
|
562
|
-
* is released, not the handler itself. This means two handlers may run concurrently
|
|
563
|
-
* on the same thread. The old handler's `releaseLock()` call becomes a no-op since
|
|
564
|
-
* the token no longer matches.
|
|
565
|
-
*/
|
|
566
|
-
onLockConflict?: "force" | "drop" | ((threadId: string, message: Message) => "force" | "drop" | Promise<"force" | "drop">);
|
|
567
|
-
/** State adapter for subscriptions and locking */
|
|
568
|
-
state: StateAdapter;
|
|
569
|
-
/**
|
|
570
|
-
* Update interval for fallback streaming (post + edit) in milliseconds.
|
|
571
|
-
* Defaults to 500ms. Lower values provide smoother updates but may hit rate limits.
|
|
572
|
-
*/
|
|
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;
|
|
596
|
-
/** Default bot username across all adapters */
|
|
597
|
-
userName: string;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Options for webhook handling.
|
|
601
|
-
*/
|
|
602
|
-
interface WebhookOptions {
|
|
603
|
-
/**
|
|
604
|
-
* Override the default modal-opening behavior to handle it inline
|
|
605
|
-
* within the current webhook response cycle.
|
|
606
|
-
* When provided, called instead of adapter.openModal().
|
|
607
|
-
* Used by Teams to return modal content in the HTTP invoke response.
|
|
608
|
-
*
|
|
609
|
-
* The returned `viewId` is platform-specific (e.g. Slack's view ID).
|
|
610
|
-
* Adapters that don't produce a view ID may return void.
|
|
611
|
-
*/
|
|
612
|
-
onOpenModal?: (modal: ModalElement, contextId: string) => Promise<{
|
|
613
|
-
viewId: string;
|
|
614
|
-
} | undefined>;
|
|
615
|
-
/**
|
|
616
|
-
* Function to run message handling in the background.
|
|
617
|
-
* Use this to ensure fast webhook responses while processing continues.
|
|
618
|
-
*
|
|
619
|
-
* @example
|
|
620
|
-
* // Next.js App Router
|
|
621
|
-
* import { after } from "next/server";
|
|
622
|
-
* chat.webhooks.slack(request, { waitUntil: (p) => after(() => p) });
|
|
623
|
-
*
|
|
624
|
-
* @example
|
|
625
|
-
* // Vercel Functions
|
|
626
|
-
* import { waitUntil } from "@vercel/functions";
|
|
627
|
-
* chat.webhooks.slack(request, { waitUntil });
|
|
628
|
-
*/
|
|
629
|
-
waitUntil?: (task: Promise<unknown>) => void;
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Adapter interface with generics for platform-specific types.
|
|
633
|
-
* @template TThreadId - Platform-specific thread ID data type
|
|
634
|
-
* @template TRawMessage - Platform-specific raw message type
|
|
635
|
-
*/
|
|
636
|
-
interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
|
|
637
|
-
/** Add a reaction to a message */
|
|
638
|
-
addReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
|
|
639
|
-
/** Bot user ID for platforms that use IDs in mentions (e.g., Slack's <@U123>) */
|
|
640
|
-
readonly botUserId?: string;
|
|
641
|
-
/**
|
|
642
|
-
* Derive channel ID from a thread ID.
|
|
643
|
-
* Default fallback: first two colon-separated parts (e.g., "slack:C123").
|
|
644
|
-
* Adapters with different structures should override this.
|
|
645
|
-
*/
|
|
646
|
-
channelIdFromThreadId(threadId: string): string;
|
|
647
|
-
/** Decode thread ID string back to platform-specific data */
|
|
648
|
-
decodeThreadId(threadId: string): TThreadId;
|
|
649
|
-
/** Delete a message */
|
|
650
|
-
deleteMessage(threadId: string, messageId: string): Promise<void>;
|
|
651
|
-
/** Cleanup hook called when Chat instance is shutdown */
|
|
652
|
-
disconnect?(): Promise<void>;
|
|
653
|
-
/** Edit an existing message */
|
|
654
|
-
editMessage(threadId: string, messageId: string, message: AdapterPostableMessage): Promise<RawMessage<TRawMessage>>;
|
|
655
|
-
/**
|
|
656
|
-
* Edit a previously posted object (Plan, Poll, etc.).
|
|
657
|
-
* If not implemented, object updates will throw PlanNotSupportedError.
|
|
658
|
-
*
|
|
659
|
-
* @param threadId - The thread containing the message
|
|
660
|
-
* @param messageId - The message ID to edit
|
|
661
|
-
* @param kind - The object kind (e.g., "plan")
|
|
662
|
-
* @param data - The object data (type depends on kind)
|
|
663
|
-
*/
|
|
664
|
-
editObject?(threadId: string, messageId: string, kind: string, data: unknown): Promise<RawMessage<TRawMessage>>;
|
|
665
|
-
/** Encode platform-specific data into a thread ID string */
|
|
666
|
-
encodeThreadId(platformData: TThreadId): string;
|
|
667
|
-
/**
|
|
668
|
-
* Fetch channel info/metadata.
|
|
669
|
-
*/
|
|
670
|
-
fetchChannelInfo?(channelId: string): Promise<ChannelInfo>;
|
|
671
|
-
/**
|
|
672
|
-
* Fetch channel-level messages (top-level, not thread replies).
|
|
673
|
-
* For example, Slack's conversations.history vs conversations.replies.
|
|
674
|
-
*/
|
|
675
|
-
fetchChannelMessages?(channelId: string, options?: FetchOptions): Promise<FetchResult<TRawMessage>>;
|
|
676
|
-
/**
|
|
677
|
-
* Fetch a single message by ID.
|
|
678
|
-
* Optional - adapters that don't implement this will return null.
|
|
679
|
-
*
|
|
680
|
-
* @param threadId - The thread ID containing the message
|
|
681
|
-
* @param messageId - The platform-specific message ID
|
|
682
|
-
* @returns The message, or null if not found/not supported
|
|
683
|
-
*/
|
|
684
|
-
fetchMessage?(threadId: string, messageId: string): Promise<Message<TRawMessage> | null>;
|
|
685
|
-
/**
|
|
686
|
-
* Fetch messages from a thread.
|
|
687
|
-
*
|
|
688
|
-
* **Direction behavior:**
|
|
689
|
-
* - `backward` (default): Fetches the most recent messages. Use this for loading
|
|
690
|
-
* a chat view. The `nextCursor` points to older messages.
|
|
691
|
-
* - `forward`: Fetches the oldest messages first. Use this for iterating through
|
|
692
|
-
* message history. The `nextCursor` points to newer messages.
|
|
693
|
-
*
|
|
694
|
-
* **Message ordering:**
|
|
695
|
-
* Messages within each page are always returned in chronological order (oldest first),
|
|
696
|
-
* regardless of direction. This is the natural reading order for chat messages.
|
|
697
|
-
*
|
|
698
|
-
* @example
|
|
699
|
-
* ```typescript
|
|
700
|
-
* // Load most recent 50 messages for display
|
|
701
|
-
* const recent = await adapter.fetchMessages(threadId, { limit: 50 });
|
|
702
|
-
* // recent.messages: [older, ..., newest] in chronological order
|
|
703
|
-
*
|
|
704
|
-
* // Paginate backward to load older messages
|
|
705
|
-
* const older = await adapter.fetchMessages(threadId, {
|
|
706
|
-
* limit: 50,
|
|
707
|
-
* cursor: recent.nextCursor,
|
|
708
|
-
* });
|
|
709
|
-
*
|
|
710
|
-
* // Iterate through all history from the beginning
|
|
711
|
-
* const history = await adapter.fetchMessages(threadId, {
|
|
712
|
-
* limit: 100,
|
|
713
|
-
* direction: 'forward',
|
|
714
|
-
* });
|
|
715
|
-
* ```
|
|
716
|
-
*/
|
|
717
|
-
fetchMessages(threadId: string, options?: FetchOptions): Promise<FetchResult<TRawMessage>>;
|
|
718
|
-
fetchSubject?(raw: TRawMessage): Promise<MessageSubject | null>;
|
|
719
|
-
/** Fetch thread metadata */
|
|
720
|
-
fetchThread(threadId: string): Promise<ThreadInfo>;
|
|
721
|
-
/**
|
|
722
|
-
* Get the visibility scope of a channel containing the thread.
|
|
723
|
-
*
|
|
724
|
-
* This distinguishes between private channels, workspace-visible channels,
|
|
725
|
-
* and externally shared channels (e.g., Slack Connect).
|
|
726
|
-
*
|
|
727
|
-
* @param threadId - The thread ID to check
|
|
728
|
-
* @returns The channel visibility scope
|
|
729
|
-
*/
|
|
730
|
-
getChannelVisibility?(threadId: string): ChannelVisibility;
|
|
731
|
-
/**
|
|
732
|
-
* Look up user information by user ID.
|
|
733
|
-
* Optional — not all platforms support this.
|
|
734
|
-
*
|
|
735
|
-
* @param userId - Platform-specific user ID
|
|
736
|
-
* @returns User info, or null if user not found
|
|
737
|
-
*/
|
|
738
|
-
getUser?(userId: string): Promise<UserInfo | null>;
|
|
739
|
-
/** Handle incoming webhook request */
|
|
740
|
-
handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;
|
|
741
|
-
/** Called when Chat instance is created (internal use) */
|
|
742
|
-
initialize(chat: ChatInstance): Promise<void>;
|
|
743
|
-
/**
|
|
744
|
-
* Check if a thread is a direct message conversation.
|
|
745
|
-
*
|
|
746
|
-
* @param threadId - The thread ID to check
|
|
747
|
-
* @returns True if the thread is a DM, false otherwise
|
|
748
|
-
*/
|
|
749
|
-
isDM?(threadId: string): boolean;
|
|
750
|
-
/**
|
|
751
|
-
* List threads in a channel.
|
|
752
|
-
*/
|
|
753
|
-
listThreads?(channelId: string, options?: ListThreadsOptions): Promise<ListThreadsResult<TRawMessage>>;
|
|
754
|
-
/**
|
|
755
|
-
* Default lock scope for this adapter.
|
|
756
|
-
* - `'thread'` (default): lock per threadId
|
|
757
|
-
* - `'channel'`: lock per channelId (for channel-based platforms like WhatsApp, Telegram)
|
|
758
|
-
*
|
|
759
|
-
* Can be overridden by `ChatConfig.lockScope`.
|
|
760
|
-
*/
|
|
761
|
-
readonly lockScope?: LockScope;
|
|
762
|
-
/** Unique name for this adapter (e.g., "slack", "teams") */
|
|
763
|
-
readonly name: string;
|
|
764
|
-
/**
|
|
765
|
-
* Optional hook called when a thread is subscribed to.
|
|
766
|
-
* Adapters can use this to set up platform-specific subscriptions
|
|
767
|
-
* (e.g., Google Chat Workspace Events).
|
|
768
|
-
*/
|
|
769
|
-
onThreadSubscribe?(threadId: string): Promise<void>;
|
|
770
|
-
/**
|
|
771
|
-
* Open a direct message conversation with a user.
|
|
772
|
-
*
|
|
773
|
-
* @param userId - The platform-specific user ID
|
|
774
|
-
* @returns The thread ID for the DM conversation
|
|
775
|
-
*
|
|
776
|
-
* @example
|
|
777
|
-
* ```typescript
|
|
778
|
-
* const dmThreadId = await adapter.openDM("U123456");
|
|
779
|
-
* await adapter.postMessage(dmThreadId, "Hello!");
|
|
780
|
-
* ```
|
|
781
|
-
*/
|
|
782
|
-
openDM?(userId: string): Promise<string>;
|
|
783
|
-
/**
|
|
784
|
-
* Open a modal/dialog form.
|
|
785
|
-
*
|
|
786
|
-
* @param triggerId - Platform-specific trigger ID from the action event
|
|
787
|
-
* @param modal - The modal element to display
|
|
788
|
-
* @param contextId - Optional context ID for server-side stored thread/message context
|
|
789
|
-
* @returns The view/dialog ID
|
|
790
|
-
*/
|
|
791
|
-
openModal?(triggerId: string, modal: ModalElement, contextId?: string): Promise<{
|
|
792
|
-
viewId: string;
|
|
793
|
-
}>;
|
|
794
|
-
/** Parse platform message format to normalized format */
|
|
795
|
-
parseMessage(raw: TRawMessage): Message<TRawMessage>;
|
|
796
|
-
/**
|
|
797
|
-
* @deprecated Renamed to {@link Adapter.persistThreadHistory}. Both flags
|
|
798
|
-
* are read for backwards compatibility; either being `true` enables
|
|
799
|
-
* persistence.
|
|
800
|
-
*/
|
|
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;
|
|
808
|
-
/**
|
|
809
|
-
* Post a message to channel top-level (not in a thread).
|
|
810
|
-
*/
|
|
811
|
-
postChannelMessage?(channelId: string, message: AdapterPostableMessage): Promise<RawMessage<TRawMessage>>;
|
|
812
|
-
/**
|
|
813
|
-
* Post an ephemeral message visible only to a specific user.
|
|
814
|
-
*
|
|
815
|
-
* This is optional - if not implemented, Thread.postEphemeral will
|
|
816
|
-
* fall back to openDM + postMessage when fallbackToDM is true.
|
|
817
|
-
*
|
|
818
|
-
* @param threadId - The thread to post in
|
|
819
|
-
* @param userId - The user who should see the message
|
|
820
|
-
* @param message - The message content
|
|
821
|
-
* @returns EphemeralMessage with usedFallback: false
|
|
822
|
-
*/
|
|
823
|
-
postEphemeral?(threadId: string, userId: string, message: AdapterPostableMessage): Promise<EphemeralMessage<TRawMessage>>;
|
|
824
|
-
/** Post a message to a thread */
|
|
825
|
-
postMessage(threadId: string, message: AdapterPostableMessage): Promise<RawMessage<TRawMessage>>;
|
|
826
|
-
/**
|
|
827
|
-
* Post a special object (Plan, Poll, etc.) as a single message.
|
|
828
|
-
* If not implemented, posting such objects will throw PlanNotSupportedError.
|
|
829
|
-
*
|
|
830
|
-
* @param threadId - The thread to post to
|
|
831
|
-
* @param kind - The object kind (e.g., "plan")
|
|
832
|
-
* @param data - The object data (type depends on kind)
|
|
833
|
-
*/
|
|
834
|
-
postObject?(threadId: string, kind: string, data: unknown): Promise<RawMessage<TRawMessage>>;
|
|
835
|
-
/**
|
|
836
|
-
* Reconstruct fetchData on an attachment after deserialization.
|
|
837
|
-
* Called during message rehydration for queue/debounce strategies.
|
|
838
|
-
* Uses fetchMetadata and adapter auth context to rebuild the download closure.
|
|
839
|
-
*/
|
|
840
|
-
rehydrateAttachment?(attachment: Attachment): Attachment;
|
|
841
|
-
/** Remove a reaction from a message */
|
|
842
|
-
removeReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
|
|
843
|
-
/** Render formatted content to platform-specific string */
|
|
844
|
-
renderFormatted(content: FormattedContent): string;
|
|
845
|
-
/**
|
|
846
|
-
* Schedule a message for future delivery.
|
|
847
|
-
*
|
|
848
|
-
* Optional — only supported by adapters with native scheduling APIs (e.g., Slack).
|
|
849
|
-
* Thread.schedule() will throw NotImplementedError if this method is absent.
|
|
850
|
-
*
|
|
851
|
-
* @param threadId - The thread to post in
|
|
852
|
-
* @param message - The message content
|
|
853
|
-
* @param options - Scheduling options including the target delivery time
|
|
854
|
-
* @returns A ScheduledMessage with cancel() capability
|
|
855
|
-
*/
|
|
856
|
-
scheduleMessage?(threadId: string, message: AdapterPostableMessage, options: {
|
|
857
|
-
postAt: Date;
|
|
858
|
-
}): Promise<ScheduledMessage<TRawMessage>>;
|
|
859
|
-
/** Show typing indicator */
|
|
860
|
-
startTyping(threadId: string, status?: string): Promise<void>;
|
|
861
|
-
/**
|
|
862
|
-
* Stream a message using platform-native streaming APIs.
|
|
863
|
-
*
|
|
864
|
-
* The adapter consumes the async iterable and handles the entire streaming lifecycle.
|
|
865
|
-
* Only available on platforms with native streaming support (e.g., Slack).
|
|
866
|
-
*
|
|
867
|
-
* The stream can yield plain strings (text chunks) or {@link StreamChunk} objects
|
|
868
|
-
* for rich content like task progress cards. Adapters that don't support structured
|
|
869
|
-
* chunks will extract text from `markdown_text` chunks and ignore other types.
|
|
870
|
-
*
|
|
871
|
-
* @param threadId - The thread to stream to
|
|
872
|
-
* @param textStream - Async iterable of text chunks or structured StreamChunk objects
|
|
873
|
-
* @param options - Platform-specific streaming options
|
|
874
|
-
* @returns The raw message after streaming completes
|
|
875
|
-
*/
|
|
876
|
-
stream?(threadId: string, textStream: AsyncIterable<string | StreamChunk>, options?: StreamOptions): Promise<RawMessage<TRawMessage>>;
|
|
877
|
-
/** Bot username (can override global userName) */
|
|
878
|
-
readonly userName: string;
|
|
879
|
-
}
|
|
880
|
-
/**
|
|
881
|
-
* A structured streaming chunk for platform-native rich content.
|
|
882
|
-
*
|
|
883
|
-
* On Slack, these map directly to streaming chunk types:
|
|
884
|
-
* - `markdown_text`: Streamed text content
|
|
885
|
-
* - `task_update`: Tool/step progress cards (pending → in_progress → complete → error)
|
|
886
|
-
* - `plan_update`: Plan title updates
|
|
887
|
-
*
|
|
888
|
-
* Adapters that don't support structured chunks will extract `text` from
|
|
889
|
-
* `markdown_text` chunks and ignore other types gracefully.
|
|
890
|
-
*/
|
|
891
|
-
type StreamChunk = MarkdownTextChunk | TaskUpdateChunk | PlanUpdateChunk;
|
|
892
|
-
interface MarkdownTextChunk {
|
|
893
|
-
text: string;
|
|
894
|
-
type: "markdown_text";
|
|
895
|
-
}
|
|
896
|
-
interface TaskUpdateChunk {
|
|
897
|
-
details?: string;
|
|
898
|
-
id: string;
|
|
899
|
-
output?: string;
|
|
900
|
-
status: "pending" | "in_progress" | "complete" | "error";
|
|
901
|
-
title: string;
|
|
902
|
-
type: "task_update";
|
|
903
|
-
}
|
|
904
|
-
interface PlanUpdateChunk {
|
|
905
|
-
title: string;
|
|
906
|
-
type: "plan_update";
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Options for streaming messages.
|
|
910
|
-
* Platform-specific options are passed through to the adapter.
|
|
911
|
-
*/
|
|
912
|
-
interface StreamOptions {
|
|
913
|
-
/** Slack: The team/workspace ID */
|
|
914
|
-
recipientTeamId?: string;
|
|
915
|
-
/** Slack: The user ID to stream to (for AI assistant context) */
|
|
916
|
-
recipientUserId?: string;
|
|
917
|
-
/** Block Kit elements to attach when stopping the stream (Slack only, via chat.stopStream) */
|
|
918
|
-
stopBlocks?: unknown[];
|
|
919
|
-
/**
|
|
920
|
-
* Slack: Controls how task_update chunks are displayed.
|
|
921
|
-
* - `"timeline"` — individual task cards shown inline with text (default)
|
|
922
|
-
* - `"plan"` — all tasks grouped into a single plan block
|
|
923
|
-
*/
|
|
924
|
-
taskDisplayMode?: "timeline" | "plan";
|
|
925
|
-
/** Minimum interval between updates in ms (default: 1000). Used for fallback mode (GChat/Teams). */
|
|
926
|
-
updateIntervalMs?: number;
|
|
927
|
-
}
|
|
928
|
-
/** Internal interface for Chat instance passed to adapters */
|
|
929
|
-
interface ChatInstance {
|
|
930
|
-
/** Get the configured logger, optionally with a child prefix */
|
|
931
|
-
getLogger(prefix?: string): Logger;
|
|
932
|
-
getState(): StateAdapter;
|
|
933
|
-
getUserName(): string;
|
|
934
|
-
/**
|
|
935
|
-
* @deprecated Use processMessage instead. This method is for internal use.
|
|
936
|
-
*/
|
|
937
|
-
handleIncomingMessage(adapter: Adapter, threadId: string, message: Message): Promise<void>;
|
|
938
|
-
/**
|
|
939
|
-
* Process an incoming action event (button click) from an adapter.
|
|
940
|
-
* Handles waitUntil registration and error catching internally.
|
|
941
|
-
*
|
|
942
|
-
* @param event - The action event (without thread field, will be added)
|
|
943
|
-
* @param options - Webhook options including waitUntil
|
|
944
|
-
*/
|
|
945
|
-
processAction(event: Omit<ActionEvent, "thread" | "openModal"> & {
|
|
946
|
-
adapter: Adapter;
|
|
947
|
-
}, options: WebhookOptions | undefined): Promise<void>;
|
|
948
|
-
processAppHomeOpened(event: AppHomeOpenedEvent, options?: WebhookOptions): void;
|
|
949
|
-
processAssistantContextChanged(event: AssistantContextChangedEvent, options?: WebhookOptions): void;
|
|
950
|
-
processAssistantThreadStarted(event: AssistantThreadStartedEvent, options?: WebhookOptions): void;
|
|
951
|
-
processMemberJoinedChannel(event: MemberJoinedChannelEvent, options?: WebhookOptions): void;
|
|
952
|
-
/**
|
|
953
|
-
* Process an incoming message from an adapter.
|
|
954
|
-
* Handles waitUntil registration and error catching internally.
|
|
955
|
-
*
|
|
956
|
-
* @param adapter - The adapter that received the message
|
|
957
|
-
* @param threadId - The thread ID
|
|
958
|
-
* @param message - Either a parsed message, or a factory function for lazy async parsing
|
|
959
|
-
* @param options - Webhook options including waitUntil
|
|
960
|
-
*/
|
|
961
|
-
processMessage(adapter: Adapter, threadId: string, message: Message | (() => Promise<Message>), options?: WebhookOptions): Promise<void>;
|
|
962
|
-
/**
|
|
963
|
-
* Process a modal close event from an adapter.
|
|
964
|
-
*
|
|
965
|
-
* @param event - The modal close event (without relatedThread/relatedMessage/relatedChannel)
|
|
966
|
-
* @param contextId - Context ID for retrieving stored thread/message/channel context
|
|
967
|
-
* @param options - Webhook options
|
|
968
|
-
*/
|
|
969
|
-
processModalClose(event: Omit<ModalCloseEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, options?: WebhookOptions): void;
|
|
970
|
-
/**
|
|
971
|
-
* Process a modal submit event from an adapter.
|
|
972
|
-
*
|
|
973
|
-
* @param event - The modal submit event (without relatedThread/relatedMessage/relatedChannel)
|
|
974
|
-
* @param contextId - Context ID for retrieving stored thread/message/channel context
|
|
975
|
-
* @param options - Webhook options
|
|
976
|
-
*/
|
|
977
|
-
processModalSubmit(event: Omit<ModalSubmitEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, options?: WebhookOptions): Promise<ModalResponse | undefined>;
|
|
978
|
-
/**
|
|
979
|
-
* Process an interactive options load event from an adapter.
|
|
980
|
-
* Returns normalized select options for the adapter to render.
|
|
981
|
-
*/
|
|
982
|
-
processOptionsLoad(event: OptionsLoadEvent, options?: WebhookOptions): Promise<OptionsLoadResult | undefined>;
|
|
983
|
-
/**
|
|
984
|
-
* Process an incoming reaction event from an adapter.
|
|
985
|
-
* Handles waitUntil registration and error catching internally.
|
|
986
|
-
*
|
|
987
|
-
* @param event - The reaction event (without adapter field, will be added)
|
|
988
|
-
* @param options - Webhook options including waitUntil
|
|
989
|
-
*/
|
|
990
|
-
processReaction(event: Omit<ReactionEvent, "adapter" | "thread"> & {
|
|
991
|
-
adapter?: Adapter;
|
|
992
|
-
}, options?: WebhookOptions): void;
|
|
993
|
-
/**
|
|
994
|
-
* Process an incoming slash command from an adapter.
|
|
995
|
-
* Handles waitUntil registration and error catching internally.
|
|
996
|
-
*
|
|
997
|
-
* @param event - The slash command event
|
|
998
|
-
* @param options - Webhook options including waitUntil
|
|
999
|
-
*/
|
|
1000
|
-
processSlashCommand(event: Omit<SlashCommandEvent, "channel" | "openModal"> & {
|
|
1001
|
-
adapter: Adapter;
|
|
1002
|
-
channelId: string;
|
|
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;
|
|
1010
|
-
}
|
|
1011
|
-
/** Lock scope determines which messages contend for the same lock. */
|
|
1012
|
-
type LockScope = "thread" | "channel";
|
|
1013
|
-
/** Context provided to the lockScope resolver function. */
|
|
1014
|
-
interface LockScopeContext {
|
|
1015
|
-
adapter: Adapter;
|
|
1016
|
-
channelId: string;
|
|
1017
|
-
isDM: boolean;
|
|
1018
|
-
threadId: string;
|
|
1019
|
-
}
|
|
1020
|
-
/** Concurrency strategy for overlapping messages on the same thread. */
|
|
1021
|
-
type ConcurrencyStrategy = "drop" | "queue" | "debounce" | "concurrent";
|
|
1022
|
-
/** Fine-grained concurrency configuration. */
|
|
1023
|
-
interface ConcurrencyConfig {
|
|
1024
|
-
/** Debounce window in milliseconds (debounce strategy). Default: 1500. */
|
|
1025
|
-
debounceMs?: number;
|
|
1026
|
-
/** Max concurrent handlers per thread (concurrent strategy). Default: Infinity. */
|
|
1027
|
-
maxConcurrent?: number;
|
|
1028
|
-
/** Max queued messages per thread (queue/debounce strategy). Default: 10. */
|
|
1029
|
-
maxQueueSize?: number;
|
|
1030
|
-
/** What to do when queue is full. Default: 'drop-oldest'. */
|
|
1031
|
-
onQueueFull?: "drop-oldest" | "drop-newest";
|
|
1032
|
-
/** TTL for queued entries in milliseconds. Default: 90000 (90s). */
|
|
1033
|
-
queueEntryTtlMs?: number;
|
|
1034
|
-
/** The concurrency strategy to use. */
|
|
1035
|
-
strategy: ConcurrencyStrategy;
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* An entry in the per-thread message queue.
|
|
1039
|
-
* Used by the `queue` and `debounce` concurrency strategies.
|
|
1040
|
-
*/
|
|
1041
|
-
interface QueueEntry {
|
|
1042
|
-
/** When this entry was enqueued (Unix ms). */
|
|
1043
|
-
enqueuedAt: number;
|
|
1044
|
-
/** When this entry expires (Unix ms). Stale entries are discarded on dequeue. */
|
|
1045
|
-
expiresAt: number;
|
|
1046
|
-
/** The queued message. */
|
|
1047
|
-
message: Message;
|
|
1048
|
-
}
|
|
1049
|
-
/**
|
|
1050
|
-
* Context provided to message handlers when messages were queued
|
|
1051
|
-
* while a previous handler was running.
|
|
1052
|
-
*/
|
|
1053
|
-
interface MessageContext {
|
|
1054
|
-
/**
|
|
1055
|
-
* Messages that arrived while the previous handler was running,
|
|
1056
|
-
* in chronological order, excluding the current message (which is the latest).
|
|
1057
|
-
*/
|
|
1058
|
-
skipped: Message[];
|
|
1059
|
-
/** Total messages received since last handler ran (skipped.length + 1). */
|
|
1060
|
-
totalSinceLastHandler: number;
|
|
1061
|
-
}
|
|
1062
|
-
interface StateAdapter {
|
|
1063
|
-
/** Acquire a lock on a thread (returns null if already locked) */
|
|
1064
|
-
acquireLock(threadId: string, ttlMs: number): Promise<Lock | null>;
|
|
1065
|
-
/** Atomically append a value to a list. Trims to maxLength (keeping newest). Refreshes TTL. */
|
|
1066
|
-
appendToList(key: string, value: unknown, options?: {
|
|
1067
|
-
maxLength?: number;
|
|
1068
|
-
ttlMs?: number;
|
|
1069
|
-
}): Promise<void>;
|
|
1070
|
-
/** Connect to the state backend */
|
|
1071
|
-
connect(): Promise<void>;
|
|
1072
|
-
/** Delete a cached value */
|
|
1073
|
-
delete(key: string): Promise<void>;
|
|
1074
|
-
/** Pop the next message from the thread's queue. Returns null if empty. */
|
|
1075
|
-
dequeue(threadId: string): Promise<QueueEntry | null>;
|
|
1076
|
-
/** Disconnect from the state backend */
|
|
1077
|
-
disconnect(): Promise<void>;
|
|
1078
|
-
/** Atomically append a message to the thread's pending queue. Returns new queue depth. */
|
|
1079
|
-
enqueue(threadId: string, entry: QueueEntry, maxSize: number): Promise<number>;
|
|
1080
|
-
/** Extend a lock's TTL */
|
|
1081
|
-
extendLock(lock: Lock, ttlMs: number): Promise<boolean>;
|
|
1082
|
-
/**
|
|
1083
|
-
* Force-release a lock on a thread, regardless of ownership token.
|
|
1084
|
-
* The previous lock holder's handler continues running — only the lock is released.
|
|
1085
|
-
* The old handler's `releaseLock()` becomes a no-op (token mismatch).
|
|
1086
|
-
*/
|
|
1087
|
-
forceReleaseLock(threadId: string): Promise<void>;
|
|
1088
|
-
/** Get a cached value by key */
|
|
1089
|
-
get<T = unknown>(key: string): Promise<T | null>;
|
|
1090
|
-
/** Read all values from a list in insertion order. Returns empty array if key does not exist. */
|
|
1091
|
-
getList<T = unknown>(key: string): Promise<T[]>;
|
|
1092
|
-
/** Check if subscribed to a thread */
|
|
1093
|
-
isSubscribed(threadId: string): Promise<boolean>;
|
|
1094
|
-
/** Get the current queue depth for a thread. */
|
|
1095
|
-
queueDepth(threadId: string): Promise<number>;
|
|
1096
|
-
/** Release a lock */
|
|
1097
|
-
releaseLock(lock: Lock): Promise<void>;
|
|
1098
|
-
/** Set a cached value with optional TTL in milliseconds */
|
|
1099
|
-
set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void>;
|
|
1100
|
-
/** Atomically set a value only if the key does not already exist. Returns true if set, false if key existed. */
|
|
1101
|
-
setIfNotExists(key: string, value: unknown, ttlMs?: number): Promise<boolean>;
|
|
1102
|
-
/** Subscribe to a thread (persists across restarts) */
|
|
1103
|
-
subscribe(threadId: string): Promise<void>;
|
|
1104
|
-
/** Unsubscribe from a thread */
|
|
1105
|
-
unsubscribe(threadId: string): Promise<void>;
|
|
1106
|
-
}
|
|
1107
|
-
interface Lock {
|
|
1108
|
-
expiresAt: number;
|
|
1109
|
-
threadId: string;
|
|
1110
|
-
token: string;
|
|
1111
|
-
}
|
|
1112
|
-
/**
|
|
1113
|
-
* Base interface for entities that can receive messages.
|
|
1114
|
-
* Both Thread and Channel extend this interface.
|
|
1115
|
-
*
|
|
1116
|
-
* @template TState - Custom state type stored per entity
|
|
1117
|
-
* @template TRawMessage - Platform-specific raw message type
|
|
1118
|
-
*/
|
|
1119
|
-
interface Postable<TState = Record<string, unknown>, TRawMessage = unknown> {
|
|
1120
|
-
/** The adapter this entity belongs to */
|
|
1121
|
-
readonly adapter: Adapter;
|
|
1122
|
-
/** The visibility scope of this channel */
|
|
1123
|
-
readonly channelVisibility: ChannelVisibility;
|
|
1124
|
-
/** Unique ID */
|
|
1125
|
-
readonly id: string;
|
|
1126
|
-
/** Whether this is a direct message conversation */
|
|
1127
|
-
readonly isDM: boolean;
|
|
1128
|
-
/**
|
|
1129
|
-
* Get a platform-specific mention string for a user.
|
|
1130
|
-
*/
|
|
1131
|
-
mentionUser(userId: string): string;
|
|
1132
|
-
/**
|
|
1133
|
-
* Iterate messages newest first (backward from most recent).
|
|
1134
|
-
* Auto-paginates lazily — only fetches pages as consumed.
|
|
1135
|
-
*/
|
|
1136
|
-
readonly messages: AsyncIterable<Message<TRawMessage>>;
|
|
1137
|
-
/**
|
|
1138
|
-
* Post a message.
|
|
1139
|
-
*/
|
|
1140
|
-
post<T extends PostableObject>(message: T): Promise<T>;
|
|
1141
|
-
post(message: string | PostableMessage | ChatElement): Promise<SentMessage<TRawMessage>>;
|
|
1142
|
-
/**
|
|
1143
|
-
* Post an ephemeral message visible only to a specific user.
|
|
1144
|
-
*/
|
|
1145
|
-
postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage<TRawMessage> | null>;
|
|
1146
|
-
/**
|
|
1147
|
-
* Schedule a message for future delivery.
|
|
1148
|
-
*
|
|
1149
|
-
* Currently only supported by the Slack adapter. Other adapters
|
|
1150
|
-
* will throw NotImplementedError.
|
|
1151
|
-
*
|
|
1152
|
-
* @param message - The message content (streaming not supported)
|
|
1153
|
-
* @param options - Scheduling options including the target delivery time
|
|
1154
|
-
* @returns A ScheduledMessage with cancel() capability
|
|
1155
|
-
*
|
|
1156
|
-
* @example
|
|
1157
|
-
* ```typescript
|
|
1158
|
-
* const scheduled = await thread.schedule("Reminder: standup!", {
|
|
1159
|
-
* postAt: new Date("2026-03-09T09:00:00Z"),
|
|
1160
|
-
* });
|
|
1161
|
-
*
|
|
1162
|
-
* // Cancel before it's sent
|
|
1163
|
-
* await scheduled.cancel();
|
|
1164
|
-
* ```
|
|
1165
|
-
*/
|
|
1166
|
-
schedule(message: AdapterPostableMessage | ChatElement, options: {
|
|
1167
|
-
postAt: Date;
|
|
1168
|
-
}): Promise<ScheduledMessage<TRawMessage>>;
|
|
1169
|
-
/**
|
|
1170
|
-
* Set the state. Merges with existing state by default.
|
|
1171
|
-
*/
|
|
1172
|
-
setState(state: Partial<TState>, options?: {
|
|
1173
|
-
replace?: boolean;
|
|
1174
|
-
}): Promise<void>;
|
|
1175
|
-
/** Show typing indicator */
|
|
1176
|
-
startTyping(status?: string): Promise<void>;
|
|
1177
|
-
/**
|
|
1178
|
-
* Get the current state.
|
|
1179
|
-
* Returns null if no state has been set.
|
|
1180
|
-
*/
|
|
1181
|
-
readonly state: Promise<TState | null>;
|
|
1182
|
-
}
|
|
1183
|
-
/**
|
|
1184
|
-
* Represents a channel/conversation container that holds threads.
|
|
1185
|
-
* Extends Postable for message posting capabilities.
|
|
1186
|
-
*
|
|
1187
|
-
* @template TState - Custom state type stored per channel
|
|
1188
|
-
* @template TRawMessage - Platform-specific raw message type
|
|
1189
|
-
*/
|
|
1190
|
-
interface Channel<TState = Record<string, unknown>, TRawMessage = unknown> extends Postable<TState, TRawMessage> {
|
|
1191
|
-
/** Fetch channel metadata from the platform */
|
|
1192
|
-
fetchMetadata(): Promise<ChannelInfo>;
|
|
1193
|
-
/** Channel name (e.g., "#general"). Null until fetchInfo() is called. */
|
|
1194
|
-
readonly name: string | null;
|
|
1195
|
-
/**
|
|
1196
|
-
* Iterate threads in this channel, most recently active first.
|
|
1197
|
-
* Returns ThreadSummary (lightweight) for efficiency.
|
|
1198
|
-
* Empty iterable on threadless platforms.
|
|
1199
|
-
*/
|
|
1200
|
-
threads(): AsyncIterable<ThreadSummary<TRawMessage>>;
|
|
1201
|
-
/**
|
|
1202
|
-
* Serialize the channel to a plain JSON object.
|
|
1203
|
-
* Use this to pass channel data to external systems like workflow engines.
|
|
1204
|
-
*/
|
|
1205
|
-
toJSON(): SerializedChannel;
|
|
1206
|
-
}
|
|
1207
|
-
/**
|
|
1208
|
-
* Lightweight summary of a thread within a channel.
|
|
1209
|
-
*/
|
|
1210
|
-
interface ThreadSummary<TRawMessage = unknown> {
|
|
1211
|
-
/** Full thread ID */
|
|
1212
|
-
id: string;
|
|
1213
|
-
/** Timestamp of most recent reply */
|
|
1214
|
-
lastReplyAt?: Date;
|
|
1215
|
-
/** Reply count (if available) */
|
|
1216
|
-
replyCount?: number;
|
|
1217
|
-
/** Root/first message of the thread */
|
|
1218
|
-
rootMessage: Message<TRawMessage>;
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* Channel metadata returned by fetchInfo().
|
|
1222
|
-
*/
|
|
1223
|
-
interface ChannelInfo {
|
|
1224
|
-
/** The visibility scope of this channel */
|
|
1225
|
-
channelVisibility?: ChannelVisibility;
|
|
1226
|
-
id: string;
|
|
1227
|
-
isDM?: boolean;
|
|
1228
|
-
memberCount?: number;
|
|
1229
|
-
metadata: Record<string, unknown>;
|
|
1230
|
-
name?: string;
|
|
1231
|
-
}
|
|
1232
|
-
/**
|
|
1233
|
-
* Options for listing threads in a channel.
|
|
1234
|
-
*/
|
|
1235
|
-
interface ListThreadsOptions {
|
|
1236
|
-
cursor?: string;
|
|
1237
|
-
limit?: number;
|
|
1238
|
-
}
|
|
1239
|
-
/**
|
|
1240
|
-
* Result of listing threads in a channel.
|
|
1241
|
-
*/
|
|
1242
|
-
interface ListThreadsResult<TRawMessage = unknown> {
|
|
1243
|
-
nextCursor?: string;
|
|
1244
|
-
threads: ThreadSummary<TRawMessage>[];
|
|
1245
|
-
}
|
|
1246
|
-
/** Default TTL for thread state (30 days in milliseconds) */
|
|
1247
|
-
declare const THREAD_STATE_TTL_MS: number;
|
|
1248
|
-
/**
|
|
1249
|
-
* Thread interface with support for custom state.
|
|
1250
|
-
* Extends Postable for shared message posting capabilities.
|
|
1251
|
-
*
|
|
1252
|
-
* @template TState - Custom state type stored per-thread (default: Record<string, unknown>)
|
|
1253
|
-
* @template TRawMessage - Platform-specific raw message type
|
|
1254
|
-
*/
|
|
1255
|
-
interface Thread<TState = Record<string, unknown>, TRawMessage = unknown> extends Postable<TState, TRawMessage> {
|
|
1256
|
-
/**
|
|
1257
|
-
* Async iterator for all messages in the thread.
|
|
1258
|
-
* Messages are yielded in chronological order (oldest first).
|
|
1259
|
-
* Automatically handles pagination.
|
|
1260
|
-
*/
|
|
1261
|
-
allMessages: AsyncIterable<Message<TRawMessage>>;
|
|
1262
|
-
/** Get the Channel containing this thread */
|
|
1263
|
-
readonly channel: Channel<TState, TRawMessage>;
|
|
1264
|
-
/** Channel/conversation ID */
|
|
1265
|
-
readonly channelId: string;
|
|
1266
|
-
/**
|
|
1267
|
-
* Wrap a Message object as a SentMessage with edit/delete capabilities.
|
|
1268
|
-
* Used internally for reconstructing messages from serialized data.
|
|
1269
|
-
*/
|
|
1270
|
-
createSentMessageFromMessage(message: Message<TRawMessage>): SentMessage<TRawMessage>;
|
|
1271
|
-
/**
|
|
1272
|
-
* Get the unique human participants in this thread.
|
|
1273
|
-
*
|
|
1274
|
-
* Scans all messages in the thread and returns deduplicated authors,
|
|
1275
|
-
* excluding the bot itself. Useful for deciding whether to subscribe
|
|
1276
|
-
* based on how many humans are participating — subscribe when it's a
|
|
1277
|
-
* 1:1 conversation, unsubscribe when others join so humans can talk
|
|
1278
|
-
* without the bot replying to every message.
|
|
1279
|
-
*
|
|
1280
|
-
* @returns Array of unique non-bot authors
|
|
1281
|
-
*
|
|
1282
|
-
* @example
|
|
1283
|
-
* ```typescript
|
|
1284
|
-
* // Subscribe only when one person is talking to the bot
|
|
1285
|
-
* bot.onNewMention(async (thread, message) => {
|
|
1286
|
-
* const participants = await thread.getParticipants();
|
|
1287
|
-
* if (participants.length === 1) {
|
|
1288
|
-
* await thread.subscribe();
|
|
1289
|
-
* await thread.post("I'm here to help!");
|
|
1290
|
-
* }
|
|
1291
|
-
* });
|
|
1292
|
-
*
|
|
1293
|
-
* // Unsubscribe when the thread becomes a group conversation
|
|
1294
|
-
* bot.onSubscribedMessage(async (thread, message) => {
|
|
1295
|
-
* const participants = await thread.getParticipants();
|
|
1296
|
-
* if (participants.length > 1) {
|
|
1297
|
-
* await thread.unsubscribe();
|
|
1298
|
-
* return;
|
|
1299
|
-
* }
|
|
1300
|
-
* await thread.post("Still here to help!");
|
|
1301
|
-
* });
|
|
1302
|
-
* ```
|
|
1303
|
-
*/
|
|
1304
|
-
getParticipants(): Promise<Author[]>;
|
|
1305
|
-
/**
|
|
1306
|
-
* Check if this thread is currently subscribed.
|
|
1307
|
-
*
|
|
1308
|
-
* In subscribed message handlers, this is optimized to return true immediately
|
|
1309
|
-
* without a state lookup, since we already know we're in a subscribed context.
|
|
1310
|
-
*
|
|
1311
|
-
* @returns Promise resolving to true if subscribed, false otherwise
|
|
1312
|
-
*/
|
|
1313
|
-
isSubscribed(): Promise<boolean>;
|
|
1314
|
-
/**
|
|
1315
|
-
* Get a platform-specific mention string for a user.
|
|
1316
|
-
* Use this to @-mention a user in a message.
|
|
1317
|
-
* @example
|
|
1318
|
-
* await thread.post(`Hey ${thread.mentionUser(userId)}, check this out!`);
|
|
1319
|
-
*/
|
|
1320
|
-
mentionUser(userId: string): string;
|
|
1321
|
-
/**
|
|
1322
|
-
* Post a message to this thread.
|
|
1323
|
-
*
|
|
1324
|
-
* Supports text, markdown, cards, and streaming from async iterables.
|
|
1325
|
-
* When posting a stream (e.g., from AI SDK), uses platform-native streaming
|
|
1326
|
-
* APIs when available (Slack), or falls back to post + edit with throttling.
|
|
1327
|
-
*
|
|
1328
|
-
* @param message - String, PostableMessage, JSX Card, or AsyncIterable<string>
|
|
1329
|
-
* @returns A SentMessage with methods to edit, delete, or add reactions
|
|
1330
|
-
*
|
|
1331
|
-
* @example
|
|
1332
|
-
* ```typescript
|
|
1333
|
-
* // Simple string
|
|
1334
|
-
* await thread.post("Hello!");
|
|
1335
|
-
*
|
|
1336
|
-
* // Markdown
|
|
1337
|
-
* await thread.post({ markdown: "**Bold** and _italic_" });
|
|
1338
|
-
*
|
|
1339
|
-
* // With emoji
|
|
1340
|
-
* await thread.post(`${emoji.thumbs_up} Great job!`);
|
|
1341
|
-
*
|
|
1342
|
-
* // JSX Card (with @jsxImportSource chat)
|
|
1343
|
-
* await thread.post(
|
|
1344
|
-
* <Card title="Welcome!">
|
|
1345
|
-
* <Text>Hello world</Text>
|
|
1346
|
-
* </Card>
|
|
1347
|
-
* );
|
|
1348
|
-
*
|
|
1349
|
-
* // Stream from AI SDK
|
|
1350
|
-
* const result = await agent.stream({ prompt: message.text });
|
|
1351
|
-
* await thread.post(result.textStream);
|
|
1352
|
-
*
|
|
1353
|
-
* // Stream with options via StreamingPlan PostableObject
|
|
1354
|
-
* const stream = new StreamingPlan(result.fullStream, {
|
|
1355
|
-
* groupTasks: "plan",
|
|
1356
|
-
* endWith: [feedbackBlocks],
|
|
1357
|
-
* });
|
|
1358
|
-
* await thread.post(stream);
|
|
1359
|
-
*
|
|
1360
|
-
* // Plan with live updates
|
|
1361
|
-
* const plan = new Plan({ initialMessage: "Working..." });
|
|
1362
|
-
* await thread.post(plan);
|
|
1363
|
-
* await plan.addTask({ title: "Step 1" });
|
|
1364
|
-
* await plan.complete({ completeMessage: "Done!" });
|
|
1365
|
-
* ```
|
|
1366
|
-
*/
|
|
1367
|
-
post<T extends PostableObject>(message: T): Promise<T>;
|
|
1368
|
-
post(message: string | PostableMessage | ChatElement): Promise<SentMessage<TRawMessage>>;
|
|
1369
|
-
/**
|
|
1370
|
-
* Post an ephemeral message visible only to a specific user.
|
|
1371
|
-
*
|
|
1372
|
-
* **Platform Behavior:**
|
|
1373
|
-
* - **Slack**: Native ephemeral (session-dependent, disappears on reload)
|
|
1374
|
-
* - **Google Chat**: Native private message (persists, only target user sees it)
|
|
1375
|
-
* - **Discord**: No native support - requires fallbackToDM: true
|
|
1376
|
-
* - **Teams**: No native support - requires fallbackToDM: true
|
|
1377
|
-
*
|
|
1378
|
-
* @param user - User ID string or Author object (from message.author or event.user)
|
|
1379
|
-
* @param message - Message content (string, markdown, card, etc.). Streaming is not supported.
|
|
1380
|
-
* @param options.fallbackToDM - Required. If true, falls back to DM when native
|
|
1381
|
-
* ephemeral is not supported. If false, returns null when unsupported.
|
|
1382
|
-
* @returns EphemeralMessage with `usedFallback: true` if DM was used, or null
|
|
1383
|
-
* if native ephemeral not supported and fallbackToDM is false
|
|
1384
|
-
*
|
|
1385
|
-
* @example
|
|
1386
|
-
* ```typescript
|
|
1387
|
-
* // Always send (DM fallback on Discord/Teams)
|
|
1388
|
-
* await thread.postEphemeral(user, 'Only you can see this!', { fallbackToDM: true })
|
|
1389
|
-
*
|
|
1390
|
-
* // Only send if native ephemeral supported (Slack/GChat)
|
|
1391
|
-
* const result = await thread.postEphemeral(user, 'Secret!', { fallbackToDM: false })
|
|
1392
|
-
* if (!result) {
|
|
1393
|
-
* // Platform doesn't support native ephemeral - handle accordingly
|
|
1394
|
-
* }
|
|
1395
|
-
* ```
|
|
1396
|
-
*/
|
|
1397
|
-
postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage<TRawMessage> | null>;
|
|
1398
|
-
/** Recently fetched messages (cached) */
|
|
1399
|
-
recentMessages: Message<TRawMessage>[];
|
|
1400
|
-
/**
|
|
1401
|
-
* Refresh `recentMessages` from the API.
|
|
1402
|
-
*
|
|
1403
|
-
* Fetches the latest 50 messages and updates `recentMessages`.
|
|
1404
|
-
*/
|
|
1405
|
-
refresh(): Promise<void>;
|
|
1406
|
-
/**
|
|
1407
|
-
* Show typing indicator in the thread.
|
|
1408
|
-
*
|
|
1409
|
-
* Some platforms support persistent typing indicators, others just send once.
|
|
1410
|
-
* Optional status (e.g. "Typing...", "Searching documents...") is shown where supported.
|
|
1411
|
-
*/
|
|
1412
|
-
startTyping(status?: string): Promise<void>;
|
|
1413
|
-
/**
|
|
1414
|
-
* Subscribe to future messages in this thread.
|
|
1415
|
-
*
|
|
1416
|
-
* Once subscribed, all messages in this thread will trigger `onSubscribedMessage` handlers.
|
|
1417
|
-
* The initial message that triggered subscription will NOT fire the handler.
|
|
1418
|
-
*
|
|
1419
|
-
* @example
|
|
1420
|
-
* ```typescript
|
|
1421
|
-
* chat.onNewMention(async (thread, message) => {
|
|
1422
|
-
* await thread.subscribe(); // Subscribe to follow-up messages
|
|
1423
|
-
* await thread.post("I'm now watching this thread!");
|
|
1424
|
-
* });
|
|
1425
|
-
* ```
|
|
1426
|
-
*/
|
|
1427
|
-
subscribe(): Promise<void>;
|
|
1428
|
-
/**
|
|
1429
|
-
* Serialize the thread to a plain JSON object.
|
|
1430
|
-
* Use this to pass thread data to external systems like workflow engines.
|
|
1431
|
-
*/
|
|
1432
|
-
toJSON(): SerializedThread;
|
|
1433
|
-
/**
|
|
1434
|
-
* Unsubscribe from this thread.
|
|
1435
|
-
*
|
|
1436
|
-
* Future messages will no longer trigger `onSubscribedMessage` handlers.
|
|
1437
|
-
*/
|
|
1438
|
-
unsubscribe(): Promise<void>;
|
|
1439
|
-
}
|
|
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
|
-
}
|
|
1459
|
-
interface ThreadInfo {
|
|
1460
|
-
channelId: string;
|
|
1461
|
-
channelName?: string;
|
|
1462
|
-
/** The visibility scope of this channel */
|
|
1463
|
-
channelVisibility?: ChannelVisibility;
|
|
1464
|
-
id: string;
|
|
1465
|
-
/** Whether this is a direct message conversation */
|
|
1466
|
-
isDM?: boolean;
|
|
1467
|
-
/** Platform-specific metadata */
|
|
1468
|
-
metadata: Record<string, unknown>;
|
|
1469
|
-
}
|
|
1470
|
-
/**
|
|
1471
|
-
* Direction for fetching messages.
|
|
1472
|
-
*
|
|
1473
|
-
* - `backward`: Fetch most recent messages first. Pagination moves toward older messages.
|
|
1474
|
-
* This is the default, suitable for loading a chat view (show latest messages first).
|
|
1475
|
-
*
|
|
1476
|
-
* - `forward`: Fetch oldest messages first. Pagination moves toward newer messages.
|
|
1477
|
-
* Suitable for iterating through message history from the beginning.
|
|
1478
|
-
*
|
|
1479
|
-
* In both directions, messages within each page are returned in chronological order
|
|
1480
|
-
* (oldest first), which is the natural reading order for chat messages.
|
|
1481
|
-
*
|
|
1482
|
-
* @example
|
|
1483
|
-
* ```typescript
|
|
1484
|
-
* // Load most recent 50 messages (default)
|
|
1485
|
-
* const recent = await adapter.fetchMessages(threadId, { limit: 50 });
|
|
1486
|
-
* // recent.messages: [older, ..., newest] (chronological within page)
|
|
1487
|
-
* // recent.nextCursor: points to older messages
|
|
1488
|
-
*
|
|
1489
|
-
* // Iterate through all history from beginning
|
|
1490
|
-
* const history = await adapter.fetchMessages(threadId, {
|
|
1491
|
-
* limit: 50,
|
|
1492
|
-
* direction: 'forward',
|
|
1493
|
-
* });
|
|
1494
|
-
* // history.messages: [oldest, ..., newer] (chronological within page)
|
|
1495
|
-
* // history.nextCursor: points to even newer messages
|
|
1496
|
-
* ```
|
|
1497
|
-
*/
|
|
1498
|
-
type FetchDirection = "forward" | "backward";
|
|
1499
|
-
/**
|
|
1500
|
-
* Options for fetching messages from a thread.
|
|
1501
|
-
*/
|
|
1502
|
-
interface FetchOptions {
|
|
1503
|
-
/**
|
|
1504
|
-
* Pagination cursor for fetching the next page of messages.
|
|
1505
|
-
* Pass the `nextCursor` from a previous `FetchResult`.
|
|
1506
|
-
*/
|
|
1507
|
-
cursor?: string;
|
|
1508
|
-
/**
|
|
1509
|
-
* Direction to fetch messages.
|
|
1510
|
-
*
|
|
1511
|
-
* - `backward` (default): Fetch most recent messages. Cursor moves to older messages.
|
|
1512
|
-
* - `forward`: Fetch oldest messages. Cursor moves to newer messages.
|
|
1513
|
-
*
|
|
1514
|
-
* Messages within each page are always returned in chronological order (oldest first).
|
|
1515
|
-
*/
|
|
1516
|
-
direction?: FetchDirection;
|
|
1517
|
-
/** Maximum number of messages to fetch. Default varies by adapter (50-100). */
|
|
1518
|
-
limit?: number;
|
|
1519
|
-
}
|
|
1520
|
-
/**
|
|
1521
|
-
* Result of fetching messages from a thread.
|
|
1522
|
-
*/
|
|
1523
|
-
interface FetchResult<TRawMessage = unknown> {
|
|
1524
|
-
/**
|
|
1525
|
-
* Messages in chronological order (oldest first within this page).
|
|
1526
|
-
*
|
|
1527
|
-
* For `direction: 'backward'` (default): These are the N most recent messages.
|
|
1528
|
-
* For `direction: 'forward'`: These are the N oldest messages (or next N after cursor).
|
|
1529
|
-
*/
|
|
1530
|
-
messages: Message<TRawMessage>[];
|
|
1531
|
-
/**
|
|
1532
|
-
* Cursor for fetching the next page.
|
|
1533
|
-
* Pass this as `cursor` in the next `fetchMessages` call.
|
|
1534
|
-
*
|
|
1535
|
-
* - For `direction: 'backward'`: Points to older messages.
|
|
1536
|
-
* - For `direction: 'forward'`: Points to newer messages.
|
|
1537
|
-
*
|
|
1538
|
-
* Undefined if there are no more messages in that direction.
|
|
1539
|
-
*/
|
|
1540
|
-
nextCursor?: string;
|
|
1541
|
-
}
|
|
1542
|
-
/**
|
|
1543
|
-
* Formatted content using mdast AST.
|
|
1544
|
-
* This is the canonical representation of message formatting.
|
|
1545
|
-
*/
|
|
1546
|
-
type FormattedContent = Root;
|
|
1547
|
-
/** Raw message returned from adapter (before wrapping as SentMessage) */
|
|
1548
|
-
interface RawMessage<TRawMessage = unknown> {
|
|
1549
|
-
id: string;
|
|
1550
|
-
raw: TRawMessage;
|
|
1551
|
-
threadId: string;
|
|
1552
|
-
}
|
|
1553
|
-
interface Author {
|
|
1554
|
-
/** Display name */
|
|
1555
|
-
fullName: string;
|
|
1556
|
-
/** Whether the author is a bot */
|
|
1557
|
-
isBot: boolean | "unknown";
|
|
1558
|
-
/** Whether the author is this bot */
|
|
1559
|
-
isMe: boolean;
|
|
1560
|
-
/** Unique user ID */
|
|
1561
|
-
userId: string;
|
|
1562
|
-
/** Username/handle for @-mentions */
|
|
1563
|
-
userName: string;
|
|
1564
|
-
}
|
|
1565
|
-
/** User information returned by adapter.getUser() */
|
|
1566
|
-
interface UserInfo {
|
|
1567
|
-
/** URL to the user's avatar/profile image */
|
|
1568
|
-
avatarUrl?: string;
|
|
1569
|
-
/** User's email address (requires appropriate scopes on some platforms) */
|
|
1570
|
-
email?: string;
|
|
1571
|
-
/** User's display name / full name */
|
|
1572
|
-
fullName: string;
|
|
1573
|
-
/** Whether the user is a bot */
|
|
1574
|
-
isBot: boolean;
|
|
1575
|
-
/** Platform-specific user ID */
|
|
1576
|
-
userId: string;
|
|
1577
|
-
/** Username/handle */
|
|
1578
|
-
userName: string;
|
|
1579
|
-
}
|
|
1580
|
-
interface MessageMetadata {
|
|
1581
|
-
/** When the message was sent */
|
|
1582
|
-
dateSent: Date;
|
|
1583
|
-
/** Whether the message has been edited */
|
|
1584
|
-
edited: boolean;
|
|
1585
|
-
/** When the message was last edited */
|
|
1586
|
-
editedAt?: Date;
|
|
1587
|
-
}
|
|
1588
|
-
interface SentMessage<TRawMessage = unknown> extends Omit<Message<TRawMessage>, "subject"> {
|
|
1589
|
-
/** Add a reaction to this message */
|
|
1590
|
-
addReaction(emoji: EmojiValue | string): Promise<void>;
|
|
1591
|
-
/** Delete this message */
|
|
1592
|
-
delete(): Promise<void>;
|
|
1593
|
-
/** Edit this message with text, a PostableMessage, or a JSX Card element */
|
|
1594
|
-
edit(newContent: string | PostableMessage | ChatElement): Promise<SentMessage<TRawMessage>>;
|
|
1595
|
-
/** Remove a reaction from this message */
|
|
1596
|
-
removeReaction(emoji: EmojiValue | string): Promise<void>;
|
|
1597
|
-
}
|
|
1598
|
-
/**
|
|
1599
|
-
* Result of posting an ephemeral message.
|
|
1600
|
-
*
|
|
1601
|
-
* Ephemeral messages are visible only to a specific user and typically
|
|
1602
|
-
* cannot be edited or deleted (platform-dependent).
|
|
1603
|
-
*/
|
|
1604
|
-
interface EphemeralMessage<TRawMessage = unknown> {
|
|
1605
|
-
/** Message ID (may be empty for some platforms) */
|
|
1606
|
-
id: string;
|
|
1607
|
-
/** Platform-specific raw response */
|
|
1608
|
-
raw: TRawMessage;
|
|
1609
|
-
/** Thread ID where message was sent (or DM thread if fallback was used) */
|
|
1610
|
-
threadId: string;
|
|
1611
|
-
/** Whether this used native ephemeral or fell back to DM */
|
|
1612
|
-
usedFallback: boolean;
|
|
1613
|
-
}
|
|
1614
|
-
/**
|
|
1615
|
-
* Options for posting ephemeral messages.
|
|
1616
|
-
*/
|
|
1617
|
-
interface PostEphemeralOptions {
|
|
1618
|
-
/**
|
|
1619
|
-
* Controls behavior when native ephemeral is not supported by the platform.
|
|
1620
|
-
*
|
|
1621
|
-
* - `true`: Falls back to sending a DM to the user
|
|
1622
|
-
* - `false`: Returns `null` if native ephemeral is not supported
|
|
1623
|
-
*/
|
|
1624
|
-
fallbackToDM: boolean;
|
|
1625
|
-
}
|
|
1626
|
-
/**
|
|
1627
|
-
* Result of scheduling a message for future delivery.
|
|
1628
|
-
*
|
|
1629
|
-
* Currently only supported by the Slack adapter via `chat.scheduleMessage`.
|
|
1630
|
-
* Other adapters will throw `NotImplementedError` when `schedule()` is called.
|
|
1631
|
-
*/
|
|
1632
|
-
interface ScheduledMessage<TRawMessage = unknown> {
|
|
1633
|
-
/** Cancel the scheduled message before it's sent */
|
|
1634
|
-
cancel(): Promise<void>;
|
|
1635
|
-
/** Channel ID where the message will be posted */
|
|
1636
|
-
channelId: string;
|
|
1637
|
-
/** When the message will be sent */
|
|
1638
|
-
postAt: Date;
|
|
1639
|
-
/** Platform-specific raw response */
|
|
1640
|
-
raw: TRawMessage;
|
|
1641
|
-
/** Platform-specific scheduled message ID */
|
|
1642
|
-
scheduledMessageId: string;
|
|
1643
|
-
}
|
|
1644
|
-
/**
|
|
1645
|
-
* Input type for adapter postMessage/editMessage methods.
|
|
1646
|
-
* This excludes streams since adapters handle content synchronously.
|
|
1647
|
-
*/
|
|
1648
|
-
type AdapterPostableMessage = string | PostableRaw | PostableMarkdown | PostableAst | PostableCard | CardElement;
|
|
1649
|
-
/**
|
|
1650
|
-
* A message that can be posted to a thread.
|
|
1651
|
-
*
|
|
1652
|
-
* - `string` - Raw text, passed through as-is to the platform
|
|
1653
|
-
* - `{ raw: string }` - Explicit raw text, passed through as-is
|
|
1654
|
-
* - `{ markdown: string }` - Markdown text, converted to platform format
|
|
1655
|
-
* - `{ ast: Root }` - mdast AST, converted to platform format
|
|
1656
|
-
* - `{ card: CardElement }` - Rich card with buttons (Block Kit / Adaptive Cards / GChat Cards)
|
|
1657
|
-
* - `CardElement` - Direct card element
|
|
1658
|
-
* - `AsyncIterable<string>` - Streaming text (e.g., from AI SDK's textStream)
|
|
1659
|
-
* - `AsyncIterable<string | StreamEvent>` - AI SDK fullStream (auto-detected, extracts text with step separators)
|
|
1660
|
-
*/
|
|
1661
|
-
type PostableMessage = AdapterPostableMessage | AsyncIterable<string | StreamChunk | StreamEvent> | PostableObject;
|
|
1662
|
-
/**
|
|
1663
|
-
* Duck-typed stream event compatible with AI SDK's `fullStream`.
|
|
1664
|
-
* - `text-delta` events are extracted as text output.
|
|
1665
|
-
* - `finish-step` events trigger paragraph separators between steps.
|
|
1666
|
-
* - All other event types (tool-call, tool-result, etc.) are silently skipped.
|
|
1667
|
-
*/
|
|
1668
|
-
type StreamEvent = {
|
|
1669
|
-
textDelta: string;
|
|
1670
|
-
type: "text-delta";
|
|
1671
|
-
} | {
|
|
1672
|
-
type: "finish-step";
|
|
1673
|
-
} | {
|
|
1674
|
-
type: string;
|
|
1675
|
-
};
|
|
1676
|
-
interface PostableRaw {
|
|
1677
|
-
/** File/image attachments */
|
|
1678
|
-
attachments?: Attachment[];
|
|
1679
|
-
/** Files to upload */
|
|
1680
|
-
files?: FileUpload[];
|
|
1681
|
-
/** Raw text passed through as-is to the platform */
|
|
1682
|
-
raw: string;
|
|
1683
|
-
}
|
|
1684
|
-
interface PostableMarkdown {
|
|
1685
|
-
/** File/image attachments */
|
|
1686
|
-
attachments?: Attachment[];
|
|
1687
|
-
/** Files to upload */
|
|
1688
|
-
files?: FileUpload[];
|
|
1689
|
-
/** Markdown text, converted to platform format */
|
|
1690
|
-
markdown: string;
|
|
1691
|
-
}
|
|
1692
|
-
interface PostableAst {
|
|
1693
|
-
/** mdast AST, converted to platform format */
|
|
1694
|
-
ast: Root;
|
|
1695
|
-
/** File/image attachments */
|
|
1696
|
-
attachments?: Attachment[];
|
|
1697
|
-
/** Files to upload */
|
|
1698
|
-
files?: FileUpload[];
|
|
1699
|
-
}
|
|
1700
|
-
interface PostableCard {
|
|
1701
|
-
/** Rich card element */
|
|
1702
|
-
card: CardElement;
|
|
1703
|
-
/** Fallback text for platforms/clients that can't render cards */
|
|
1704
|
-
fallbackText?: string;
|
|
1705
|
-
/** Files to upload */
|
|
1706
|
-
files?: FileUpload[];
|
|
1707
|
-
}
|
|
1708
|
-
interface Attachment {
|
|
1709
|
-
/** Binary data (for uploading or if already fetched) */
|
|
1710
|
-
data?: Buffer | Blob;
|
|
1711
|
-
/**
|
|
1712
|
-
* Fetch the attachment data.
|
|
1713
|
-
* For platforms that require authentication (like Slack private URLs),
|
|
1714
|
-
* this method handles the auth automatically.
|
|
1715
|
-
*/
|
|
1716
|
-
fetchData?: () => Promise<Buffer>;
|
|
1717
|
-
/**
|
|
1718
|
-
* Platform-specific metadata needed to reconstruct fetchData after serialization.
|
|
1719
|
-
* Adapters store IDs here (e.g. WhatsApp mediaId, Telegram fileId) so that
|
|
1720
|
-
* fetchData can be rebuilt when a message is rehydrated from the queue.
|
|
1721
|
-
*/
|
|
1722
|
-
fetchMetadata?: Record<string, string>;
|
|
1723
|
-
/** Image/video height (if applicable) */
|
|
1724
|
-
height?: number;
|
|
1725
|
-
/** MIME type */
|
|
1726
|
-
mimeType?: string;
|
|
1727
|
-
/** Filename */
|
|
1728
|
-
name?: string;
|
|
1729
|
-
/** File size in bytes */
|
|
1730
|
-
size?: number;
|
|
1731
|
-
/** Type of attachment */
|
|
1732
|
-
type: "image" | "file" | "video" | "audio";
|
|
1733
|
-
/** URL to the file (for linking/downloading) */
|
|
1734
|
-
url?: string;
|
|
1735
|
-
/** Image/video width (if applicable) */
|
|
1736
|
-
width?: number;
|
|
1737
|
-
}
|
|
1738
|
-
/**
|
|
1739
|
-
* A link found in a message, with optional unfurl metadata.
|
|
1740
|
-
*
|
|
1741
|
-
* On the initial message event, only `url` is available (unfurl metadata
|
|
1742
|
-
* arrives later via `message_changed`). The `fetchMessage` callback is
|
|
1743
|
-
* provided when the URL points to another chat message on the same platform.
|
|
1744
|
-
*/
|
|
1745
|
-
interface LinkPreview {
|
|
1746
|
-
/** Description from unfurl metadata (if available) */
|
|
1747
|
-
description?: string;
|
|
1748
|
-
/** If this links to a chat message, fetch the full Message */
|
|
1749
|
-
fetchMessage?: () => Promise<Message>;
|
|
1750
|
-
/** Preview image URL (if available) */
|
|
1751
|
-
imageUrl?: string;
|
|
1752
|
-
/** Site name (e.g., "Vercel") */
|
|
1753
|
-
siteName?: string;
|
|
1754
|
-
/** Title from unfurl metadata (if available) */
|
|
1755
|
-
title?: string;
|
|
1756
|
-
/** The URL */
|
|
1757
|
-
url: string;
|
|
1758
|
-
}
|
|
1759
|
-
/**
|
|
1760
|
-
* File to upload with a message.
|
|
1761
|
-
*/
|
|
1762
|
-
interface FileUpload {
|
|
1763
|
-
/** Binary data */
|
|
1764
|
-
data: Buffer | Blob | ArrayBuffer;
|
|
1765
|
-
/** Filename */
|
|
1766
|
-
filename: string;
|
|
1767
|
-
/** MIME type (optional, will be inferred from filename if not provided) */
|
|
1768
|
-
mimeType?: string;
|
|
1769
|
-
}
|
|
1770
|
-
/**
|
|
1771
|
-
* Handler for new @-mentions of the bot.
|
|
1772
|
-
*
|
|
1773
|
-
* **Important**: This handler is ONLY called for mentions in **unsubscribed** threads.
|
|
1774
|
-
* Once a thread is subscribed (via `thread.subscribe()`), subsequent messages
|
|
1775
|
-
* including @-mentions go to `onSubscribedMessage` handlers instead.
|
|
1776
|
-
*
|
|
1777
|
-
* To detect mentions in subscribed threads, check `message.isMention`:
|
|
1778
|
-
*
|
|
1779
|
-
* @example
|
|
1780
|
-
* ```typescript
|
|
1781
|
-
* // Handle new mentions (unsubscribed threads only)
|
|
1782
|
-
* chat.onNewMention(async (thread, message) => {
|
|
1783
|
-
* await thread.subscribe(); // Subscribe to follow-up messages
|
|
1784
|
-
* await thread.post("Hello! I'll be watching this thread.");
|
|
1785
|
-
* });
|
|
1786
|
-
*
|
|
1787
|
-
* // Handle all messages in subscribed threads
|
|
1788
|
-
* chat.onSubscribedMessage(async (thread, message) => {
|
|
1789
|
-
* if (message.isMention) {
|
|
1790
|
-
* // User @-mentioned us in a thread we're already watching
|
|
1791
|
-
* await thread.post("You mentioned me again!");
|
|
1792
|
-
* }
|
|
1793
|
-
* });
|
|
1794
|
-
* ```
|
|
1795
|
-
*/
|
|
1796
|
-
type MentionHandler<TState = Record<string, unknown>> = (thread: Thread<TState>, message: Message, context?: MessageContext) => void | Promise<void>;
|
|
1797
|
-
/**
|
|
1798
|
-
* Handler for direct messages (1:1 conversations with the bot).
|
|
1799
|
-
*
|
|
1800
|
-
* Registered via `chat.onDirectMessage(handler)`. Called when a message
|
|
1801
|
-
* is received in a DM thread that is not subscribed. If no `onDirectMessage`
|
|
1802
|
-
* handlers are registered, DMs fall through to `onNewMention` for backward
|
|
1803
|
-
* compatibility.
|
|
1804
|
-
*/
|
|
1805
|
-
type DirectMessageHandler<TState = Record<string, unknown>> = (thread: Thread<TState>, message: Message, channel: Channel<TState>, context?: MessageContext) => void | Promise<void>;
|
|
1806
|
-
/**
|
|
1807
|
-
* Handler for messages matching a regex pattern.
|
|
1808
|
-
*
|
|
1809
|
-
* Registered via `chat.onNewMessage(pattern, handler)`. Called when a message
|
|
1810
|
-
* matches the pattern in an unsubscribed thread.
|
|
1811
|
-
*/
|
|
1812
|
-
type MessageHandler<TState = Record<string, unknown>> = (thread: Thread<TState>, message: Message, context?: MessageContext) => void | Promise<void>;
|
|
1813
|
-
/**
|
|
1814
|
-
* Handler for messages in subscribed threads.
|
|
1815
|
-
*
|
|
1816
|
-
* Called for all messages in threads that have been subscribed via `thread.subscribe()`.
|
|
1817
|
-
* This includes:
|
|
1818
|
-
* - Follow-up messages from users
|
|
1819
|
-
* - Messages that @-mention the bot (check `message.isMention`)
|
|
1820
|
-
*
|
|
1821
|
-
* Does NOT fire for:
|
|
1822
|
-
* - The message that triggered the subscription (e.g., the initial @mention)
|
|
1823
|
-
* - Messages sent by the bot itself
|
|
1824
|
-
*
|
|
1825
|
-
* @example
|
|
1826
|
-
* ```typescript
|
|
1827
|
-
* chat.onSubscribedMessage(async (thread, message) => {
|
|
1828
|
-
* // Handle all follow-up messages
|
|
1829
|
-
* if (message.isMention) {
|
|
1830
|
-
* // User @-mentioned us in a subscribed thread
|
|
1831
|
-
* }
|
|
1832
|
-
* await thread.post(`Got your message: ${message.text}`);
|
|
1833
|
-
* });
|
|
1834
|
-
* ```
|
|
1835
|
-
*/
|
|
1836
|
-
type SubscribedMessageHandler<TState = Record<string, unknown>> = (thread: Thread<TState>, message: Message, context?: MessageContext) => void | Promise<void>;
|
|
1837
|
-
/**
|
|
1838
|
-
* Well-known emoji that work across platforms (Slack and Google Chat).
|
|
1839
|
-
* These are normalized to a common format regardless of platform.
|
|
1840
|
-
*/
|
|
1841
|
-
type WellKnownEmoji = "thumbs_up" | "thumbs_down" | "clap" | "wave" | "pray" | "muscle" | "ok_hand" | "point_up" | "point_down" | "point_left" | "point_right" | "raised_hands" | "shrug" | "facepalm" | "heart" | "smile" | "laugh" | "thinking" | "sad" | "cry" | "angry" | "love_eyes" | "cool" | "wink" | "surprised" | "worried" | "confused" | "neutral" | "sleeping" | "sick" | "mind_blown" | "relieved" | "grimace" | "rolling_eyes" | "hug" | "zany" | "check" | "x" | "question" | "exclamation" | "warning" | "stop" | "info" | "100" | "fire" | "star" | "sparkles" | "lightning" | "boom" | "eyes" | "green_circle" | "yellow_circle" | "red_circle" | "blue_circle" | "white_circle" | "black_circle" | "rocket" | "party" | "confetti" | "balloon" | "gift" | "trophy" | "medal" | "lightbulb" | "gear" | "wrench" | "hammer" | "bug" | "link" | "lock" | "unlock" | "key" | "pin" | "memo" | "clipboard" | "calendar" | "clock" | "hourglass" | "bell" | "megaphone" | "speech_bubble" | "email" | "inbox" | "outbox" | "package" | "folder" | "file" | "chart_up" | "chart_down" | "coffee" | "pizza" | "beer" | "arrow_up" | "arrow_down" | "arrow_left" | "arrow_right" | "refresh" | "sun" | "cloud" | "rain" | "snow" | "rainbow";
|
|
1842
|
-
/**
|
|
1843
|
-
* Platform-specific emoji formats for a single emoji.
|
|
1844
|
-
*/
|
|
1845
|
-
interface EmojiFormats {
|
|
1846
|
-
/** Google Chat unicode emoji, e.g., "👍", "❤️" */
|
|
1847
|
-
gchat: string | string[];
|
|
1848
|
-
/** Slack emoji name (without colons), e.g., "+1", "heart" */
|
|
1849
|
-
slack: string | string[];
|
|
1850
|
-
}
|
|
1851
|
-
/**
|
|
1852
|
-
* Emoji map type - can be extended by users to add custom emoji.
|
|
1853
|
-
*
|
|
1854
|
-
* @example
|
|
1855
|
-
* ```typescript
|
|
1856
|
-
* // Extend with custom emoji
|
|
1857
|
-
* declare module "chat" {
|
|
1858
|
-
* interface CustomEmojiMap {
|
|
1859
|
-
* "custom_emoji": EmojiFormats;
|
|
1860
|
-
* }
|
|
1861
|
-
* }
|
|
1862
|
-
*
|
|
1863
|
-
* const myEmojiMap: EmojiMapConfig = {
|
|
1864
|
-
* custom_emoji: { slack: "custom", gchat: "🎯" },
|
|
1865
|
-
* };
|
|
1866
|
-
* ```
|
|
1867
|
-
*/
|
|
1868
|
-
interface CustomEmojiMap {
|
|
1869
|
-
}
|
|
1870
|
-
/**
|
|
1871
|
-
* Full emoji type including well-known and custom emoji.
|
|
1872
|
-
*/
|
|
1873
|
-
type Emoji = WellKnownEmoji | keyof CustomEmojiMap;
|
|
1874
|
-
/**
|
|
1875
|
-
* Configuration for emoji mapping.
|
|
1876
|
-
*/
|
|
1877
|
-
type EmojiMapConfig = Partial<Record<Emoji, EmojiFormats>>;
|
|
1878
|
-
/**
|
|
1879
|
-
* Immutable emoji value object with object identity.
|
|
1880
|
-
*
|
|
1881
|
-
* These objects are singletons - the same emoji name always returns
|
|
1882
|
-
* the same frozen object instance, enabling `===` comparison.
|
|
1883
|
-
*
|
|
1884
|
-
* @example
|
|
1885
|
-
* ```typescript
|
|
1886
|
-
* // Object identity comparison works
|
|
1887
|
-
* if (event.emoji === emoji.thumbs_up) {
|
|
1888
|
-
* console.log("User gave a thumbs up!");
|
|
1889
|
-
* }
|
|
1890
|
-
*
|
|
1891
|
-
* // Works in template strings via toString()
|
|
1892
|
-
* await thread.post(`${emoji.thumbs_up} Great job!`);
|
|
1893
|
-
* ```
|
|
1894
|
-
*/
|
|
1895
|
-
interface EmojiValue {
|
|
1896
|
-
/** The normalized emoji name (e.g., "thumbs_up") */
|
|
1897
|
-
readonly name: string;
|
|
1898
|
-
/** Returns the placeholder string (for JSON.stringify) */
|
|
1899
|
-
toJSON(): string;
|
|
1900
|
-
/** Returns the placeholder string for message formatting */
|
|
1901
|
-
toString(): string;
|
|
1902
|
-
}
|
|
1903
|
-
/**
|
|
1904
|
-
* Reaction event fired when a user adds or removes a reaction.
|
|
1905
|
-
*/
|
|
1906
|
-
interface ReactionEvent<TRawMessage = unknown> {
|
|
1907
|
-
/** The adapter that received the event */
|
|
1908
|
-
adapter: Adapter;
|
|
1909
|
-
/** Whether the reaction was added (true) or removed (false) */
|
|
1910
|
-
added: boolean;
|
|
1911
|
-
/** The normalized emoji as an EmojiValue singleton (enables `===` comparison) */
|
|
1912
|
-
emoji: EmojiValue;
|
|
1913
|
-
/** The message that was reacted to (if available) */
|
|
1914
|
-
message?: Message<TRawMessage>;
|
|
1915
|
-
/** The message ID that was reacted to */
|
|
1916
|
-
messageId: string;
|
|
1917
|
-
/** Platform-specific raw event data */
|
|
1918
|
-
raw: unknown;
|
|
1919
|
-
/** The raw platform-specific emoji (e.g., "+1" for Slack, "👍" for GChat) */
|
|
1920
|
-
rawEmoji: string;
|
|
1921
|
-
/**
|
|
1922
|
-
* The thread where the reaction occurred.
|
|
1923
|
-
* Use this to post replies or check subscription status.
|
|
1924
|
-
*
|
|
1925
|
-
* @example
|
|
1926
|
-
* ```typescript
|
|
1927
|
-
* chat.onReaction([emoji.thumbs_up], async (event) => {
|
|
1928
|
-
* await event.thread.post(`Thanks for the ${event.emoji}!`);
|
|
1929
|
-
* });
|
|
1930
|
-
* ```
|
|
1931
|
-
*/
|
|
1932
|
-
thread: Thread<TRawMessage>;
|
|
1933
|
-
/** The thread ID */
|
|
1934
|
-
threadId: string;
|
|
1935
|
-
/** The user who added/removed the reaction */
|
|
1936
|
-
user: Author;
|
|
1937
|
-
}
|
|
1938
|
-
/**
|
|
1939
|
-
* Handler for reaction events.
|
|
1940
|
-
*
|
|
1941
|
-
* @example
|
|
1942
|
-
* ```typescript
|
|
1943
|
-
* // Handle specific emoji
|
|
1944
|
-
* chat.onReaction(["thumbs_up", "heart"], async (event) => {
|
|
1945
|
-
* console.log(`${event.user.userName} ${event.added ? "added" : "removed"} ${event.emoji}`);
|
|
1946
|
-
* });
|
|
1947
|
-
*
|
|
1948
|
-
* // Handle all reactions
|
|
1949
|
-
* chat.onReaction(async (event) => {
|
|
1950
|
-
* // ...
|
|
1951
|
-
* });
|
|
1952
|
-
* ```
|
|
1953
|
-
*/
|
|
1954
|
-
type ReactionHandler = (event: ReactionEvent) => void | Promise<void>;
|
|
1955
|
-
/**
|
|
1956
|
-
* Action event fired when a user clicks a button in a card.
|
|
1957
|
-
*
|
|
1958
|
-
* @example
|
|
1959
|
-
* ```typescript
|
|
1960
|
-
* chat.onAction("approve", async (event) => {
|
|
1961
|
-
* await event.thread.post(`Order ${event.value} approved by ${event.user.userName}`);
|
|
1962
|
-
* });
|
|
1963
|
-
* ```
|
|
1964
|
-
*/
|
|
1965
|
-
interface ActionEvent<TRawMessage = unknown> {
|
|
1966
|
-
/** The action ID from the button (matches Button's `id` prop) */
|
|
1967
|
-
actionId: string;
|
|
1968
|
-
/** The adapter that received the event */
|
|
1969
|
-
adapter: Adapter;
|
|
1970
|
-
/** The message ID containing the card */
|
|
1971
|
-
messageId: string;
|
|
1972
|
-
/**
|
|
1973
|
-
* Open a modal/dialog form in response to this action.
|
|
1974
|
-
*
|
|
1975
|
-
* @param modal - The modal element to display (JSX or ModalElement)
|
|
1976
|
-
* @returns The view/dialog ID, or undefined if modals are not supported
|
|
1977
|
-
*/
|
|
1978
|
-
openModal(modal: ModalElement | ChatElement): Promise<{
|
|
1979
|
-
viewId: string;
|
|
1980
|
-
} | undefined>;
|
|
1981
|
-
/** Platform-specific raw event data */
|
|
1982
|
-
raw: unknown;
|
|
1983
|
-
/** The thread where the action occurred (null for view-based actions like home tab buttons) */
|
|
1984
|
-
thread: Thread<TRawMessage> | null;
|
|
1985
|
-
/** The thread ID */
|
|
1986
|
-
threadId: string;
|
|
1987
|
-
/** Trigger ID for opening modals (required by some platforms, may expire quickly) */
|
|
1988
|
-
triggerId?: string;
|
|
1989
|
-
/** User who clicked the button */
|
|
1990
|
-
user: Author;
|
|
1991
|
-
/** Optional value/payload from the button */
|
|
1992
|
-
value?: string;
|
|
1993
|
-
}
|
|
1994
|
-
/**
|
|
1995
|
-
* Handler for action events (button clicks in cards).
|
|
1996
|
-
*
|
|
1997
|
-
* @example
|
|
1998
|
-
* ```typescript
|
|
1999
|
-
* // Handle specific action
|
|
2000
|
-
* chat.onAction("approve", async (event) => {
|
|
2001
|
-
* await event.thread.post("Approved!");
|
|
2002
|
-
* });
|
|
2003
|
-
*
|
|
2004
|
-
* // Handle multiple actions
|
|
2005
|
-
* chat.onAction(["approve", "reject"], async (event) => {
|
|
2006
|
-
* if (event.actionId === "approve") {
|
|
2007
|
-
* // ...
|
|
2008
|
-
* }
|
|
2009
|
-
* });
|
|
2010
|
-
*
|
|
2011
|
-
* // Handle all actions (catch-all)
|
|
2012
|
-
* chat.onAction(async (event) => {
|
|
2013
|
-
* console.log(`Action: ${event.actionId}`);
|
|
2014
|
-
* });
|
|
2015
|
-
* ```
|
|
2016
|
-
*/
|
|
2017
|
-
type ActionHandler = (event: ActionEvent) => void | Promise<void>;
|
|
2018
|
-
/**
|
|
2019
|
-
* Event emitted when an adapter needs dynamic options for an external select.
|
|
2020
|
-
*/
|
|
2021
|
-
interface OptionsLoadEvent {
|
|
2022
|
-
/** The action ID of the select requesting options */
|
|
2023
|
-
actionId: string;
|
|
2024
|
-
/** The adapter that received this event */
|
|
2025
|
-
adapter: Adapter;
|
|
2026
|
-
/** The current user-entered query text */
|
|
2027
|
-
query: string;
|
|
2028
|
-
/** Raw platform-specific payload */
|
|
2029
|
-
raw: unknown;
|
|
2030
|
-
/** The user requesting options */
|
|
2031
|
-
user: Author;
|
|
2032
|
-
}
|
|
2033
|
-
interface OptionsLoadGroup {
|
|
2034
|
-
label: string;
|
|
2035
|
-
options: SelectOptionElement[];
|
|
2036
|
-
}
|
|
2037
|
-
type OptionsLoadResult = SelectOptionElement[] | OptionsLoadGroup[];
|
|
2038
|
-
type OptionsLoadHandler = (event: OptionsLoadEvent) => OptionsLoadResult | Promise<OptionsLoadResult | undefined> | undefined;
|
|
2039
|
-
/**
|
|
2040
|
-
* Event emitted when a user submits a modal form.
|
|
2041
|
-
*/
|
|
2042
|
-
interface ModalSubmitEvent<TRawMessage = unknown> {
|
|
2043
|
-
/** The adapter that received this event */
|
|
2044
|
-
adapter: Adapter;
|
|
2045
|
-
/** The callback ID specified when creating the modal */
|
|
2046
|
-
callbackId: string;
|
|
2047
|
-
/**
|
|
2048
|
-
* The private metadata string set when the modal was created.
|
|
2049
|
-
* Use this to pass arbitrary context (e.g., JSON) through the modal lifecycle.
|
|
2050
|
-
*/
|
|
2051
|
-
privateMetadata?: string;
|
|
2052
|
-
/** Raw platform-specific payload */
|
|
2053
|
-
raw: unknown;
|
|
2054
|
-
/**
|
|
2055
|
-
* The channel where the modal was originally triggered from.
|
|
2056
|
-
* Available when the modal was opened via SlashCommandEvent.openModal().
|
|
2057
|
-
*/
|
|
2058
|
-
relatedChannel?: Channel<Record<string, unknown>, TRawMessage>;
|
|
2059
|
-
/**
|
|
2060
|
-
* The message that contained the action which opened the modal.
|
|
2061
|
-
* Available when the modal was opened from a message action via ActionEvent.openModal().
|
|
2062
|
-
* This is a SentMessage with edit/delete capabilities.
|
|
2063
|
-
*/
|
|
2064
|
-
relatedMessage?: SentMessage<TRawMessage>;
|
|
2065
|
-
/**
|
|
2066
|
-
* The thread where the modal was originally triggered from.
|
|
2067
|
-
* Available when the modal was opened via ActionEvent.openModal().
|
|
2068
|
-
*/
|
|
2069
|
-
relatedThread?: Thread<Record<string, unknown>, TRawMessage>;
|
|
2070
|
-
/** The user who submitted the modal */
|
|
2071
|
-
user: Author;
|
|
2072
|
-
/** Form field values keyed by input ID */
|
|
2073
|
-
values: Record<string, string>;
|
|
2074
|
-
/** Platform-specific view/dialog ID */
|
|
2075
|
-
viewId: string;
|
|
2076
|
-
}
|
|
2077
|
-
/**
|
|
2078
|
-
* Event emitted when a user closes/cancels a modal (requires notifyOnClose).
|
|
2079
|
-
*/
|
|
2080
|
-
interface ModalCloseEvent<TRawMessage = unknown> {
|
|
2081
|
-
/** The adapter that received this event */
|
|
2082
|
-
adapter: Adapter;
|
|
2083
|
-
/** The callback ID specified when creating the modal */
|
|
2084
|
-
callbackId: string;
|
|
2085
|
-
/**
|
|
2086
|
-
* The private metadata string set when the modal was created.
|
|
2087
|
-
* Use this to pass arbitrary context (e.g., JSON) through the modal lifecycle.
|
|
2088
|
-
*/
|
|
2089
|
-
privateMetadata?: string;
|
|
2090
|
-
/** Raw platform-specific payload */
|
|
2091
|
-
raw: unknown;
|
|
2092
|
-
/**
|
|
2093
|
-
* The channel where the modal was originally triggered from.
|
|
2094
|
-
* Available when the modal was opened via SlashCommandEvent.openModal().
|
|
2095
|
-
*/
|
|
2096
|
-
relatedChannel?: Channel<Record<string, unknown>, TRawMessage>;
|
|
2097
|
-
/**
|
|
2098
|
-
* The message that contained the action which opened the modal.
|
|
2099
|
-
* Available when the modal was opened from a message action via ActionEvent.openModal().
|
|
2100
|
-
* This is a SentMessage with edit/delete capabilities.
|
|
2101
|
-
*/
|
|
2102
|
-
relatedMessage?: SentMessage<TRawMessage>;
|
|
2103
|
-
/**
|
|
2104
|
-
* The thread where the modal was originally triggered from.
|
|
2105
|
-
* Available when the modal was opened via ActionEvent.openModal().
|
|
2106
|
-
*/
|
|
2107
|
-
relatedThread?: Thread<Record<string, unknown>, TRawMessage>;
|
|
2108
|
-
/** The user who closed the modal */
|
|
2109
|
-
user: Author;
|
|
2110
|
-
/** Platform-specific view/dialog ID */
|
|
2111
|
-
viewId: string;
|
|
2112
|
-
}
|
|
2113
|
-
interface ModalErrorsResponse {
|
|
2114
|
-
action: "errors";
|
|
2115
|
-
errors: Record<string, string>;
|
|
2116
|
-
}
|
|
2117
|
-
interface ModalUpdateResponse {
|
|
2118
|
-
action: "update";
|
|
2119
|
-
modal: ModalElement;
|
|
2120
|
-
}
|
|
2121
|
-
interface ModalPushResponse {
|
|
2122
|
-
action: "push";
|
|
2123
|
-
modal: ModalElement;
|
|
2124
|
-
}
|
|
2125
|
-
interface ModalCloseResponse {
|
|
2126
|
-
action: "close";
|
|
2127
|
-
}
|
|
2128
|
-
interface ModalClearResponse {
|
|
2129
|
-
action: "clear";
|
|
2130
|
-
}
|
|
2131
|
-
type ModalResponse = ModalCloseResponse | ModalClearResponse | ModalErrorsResponse | ModalUpdateResponse | ModalPushResponse;
|
|
2132
|
-
type ModalSubmitHandler = (event: ModalSubmitEvent) => void | Promise<ModalResponse | void | undefined>;
|
|
2133
|
-
type ModalCloseHandler = (event: ModalCloseEvent) => void | Promise<void>;
|
|
2134
|
-
/**
|
|
2135
|
-
* Event emitted when a user invokes a slash command.
|
|
2136
|
-
*
|
|
2137
|
-
* Slash commands are triggered when a user types `/command` in the message composer.
|
|
2138
|
-
* The event provides access to the channel where the command was invoked, allowing
|
|
2139
|
-
* you to post responses using standard SDK methods.
|
|
2140
|
-
*
|
|
2141
|
-
* @example
|
|
2142
|
-
* ```typescript
|
|
2143
|
-
* chat.onSlashCommand("/help", async (event) => {
|
|
2144
|
-
* // Post visible to everyone in the channel
|
|
2145
|
-
* await event.channel.post("Here are the available commands...");
|
|
2146
|
-
* });
|
|
2147
|
-
*
|
|
2148
|
-
* chat.onSlashCommand("/secret", async (event) => {
|
|
2149
|
-
* // Post ephemeral (only the invoking user sees it)
|
|
2150
|
-
* await event.channel.postEphemeral(
|
|
2151
|
-
* event.user,
|
|
2152
|
-
* "This is just for you!",
|
|
2153
|
-
* { fallbackToDM: false }
|
|
2154
|
-
* );
|
|
2155
|
-
* });
|
|
2156
|
-
*
|
|
2157
|
-
* chat.onSlashCommand("/feedback", async (event) => {
|
|
2158
|
-
* // Open a modal
|
|
2159
|
-
* await event.openModal({
|
|
2160
|
-
* type: "modal",
|
|
2161
|
-
* callbackId: "feedback_modal",
|
|
2162
|
-
* title: "Submit Feedback",
|
|
2163
|
-
* children: [{ type: "text_input", id: "feedback", label: "Your feedback" }],
|
|
2164
|
-
* });
|
|
2165
|
-
* });
|
|
2166
|
-
* ```
|
|
2167
|
-
*/
|
|
2168
|
-
interface SlashCommandEvent<TState = Record<string, unknown>> {
|
|
2169
|
-
/** The adapter that received this event */
|
|
2170
|
-
adapter: Adapter;
|
|
2171
|
-
/** The channel where the command was invoked */
|
|
2172
|
-
channel: Channel<TState>;
|
|
2173
|
-
/** The slash command name (e.g., "/help") */
|
|
2174
|
-
command: string;
|
|
2175
|
-
/**
|
|
2176
|
-
* Open a modal/dialog form in response to this slash command.
|
|
2177
|
-
*
|
|
2178
|
-
* @param modal - The modal element to display (JSX or ModalElement)
|
|
2179
|
-
* @returns The view/dialog ID, or undefined if modals are not supported
|
|
2180
|
-
*/
|
|
2181
|
-
openModal(modal: ModalElement | ChatElement): Promise<{
|
|
2182
|
-
viewId: string;
|
|
2183
|
-
} | undefined>;
|
|
2184
|
-
/** Platform-specific raw payload */
|
|
2185
|
-
raw: unknown;
|
|
2186
|
-
/** Arguments text after the command (e.g., "topic search" from "/help topic search") */
|
|
2187
|
-
text: string;
|
|
2188
|
-
/** Trigger ID for opening modals (time-limited, typically ~3 seconds) */
|
|
2189
|
-
triggerId?: string;
|
|
2190
|
-
/** The user who invoked the command */
|
|
2191
|
-
user: Author;
|
|
2192
|
-
}
|
|
2193
|
-
/**
|
|
2194
|
-
* Handler for slash command events.
|
|
2195
|
-
*
|
|
2196
|
-
* @example
|
|
2197
|
-
* ```typescript
|
|
2198
|
-
* // Handle a specific command
|
|
2199
|
-
* chat.onSlashCommand("/status", async (event) => {
|
|
2200
|
-
* await event.channel.post("All systems operational!");
|
|
2201
|
-
* });
|
|
2202
|
-
*
|
|
2203
|
-
* // Handle multiple commands
|
|
2204
|
-
* chat.onSlashCommand(["/help", "/info"], async (event) => {
|
|
2205
|
-
* await event.channel.post(`You invoked ${event.command}`);
|
|
2206
|
-
* });
|
|
2207
|
-
*
|
|
2208
|
-
* // Catch-all handler
|
|
2209
|
-
* chat.onSlashCommand(async (event) => {
|
|
2210
|
-
* console.log(`Command: ${event.command}, Args: ${event.text}`);
|
|
2211
|
-
* });
|
|
2212
|
-
* ```
|
|
2213
|
-
*/
|
|
2214
|
-
type SlashCommandHandler<TState = Record<string, unknown>> = (event: SlashCommandEvent<TState>) => void | Promise<void>;
|
|
2215
|
-
interface AssistantThreadStartedEvent {
|
|
2216
|
-
adapter: Adapter;
|
|
2217
|
-
channelId: string;
|
|
2218
|
-
context: {
|
|
2219
|
-
channelId?: string;
|
|
2220
|
-
teamId?: string;
|
|
2221
|
-
enterpriseId?: string;
|
|
2222
|
-
threadEntryPoint?: string;
|
|
2223
|
-
forceSearch?: boolean;
|
|
2224
|
-
};
|
|
2225
|
-
threadId: string;
|
|
2226
|
-
threadTs: string;
|
|
2227
|
-
userId: string;
|
|
2228
|
-
}
|
|
2229
|
-
type AssistantThreadStartedHandler = (event: AssistantThreadStartedEvent) => void | Promise<void>;
|
|
2230
|
-
interface AssistantContextChangedEvent {
|
|
2231
|
-
adapter: Adapter;
|
|
2232
|
-
channelId: string;
|
|
2233
|
-
context: {
|
|
2234
|
-
channelId?: string;
|
|
2235
|
-
teamId?: string;
|
|
2236
|
-
enterpriseId?: string;
|
|
2237
|
-
threadEntryPoint?: string;
|
|
2238
|
-
forceSearch?: boolean;
|
|
2239
|
-
};
|
|
2240
|
-
threadId: string;
|
|
2241
|
-
threadTs: string;
|
|
2242
|
-
userId: string;
|
|
2243
|
-
}
|
|
2244
|
-
type AssistantContextChangedHandler = (event: AssistantContextChangedEvent) => void | Promise<void>;
|
|
2245
|
-
interface AppHomeOpenedEvent {
|
|
2246
|
-
adapter: Adapter;
|
|
2247
|
-
channelId: string;
|
|
2248
|
-
userId: string;
|
|
2249
|
-
}
|
|
2250
|
-
type AppHomeOpenedHandler = (event: AppHomeOpenedEvent) => void | Promise<void>;
|
|
2251
|
-
interface MemberJoinedChannelEvent {
|
|
2252
|
-
adapter: Adapter;
|
|
2253
|
-
channelId: string;
|
|
2254
|
-
inviterId?: string;
|
|
2255
|
-
userId: string;
|
|
2256
|
-
}
|
|
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
|
-
}
|
|
2393
|
-
|
|
2394
|
-
/**
|
|
2395
|
-
* Message class with serialization support for workflow engines.
|
|
2396
|
-
*/
|
|
2397
|
-
|
|
2398
|
-
/**
|
|
2399
|
-
* Input data for creating a Message instance.
|
|
2400
|
-
* Use this interface when constructing Message objects.
|
|
2401
|
-
*/
|
|
2402
|
-
interface MessageData<TRawMessage = unknown> {
|
|
2403
|
-
/** Attachments */
|
|
2404
|
-
attachments: Attachment[];
|
|
2405
|
-
/** Message author */
|
|
2406
|
-
author: Author;
|
|
2407
|
-
/** Structured formatting as an AST (mdast Root) */
|
|
2408
|
-
formatted: FormattedContent;
|
|
2409
|
-
/** Unique message ID */
|
|
2410
|
-
id: string;
|
|
2411
|
-
/** Whether the bot is @-mentioned in this message */
|
|
2412
|
-
isMention?: boolean;
|
|
2413
|
-
/** Links found in the message */
|
|
2414
|
-
links?: LinkPreview[];
|
|
2415
|
-
/** Message metadata */
|
|
2416
|
-
metadata: MessageMetadata;
|
|
2417
|
-
/** Platform-specific raw payload (escape hatch) */
|
|
2418
|
-
raw: TRawMessage;
|
|
2419
|
-
/** Plain text content (all formatting stripped) */
|
|
2420
|
-
text: string;
|
|
2421
|
-
/** Thread this message belongs to */
|
|
2422
|
-
threadId: string;
|
|
2423
|
-
}
|
|
2424
|
-
/**
|
|
2425
|
-
* Serialized message data for passing to external systems (e.g., workflow engines).
|
|
2426
|
-
* Dates are converted to ISO strings, and non-serializable fields are omitted.
|
|
2427
|
-
*/
|
|
2428
|
-
interface SerializedMessage {
|
|
2429
|
-
_type: "chat:Message";
|
|
2430
|
-
attachments: Array<{
|
|
2431
|
-
type: "image" | "file" | "video" | "audio";
|
|
2432
|
-
url?: string;
|
|
2433
|
-
name?: string;
|
|
2434
|
-
mimeType?: string;
|
|
2435
|
-
size?: number;
|
|
2436
|
-
width?: number;
|
|
2437
|
-
height?: number;
|
|
2438
|
-
fetchMetadata?: Record<string, string>;
|
|
2439
|
-
}>;
|
|
2440
|
-
author: {
|
|
2441
|
-
userId: string;
|
|
2442
|
-
userName: string;
|
|
2443
|
-
fullName: string;
|
|
2444
|
-
isBot: boolean | "unknown";
|
|
2445
|
-
isMe: boolean;
|
|
2446
|
-
};
|
|
2447
|
-
formatted: Root;
|
|
2448
|
-
id: string;
|
|
2449
|
-
isMention?: boolean;
|
|
2450
|
-
links?: Array<{
|
|
2451
|
-
url: string;
|
|
2452
|
-
title?: string;
|
|
2453
|
-
description?: string;
|
|
2454
|
-
imageUrl?: string;
|
|
2455
|
-
siteName?: string;
|
|
2456
|
-
}>;
|
|
2457
|
-
metadata: {
|
|
2458
|
-
dateSent: string;
|
|
2459
|
-
edited: boolean;
|
|
2460
|
-
editedAt?: string;
|
|
2461
|
-
};
|
|
2462
|
-
raw: unknown;
|
|
2463
|
-
text: string;
|
|
2464
|
-
threadId: string;
|
|
2465
|
-
}
|
|
2466
|
-
/**
|
|
2467
|
-
* A chat message with serialization support for workflow engines.
|
|
2468
|
-
*
|
|
2469
|
-
* @example
|
|
2470
|
-
* ```typescript
|
|
2471
|
-
* // Create a message
|
|
2472
|
-
* const message = new Message({
|
|
2473
|
-
* id: "msg-1",
|
|
2474
|
-
* threadId: "slack:C123:1234.5678",
|
|
2475
|
-
* text: "Hello world",
|
|
2476
|
-
* formatted: parseMarkdown("Hello world"),
|
|
2477
|
-
* raw: {},
|
|
2478
|
-
* author: { userId: "U123", userName: "user", fullName: "User", isBot: false, isMe: false },
|
|
2479
|
-
* metadata: { dateSent: new Date(), edited: false },
|
|
2480
|
-
* attachments: [],
|
|
2481
|
-
* });
|
|
2482
|
-
*
|
|
2483
|
-
* // Serialize for workflow
|
|
2484
|
-
* const serialized = message.toJSON();
|
|
2485
|
-
* ```
|
|
2486
|
-
*/
|
|
2487
|
-
declare class Message<TRawMessage = unknown> {
|
|
2488
|
-
/** Unique message ID */
|
|
2489
|
-
readonly id: string;
|
|
2490
|
-
/** Thread this message belongs to */
|
|
2491
|
-
readonly threadId: string;
|
|
2492
|
-
/** Plain text content (all formatting stripped) */
|
|
2493
|
-
text: string;
|
|
2494
|
-
/**
|
|
2495
|
-
* Structured formatting as an AST (mdast Root).
|
|
2496
|
-
* This is the canonical representation - use this for processing.
|
|
2497
|
-
* Use `stringifyMarkdown(message.formatted)` to get markdown string.
|
|
2498
|
-
*/
|
|
2499
|
-
formatted: FormattedContent;
|
|
2500
|
-
/** Platform-specific raw payload (escape hatch) */
|
|
2501
|
-
raw: TRawMessage;
|
|
2502
|
-
/** Message author */
|
|
2503
|
-
author: Author;
|
|
2504
|
-
/** Message metadata */
|
|
2505
|
-
metadata: MessageMetadata;
|
|
2506
|
-
/** Attachments */
|
|
2507
|
-
attachments: Attachment[];
|
|
2508
|
-
/**
|
|
2509
|
-
* Whether the bot is @-mentioned in this message.
|
|
2510
|
-
*
|
|
2511
|
-
* This is set by the Chat SDK before passing the message to handlers.
|
|
2512
|
-
* It checks for `@username` in the message text using the adapter's
|
|
2513
|
-
* configured `userName` and optional `botUserId`.
|
|
2514
|
-
*
|
|
2515
|
-
* @example
|
|
2516
|
-
* ```typescript
|
|
2517
|
-
* chat.onSubscribedMessage(async (thread, message) => {
|
|
2518
|
-
* if (message.isMention) {
|
|
2519
|
-
* await thread.post("You mentioned me!");
|
|
2520
|
-
* }
|
|
2521
|
-
* });
|
|
2522
|
-
* ```
|
|
2523
|
-
*/
|
|
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;
|
|
2535
|
-
/** Links found in the message */
|
|
2536
|
-
links: LinkPreview[];
|
|
2537
|
-
private _subjectPromise?;
|
|
2538
|
-
get subject(): Promise<MessageSubject | null>;
|
|
2539
|
-
constructor(data: MessageData<TRawMessage>);
|
|
2540
|
-
/**
|
|
2541
|
-
* Serialize the message to a plain JSON object.
|
|
2542
|
-
* Use this to pass message data to external systems like workflow engines.
|
|
2543
|
-
*
|
|
2544
|
-
* Note: Attachment `data` (Buffer) and `fetchData` (function) are omitted
|
|
2545
|
-
* as they're not serializable.
|
|
2546
|
-
*/
|
|
2547
|
-
toJSON(): SerializedMessage;
|
|
2548
|
-
/**
|
|
2549
|
-
* Reconstruct a Message from serialized JSON data.
|
|
2550
|
-
* Converts ISO date strings back to Date objects.
|
|
2551
|
-
*/
|
|
2552
|
-
static fromJSON<TRawMessage = unknown>(json: SerializedMessage): Message<TRawMessage>;
|
|
2553
|
-
/**
|
|
2554
|
-
* Serialize a Message instance for @workflow/serde.
|
|
2555
|
-
* This static method is automatically called by workflow serialization.
|
|
2556
|
-
*/
|
|
2557
|
-
static [WORKFLOW_SERIALIZE](instance: Message): SerializedMessage;
|
|
2558
|
-
/**
|
|
2559
|
-
* Deserialize a Message from @workflow/serde.
|
|
2560
|
-
* This static method is automatically called by workflow deserialization.
|
|
2561
|
-
*/
|
|
2562
|
-
static [WORKFLOW_DESERIALIZE](data: SerializedMessage): Message;
|
|
2563
|
-
}
|
|
2564
|
-
|
|
2565
|
-
/**
|
|
2566
|
-
* Content part types structurally identical to AI SDK's TextPart, ImagePart,
|
|
2567
|
-
* FilePart so that AiMessage[] is directly assignable to ModelMessage[].
|
|
2568
|
-
* @see https://ai-sdk.dev/docs/reference/ai-sdk-core/model-message
|
|
2569
|
-
*/
|
|
2570
|
-
/** Matches AI SDK's DataContent */
|
|
2571
|
-
type DataContent = string | Uint8Array | ArrayBuffer | Buffer;
|
|
2572
|
-
interface AiTextPart {
|
|
2573
|
-
text: string;
|
|
2574
|
-
type: "text";
|
|
2575
|
-
}
|
|
2576
|
-
interface AiImagePart {
|
|
2577
|
-
image: DataContent | URL;
|
|
2578
|
-
mediaType?: string;
|
|
2579
|
-
type: "image";
|
|
2580
|
-
}
|
|
2581
|
-
interface AiFilePart {
|
|
2582
|
-
data: DataContent | URL;
|
|
2583
|
-
filename?: string;
|
|
2584
|
-
mediaType: string;
|
|
2585
|
-
type: "file";
|
|
2586
|
-
}
|
|
2587
|
-
type AiMessagePart = AiTextPart | AiImagePart | AiFilePart;
|
|
2588
|
-
/**
|
|
2589
|
-
* A message formatted for AI SDK consumption.
|
|
2590
|
-
*
|
|
2591
|
-
* This is a discriminated union matching AI SDK's ModelMessage type:
|
|
2592
|
-
* - User messages can have text, image, and file parts
|
|
2593
|
-
* - Assistant messages have string content only
|
|
2594
|
-
*/
|
|
2595
|
-
type AiMessage = AiUserMessage | AiAssistantMessage;
|
|
2596
|
-
interface AiUserMessage {
|
|
2597
|
-
content: string | AiMessagePart[];
|
|
2598
|
-
role: "user";
|
|
2599
|
-
}
|
|
2600
|
-
interface AiAssistantMessage {
|
|
2601
|
-
content: string;
|
|
2602
|
-
role: "assistant";
|
|
2603
|
-
}
|
|
2604
|
-
/**
|
|
2605
|
-
* Options for converting messages to AI SDK format.
|
|
2606
|
-
*/
|
|
2607
|
-
interface ToAiMessagesOptions {
|
|
2608
|
-
/** When true, prefixes user messages with "[username]: " for multi-user context */
|
|
2609
|
-
includeNames?: boolean;
|
|
2610
|
-
/**
|
|
2611
|
-
* Called when an attachment type is not supported (video, audio).
|
|
2612
|
-
* Defaults to `console.warn`.
|
|
2613
|
-
*/
|
|
2614
|
-
onUnsupportedAttachment?: (attachment: Attachment, message: Message) => void;
|
|
2615
|
-
/**
|
|
2616
|
-
* Called for each message after default processing (text, links, attachments).
|
|
2617
|
-
* Return the message (modified or as-is) to include it, or `null` to skip it.
|
|
2618
|
-
*
|
|
2619
|
-
* @param aiMessage - The processed AI message
|
|
2620
|
-
* @param source - The original chat Message
|
|
2621
|
-
* @returns The message to include, or null to skip
|
|
2622
|
-
*/
|
|
2623
|
-
transformMessage?: (aiMessage: AiMessage, source: Message) => AiMessage | null | Promise<AiMessage | null>;
|
|
2624
|
-
}
|
|
2625
|
-
/**
|
|
2626
|
-
* Convert chat SDK messages to AI SDK conversation format.
|
|
2627
|
-
*
|
|
2628
|
-
* - Filters out messages with empty/whitespace-only text
|
|
2629
|
-
* - Maps `author.isMe === true` to `"assistant"`, otherwise `"user"`
|
|
2630
|
-
* - Uses `message.text` for content
|
|
2631
|
-
* - Appends link metadata when available
|
|
2632
|
-
* - Includes image attachments and text files as `FilePart`
|
|
2633
|
-
* - Uses `fetchData()` when available to include attachment data inline (base64)
|
|
2634
|
-
* - Warns on unsupported attachment types (video, audio)
|
|
2635
|
-
*
|
|
2636
|
-
* Works with `FetchResult.messages`, `thread.recentMessages`, or collected iterables.
|
|
2637
|
-
*
|
|
2638
|
-
* @example
|
|
2639
|
-
* ```typescript
|
|
2640
|
-
* const result = await thread.adapter.fetchMessages(thread.id, { limit: 20 });
|
|
2641
|
-
* const history = await toAiMessages(result.messages);
|
|
2642
|
-
* const response = await agent.stream({ prompt: history });
|
|
2643
|
-
* ```
|
|
2644
|
-
*/
|
|
2645
|
-
declare function toAiMessages(messages: Message[], options?: ToAiMessagesOptions): Promise<AiMessage[]>;
|
|
2646
|
-
|
|
2647
|
-
/** Filter can be EmojiValue objects, emoji names, or raw emoji formats */
|
|
2648
|
-
type EmojiFilter = EmojiValue | string;
|
|
2649
|
-
/**
|
|
2650
|
-
* Type-safe webhook handler that is available for each adapter.
|
|
2651
|
-
*/
|
|
2652
|
-
type WebhookHandler = (request: Request, options?: WebhookOptions) => Promise<Response>;
|
|
2653
|
-
/**
|
|
2654
|
-
* Creates a type-safe webhooks object based on the adapter names.
|
|
2655
|
-
*/
|
|
2656
|
-
type Webhooks<TAdapters extends Record<string, Adapter>> = {
|
|
2657
|
-
[K in keyof TAdapters]: WebhookHandler;
|
|
2658
|
-
};
|
|
2659
|
-
/**
|
|
2660
|
-
* Main Chat class with type-safe adapter inference and custom thread state.
|
|
2661
|
-
*
|
|
2662
|
-
* @template TAdapters - Map of adapter names to Adapter instances
|
|
2663
|
-
* @template TState - Custom state type stored per-thread (default: Record<string, unknown>)
|
|
2664
|
-
*
|
|
2665
|
-
* @example
|
|
2666
|
-
* // Define custom thread state type
|
|
2667
|
-
* interface MyThreadState {
|
|
2668
|
-
* aiMode?: boolean;
|
|
2669
|
-
* userName?: string;
|
|
2670
|
-
* }
|
|
2671
|
-
*
|
|
2672
|
-
* const chat = new Chat<typeof adapters, MyThreadState>({
|
|
2673
|
-
* userName: "mybot",
|
|
2674
|
-
* adapters: {
|
|
2675
|
-
* slack: createSlackAdapter({ ... }),
|
|
2676
|
-
* teams: createTeamsAdapter({ ... }),
|
|
2677
|
-
* },
|
|
2678
|
-
* state: createMemoryState(),
|
|
2679
|
-
* });
|
|
2680
|
-
*
|
|
2681
|
-
* // Type-safe thread state
|
|
2682
|
-
* chat.onNewMention(async (thread, message) => {
|
|
2683
|
-
* await thread.setState({ aiMode: true });
|
|
2684
|
-
* const state = await thread.state; // Type: MyThreadState | null
|
|
2685
|
-
* });
|
|
2686
|
-
*/
|
|
2687
|
-
declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Adapter>, TState = Record<string, unknown>> implements ChatInstance {
|
|
2688
|
-
/**
|
|
2689
|
-
* Register this Chat instance as the global singleton.
|
|
2690
|
-
* Required for Thread deserialization via @workflow/serde.
|
|
2691
|
-
*
|
|
2692
|
-
* @example
|
|
2693
|
-
* ```typescript
|
|
2694
|
-
* const chat = new Chat({ ... });
|
|
2695
|
-
* chat.registerSingleton();
|
|
2696
|
-
*
|
|
2697
|
-
* // Now threads can be deserialized without passing chat explicitly
|
|
2698
|
-
* const thread = ThreadImpl.fromJSON(serializedThread);
|
|
2699
|
-
* ```
|
|
2700
|
-
*/
|
|
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;
|
|
2710
|
-
/**
|
|
2711
|
-
* Get the registered singleton Chat instance.
|
|
2712
|
-
* Throws if no singleton has been registered.
|
|
2713
|
-
*/
|
|
2714
|
-
static getSingleton(): Chat;
|
|
2715
|
-
/**
|
|
2716
|
-
* Check if a singleton has been registered.
|
|
2717
|
-
*/
|
|
2718
|
-
static hasSingleton(): boolean;
|
|
2719
|
-
private readonly adapters;
|
|
2720
|
-
private readonly _stateAdapter;
|
|
2721
|
-
private readonly userName;
|
|
2722
|
-
private readonly logger;
|
|
2723
|
-
private readonly _streamingUpdateIntervalMs;
|
|
2724
|
-
private readonly _fallbackStreamingPlaceholderText;
|
|
2725
|
-
private readonly _dedupeTtlMs;
|
|
2726
|
-
private readonly _onLockConflict;
|
|
2727
|
-
private readonly _threadHistory;
|
|
2728
|
-
private readonly _identity;
|
|
2729
|
-
private readonly _transcripts;
|
|
2730
|
-
private readonly _concurrencyStrategy;
|
|
2731
|
-
private readonly _concurrencyConfig;
|
|
2732
|
-
private readonly _concurrentSlots;
|
|
2733
|
-
private readonly _lockScope;
|
|
2734
|
-
private readonly mentionHandlers;
|
|
2735
|
-
private readonly directMessageHandlers;
|
|
2736
|
-
private readonly messagePatterns;
|
|
2737
|
-
private readonly subscribedMessageHandlers;
|
|
2738
|
-
private readonly reactionHandlers;
|
|
2739
|
-
private readonly actionHandlers;
|
|
2740
|
-
private readonly optionsLoadHandlers;
|
|
2741
|
-
private readonly modalSubmitHandlers;
|
|
2742
|
-
private readonly modalCloseHandlers;
|
|
2743
|
-
private readonly slashCommandHandlers;
|
|
2744
|
-
private readonly assistantThreadStartedHandlers;
|
|
2745
|
-
private readonly assistantContextChangedHandlers;
|
|
2746
|
-
private readonly appHomeOpenedHandlers;
|
|
2747
|
-
private readonly memberJoinedChannelHandlers;
|
|
2748
|
-
/** Initialization state */
|
|
2749
|
-
private initPromise;
|
|
2750
|
-
private initialized;
|
|
2751
|
-
/**
|
|
2752
|
-
* Type-safe webhook handlers keyed by adapter name.
|
|
2753
|
-
* @example
|
|
2754
|
-
* chat.webhooks.slack(request, { backgroundTask: waitUntil });
|
|
2755
|
-
*/
|
|
2756
|
-
readonly webhooks: Webhooks<TAdapters>;
|
|
2757
|
-
constructor(config: ChatConfig<TAdapters>);
|
|
2758
|
-
/**
|
|
2759
|
-
* Handle a webhook request for a specific adapter.
|
|
2760
|
-
* Automatically initializes adapters on first call.
|
|
2761
|
-
*/
|
|
2762
|
-
private handleWebhook;
|
|
2763
|
-
/**
|
|
2764
|
-
* Ensure the chat instance is initialized.
|
|
2765
|
-
* This is called automatically before handling webhooks.
|
|
2766
|
-
*/
|
|
2767
|
-
private ensureInitialized;
|
|
2768
|
-
private doInitialize;
|
|
2769
|
-
/**
|
|
2770
|
-
* Gracefully shut down the chat instance.
|
|
2771
|
-
*/
|
|
2772
|
-
shutdown(): Promise<void>;
|
|
2773
|
-
/**
|
|
2774
|
-
* Initialize the chat instance and all adapters.
|
|
2775
|
-
* This is called automatically when handling webhooks, but can be called
|
|
2776
|
-
* manually for non-webhook use cases (e.g., Gateway listeners).
|
|
2777
|
-
*/
|
|
2778
|
-
initialize(): Promise<void>;
|
|
2779
|
-
/**
|
|
2780
|
-
* Register a handler for new @-mentions of the bot.
|
|
2781
|
-
*
|
|
2782
|
-
* **Important**: This handler is ONLY called for mentions in **unsubscribed** threads.
|
|
2783
|
-
* Once a thread is subscribed (via `thread.subscribe()`), subsequent messages
|
|
2784
|
-
* including @-mentions go to `onSubscribedMessage` handlers instead.
|
|
2785
|
-
*
|
|
2786
|
-
* To detect mentions in subscribed threads, check `message.isMention`:
|
|
2787
|
-
*
|
|
2788
|
-
* @example
|
|
2789
|
-
* ```typescript
|
|
2790
|
-
* // Handle new mentions (unsubscribed threads only)
|
|
2791
|
-
* chat.onNewMention(async (thread, message) => {
|
|
2792
|
-
* await thread.subscribe(); // Subscribe to follow-up messages
|
|
2793
|
-
* await thread.post("Hello! I'll be watching this thread.");
|
|
2794
|
-
* });
|
|
2795
|
-
*
|
|
2796
|
-
* // Handle all messages in subscribed threads
|
|
2797
|
-
* chat.onSubscribedMessage(async (thread, message) => {
|
|
2798
|
-
* if (message.isMention) {
|
|
2799
|
-
* // User @-mentioned us in a thread we're already watching
|
|
2800
|
-
* await thread.post("You mentioned me again!");
|
|
2801
|
-
* }
|
|
2802
|
-
* });
|
|
2803
|
-
* ```
|
|
2804
|
-
*/
|
|
2805
|
-
onNewMention(handler: MentionHandler<TState>): void;
|
|
2806
|
-
/**
|
|
2807
|
-
* Register a handler for direct messages.
|
|
2808
|
-
*
|
|
2809
|
-
* Called when a message is received in a DM thread that is not subscribed.
|
|
2810
|
-
* If no `onDirectMessage` handlers are registered, DMs fall through to
|
|
2811
|
-
* `onNewMention` for backward compatibility.
|
|
2812
|
-
*
|
|
2813
|
-
* @param handler - Handler called for DM messages
|
|
2814
|
-
*
|
|
2815
|
-
* @example
|
|
2816
|
-
* ```typescript
|
|
2817
|
-
* chat.onDirectMessage(async (thread, message) => {
|
|
2818
|
-
* await thread.subscribe();
|
|
2819
|
-
* await thread.post("Thanks for the DM!");
|
|
2820
|
-
* });
|
|
2821
|
-
* ```
|
|
2822
|
-
*/
|
|
2823
|
-
onDirectMessage(handler: DirectMessageHandler<TState>): void;
|
|
2824
|
-
/**
|
|
2825
|
-
* Register a handler for messages matching a regex pattern.
|
|
2826
|
-
*
|
|
2827
|
-
* @param pattern - Regular expression to match against message text
|
|
2828
|
-
* @param handler - Handler called when pattern matches
|
|
2829
|
-
*
|
|
2830
|
-
* @example
|
|
2831
|
-
* ```typescript
|
|
2832
|
-
* // Match messages starting with "!help"
|
|
2833
|
-
* chat.onNewMessage(/^!help/, async (thread, message) => {
|
|
2834
|
-
* await thread.post("Available commands: !help, !status, !ping");
|
|
2835
|
-
* });
|
|
2836
|
-
* ```
|
|
2837
|
-
*/
|
|
2838
|
-
onNewMessage(pattern: RegExp, handler: MessageHandler<TState>): void;
|
|
2839
|
-
/**
|
|
2840
|
-
* Register a handler for messages in subscribed threads.
|
|
2841
|
-
*
|
|
2842
|
-
* Called for all messages in threads that have been subscribed via `thread.subscribe()`.
|
|
2843
|
-
* This includes:
|
|
2844
|
-
* - Follow-up messages from users
|
|
2845
|
-
* - Messages that @-mention the bot (check `message.isMention`)
|
|
2846
|
-
*
|
|
2847
|
-
* Does NOT fire for:
|
|
2848
|
-
* - The message that triggered the subscription (e.g., the initial @mention)
|
|
2849
|
-
* - Messages sent by the bot itself
|
|
2850
|
-
*
|
|
2851
|
-
* @example
|
|
2852
|
-
* ```typescript
|
|
2853
|
-
* chat.onSubscribedMessage(async (thread, message) => {
|
|
2854
|
-
* // Handle all follow-up messages
|
|
2855
|
-
* if (message.isMention) {
|
|
2856
|
-
* // User @-mentioned us in a subscribed thread
|
|
2857
|
-
* }
|
|
2858
|
-
* await thread.post(`Got your message: ${message.text}`);
|
|
2859
|
-
* });
|
|
2860
|
-
* ```
|
|
2861
|
-
*/
|
|
2862
|
-
onSubscribedMessage(handler: SubscribedMessageHandler<TState>): void;
|
|
2863
|
-
/**
|
|
2864
|
-
* Register a handler for reaction events.
|
|
2865
|
-
*
|
|
2866
|
-
* @example
|
|
2867
|
-
* ```typescript
|
|
2868
|
-
* // Handle specific emoji using EmojiValue objects (recommended)
|
|
2869
|
-
* chat.onReaction([emoji.thumbs_up, emoji.heart], async (event) => {
|
|
2870
|
-
* if (event.emoji === emoji.thumbs_up) {
|
|
2871
|
-
* console.log("Thumbs up!");
|
|
2872
|
-
* }
|
|
2873
|
-
* });
|
|
2874
|
-
*
|
|
2875
|
-
* // Handle all reactions
|
|
2876
|
-
* chat.onReaction(async (event) => {
|
|
2877
|
-
* console.log(`${event.added ? "Added" : "Removed"} ${event.emoji.name}`);
|
|
2878
|
-
* });
|
|
2879
|
-
* ```
|
|
2880
|
-
*
|
|
2881
|
-
* @param emojiOrHandler - Either an array of emoji to filter (EmojiValue or string), or the handler
|
|
2882
|
-
* @param handler - The handler (if emoji filter is provided)
|
|
2883
|
-
*/
|
|
2884
|
-
onReaction(handler: ReactionHandler): void;
|
|
2885
|
-
onReaction(emoji: EmojiFilter[], handler: ReactionHandler): void;
|
|
2886
|
-
/**
|
|
2887
|
-
* Register a handler for action events (button clicks in cards).
|
|
2888
|
-
*
|
|
2889
|
-
* @example
|
|
2890
|
-
* ```typescript
|
|
2891
|
-
* // Handle specific action
|
|
2892
|
-
* chat.onAction("approve", async (event) => {
|
|
2893
|
-
* await event.thread.post("Approved!");
|
|
2894
|
-
* });
|
|
2895
|
-
*
|
|
2896
|
-
* // Handle multiple actions
|
|
2897
|
-
* chat.onAction(["approve", "reject"], async (event) => {
|
|
2898
|
-
* if (event.actionId === "approve") {
|
|
2899
|
-
* await event.thread.post("Approved!");
|
|
2900
|
-
* } else {
|
|
2901
|
-
* await event.thread.post("Rejected!");
|
|
2902
|
-
* }
|
|
2903
|
-
* });
|
|
2904
|
-
*
|
|
2905
|
-
* // Handle all actions (catch-all)
|
|
2906
|
-
* chat.onAction(async (event) => {
|
|
2907
|
-
* console.log(`Action: ${event.actionId}`);
|
|
2908
|
-
* });
|
|
2909
|
-
* ```
|
|
2910
|
-
*
|
|
2911
|
-
* @param actionIdOrHandler - Either an action ID, array of action IDs, or the handler
|
|
2912
|
-
* @param handler - The handler (if action ID filter is provided)
|
|
2913
|
-
*/
|
|
2914
|
-
onAction(handler: ActionHandler): void;
|
|
2915
|
-
onAction(actionIds: string[] | string, handler: ActionHandler): void;
|
|
2916
|
-
/**
|
|
2917
|
-
* Register a handler for loading dynamic options for external selects.
|
|
2918
|
-
* Specific action IDs run before catch-all handlers.
|
|
2919
|
-
*/
|
|
2920
|
-
onOptionsLoad(handler: OptionsLoadHandler): void;
|
|
2921
|
-
onOptionsLoad(actionIds: string[] | string, handler: OptionsLoadHandler): void;
|
|
2922
|
-
/**
|
|
2923
|
-
* Register a handler for modal form submissions.
|
|
2924
|
-
*
|
|
2925
|
-
* @example
|
|
2926
|
-
* ```typescript
|
|
2927
|
-
* // Handle specific modal
|
|
2928
|
-
* chat.onModalSubmit("settings-modal", async (event) => {
|
|
2929
|
-
* const name = event.values["name"];
|
|
2930
|
-
* await event.relatedThread?.post(`Updated name to ${name}`);
|
|
2931
|
-
* });
|
|
2932
|
-
*
|
|
2933
|
-
* // Handle all modal submissions
|
|
2934
|
-
* chat.onModalSubmit(async (event) => {
|
|
2935
|
-
* console.log(`Modal ${event.callbackId} submitted`);
|
|
2936
|
-
* });
|
|
2937
|
-
* ```
|
|
2938
|
-
*
|
|
2939
|
-
* @param callbackIdOrHandler - Either a callback ID, array of callback IDs, or the handler
|
|
2940
|
-
* @param handler - The handler (if callback ID filter is provided)
|
|
2941
|
-
*/
|
|
2942
|
-
onModalSubmit(handler: ModalSubmitHandler): void;
|
|
2943
|
-
onModalSubmit(callbackIds: string[] | string, handler: ModalSubmitHandler): void;
|
|
2944
|
-
/**
|
|
2945
|
-
* Register a handler for modal close/cancel events.
|
|
2946
|
-
* Only fires when the modal was created with `notifyOnClose: true`.
|
|
2947
|
-
*
|
|
2948
|
-
* @example
|
|
2949
|
-
* ```typescript
|
|
2950
|
-
* // Handle specific modal close
|
|
2951
|
-
* chat.onModalClose("settings-modal", async (event) => {
|
|
2952
|
-
* console.log("User cancelled settings");
|
|
2953
|
-
* });
|
|
2954
|
-
*
|
|
2955
|
-
* // Handle all modal close events
|
|
2956
|
-
* chat.onModalClose(async (event) => {
|
|
2957
|
-
* console.log(`Modal ${event.callbackId} closed`);
|
|
2958
|
-
* });
|
|
2959
|
-
* ```
|
|
2960
|
-
*
|
|
2961
|
-
* @param callbackIdOrHandler - Either a callback ID, array of callback IDs, or the handler
|
|
2962
|
-
* @param handler - The handler (if callback ID filter is provided)
|
|
2963
|
-
*/
|
|
2964
|
-
onModalClose(handler: ModalCloseHandler): void;
|
|
2965
|
-
onModalClose(callbackIds: string[] | string, handler: ModalCloseHandler): void;
|
|
2966
|
-
/**
|
|
2967
|
-
* Register a handler for slash command events.
|
|
2968
|
-
*
|
|
2969
|
-
* Slash commands are triggered when a user types `/command` in the message composer.
|
|
2970
|
-
* Use `event.channel.post()` or `event.channel.postEphemeral()` to respond.
|
|
2971
|
-
*
|
|
2972
|
-
* @example
|
|
2973
|
-
* ```typescript
|
|
2974
|
-
* // Handle a specific command
|
|
2975
|
-
* chat.onSlashCommand("/help", async (event) => {
|
|
2976
|
-
* await event.channel.post("Here are the available commands...");
|
|
2977
|
-
* });
|
|
2978
|
-
*
|
|
2979
|
-
* // Handle multiple commands
|
|
2980
|
-
* chat.onSlashCommand(["/status", "/health"], async (event) => {
|
|
2981
|
-
* await event.channel.post("All systems operational!");
|
|
2982
|
-
* });
|
|
2983
|
-
*
|
|
2984
|
-
* // Handle all commands (catch-all)
|
|
2985
|
-
* chat.onSlashCommand(async (event) => {
|
|
2986
|
-
* console.log(`Received command: ${event.command} ${event.text}`);
|
|
2987
|
-
* });
|
|
2988
|
-
*
|
|
2989
|
-
* // Open a modal from a slash command
|
|
2990
|
-
* chat.onSlashCommand("/feedback", async (event) => {
|
|
2991
|
-
* await event.openModal({
|
|
2992
|
-
* callbackId: "feedback_modal",
|
|
2993
|
-
* title: "Submit Feedback",
|
|
2994
|
-
* inputs: [{ id: "feedback", type: "text_input", label: "Your feedback" }],
|
|
2995
|
-
* });
|
|
2996
|
-
* });
|
|
2997
|
-
* ```
|
|
2998
|
-
*
|
|
2999
|
-
* @param commandOrHandler - Either a command, array of commands, or the handler
|
|
3000
|
-
* @param handler - The handler (if command filter is provided)
|
|
3001
|
-
*/
|
|
3002
|
-
onSlashCommand(handler: SlashCommandHandler<TState>): void;
|
|
3003
|
-
onSlashCommand(commands: string[] | string, handler: SlashCommandHandler<TState>): void;
|
|
3004
|
-
onAssistantThreadStarted(handler: AssistantThreadStartedHandler): void;
|
|
3005
|
-
onAssistantContextChanged(handler: AssistantContextChangedHandler): void;
|
|
3006
|
-
onAppHomeOpened(handler: AppHomeOpenedHandler): void;
|
|
3007
|
-
onMemberJoinedChannel(handler: MemberJoinedChannelHandler): void;
|
|
3008
|
-
/**
|
|
3009
|
-
* Get an adapter by name with type safety.
|
|
3010
|
-
*/
|
|
3011
|
-
getAdapter<K extends keyof TAdapters>(name: K): TAdapters[K];
|
|
3012
|
-
/**
|
|
3013
|
-
* Get a JSON.parse reviver function that automatically deserializes
|
|
3014
|
-
* chat:Thread and chat:Message objects.
|
|
3015
|
-
*
|
|
3016
|
-
* Use this when parsing JSON that contains serialized Thread or Message objects
|
|
3017
|
-
* (e.g., from workflow engine payloads).
|
|
3018
|
-
*
|
|
3019
|
-
* @returns A reviver function for JSON.parse
|
|
3020
|
-
*
|
|
3021
|
-
* @example
|
|
3022
|
-
* ```typescript
|
|
3023
|
-
* // Parse workflow payload with automatic deserialization
|
|
3024
|
-
* const data = JSON.parse(payload, chat.reviver());
|
|
3025
|
-
*
|
|
3026
|
-
* // data.thread is now a ThreadImpl instance
|
|
3027
|
-
* // data.message is now a Message object with Date fields restored
|
|
3028
|
-
* await data.thread.post("Hello from workflow!");
|
|
3029
|
-
* ```
|
|
3030
|
-
*/
|
|
3031
|
-
reviver(): (key: string, value: unknown) => unknown;
|
|
3032
|
-
/**
|
|
3033
|
-
* Process an incoming message from an adapter.
|
|
3034
|
-
* Handles waitUntil registration and error catching internally.
|
|
3035
|
-
* Adapters should call this instead of handleIncomingMessage directly.
|
|
3036
|
-
*/
|
|
3037
|
-
processMessage(adapter: Adapter, threadId: string, messageOrFactory: Message | (() => Promise<Message>), options?: WebhookOptions): Promise<void>;
|
|
3038
|
-
/**
|
|
3039
|
-
* Process an incoming reaction event from an adapter.
|
|
3040
|
-
* Handles waitUntil registration and error catching internally.
|
|
3041
|
-
*/
|
|
3042
|
-
processReaction(event: Omit<ReactionEvent, "adapter" | "thread"> & {
|
|
3043
|
-
adapter?: Adapter;
|
|
3044
|
-
}, options?: WebhookOptions): void;
|
|
3045
|
-
/**
|
|
3046
|
-
* Process an incoming action event (button click) from an adapter.
|
|
3047
|
-
* Handles waitUntil registration and error catching internally.
|
|
3048
|
-
*/
|
|
3049
|
-
processAction(event: Omit<ActionEvent, "thread" | "openModal"> & {
|
|
3050
|
-
adapter: Adapter;
|
|
3051
|
-
}, options: WebhookOptions | undefined): Promise<void>;
|
|
3052
|
-
processOptionsLoad(event: OptionsLoadEvent, _options?: WebhookOptions): Promise<OptionsLoadResult | undefined>;
|
|
3053
|
-
processModalSubmit(event: Omit<ModalSubmitEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, options?: WebhookOptions): Promise<ModalResponse | undefined>;
|
|
3054
|
-
processModalClose(event: Omit<ModalCloseEvent, "relatedThread" | "relatedMessage" | "relatedChannel">, contextId?: string, options?: WebhookOptions): void;
|
|
3055
|
-
/**
|
|
3056
|
-
* Process an incoming slash command from an adapter.
|
|
3057
|
-
* Handles waitUntil registration and error catching internally.
|
|
3058
|
-
*/
|
|
3059
|
-
processSlashCommand(event: Omit<SlashCommandEvent, "channel" | "openModal"> & {
|
|
3060
|
-
adapter: Adapter;
|
|
3061
|
-
channelId: string;
|
|
3062
|
-
}, options: WebhookOptions | undefined): void;
|
|
3063
|
-
processAssistantThreadStarted(event: AssistantThreadStartedEvent, options?: WebhookOptions): void;
|
|
3064
|
-
processAssistantContextChanged(event: AssistantContextChangedEvent, options?: WebhookOptions): void;
|
|
3065
|
-
processAppHomeOpened(event: AppHomeOpenedEvent, options?: WebhookOptions): void;
|
|
3066
|
-
processMemberJoinedChannel(event: MemberJoinedChannelEvent, options?: WebhookOptions): void;
|
|
3067
|
-
/**
|
|
3068
|
-
* Handle a slash command event internally.
|
|
3069
|
-
*/
|
|
3070
|
-
private handleSlashCommandEvent;
|
|
3071
|
-
/**
|
|
3072
|
-
* Store modal context server-side with a context ID.
|
|
3073
|
-
* Called when opening a modal to preserve thread/message/channel for the submit handler.
|
|
3074
|
-
*/
|
|
3075
|
-
private storeModalContext;
|
|
3076
|
-
/**
|
|
3077
|
-
* Retrieve and delete modal context from server-side storage.
|
|
3078
|
-
* Called when processing modal submit/close to reconstruct thread/message/channel.
|
|
3079
|
-
*/
|
|
3080
|
-
private retrieveModalContext;
|
|
3081
|
-
/**
|
|
3082
|
-
* Handle an action event internally.
|
|
3083
|
-
*/
|
|
3084
|
-
private handleActionEvent;
|
|
3085
|
-
/**
|
|
3086
|
-
* Handle a reaction event internally.
|
|
3087
|
-
*/
|
|
3088
|
-
private handleReactionEvent;
|
|
3089
|
-
getState(): StateAdapter;
|
|
3090
|
-
getUserName(): string;
|
|
3091
|
-
getLogger(prefix?: string): Logger;
|
|
3092
|
-
/**
|
|
3093
|
-
* Open a direct message conversation with a user.
|
|
3094
|
-
*
|
|
3095
|
-
* Accepts either a user ID string or an Author object (from message.author or event.user).
|
|
3096
|
-
*
|
|
3097
|
-
* The adapter is automatically inferred from the userId format:
|
|
3098
|
-
* - Slack: `U...` (e.g., "U00FAKEUSER1")
|
|
3099
|
-
* - Teams: `29:...` (e.g., "29:198PbJuw...")
|
|
3100
|
-
* - Google Chat: `users/...` (e.g., "users/100000000000000000001")
|
|
3101
|
-
* - Discord: numeric snowflake (e.g., "1033044521375764530")
|
|
3102
|
-
*
|
|
3103
|
-
* @param user - Platform-specific user ID string, or an Author object
|
|
3104
|
-
* @returns A Thread that can be used to post messages
|
|
3105
|
-
*
|
|
3106
|
-
* @example
|
|
3107
|
-
* ```ts
|
|
3108
|
-
* // Using user ID directly
|
|
3109
|
-
* const dmThread = await chat.openDM("U123456");
|
|
3110
|
-
* await dmThread.post("Hello via DM!");
|
|
3111
|
-
*
|
|
3112
|
-
* // Using Author object from a message
|
|
3113
|
-
* chat.onSubscribedMessage(async (thread, message) => {
|
|
3114
|
-
* const dmThread = await chat.openDM(message.author);
|
|
3115
|
-
* await dmThread.post("Hello via DM!");
|
|
3116
|
-
* });
|
|
3117
|
-
* ```
|
|
3118
|
-
*/
|
|
3119
|
-
openDM(user: string | Author): Promise<Thread<TState>>;
|
|
3120
|
-
/**
|
|
3121
|
-
* Look up user information by user ID.
|
|
3122
|
-
*
|
|
3123
|
-
* The adapter is automatically inferred from the user ID format.
|
|
3124
|
-
* Returns user details including email (where available — requires
|
|
3125
|
-
* appropriate scopes on some platforms, e.g. `users:read.email` on Slack).
|
|
3126
|
-
*
|
|
3127
|
-
* @param user - Platform-specific user ID string, or an Author object
|
|
3128
|
-
* @returns User info, or null if user not found
|
|
3129
|
-
*
|
|
3130
|
-
* @example
|
|
3131
|
-
* ```typescript
|
|
3132
|
-
* const user = await chat.getUser("U123456");
|
|
3133
|
-
* console.log(user?.email); // "alice@company.com"
|
|
3134
|
-
* ```
|
|
3135
|
-
*/
|
|
3136
|
-
getUser(user: string | Author): Promise<UserInfo | null>;
|
|
3137
|
-
/**
|
|
3138
|
-
* Get a Channel by its channel ID.
|
|
3139
|
-
*
|
|
3140
|
-
* The adapter is automatically inferred from the channel ID prefix.
|
|
3141
|
-
*
|
|
3142
|
-
* @param channelId - Channel ID (e.g., "slack:C123ABC", "gchat:spaces/ABC123")
|
|
3143
|
-
* @returns A Channel that can be used to list threads, post messages, iterate messages, etc.
|
|
3144
|
-
*
|
|
3145
|
-
* @example
|
|
3146
|
-
* ```typescript
|
|
3147
|
-
* const channel = chat.channel("slack:C123ABC");
|
|
3148
|
-
*
|
|
3149
|
-
* // Iterate messages newest first
|
|
3150
|
-
* for await (const msg of channel.messages) {
|
|
3151
|
-
* console.log(msg.text);
|
|
3152
|
-
* }
|
|
3153
|
-
*
|
|
3154
|
-
* // List threads
|
|
3155
|
-
* for await (const t of channel.threads()) {
|
|
3156
|
-
* console.log(t.rootMessage.text, t.replyCount);
|
|
3157
|
-
* }
|
|
3158
|
-
*
|
|
3159
|
-
* // Post to channel
|
|
3160
|
-
* await channel.post("Hello channel!");
|
|
3161
|
-
* ```
|
|
3162
|
-
*/
|
|
3163
|
-
channel(channelId: string): Channel<TState>;
|
|
3164
|
-
/**
|
|
3165
|
-
* Get a Thread handle by its thread ID.
|
|
3166
|
-
*
|
|
3167
|
-
* The adapter is automatically inferred from the thread ID prefix.
|
|
3168
|
-
*
|
|
3169
|
-
* @param threadId - Full thread ID (e.g., "slack:C123ABC:1234567890.123456")
|
|
3170
|
-
* @returns A Thread that can be used to post messages, subscribe, etc.
|
|
3171
|
-
*
|
|
3172
|
-
* @example
|
|
3173
|
-
* ```typescript
|
|
3174
|
-
* const thread = chat.thread("slack:C123ABC:1234567890.123456");
|
|
3175
|
-
* await thread.post("Hello from outside a webhook!");
|
|
3176
|
-
* ```
|
|
3177
|
-
*/
|
|
3178
|
-
thread(threadId: string): Thread<TState>;
|
|
3179
|
-
/**
|
|
3180
|
-
* Infer which adapter to use based on the userId format.
|
|
3181
|
-
*/
|
|
3182
|
-
private inferAdapterFromUserId;
|
|
3183
|
-
/**
|
|
3184
|
-
* Resolve the lock key for a message based on lock scope.
|
|
3185
|
-
* With 'thread' scope, returns threadId. With 'channel' scope,
|
|
3186
|
-
* returns channelId (derived via adapter.channelIdFromThreadId).
|
|
3187
|
-
*/
|
|
3188
|
-
private getLockKey;
|
|
3189
|
-
/**
|
|
3190
|
-
* Handle an incoming message from an adapter.
|
|
3191
|
-
* This is called by adapters when they receive a webhook.
|
|
3192
|
-
*
|
|
3193
|
-
* The Chat class handles common concerns centrally:
|
|
3194
|
-
* - Deduplication: Same message may arrive multiple times (e.g., Slack sends
|
|
3195
|
-
* both `message` and `app_mention` events, GChat sends direct webhook + Pub/Sub)
|
|
3196
|
-
* - Bot filtering: Messages from the bot itself are skipped
|
|
3197
|
-
* - Concurrency: Controlled by `concurrency` config (drop, queue, debounce, concurrent)
|
|
3198
|
-
*/
|
|
3199
|
-
handleIncomingMessage(adapter: Adapter, threadId: string, message: Message): Promise<void>;
|
|
3200
|
-
/**
|
|
3201
|
-
* Drop strategy: acquire lock or fail. Original behavior.
|
|
3202
|
-
*/
|
|
3203
|
-
private handleDrop;
|
|
3204
|
-
/**
|
|
3205
|
-
* Queue/Debounce strategy: enqueue if lock is busy, drain after processing.
|
|
3206
|
-
*/
|
|
3207
|
-
private handleQueueOrDebounce;
|
|
3208
|
-
/**
|
|
3209
|
-
* Debounce loop: wait for debounceMs, check if newer message arrived,
|
|
3210
|
-
* repeat until no new messages, then process the final message.
|
|
3211
|
-
*/
|
|
3212
|
-
private debounceLoop;
|
|
3213
|
-
/**
|
|
3214
|
-
* Drain queue: collect all pending messages, dispatch the latest with
|
|
3215
|
-
* skipped context, then check for more.
|
|
3216
|
-
*/
|
|
3217
|
-
private drainQueue;
|
|
3218
|
-
/**
|
|
3219
|
-
* Concurrent strategy: no locking, process immediately — but cap
|
|
3220
|
-
* simultaneous handlers per thread at `maxConcurrent` (default Infinity).
|
|
3221
|
-
*/
|
|
3222
|
-
private handleConcurrent;
|
|
3223
|
-
private acquireConcurrentSlot;
|
|
3224
|
-
private releaseConcurrentSlot;
|
|
3225
|
-
/**
|
|
3226
|
-
* Dispatch a message to the appropriate handler chain based on
|
|
3227
|
-
* subscription status, mention detection, and pattern matching.
|
|
3228
|
-
*/
|
|
3229
|
-
private dispatchToHandlers;
|
|
3230
|
-
private createThread;
|
|
3231
|
-
/**
|
|
3232
|
-
* Detect if the bot was mentioned in the message.
|
|
3233
|
-
* All adapters normalize mentions to @name format, so we just check for @username.
|
|
3234
|
-
*/
|
|
3235
|
-
private detectMention;
|
|
3236
|
-
private escapeRegex;
|
|
3237
|
-
/**
|
|
3238
|
-
* Reconstruct a proper Message instance from a dequeued entry.
|
|
3239
|
-
* After JSON roundtrip through the state adapter, the message is a plain
|
|
3240
|
-
* object (not a Message instance). This restores class invariants like
|
|
3241
|
-
* `links` defaulting to `[]` and `metadata.dateSent` being a Date.
|
|
3242
|
-
*/
|
|
3243
|
-
private rehydrateMessage;
|
|
3244
|
-
private runHandlers;
|
|
3245
|
-
}
|
|
3246
|
-
|
|
3247
110
|
/**
|
|
3248
111
|
* Normalizes an async iterable stream for use with `thread.post()`.
|
|
3249
112
|
*
|
|
@@ -3848,4 +711,4 @@ declare const Select: SelectComponent;
|
|
|
3848
711
|
declare const SelectOption: SelectOptionComponent;
|
|
3849
712
|
declare const TextInput: TextInputComponent;
|
|
3850
713
|
|
|
3851
|
-
export {
|
|
714
|
+
export { Actions, ActionsComponent, Adapter, AdapterPostableMessage, type AddTaskOptions, BaseFormatConverter, Button, ButtonComponent, Card, CardChild, CardComponent, CardElement, CardLink, CardLinkComponent, CardText, ChatError, type CompletePlanOptions, CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, DividerComponent, EmojiFormats, EmojiMapConfig, EmojiResolver, EmojiValue, ExternalSelect, ExternalSelectComponent, Field, FieldComponent, Fields, FieldsComponent, type FormatConverter, Image, ImageComponent, LinkButton, LinkButtonComponent, LockError, type MarkdownConverter, MessageHistoryCache, type MessageHistoryConfig, Modal, ModalComponent, NotImplementedError, Plan, type PlanContent, type PlanModel, type PlanModelTask, type PlanTask, type PlanTaskStatus, PostableObject, PostableObjectContext, RadioSelect, RadioSelectComponent, RateLimitError, Section, SectionComponent, Select, SelectComponent, SelectOption, SelectOptionComponent, type StartPlanOptions, StreamChunk, StreamEvent, StreamingMarkdownRenderer, StreamingPlan, type StreamingPlanData, type StreamingPlanOptions, Table, TextComponent, TextInput, TextInputComponent, ThreadHistoryCache, ThreadHistoryConfig, type UpdateTaskInput, WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, emoji, emphasis, fromFullStream, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, reviver, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toCardElement, toModalElement, toPlainText, walkAst };
|