@camelai/run 0.0.0-stage → 0.11.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,237 @@
1
+ /**
2
+ * A chat with one agent, for any UI framework: the agent's messages as simple typed parts, its status,
3
+ * the input it waits on, and the actions (send, answer, stop, loadOlder), over your server's agent
4
+ * handler (`createAgentHandler`) and the browser watcher. No dependencies and no Node APIs.
5
+ *
6
+ * const chat = createAgentChat({ endpoint: "/api/agent" });
7
+ * chat.subscribe(() => render(chat.getSnapshot()));
8
+ * await chat.send("Where is my order?");
9
+ *
10
+ * The snapshot is immutable, and a message or part that did not change is the same object from one
11
+ * snapshot to the next, so a UI re-renders only what changed (and keys rows by `id`: a sent message
12
+ * keeps its id when the agent's copy of it arrives).
13
+ */
14
+ import { type WatchOptions } from "./watch.ts";
15
+ import type { AgentInput, Sender } from "./typescript.ts";
16
+ import type { AgentEvent, AssistantMessage, ImageContent, Message, TextContent } from "./types.ts";
17
+ export type { AgentInput, Sender };
18
+ export type ChatStatus = "connecting" | "ready" | "submitted" | "streaming" | "input_required" | "error";
19
+ /** A failure: `code` is stable (the handler's or the runtime's), `message` is for people. */
20
+ export interface ChatError {
21
+ code: string;
22
+ message: string;
23
+ status?: number;
24
+ }
25
+ export interface TextPart {
26
+ type: "text";
27
+ id: string;
28
+ text: string;
29
+ streaming: boolean;
30
+ }
31
+ export interface ReasoningPart {
32
+ type: "reasoning";
33
+ id: string;
34
+ text: string;
35
+ streaming: boolean;
36
+ redacted?: boolean;
37
+ }
38
+ export interface ImagePart {
39
+ type: "image";
40
+ id: string;
41
+ url: string;
42
+ mimeType: string;
43
+ }
44
+ /**
45
+ * A file the agent handed over (`present_file`). `url` is a signed link while one is known; else get
46
+ * one with `chat.fileUrl(path)`.
47
+ */
48
+ export interface FilePart {
49
+ type: "file";
50
+ id: string;
51
+ path: string;
52
+ name: string;
53
+ contentType?: string;
54
+ size?: number;
55
+ caption?: string;
56
+ url?: string;
57
+ toolCallId: string;
58
+ }
59
+ export type ToolState = "input_streaming" | "running" | "input_required" | "done" | "error";
60
+ export interface ToolProgress {
61
+ progress?: number;
62
+ total?: number;
63
+ message?: string;
64
+ text?: string;
65
+ }
66
+ /** A tool call: its arguments (partial while `input_streaming`), and its result once there is one. */
67
+ export interface ToolPart {
68
+ type: "tool";
69
+ id: string;
70
+ name: string;
71
+ args: Record<string, unknown>;
72
+ state: ToolState;
73
+ /** The result's text, its content blocks, `details`, and `data`: the text parsed, when it is JSON. */
74
+ result?: {
75
+ text: string;
76
+ content: (TextContent | ImageContent)[];
77
+ details?: unknown;
78
+ data?: unknown;
79
+ };
80
+ progress?: ToolProgress;
81
+ /** What the call waits on from a person, while `input_required`. */
82
+ input?: ChatInput;
83
+ }
84
+ export type UserPart = TextPart | ImagePart;
85
+ export type AssistantPart = TextPart | ReasoningPart | ToolPart | FilePart;
86
+ export interface UserChatMessage {
87
+ id: string;
88
+ role: "user";
89
+ parts: UserPart[];
90
+ text: string;
91
+ from?: Sender;
92
+ metadata?: Record<string, string>;
93
+ createdAt: number;
94
+ /** sending: on its way; sent: the agent has it; failed: see `error` (and `chat.retry(id)`). */
95
+ status: "sending" | "sent" | "failed";
96
+ error?: ChatError;
97
+ /** Its index in the agent's history, once there. */
98
+ index?: number;
99
+ }
100
+ export interface AssistantChatMessage {
101
+ id: string;
102
+ role: "assistant";
103
+ parts: AssistantPart[];
104
+ createdAt: number;
105
+ /** The agent is writing it now. */
106
+ streaming: boolean;
107
+ /** How its last response ended: stopped (by `stop()`) or failed (`error`). */
108
+ stopReason?: "stop" | "aborted" | "error";
109
+ error?: string;
110
+ }
111
+ export type ChatMessage = UserChatMessage | AssistantChatMessage;
112
+ /** Human input the agent waits on, as the runtime lists it, and whether an answer is on its way. */
113
+ export type ChatInput = AgentInput & {
114
+ answering: boolean;
115
+ error?: ChatError;
116
+ };
117
+ export interface ChatSnapshot {
118
+ status: ChatStatus;
119
+ messages: ChatMessage[];
120
+ /** Everything the agent waits on (each is also on its tool part, where the call is shown). */
121
+ inputs: ChatInput[];
122
+ /** The latest failure to connect, send or act; null once things work again. */
123
+ error: ChatError | null;
124
+ hasOlder: boolean;
125
+ connected: boolean;
126
+ agentId: string | null;
127
+ }
128
+ /** An answer's value: approval or url: true/false; question: the label chosen (or labels, or own words), or a map of question to answer; form: its fields. */
129
+ export type InputValue = boolean | string | string[] | Record<string, unknown>;
130
+ export interface InputAnswer {
131
+ action: "accept" | "decline" | "cancel";
132
+ content?: unknown;
133
+ }
134
+ export interface AgentChatOptions {
135
+ /** Your agent handler's URL (`createAgentHandler`), e.g. "/api/agent". */
136
+ endpoint: string;
137
+ /** Which of the user's conversations (the handler maps it to their agent). Default: their one agent. */
138
+ thread?: string;
139
+ /** Headers for every call to the handler (an Authorization header for an API that does not use cookies). */
140
+ headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
141
+ /** Default "same-origin": cookies go with the calls. */
142
+ credentials?: RequestCredentials;
143
+ /** What a message sent while the agent works does: "queue" (default) waits for the turn; "steer" joins it. */
144
+ whileRunning?: "queue" | "steer";
145
+ /** Connect at once (default true). false: call `connect()` (a React provider does, in an effect). */
146
+ autoConnect?: boolean;
147
+ /** Passed to the watcher: `transport`, `pageSize`, `hiddenGraceMs`, `stallMs`. */
148
+ watch?: Pick<WatchOptions, "transport" | "pageSize" | "hiddenGraceMs" | "stallMs">;
149
+ /** Every event of the agent's stream, as it arrives. */
150
+ onEvent?: (event: AgentEvent) => void;
151
+ onError?: (error: ChatError) => void;
152
+ fetch?: typeof globalThis.fetch;
153
+ }
154
+ export interface SendOptions {
155
+ /** JSON for your handler's `onSend` (the page the user is on, say); the agent sees it only if you pass it on. */
156
+ data?: unknown;
157
+ whileRunning?: "queue" | "steer";
158
+ }
159
+ export interface AgentChat {
160
+ getSnapshot(): ChatSnapshot;
161
+ /** Listen for new snapshots; returns the unsubscribe. */
162
+ subscribe(listener: () => void): () => void;
163
+ /** Send a message: it shows at once (status "sending"), keyed by its id, which it keeps. */
164
+ send(text: string, options?: SendOptions): Promise<{
165
+ id: string;
166
+ }>;
167
+ /** Send a failed message again (the same id, so it is never sent twice). */
168
+ retry(messageId: string): Promise<void>;
169
+ /** Answer an input, with a value (see InputValue) or an answer. */
170
+ answer(input: ChatInput | string, value: InputValue | InputAnswer): Promise<void>;
171
+ decline(input: ChatInput | string): Promise<void>;
172
+ /** Stop the agent's running turn. */
173
+ stop(): Promise<void>;
174
+ /** Load the page of history before the oldest message shown; false when there is none. */
175
+ loadOlder(): Promise<boolean>;
176
+ /** A signed download link for a file of the agent's (a FilePart's `path`). */
177
+ fileUrl(path: string): Promise<string>;
178
+ connect(): void;
179
+ /** Close the stream; the state stays, and `connect()` opens it again. */
180
+ disconnect(): void;
181
+ /** Disconnect for good. */
182
+ destroy(): void;
183
+ }
184
+ /** An answer to `input` from a plain value (see InputValue). */
185
+ export declare function answerValue(input: Pick<AgentInput, "kind" | "detail">, value: InputValue): InputAnswer;
186
+ /** A message this client sent that is not in the agent's history (yet). */
187
+ export interface LocalSend {
188
+ id: string;
189
+ text: string;
190
+ createdAt: number;
191
+ status: "sending" | "sent" | "failed";
192
+ error?: ChatError;
193
+ data?: unknown;
194
+ whileRunning?: "queue" | "steer";
195
+ }
196
+ export interface ProjectInput {
197
+ messages: readonly (Message & {
198
+ requestId?: string;
199
+ metadata?: Record<string, string>;
200
+ from?: Sender;
201
+ })[];
202
+ indexes: readonly number[];
203
+ partial: AssistantMessage | null;
204
+ progress?: ReadonlyMap<string, unknown>;
205
+ running: boolean;
206
+ inputs?: readonly ChatInput[];
207
+ local?: readonly LocalSend[];
208
+ /** Signed links to presented files, by path. */
209
+ files?: ReadonlyMap<string, string>;
210
+ }
211
+ /** What the last projection built, to reuse what did not change. */
212
+ export type ProjectMemo = Map<string, {
213
+ sources: readonly unknown[];
214
+ value: unknown;
215
+ children: string[];
216
+ }>;
217
+ /**
218
+ * The chat's messages from the agent's (a watcher's view) and the ones sent from here:
219
+ * - a user message is one message, with the id it was sent with (its `requestId`), so the bubble
220
+ * shown when it was sent is the same row once it arrives;
221
+ * - everything the agent did between two user messages is one assistant message, each tool result
222
+ * folded into its call's part;
223
+ * - a running turn continues the last one only when that one called tools; otherwise it is a new
224
+ * message at the index its first message will take, from its first token (never an empty row);
225
+ * - a message or part whose sources did not change is the same object as last time (`memo`).
226
+ */
227
+ export declare function projectMessages(input: ProjectInput, memo?: ProjectMemo): ChatMessage[];
228
+ /**
229
+ * Where the watcher reads the agent: the runtime (with the browser token), or, when the handler proxies
230
+ * reads, the handler itself (under the thread's path), with the chat's own headers and credentials.
231
+ */
232
+ export declare function readsFrom(minted: {
233
+ url?: string;
234
+ proxy?: boolean;
235
+ }, endpoint: string, thread: string | null | undefined, doFetch: typeof globalThis.fetch, headers?: AgentChatOptions["headers"], credentials?: RequestCredentials): Pick<WatchOptions, "url" | "fetch">;
236
+ /** A chat with the user's agent, through your agent handler: see `AgentChatOptions` and `ChatSnapshot`. */
237
+ export declare function createAgentChat(options: AgentChatOptions): AgentChat;