@windmill-labs/chat-sdk 0.0.0-stage → 1.831.0

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.
@@ -0,0 +1,33 @@
1
+ import { type WindmillChatApi } from './api';
2
+ import { type AgentStreamEvent } from './stream';
3
+ export type FollowEvent =
4
+ /** Agent events decoded from the job's result stream; empty when a chunk ended mid-line. */
5
+ {
6
+ type: 'stream';
7
+ events: AgentStreamEvent[];
8
+ }
9
+ /** `streamLost`: the result was polled after the stream failed, so what streamed may stop short. */
10
+ | {
11
+ type: 'completed';
12
+ result: unknown;
13
+ streamLost?: boolean;
14
+ };
15
+ /**
16
+ * Follows a job to completion across the server's stream timeouts: every
17
+ * connection resumes from the last `stream_offset`, so no delta is repeated and
18
+ * the flow is never re-run. `onOffset` reports each offset, and its loss, so a
19
+ * caller can resume later from another connection (see the AI SDK transport).
20
+ *
21
+ * The offset indexes the stream of one sub-job (`flow_stream_job_id`, the flow's
22
+ * streaming step). A retried step gets a new one, so when the id changes the
23
+ * offset is dropped and the connection reopened from that sub-job's start.
24
+ *
25
+ * A connection that fails (a proxy restarting, the network dropping) is retried with
26
+ * backoff. The run is still going, so after a few failures in a row the job's result is
27
+ * polled instead: the rest of the answer is not streamed, but the turn still ends.
28
+ */
29
+ export declare function followJob(api: WindmillChatApi, jobId: string, options?: {
30
+ signal?: AbortSignal;
31
+ streamOffset?: number;
32
+ onOffset?: (offset: number | undefined) => void;
33
+ }): AsyncGenerator<FollowEvent>;
@@ -0,0 +1,17 @@
1
+ import type { ChatMessage, Conversation, StorageLike } from './types';
2
+ export interface LocalHistory {
3
+ listConversations(): Conversation[];
4
+ getMessages(conversationId: string): ChatMessage[];
5
+ upsertConversation(conversation: Conversation): void;
6
+ /** Changes a stored conversation's title in place; unlike `upsertConversation`, its position is kept. */
7
+ renameConversation(conversationId: string, title: string): void;
8
+ saveMessages(conversationId: string, messages: ChatMessage[]): void;
9
+ deleteConversation(conversationId: string): void;
10
+ }
11
+ /**
12
+ * Conversation history in the browser, for a credential shared by every visitor
13
+ * (server history would show them each other's chats). One key per flow, and per
14
+ * `storageKey` when the caller sets one; every operation re-reads the store so
15
+ * several tabs stay consistent.
16
+ */
17
+ export declare function createLocalHistory(storage: StorageLike | undefined, key: string): LocalHistory;
package/dist/index.cjs ADDED
@@ -0,0 +1,18 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_follow = require("./follow-Dug-Afeu.cjs");
3
+ const require_chat = require("./chat-u1tspn7Q.cjs");
4
+ exports.CHAT_UPLOADS_PREFIX = require_chat.CHAT_UPLOADS_PREFIX;
5
+ exports.TurnRunningError = require_follow.TurnRunningError;
6
+ exports.WindmillApiError = require_follow.WindmillApiError;
7
+ exports.WindmillChatApi = require_follow.WindmillChatApi;
8
+ exports.conversationIdFor = require_follow.conversationIdFor;
9
+ exports.createChat = require_chat.createChat;
10
+ exports.createStreamEventParser = require_follow.createStreamEventParser;
11
+ exports.detectRawApp = require_chat.detectRawApp;
12
+ exports.extractChatAnswer = require_follow.extractChatAnswer;
13
+ exports.followJob = require_follow.followJob;
14
+ exports.parseStreamEvents = require_follow.parseStreamEvents;
15
+ exports.readServerSentEvents = require_follow.readServerSentEvents;
16
+ exports.storedAttachmentName = require_chat.storedAttachmentName;
17
+ exports.turnRunningError = require_follow.turnRunningError;
18
+ exports.uploadAttachments = require_chat.uploadAttachments;
@@ -0,0 +1,8 @@
1
+ export { createChat } from './chat';
2
+ export { detectRawApp, type RawAppContext } from './config';
3
+ export { WindmillChatApi, WindmillApiError, TurnRunningError, turnRunningError, readServerSentEvents, type RunningTurn, type WindmillChatApiOptions, type ConversationKind, type FlowConversation, type FlowConversationMessage, type JobUpdateEvent, type CompletedJobResult } from './api';
4
+ export { parseStreamEvents, createStreamEventParser, type AgentStreamEvent } from './stream';
5
+ export { followJob, type FollowEvent } from './follow';
6
+ export { extractChatAnswer, conversationIdFor } from './utils';
7
+ export { storedAttachmentName, uploadAttachments, CHAT_UPLOADS_PREFIX, type UploadedAttachment } from './attachments';
8
+ export type { AttachmentsInput, AttachmentUpload, Chat, ChatAttachment, ChatMessage, ChatOptions, ChatRole, ChatState, ChatStatus, Conversation, FetchLike, HistoryMode, SendMessageOptions, StorageLike, TokenSource, ToolInvocation } from './types';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { _ as WindmillApiError, b as turnRunningError, g as TurnRunningError, h as parseStreamEvents, m as createStreamEventParser, o as extractChatAnswer, r as conversationIdFor, t as followJob, v as WindmillChatApi, y as readServerSentEvents } from "./follow-DXfmfPfr.js";
2
+ import { a as detectRawApp, i as uploadAttachments, n as CHAT_UPLOADS_PREFIX, r as storedAttachmentName, t as createChat } from "./chat-DgINfcUU.js";
3
+ export { CHAT_UPLOADS_PREFIX, TurnRunningError, WindmillApiError, WindmillChatApi, conversationIdFor, createChat, createStreamEventParser, detectRawApp, extractChatAnswer, followJob, parseStreamEvents, readServerSentEvents, storedAttachmentName, turnRunningError, uploadAttachments };
package/dist/react.cjs ADDED
@@ -0,0 +1,64 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_chat = require("./chat-u1tspn7Q.cjs");
3
+ let react = require("react");
4
+ //#region src/react.ts
5
+ /**
6
+ * A chat on a chat-mode flow. The chat is created once per `flowPath`, `baseUrl`,
7
+ * `workspace`, `history`, `storageKey`, credential and presence of `run`, and
8
+ * destroyed on unmount. A credential change is a new user, whose chat must not
9
+ * carry the previous one's state: a different token string, or a switch between no
10
+ * token, a token string and a token function, all recreate it. A token function is
11
+ * read through a ref on every call, so a new closure per render changes what the
12
+ * next call runs and nothing else; pass a `storageKey` per user when local history
13
+ * must not be shared. `run`, the callbacks and `inputs` are read the same way: the
14
+ * latest render's values go with the next message.
15
+ */
16
+ function useWindmillChat(options) {
17
+ const latest = (0, react.useRef)(options);
18
+ latest.current = options;
19
+ const credential = typeof options.token === "function" ? "fn" : typeof options.token === "string" ? `str:${options.token}` : "none";
20
+ const customRun = options.run !== void 0;
21
+ const chat = (0, react.useMemo)(() => require_chat.createChat({
22
+ ...options,
23
+ inputs: void 0,
24
+ token: typeof options.token === "function" ? () => {
25
+ const token = latest.current.token;
26
+ return typeof token === "function" ? token() : token ?? "";
27
+ } : options.token,
28
+ run: customRun ? (args, turn) => (latest.current.run ?? options.run)(args, turn) : void 0,
29
+ onFinish: (turn) => latest.current.onFinish?.(turn),
30
+ onError: (error, turn) => latest.current.onError?.(error, turn)
31
+ }), [
32
+ options.flowPath,
33
+ options.baseUrl,
34
+ options.workspace,
35
+ options.history,
36
+ options.storageKey,
37
+ credential,
38
+ customRun
39
+ ]);
40
+ (0, react.useEffect)(() => () => chat.destroy(), [chat]);
41
+ const state = (0, react.useSyncExternalStore)(chat.subscribe, chat.getState, chat.getState);
42
+ return (0, react.useMemo)(() => ({
43
+ ...state,
44
+ chat,
45
+ sendMessage: (text, options) => chat.sendMessage(text, {
46
+ ...options,
47
+ inputs: {
48
+ ...latest.current.inputs,
49
+ ...options?.inputs
50
+ }
51
+ }),
52
+ resumeTurn: chat.resumeTurn,
53
+ stop: chat.stop,
54
+ newConversation: chat.newConversation,
55
+ selectConversation: chat.selectConversation,
56
+ loadConversations: chat.loadConversations,
57
+ deleteConversation: chat.deleteConversation,
58
+ renameConversation: chat.renameConversation,
59
+ loadOlderMessages: chat.loadOlderMessages,
60
+ refreshMessages: chat.refreshMessages
61
+ }), [state, chat]);
62
+ }
63
+ //#endregion
64
+ exports.useWindmillChat = useWindmillChat;
@@ -0,0 +1,16 @@
1
+ import type { Chat, ChatOptions, ChatState } from './types';
2
+ export type UseWindmillChat = ChatState & Pick<Chat, 'sendMessage' | 'resumeTurn' | 'stop' | 'newConversation' | 'selectConversation' | 'loadConversations' | 'deleteConversation' | 'renameConversation' | 'loadOlderMessages' | 'refreshMessages'> & {
3
+ chat: Chat;
4
+ };
5
+ /**
6
+ * A chat on a chat-mode flow. The chat is created once per `flowPath`, `baseUrl`,
7
+ * `workspace`, `history`, `storageKey`, credential and presence of `run`, and
8
+ * destroyed on unmount. A credential change is a new user, whose chat must not
9
+ * carry the previous one's state: a different token string, or a switch between no
10
+ * token, a token string and a token function, all recreate it. A token function is
11
+ * read through a ref on every call, so a new closure per render changes what the
12
+ * next call runs and nothing else; pass a `storageKey` per user when local history
13
+ * must not be shared. `run`, the callbacks and `inputs` are read the same way: the
14
+ * latest render's values go with the next message.
15
+ */
16
+ export declare function useWindmillChat(options: ChatOptions): UseWindmillChat;
package/dist/react.js ADDED
@@ -0,0 +1,63 @@
1
+ import { t as createChat } from "./chat-DgINfcUU.js";
2
+ import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
3
+ //#region src/react.ts
4
+ /**
5
+ * A chat on a chat-mode flow. The chat is created once per `flowPath`, `baseUrl`,
6
+ * `workspace`, `history`, `storageKey`, credential and presence of `run`, and
7
+ * destroyed on unmount. A credential change is a new user, whose chat must not
8
+ * carry the previous one's state: a different token string, or a switch between no
9
+ * token, a token string and a token function, all recreate it. A token function is
10
+ * read through a ref on every call, so a new closure per render changes what the
11
+ * next call runs and nothing else; pass a `storageKey` per user when local history
12
+ * must not be shared. `run`, the callbacks and `inputs` are read the same way: the
13
+ * latest render's values go with the next message.
14
+ */
15
+ function useWindmillChat(options) {
16
+ const latest = useRef(options);
17
+ latest.current = options;
18
+ const credential = typeof options.token === "function" ? "fn" : typeof options.token === "string" ? `str:${options.token}` : "none";
19
+ const customRun = options.run !== void 0;
20
+ const chat = useMemo(() => createChat({
21
+ ...options,
22
+ inputs: void 0,
23
+ token: typeof options.token === "function" ? () => {
24
+ const token = latest.current.token;
25
+ return typeof token === "function" ? token() : token ?? "";
26
+ } : options.token,
27
+ run: customRun ? (args, turn) => (latest.current.run ?? options.run)(args, turn) : void 0,
28
+ onFinish: (turn) => latest.current.onFinish?.(turn),
29
+ onError: (error, turn) => latest.current.onError?.(error, turn)
30
+ }), [
31
+ options.flowPath,
32
+ options.baseUrl,
33
+ options.workspace,
34
+ options.history,
35
+ options.storageKey,
36
+ credential,
37
+ customRun
38
+ ]);
39
+ useEffect(() => () => chat.destroy(), [chat]);
40
+ const state = useSyncExternalStore(chat.subscribe, chat.getState, chat.getState);
41
+ return useMemo(() => ({
42
+ ...state,
43
+ chat,
44
+ sendMessage: (text, options) => chat.sendMessage(text, {
45
+ ...options,
46
+ inputs: {
47
+ ...latest.current.inputs,
48
+ ...options?.inputs
49
+ }
50
+ }),
51
+ resumeTurn: chat.resumeTurn,
52
+ stop: chat.stop,
53
+ newConversation: chat.newConversation,
54
+ selectConversation: chat.selectConversation,
55
+ loadConversations: chat.loadConversations,
56
+ deleteConversation: chat.deleteConversation,
57
+ renameConversation: chat.renameConversation,
58
+ loadOlderMessages: chat.loadOlderMessages,
59
+ refreshMessages: chat.refreshMessages
60
+ }), [state, chat]);
61
+ }
62
+ //#endregion
63
+ export { useWindmillChat };
@@ -0,0 +1,38 @@
1
+ /** The events an AI agent step streams, one JSON object per line of the job's result stream. */
2
+ export type AgentStreamEvent = {
3
+ type: 'token_delta';
4
+ content: string;
5
+ } | {
6
+ type: 'reasoning_token_delta';
7
+ content: string;
8
+ } | {
9
+ type: 'tool_call';
10
+ call_id: string;
11
+ function_name: string;
12
+ } | {
13
+ type: 'tool_call_arguments';
14
+ call_id: string;
15
+ function_name: string;
16
+ arguments: string;
17
+ } | {
18
+ type: 'tool_execution';
19
+ call_id: string;
20
+ function_name: string;
21
+ } | {
22
+ type: 'tool_result';
23
+ call_id: string;
24
+ function_name: string;
25
+ result: string;
26
+ success: boolean;
27
+ };
28
+ /**
29
+ * Incremental parser for the `new_result_stream` chunks of a job update. A chunk is
30
+ * not guaranteed to end on a line boundary, so an incomplete last line waits for the
31
+ * next `push` (or `flush` once the job completes).
32
+ */
33
+ export declare function createStreamEventParser(): {
34
+ push(chunk: string): AgentStreamEvent[];
35
+ flush(): AgentStreamEvent[];
36
+ };
37
+ /** Parses complete NDJSON lines; lines that aren't agent events are skipped. */
38
+ export declare function parseStreamEvents(ndjson: string): AgentStreamEvent[];
@@ -0,0 +1,208 @@
1
+ import type { RunningTurn } from './api';
2
+ export type ChatRole = 'user' | 'assistant' | 'tool' | 'system';
3
+ /**
4
+ * - `idle`: ready for a message
5
+ * - `submitted`: the message was sent, no answer has started streaming yet
6
+ * - `streaming`: the answer is arriving
7
+ * - `error`: the last turn failed; `error` holds why. Sending again is allowed.
8
+ */
9
+ export type ChatStatus = 'idle' | 'submitted' | 'streaming' | 'error';
10
+ /**
11
+ * Where conversation history lives.
12
+ * - `server`: Windmill's conversation store. Each Windmill user only sees their own
13
+ * conversations, so use it with the viewer's own session or a per-user token.
14
+ * - `local`: the browser's storage. Right for a token shared by every visitor.
15
+ * - `none`: nothing is kept beyond the current page.
16
+ */
17
+ export type HistoryMode = 'server' | 'local' | 'none';
18
+ export interface ToolInvocation {
19
+ callId?: string;
20
+ name: string;
21
+ /** The arguments the model passed, as a JSON string. */
22
+ arguments?: string;
23
+ result?: string;
24
+ status: 'running' | 'success' | 'error';
25
+ }
26
+ export interface ChatAttachment {
27
+ input: string;
28
+ s3: string;
29
+ storage?: string;
30
+ filename?: string;
31
+ }
32
+ export interface ChatMessage {
33
+ id: string;
34
+ role: ChatRole;
35
+ content: string;
36
+ /** The model's reasoning summary, when the provider streams one. */
37
+ reasoning?: string;
38
+ /** The call on a `tool` message, from the live stream or its stored row; `callId` is only known from the stream. */
39
+ tool?: ToolInvocation;
40
+ success: boolean;
41
+ createdAt: string;
42
+ jobId?: string;
43
+ /** The flow step that produced the message. */
44
+ stepName?: string;
45
+ /** The files a user message carried, as object-storage references. */
46
+ attachments?: ChatAttachment[];
47
+ /** True while the message is optimistic or still streaming. */
48
+ pending: boolean;
49
+ /** Id of the persisted row once the server has it; `id` itself never changes, so list keys stay stable. */
50
+ serverId?: string;
51
+ /** The server's cursor for a persisted message; unset for one created on the client. */
52
+ seq?: number;
53
+ }
54
+ export interface Conversation {
55
+ id: string;
56
+ title: string | undefined;
57
+ createdAt: string;
58
+ updatedAt: string;
59
+ /**
60
+ * Started from the flow editor's test panel rather than a deployed run. Known once the
61
+ * server has listed the conversation; unset for one only this client has seen.
62
+ */
63
+ isTest?: boolean;
64
+ /**
65
+ * The turn the conversation was still answering when the server listed it: started in
66
+ * another tab, or before this chat was created. Pass it to `resumeTurn` to follow it.
67
+ */
68
+ runningTurn?: RunningTurn;
69
+ }
70
+ export interface ChatState {
71
+ conversationId: string | undefined;
72
+ messages: ChatMessage[];
73
+ status: ChatStatus;
74
+ error: Error | undefined;
75
+ conversations: Conversation[];
76
+ /** Where history is read from. Starts as configured; drops from `server` to `local` when the credential cannot read conversations. */
77
+ history: HistoryMode;
78
+ loadingMessages: boolean;
79
+ hasMoreMessages: boolean;
80
+ }
81
+ export type TokenSource = string | (() => string | Promise<string>);
82
+ export type StorageLike = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
83
+ export type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
84
+ export interface ChatOptions {
85
+ /** Path of a deployed flow with chat mode enabled, e.g. `f/support/assistant`. */
86
+ flowPath: string;
87
+ /** Windmill origin, e.g. `https://app.windmill.dev`. Detected inside a raw app. */
88
+ baseUrl?: string;
89
+ /** Detected inside a raw app. */
90
+ workspace?: string;
91
+ /**
92
+ * A Windmill token, or a function returning one (called before every request, so it
93
+ * can fetch a short-lived token from your backend). Omit it to use the viewer's
94
+ * session: the cookie on the Windmill origin, or a sandboxed raw app's SDK token.
95
+ */
96
+ token?: TokenSource;
97
+ /** Defaults to `server` with the viewer's session and `local` with an explicit token. */
98
+ history?: HistoryMode;
99
+ /** Extra flow inputs sent with every message, next to `user_message`. */
100
+ inputs?: Record<string, unknown>;
101
+ fetch?: FetchLike;
102
+ /** Backing store for `local` history. Defaults to `localStorage`. */
103
+ storage?: StorageLike;
104
+ /**
105
+ * Namespace for `local` history, e.g. the signed-in user's id. Local history is
106
+ * per browser, per flow; without this, users sharing a browser share it.
107
+ */
108
+ storageKey?: string;
109
+ /** Messages fetched per page of server history. */
110
+ pageSize?: number;
111
+ /**
112
+ * How often, in milliseconds, the server polls a running turn for the stream
113
+ * (Enterprise; 50 at the fastest, other servers ignore it). Unset, the server
114
+ * relaxes from 100 ms to 3 s over a long turn.
115
+ */
116
+ pollDelayMs?: number;
117
+ /**
118
+ * Runs the flow for a turn and returns the job id, instead of the deployed flow at
119
+ * `flowPath`. `args` carries `user_message` and the extra inputs; the run must set
120
+ * `memory_id` to the conversation id for the conversation and its memory to line up.
121
+ * Windmill's own editor uses this to chat with an undeployed flow through a preview run.
122
+ */
123
+ run?: (args: Record<string, unknown>, turn: {
124
+ conversationId: string;
125
+ signal: AbortSignal;
126
+ }) => Promise<string>;
127
+ /** Called once a turn has its answer (a failed flow included: its error is the answer). */
128
+ onFinish?: (turn: {
129
+ conversationId: string;
130
+ jobId?: string;
131
+ messages: ChatMessage[];
132
+ }) => void;
133
+ /** Called when a turn could not run or be followed; `state.error` holds the same error. */
134
+ onError?: (error: Error, turn: {
135
+ conversationId: string;
136
+ jobId?: string;
137
+ }) => void;
138
+ }
139
+ /** A file sent with a message. It is uploaded to the workspace's object storage before the run starts. */
140
+ export interface AttachmentUpload {
141
+ /** Kept as the last segment of the stored key, its extension corrected to the media type for PNG, JPEG and PDF. */
142
+ name: string;
143
+ /** The bytes: a Blob, or a `data:` URL of them. */
144
+ data: Blob | string;
145
+ /** The file's media type. Defaults to the Blob's own type, or the data URL's. */
146
+ mediaType?: string;
147
+ }
148
+ /** The flow input the uploaded attachments are handed to: an `s3object` (`multiple: false`) or an `s3object[]`. */
149
+ export interface AttachmentsInput {
150
+ name: string;
151
+ multiple: boolean;
152
+ }
153
+ export interface SendMessageOptions {
154
+ /** Extra flow inputs for this message, on top of `ChatOptions.inputs`. */
155
+ inputs?: Record<string, unknown>;
156
+ /**
157
+ * Files to upload and hand to the flow as `{ s3, filename }` objects in `attachmentsInput`,
158
+ * the way an AI agent step reads `user_attachments`. A failed upload rejects `sendMessage`
159
+ * and the run never starts; `stop()` during the upload does the same with an `AbortError`.
160
+ */
161
+ attachments?: AttachmentUpload[];
162
+ /** Required with `attachments`, which also need message text. With `multiple: false`, more than one attachment is refused before anything uploads. */
163
+ attachmentsInput?: AttachmentsInput;
164
+ }
165
+ export interface Chat {
166
+ getState(): ChatState;
167
+ /** Calls `listener` now and on every change; returns the unsubscribe function (Svelte store contract). */
168
+ subscribe(listener: (state: ChatState) => void): () => void;
169
+ /**
170
+ * Sends a message in the current conversation, starting one when there is none. Resolves
171
+ * when the answer is complete. Rejects when the message could not be sent at all — a turn
172
+ * already running, an attachment that failed to upload — without touching the transcript.
173
+ * A conversation still answering a message sent elsewhere rejects with `TurnRunningError`:
174
+ * follow that turn with `resumeTurn`, then send again.
175
+ */
176
+ sendMessage(text: string, options?: SendMessageOptions): Promise<void>;
177
+ /**
178
+ * Follows a turn of the current conversation that this chat did not start, as named by
179
+ * `Conversation.runningTurn` or a `TurnRunningError`: its answer streams into `messages`
180
+ * from the start and the turn finishes like one sent here. Server history only; resolves
181
+ * when the answer is complete, at once when a turn is already being followed.
182
+ */
183
+ resumeTurn(turn: RunningTurn): Promise<void>;
184
+ /** Stops following the answer and asks Windmill to cancel the run. */
185
+ stop(): Promise<void>;
186
+ newConversation(): void;
187
+ selectConversation(conversationId: string): Promise<void>;
188
+ /**
189
+ * `kind` narrows server history to the flow editor's test chats, the deployed flow's
190
+ * own (the server's default), or both. Local history has no test chats and ignores it.
191
+ */
192
+ loadConversations(options?: {
193
+ page?: number;
194
+ perPage?: number;
195
+ kind?: 'test' | 'deployed' | 'all';
196
+ }): Promise<Conversation[]>;
197
+ deleteConversation(conversationId: string): Promise<void>;
198
+ /** Sets a conversation's title. The list keeps its order: only a turn moves a conversation. */
199
+ renameConversation(conversationId: string, title: string): Promise<void>;
200
+ loadOlderMessages(): Promise<void>;
201
+ /**
202
+ * Reads what the current conversation gained since its newest message held here, such
203
+ * as a turn another tab ran. Server history only; does nothing while a turn is followed.
204
+ */
205
+ refreshMessages(): Promise<void>;
206
+ /** Stops background work (stream, polling) and writes local history out. The chat stays usable. */
207
+ destroy(): void;
208
+ }
@@ -0,0 +1,33 @@
1
+ export declare function randomId(): string;
2
+ export declare function isUuid(value: string): boolean;
3
+ /**
4
+ * The Windmill conversation id for an arbitrary chat id. A UUID is used as is;
5
+ * anything else (an AI SDK chat id, for instance) maps to the same UUID every time,
6
+ * so a page can reopen its conversation without storing a second id. Hashed in plain
7
+ * JS: `crypto.subtle` only exists in secure contexts, and the mapping must not depend
8
+ * on the origin's scheme.
9
+ */
10
+ export declare function conversationIdFor(chatId: string): string;
11
+ export declare function parseJsonOr(text: string | undefined): unknown;
12
+ export declare function now(): string;
13
+ /** Same rule as the server: the first message, cut to 25 characters. */
14
+ export declare function conversationTitle(firstMessage: string): string;
15
+ /** The server's bound on a typed title: 252 characters plus an ellipsis fits its 255-char column. */
16
+ export declare function truncateTitle(title: string): string;
17
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
18
+ export declare function abortError(): Error;
19
+ export declare function isAbortError(e: unknown): boolean;
20
+ /**
21
+ * The text a chat shows for a flow result, following what Windmill persists as the
22
+ * assistant message when the last step is not an AI agent: `windmill_chat_answer`
23
+ * when the result carries one (null means no message), an agent result's `output`,
24
+ * a string as is, anything else as JSON.
25
+ */
26
+ export declare function extractChatAnswer(result: unknown): string | undefined;
27
+ /** A completed job whose result is Windmill's error envelope. */
28
+ export declare function isErrorResult(result: unknown): result is {
29
+ error: Record<string, unknown>;
30
+ };
31
+ export declare function errorResultMessage(result: {
32
+ error: Record<string, unknown>;
33
+ }): string;
package/package.json CHANGED
@@ -1,6 +1,108 @@
1
1
  {
2
2
  "name": "@windmill-labs/chat-sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "Build chat interfaces on Windmill flows deployed in chat mode, from any frontend or raw app",
4
+ "version": "1.831.0",
5
+ "author": "Ruben Fiszel",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/windmill-labs/windmill/tree/main/chat-sdk#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/windmill-labs/windmill.git",
11
+ "directory": "chat-sdk"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/windmill-labs/windmill/issues"
15
+ },
16
+ "keywords": [
17
+ "windmill",
18
+ "chat",
19
+ "ai",
20
+ "agent",
21
+ "react"
22
+ ],
23
+ "sideEffects": false,
24
+ "type": "module",
25
+ "main": "dist/index.cjs",
26
+ "module": "dist/index.js",
27
+ "types": "dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "import": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "require": {
35
+ "types": "./dist/index.d.ts",
36
+ "default": "./dist/index.cjs"
37
+ }
38
+ },
39
+ "./react": {
40
+ "import": {
41
+ "types": "./dist/react.d.ts",
42
+ "default": "./dist/react.js"
43
+ },
44
+ "require": {
45
+ "types": "./dist/react.d.ts",
46
+ "default": "./dist/react.cjs"
47
+ }
48
+ },
49
+ "./ai-sdk": {
50
+ "import": {
51
+ "types": "./dist/ai-sdk.d.ts",
52
+ "default": "./dist/ai-sdk.js"
53
+ },
54
+ "require": {
55
+ "types": "./dist/ai-sdk.d.ts",
56
+ "default": "./dist/ai-sdk.cjs"
57
+ }
58
+ },
59
+ "./assistant-ui": {
60
+ "import": {
61
+ "types": "./dist/assistant-ui.d.ts",
62
+ "default": "./dist/assistant-ui.js"
63
+ },
64
+ "require": {
65
+ "types": "./dist/assistant-ui.d.ts",
66
+ "default": "./dist/assistant-ui.cjs"
67
+ }
68
+ }
69
+ },
70
+ "files": [
71
+ "dist",
72
+ "README.md"
73
+ ],
74
+ "scripts": {
75
+ "build": "tsdown && tsc -p tsconfig.build.json",
76
+ "check": "tsc --noEmit",
77
+ "test": "bun test"
78
+ },
79
+ "peerDependencies": {
80
+ "@assistant-ui/react": ">=0.15",
81
+ "ai": ">=5",
82
+ "react": ">=18"
83
+ },
84
+ "peerDependenciesMeta": {
85
+ "@assistant-ui/react": {
86
+ "optional": true
87
+ },
88
+ "ai": {
89
+ "optional": true
90
+ },
91
+ "react": {
92
+ "optional": true
93
+ }
94
+ },
95
+ "devDependencies": {
96
+ "@ai-sdk/react": "^4.0.102",
97
+ "@assistant-ui/react": "^0.15.19",
98
+ "@happy-dom/global-registrator": "^20.14.5",
99
+ "@types/bun": "^1.3.0",
100
+ "@types/react": "^19.0.0",
101
+ "@types/react-dom": "^19.3.0",
102
+ "ai": "^7.0.99",
103
+ "react": "^19.0.0",
104
+ "react-dom": "^19.3.0",
105
+ "tsdown": "^0.12.9",
106
+ "typescript": "^5.4.5"
107
+ }
108
+ }