@cubos/agent-sdk 0.0.1136563
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +446 -0
- package/dist/admin/agents.d.ts +191 -0
- package/dist/admin/ai-providers.d.ts +122 -0
- package/dist/admin/channels.d.ts +261 -0
- package/dist/admin/client-tools.d.ts +74 -0
- package/dist/admin/component-libraries.d.ts +63 -0
- package/dist/admin/conversations.d.ts +434 -0
- package/dist/admin/global.d.ts +137 -0
- package/dist/admin/index.d.ts +67 -0
- package/dist/admin/knowledge-bases.d.ts +142 -0
- package/dist/admin/mcps.d.ts +134 -0
- package/dist/admin/paths.d.ts +9 -0
- package/dist/admin/skills.d.ts +43 -0
- package/dist/admin/task-templates.d.ts +185 -0
- package/dist/admin/users.d.ts +208 -0
- package/dist/cache.d.ts +68 -0
- package/dist/client-tools.d.ts +96 -0
- package/dist/client.d.ts +427 -0
- package/dist/errors.d.ts +52 -0
- package/dist/generated/schema.d.ts +13564 -0
- package/dist/http.d.ts +42 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +1826 -0
- package/dist/index.js.map +30 -0
- package/dist/mapping.d.ts +170 -0
- package/dist/schemas.d.ts +2 -0
- package/dist/sse.d.ts +48 -0
- package/dist/sse.js +209 -0
- package/dist/sse.js.map +11 -0
- package/dist/types.d.ts +263 -0
- package/package.json +51 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { type ConversationCache } from "./cache.js";
|
|
2
|
+
import { type ClientTool, type ClientToolsSession, type ServeClientToolsOptions } from "./client-tools.js";
|
|
3
|
+
import { type TokenSource } from "./http.js";
|
|
4
|
+
import { type FetchLike } from "./sse.js";
|
|
5
|
+
import type { Activity, ClientToolCall, Conversation, ConversationEvent, CreateConversationOptions, EnabledComponents, EventPage, Identity, ListConversationsOptions, Message, MessagePage, Page, PlanSnapshot, Todo, ToolActivity, WorkspaceDir } from "./types.js";
|
|
6
|
+
interface CommonClientOptions {
|
|
7
|
+
/** Where the Cubos Agent core is reachable, e.g. `https://agent.acme.com`.
|
|
8
|
+
* Pass `""` for a same-origin deployment. */
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
/** Tenant slug. Resolved from the token via `/me` when omitted, at the cost
|
|
11
|
+
* of one request the first time it's needed. */
|
|
12
|
+
tenant?: string;
|
|
13
|
+
/** Override for runtimes whose global `fetch` needs wrapping (proxies,
|
|
14
|
+
* instrumentation, Node < 18 polyfills). */
|
|
15
|
+
fetch?: FetchLike;
|
|
16
|
+
/** Per-request ceiling in ms; `0` disables it. Streams are exempt — they are
|
|
17
|
+
* meant to stay open. Defaults to 30s. */
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
/** How many times a 429 is retried, honouring the server's `Retry-After`.
|
|
20
|
+
* `0` surfaces the rate limit to you instead. Defaults to 2. */
|
|
21
|
+
maxRetries?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Where already-loaded conversations are kept so reopening one is instant.
|
|
24
|
+
* Defaults to a bounded in-memory LRU; pass `null` to switch it off, or your
|
|
25
|
+
* own `ConversationCache` to survive a reload.
|
|
26
|
+
*/
|
|
27
|
+
cache?: ConversationCache | null;
|
|
28
|
+
/** Messages retained per conversation. Older ones are dropped from the cache
|
|
29
|
+
* (not from the server) and come back through `loadOlder`. Defaults to 300. */
|
|
30
|
+
cacheMessageLimit?: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A short-lived token, either handed over once or fetched on demand.
|
|
34
|
+
*
|
|
35
|
+
* `getToken` is what a real app wants: tokens expire, and the SDK calls it
|
|
36
|
+
* again with `forceRefresh` after a 401. `token` exists because a script or a
|
|
37
|
+
* test that already holds one shouldn't have to write a closure for it — but a
|
|
38
|
+
* static token cannot be renewed, so it eventually 401s for good.
|
|
39
|
+
*/
|
|
40
|
+
export type UserCredential = {
|
|
41
|
+
getToken: TokenSource;
|
|
42
|
+
} | {
|
|
43
|
+
token: string;
|
|
44
|
+
};
|
|
45
|
+
export type ClientOptions = CommonClientOptions & UserCredential;
|
|
46
|
+
export interface ConversationSubscription {
|
|
47
|
+
/** Stops the streams and releases the connections. Idempotent. */
|
|
48
|
+
close(): void;
|
|
49
|
+
}
|
|
50
|
+
export interface ConversationHandlers {
|
|
51
|
+
/** Fires for the backlog on connect and for each new message after. */
|
|
52
|
+
onMessage?: (message: Message) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Every event, exactly as the server sent it, in stream order — before the
|
|
55
|
+
* handlers above see what it projected into.
|
|
56
|
+
*
|
|
57
|
+
* The curated handlers are a projection over this same frame, not a wall in
|
|
58
|
+
* front of it: taking `onEvent` costs no second connection, no second cursor
|
|
59
|
+
* and no second catch-up, and an app may take both. Reach for it when your UI
|
|
60
|
+
* shows the log itself rather than a conversation.
|
|
61
|
+
*/
|
|
62
|
+
onEvent?: (event: ConversationEvent) => void;
|
|
63
|
+
/** The event stream is live — on first connect and after every reconnect.
|
|
64
|
+
* Whatever catches up on gaps belongs here, not before `subscribe`. */
|
|
65
|
+
onOpen?: () => void;
|
|
66
|
+
/** The agent called a client tool. Its turn is suspended until someone
|
|
67
|
+
* answers the call; see `serveClientTools`. */
|
|
68
|
+
onClientToolCall?: (call: ClientToolCall) => void;
|
|
69
|
+
/** The agent reached for a tool, or that call finished. Fires twice per client
|
|
70
|
+
* tool — once running, once resolved — and once for a server-side tool, which
|
|
71
|
+
* only reports its result. Fold them with `mergeToolActivities`. */
|
|
72
|
+
onToolActivity?: (activity: ToolActivity) => void;
|
|
73
|
+
onActivity?: (activity: Activity) => void;
|
|
74
|
+
/** A turn finished. The one signal that means the agent is done — unlike
|
|
75
|
+
* `onActivity`, which goes quiet mid-turn while a client tool is answered. */
|
|
76
|
+
onTurnDone?: (seq: number) => void;
|
|
77
|
+
/** The plan, with the `seq` that says which answer it belongs to. */
|
|
78
|
+
onTodos?: (todos: Todo[], seq: number) => void;
|
|
79
|
+
onConversation?: (conversation: Conversation) => void;
|
|
80
|
+
/** Every frame's `change_seq`, in the order delivered. Feed the last one back
|
|
81
|
+
* as `since` on the next connect — that is what lets a cache pick up where it
|
|
82
|
+
* left off instead of replaying. */
|
|
83
|
+
onCursor?: (changeSeq: number) => void;
|
|
84
|
+
/** Transient stream failures. The SDK is already reconnecting; this is for
|
|
85
|
+
* logging or a "reconnecting…" hint, not for recovery. */
|
|
86
|
+
onError?: (err: unknown) => void;
|
|
87
|
+
}
|
|
88
|
+
/** What `loadHistory` resolves to: a `MessagePage` plus where it came from. */
|
|
89
|
+
export interface HistoryStart {
|
|
90
|
+
messages: Message[];
|
|
91
|
+
/** The tools behind those messages, folded and ordered by `seq`. */
|
|
92
|
+
toolActivity: ToolActivity[];
|
|
93
|
+
/** Every plan revision behind them, ordered by `seq`. */
|
|
94
|
+
plans: PlanSnapshot[];
|
|
95
|
+
/** Newest finished turn, or null. */
|
|
96
|
+
lastTurnDoneSeq: number | null;
|
|
97
|
+
oldestSeq: number | null;
|
|
98
|
+
/** Pass to `subscribe` as `since`. Null only for a conversation with no
|
|
99
|
+
* events at all. */
|
|
100
|
+
latestChangeSeq: number | null;
|
|
101
|
+
hasOlder: boolean;
|
|
102
|
+
/** True when nothing was fetched. The stream still reconciles it. */
|
|
103
|
+
fromCache: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface ListHandlers {
|
|
106
|
+
onConversation: (conversation: Conversation) => void;
|
|
107
|
+
onError?: (err: unknown) => void;
|
|
108
|
+
}
|
|
109
|
+
export declare class AgentClient {
|
|
110
|
+
#private;
|
|
111
|
+
constructor(options: ClientOptions);
|
|
112
|
+
/** Who the current token acts as. Cached — call `refreshIdentity` after
|
|
113
|
+
* swapping to a token for a different user. */
|
|
114
|
+
me(): Promise<Identity>;
|
|
115
|
+
refreshIdentity(): Promise<Identity>;
|
|
116
|
+
listConversations(opts?: ListConversationsOptions): Promise<Page<Conversation>>;
|
|
117
|
+
/**
|
|
118
|
+
* Every conversation, newest activity first, fetching pages as you go.
|
|
119
|
+
*
|
|
120
|
+
* `listConversations` hands back a cursor to thread through yourself; this is
|
|
121
|
+
* the same thing when you just want them all:
|
|
122
|
+
*
|
|
123
|
+
* ```ts
|
|
124
|
+
* for await (const conversation of client.iterateConversations()) { … }
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* Stops on `break` without fetching the next page.
|
|
128
|
+
*/
|
|
129
|
+
iterateConversations(opts?: {
|
|
130
|
+
pageSize?: number;
|
|
131
|
+
signal?: AbortSignal;
|
|
132
|
+
}): AsyncGenerator<Conversation>;
|
|
133
|
+
/**
|
|
134
|
+
* The conversation's history, newest first, paging backwards as you go — so
|
|
135
|
+
* taking the first N gives you the N most recent messages.
|
|
136
|
+
*
|
|
137
|
+
* A voice message's clip and its transcription are paired within a page; if
|
|
138
|
+
* the two land on either side of a page edge, the clip surfaces with empty
|
|
139
|
+
* text. Raise `pageSize` if that matters for your history depth.
|
|
140
|
+
*/
|
|
141
|
+
iterateMessages(id: string, opts?: {
|
|
142
|
+
pageSize?: number;
|
|
143
|
+
signal?: AbortSignal;
|
|
144
|
+
}): AsyncGenerator<Message>;
|
|
145
|
+
createConversation(opts?: CreateConversationOptions): Promise<Conversation>;
|
|
146
|
+
/**
|
|
147
|
+
* Enable component libraries on `id` — the catalogs of interactive blocks the
|
|
148
|
+
* agent may put in a reply. Replaces the whole list, so send it complete; an
|
|
149
|
+
* empty list takes the agent back to plain markdown.
|
|
150
|
+
*
|
|
151
|
+
* The libraries themselves are authored by the operator, not here: their
|
|
152
|
+
* entries are shown to the model verbatim, and writing prompt content needs an
|
|
153
|
+
* api_key this client will never hold. What you choose is which of them apply
|
|
154
|
+
* to the screen you have open.
|
|
155
|
+
*
|
|
156
|
+
* Returns the slugs together with **every tag they resolve to**. Check that
|
|
157
|
+
* against the components you can actually draw — the agent placing a tag your
|
|
158
|
+
* app has no renderer for is a silent hole in a reply, and this is the only
|
|
159
|
+
* moment both halves are in one place.
|
|
160
|
+
*
|
|
161
|
+
* Takes effect on the agent's next turn — a turn already running keeps the
|
|
162
|
+
* catalog it started with, so what the agent was told it could use and what it
|
|
163
|
+
* is held to are always the same list.
|
|
164
|
+
*/
|
|
165
|
+
setComponentLibraries(id: string, libraries: string[], signal?: AbortSignal): Promise<EnabledComponents>;
|
|
166
|
+
/**
|
|
167
|
+
* Tell the agent what your app currently has on screen — the open page, the
|
|
168
|
+
* selected record, the filters in force. Free-form: prose or JSON, whatever
|
|
169
|
+
* the agent reads best.
|
|
170
|
+
*
|
|
171
|
+
* Cheap and safe to call as often as the screen moves, **including while a
|
|
172
|
+
* turn is running**: it writes no event and starts no turn. The server copies
|
|
173
|
+
* it into the conversation the next time a turn reads it, and only when it
|
|
174
|
+
* differs from what the model was last shown — so repeating an unchanged
|
|
175
|
+
* context costs nothing at all.
|
|
176
|
+
*
|
|
177
|
+
* That is the difference from putting the context in the message text, which
|
|
178
|
+
* is what apps do without this: there it is spent on every message, it shows
|
|
179
|
+
* up in the transcript unless every render path strips it, and only the app
|
|
180
|
+
* that owns the composer can send it.
|
|
181
|
+
*
|
|
182
|
+
* `null` stops reporting. What the model was already shown stays in the log —
|
|
183
|
+
* it is the record of the screen an earlier question was asked against.
|
|
184
|
+
*/
|
|
185
|
+
setContext(id: string, context: string | null, signal?: AbortSignal): Promise<void>;
|
|
186
|
+
listComponentLibraries(id: string, signal?: AbortSignal): Promise<EnabledComponents>;
|
|
187
|
+
getConversation(id: string, signal?: AbortSignal): Promise<Conversation>;
|
|
188
|
+
renameConversation(id: string, title: string, signal?: AbortSignal): Promise<Conversation>;
|
|
189
|
+
archiveConversation(id: string, signal?: AbortSignal): Promise<Conversation>;
|
|
190
|
+
/** One page of history, oldest-first. `limit` counts events, so a page may
|
|
191
|
+
* hold fewer messages than you asked for — `iterateMessages` handles that. */
|
|
192
|
+
listMessages(id: string, opts?: {
|
|
193
|
+
before?: number;
|
|
194
|
+
limit?: number;
|
|
195
|
+
signal?: AbortSignal;
|
|
196
|
+
}): Promise<Message[]>;
|
|
197
|
+
/**
|
|
198
|
+
* The state to open a conversation with: cached if it has been opened before,
|
|
199
|
+
* fetched otherwise.
|
|
200
|
+
*
|
|
201
|
+
* A hit costs no request. It is not stale either — the caller is expected to
|
|
202
|
+
* `subscribe` with the returned `latestChangeSeq`, and the server replays
|
|
203
|
+
* every insert and every mutation past it, so anything that happened while
|
|
204
|
+
* the app was closed arrives as a delta.
|
|
205
|
+
*
|
|
206
|
+
* A cache that throws is treated as a miss: a corrupt store degrades to the
|
|
207
|
+
* network instead of breaking the conversation.
|
|
208
|
+
*/
|
|
209
|
+
loadHistory(id: string, opts?: {
|
|
210
|
+
pageSize?: number;
|
|
211
|
+
signal?: AbortSignal;
|
|
212
|
+
}): Promise<HistoryStart>;
|
|
213
|
+
/**
|
|
214
|
+
* Records the conversation's current state for the next `loadHistory`.
|
|
215
|
+
*
|
|
216
|
+
* `latestChangeSeq` must be the highest cursor folded into `messages` — the
|
|
217
|
+
* page's, or the last one `subscribe`'s `onCursor` reported. Passing a higher
|
|
218
|
+
* one would make the next connect skip the events in between; passing a lower
|
|
219
|
+
* one only costs a replay.
|
|
220
|
+
*
|
|
221
|
+
* Silently does nothing without a cache, so callers need no branch.
|
|
222
|
+
*/
|
|
223
|
+
saveHistory(id: string, state: {
|
|
224
|
+
messages: Message[];
|
|
225
|
+
toolActivity?: ToolActivity[];
|
|
226
|
+
plans?: PlanSnapshot[];
|
|
227
|
+
lastTurnDoneSeq?: number | null;
|
|
228
|
+
oldestSeq: number | null;
|
|
229
|
+
latestChangeSeq: number | null;
|
|
230
|
+
hasOlder: boolean;
|
|
231
|
+
}): Promise<void>;
|
|
232
|
+
/** Forgets one conversation, or every one of this user's. */
|
|
233
|
+
forgetHistory(id?: string): Promise<void>;
|
|
234
|
+
/**
|
|
235
|
+
* `listMessages` plus the cursors a paging UI needs: `oldestSeq` to ask for
|
|
236
|
+
* the page before this one, and `latestChangeSeq` to start a subscription
|
|
237
|
+
* from here instead of replaying everything.
|
|
238
|
+
*
|
|
239
|
+
* `hasOlder` is false only when the server returned fewer events than asked
|
|
240
|
+
* for — the one honest signal that the log is exhausted, since a page can
|
|
241
|
+
* hold events that are not messages.
|
|
242
|
+
*/
|
|
243
|
+
/**
|
|
244
|
+
* One page of the conversation's **event log**, oldest-first — the same rows
|
|
245
|
+
* `listMessagesPage` projects into messages, handed over as they came.
|
|
246
|
+
*
|
|
247
|
+
* Reach for this when the curated view is too small a window: an operator
|
|
248
|
+
* console showing tool calls, an audit trail, anything that has to see the
|
|
249
|
+
* event types the chat surface deliberately drops. `ConversationEvent` tracks
|
|
250
|
+
* the server rather than promising stability across refactors — that is the
|
|
251
|
+
* trade, and it is the same one the REST API already offers.
|
|
252
|
+
*/
|
|
253
|
+
listEventsPage(id: string, opts?: {
|
|
254
|
+
before?: number;
|
|
255
|
+
limit?: number;
|
|
256
|
+
signal?: AbortSignal;
|
|
257
|
+
}): Promise<EventPage>;
|
|
258
|
+
listMessagesPage(id: string, opts?: {
|
|
259
|
+
before?: number;
|
|
260
|
+
limit?: number;
|
|
261
|
+
signal?: AbortSignal;
|
|
262
|
+
}): Promise<MessagePage>;
|
|
263
|
+
sendMessage(id: string, content: string, signal?: AbortSignal): Promise<void>;
|
|
264
|
+
/**
|
|
265
|
+
* One image, with an optional caption that becomes the message's text.
|
|
266
|
+
*
|
|
267
|
+
* png, jpeg, webp and gif, up to 10 MB. The agent sees the picture natively
|
|
268
|
+
* when its chat model has vision, and otherwise a description from the
|
|
269
|
+
* agent's fallback vision model — either way this costs a turn, and is
|
|
270
|
+
* budgeted as one.
|
|
271
|
+
*/
|
|
272
|
+
sendImage(id: string, image: Blob, opts?: {
|
|
273
|
+
filename?: string;
|
|
274
|
+
caption?: string;
|
|
275
|
+
label?: string;
|
|
276
|
+
signal?: AbortSignal;
|
|
277
|
+
}): Promise<void>;
|
|
278
|
+
/**
|
|
279
|
+
* Up to 10 images in ONE message, so the agent reasons over the set instead of
|
|
280
|
+
* one turn per picture. `label` names an image for the model, which lets it
|
|
281
|
+
* answer about "the receipt" rather than "the second image"; `caption` is the
|
|
282
|
+
* message's own text, shared by the set.
|
|
283
|
+
*/
|
|
284
|
+
sendImages(id: string, images: Array<{
|
|
285
|
+
image: Blob;
|
|
286
|
+
filename?: string;
|
|
287
|
+
label?: string;
|
|
288
|
+
}>, opts?: {
|
|
289
|
+
caption?: string;
|
|
290
|
+
signal?: AbortSignal;
|
|
291
|
+
}): Promise<void>;
|
|
292
|
+
/**
|
|
293
|
+
* Sends a voice message. The agent's STT model transcribes it before the turn
|
|
294
|
+
* runs, so the reply answers what was said — the transcription then arrives as
|
|
295
|
+
* a normal `user` message on the stream, which is why nothing is returned
|
|
296
|
+
* here.
|
|
297
|
+
*
|
|
298
|
+
* `audio` is any `Blob`; a `MediaRecorder` chunk works as-is. Its `type`
|
|
299
|
+
* (codec included) is forwarded, so the provider gets what it needs to decode.
|
|
300
|
+
*/
|
|
301
|
+
sendAudio(id: string, audio: Blob, opts?: {
|
|
302
|
+
filename?: string;
|
|
303
|
+
signal?: AbortSignal;
|
|
304
|
+
}): Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* The bytes of one of a message's attachments, as a `Blob`.
|
|
307
|
+
*
|
|
308
|
+
* Bytes rather than a URL because the token travels in a header: an `<img
|
|
309
|
+
* src>` pointing at this route would arrive unauthenticated. Wrap it for the
|
|
310
|
+
* DOM, and revoke when the element goes away:
|
|
311
|
+
*
|
|
312
|
+
* ```ts
|
|
313
|
+
* const url = URL.createObjectURL(await client.fetchAttachment(convId, msg.id, att.id));
|
|
314
|
+
* ```
|
|
315
|
+
*
|
|
316
|
+
* `attachmentId` is optional only for a single-attachment message; omitted on
|
|
317
|
+
* a multi-image one, the server serves the first.
|
|
318
|
+
*/
|
|
319
|
+
fetchAttachment(conversationId: string, messageId: string, attachmentId?: string, signal?: AbortSignal): Promise<Blob>;
|
|
320
|
+
/**
|
|
321
|
+
* Lists **one** directory of the conversation's files — never recursive, so a
|
|
322
|
+
* workspace with thousands of files is still one small response. `path`
|
|
323
|
+
* defaults to the root.
|
|
324
|
+
*
|
|
325
|
+
* With no `atSeq` you see exactly what the agent would be shown on its next
|
|
326
|
+
* turn, which is also the tree a write starts from — including empty, once a
|
|
327
|
+
* workspace has gone untouched for long enough to expire. `atSeq` is how you
|
|
328
|
+
* reach a past snapshot, expiry and all.
|
|
329
|
+
*
|
|
330
|
+
* None of the write methods below starts a turn. A file arriving is not a
|
|
331
|
+
* question: upload what the user dropped, then send a message if you want the
|
|
332
|
+
* agent to do something about it. It finds out either way — the harness tells
|
|
333
|
+
* it what changed at the start of its next request.
|
|
334
|
+
*/
|
|
335
|
+
listFiles(id: string, opts?: {
|
|
336
|
+
path?: string;
|
|
337
|
+
atSeq?: number;
|
|
338
|
+
signal?: AbortSignal;
|
|
339
|
+
}): Promise<WorkspaceDir>;
|
|
340
|
+
/**
|
|
341
|
+
* One file's bytes, as a `Blob`. Bytes rather than a URL for the same reason
|
|
342
|
+
* as `fetchAttachment`: the token travels in a header, so an `<a href>` at
|
|
343
|
+
* this route would arrive unauthenticated.
|
|
344
|
+
*/
|
|
345
|
+
readFile(id: string, path: string, opts?: {
|
|
346
|
+
atSeq?: number;
|
|
347
|
+
signal?: AbortSignal;
|
|
348
|
+
}): Promise<Blob>;
|
|
349
|
+
/** Creates or replaces one file, creating parent directories. */
|
|
350
|
+
writeFile(id: string, path: string, file: Blob, opts?: {
|
|
351
|
+
filename?: string;
|
|
352
|
+
signal?: AbortSignal;
|
|
353
|
+
}): Promise<void>;
|
|
354
|
+
/**
|
|
355
|
+
* Writes several files as **one** snapshot. Worth preferring over a loop of
|
|
356
|
+
* `writeFile`: the agent is told about the upload as a single change rather
|
|
357
|
+
* than as N, and nothing ever observes half a set.
|
|
358
|
+
*/
|
|
359
|
+
writeFiles(id: string, files: Array<{
|
|
360
|
+
path: string;
|
|
361
|
+
file: Blob;
|
|
362
|
+
filename?: string;
|
|
363
|
+
}>, opts?: {
|
|
364
|
+
signal?: AbortSignal;
|
|
365
|
+
}): Promise<void>;
|
|
366
|
+
/** Removes a file, or a directory with everything under it. Earlier
|
|
367
|
+
* snapshots keep resolving through `atSeq`. */
|
|
368
|
+
deleteFile(id: string, path: string, signal?: AbortSignal): Promise<void>;
|
|
369
|
+
moveFile(id: string, from: string, to: string, signal?: AbortSignal): Promise<void>;
|
|
370
|
+
/**
|
|
371
|
+
* Declares the tool set on `id` without running anything — the half of
|
|
372
|
+
* `serveClientTools` that has to happen *before* the first message, since a
|
|
373
|
+
* tool the agent was never told about can't be called.
|
|
374
|
+
*
|
|
375
|
+
* Replaces the whole set, like `setComponents`.
|
|
376
|
+
*/
|
|
377
|
+
setClientTools(id: string, tools: Record<string, ClientTool<never, unknown>>, signal?: AbortSignal): Promise<void>;
|
|
378
|
+
/**
|
|
379
|
+
* Declares your functions as tools on `id` and runs them as the agent calls
|
|
380
|
+
* them — the browser half of client tools, on the end-user token.
|
|
381
|
+
*
|
|
382
|
+
* Belongs on this client and not only on the operator one: the implementation
|
|
383
|
+
* runs where the app runs, and an api_key is tenant-wide and can never be
|
|
384
|
+
* shipped to a browser. Keep the session alive for as long as the
|
|
385
|
+
* conversation is on screen, and `stop()` it when it isn't.
|
|
386
|
+
*
|
|
387
|
+
* The runner opens its own event stream by default. If you already subscribe
|
|
388
|
+
* to the conversation, pass `watch: false` and call `session.poke()` from
|
|
389
|
+
* `onOpen` and `onClientToolCall` instead: same behaviour over one connection.
|
|
390
|
+
*
|
|
391
|
+
* ```ts
|
|
392
|
+
* const session = client.serveClientTools(id, { tools, watch: false });
|
|
393
|
+
* client.subscribe(id, {
|
|
394
|
+
* onOpen: () => session.poke(),
|
|
395
|
+
* onClientToolCall: () => session.poke(),
|
|
396
|
+
* });
|
|
397
|
+
* ```
|
|
398
|
+
*/
|
|
399
|
+
serveClientTools(id: string, options: ServeClientToolsOptions): ClientToolsSession;
|
|
400
|
+
/** Injects an instruction mid-turn: unlike `sendMessage`, it lands while the
|
|
401
|
+
* agent is already working and redirects it. */
|
|
402
|
+
steer(id: string, content: string, signal?: AbortSignal): Promise<void>;
|
|
403
|
+
/**
|
|
404
|
+
* Live view of one conversation: messages, the agent's activity, and its plan.
|
|
405
|
+
* Resumes from the last frame after a drop, so a reconnect loses nothing.
|
|
406
|
+
*
|
|
407
|
+
* By default it also backfills the whole log on connect, which makes the
|
|
408
|
+
* subscription the single source of truth for a short conversation. Pass
|
|
409
|
+
* `since` — the newest `changeSeq` you already hold, from `listMessagesPage` —
|
|
410
|
+
* to skip that backfill and receive only what is new; that is what makes
|
|
411
|
+
* paging backwards meaningful, since otherwise the stream re-delivers the
|
|
412
|
+
* history you just paged through.
|
|
413
|
+
*/
|
|
414
|
+
subscribe(id: string, handlers: ConversationHandlers, opts?: {
|
|
415
|
+
since?: number;
|
|
416
|
+
}): ConversationSubscription;
|
|
417
|
+
/** Live chat list. Fires per conversation whose activity advances; upsert by
|
|
418
|
+
* id and re-sort by `lastActivityAt` locally. */
|
|
419
|
+
subscribeToConversations(handlers: ListHandlers): ConversationSubscription;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Client for an end user in a browser or mobile app, authenticated with a
|
|
423
|
+
* short-lived user token. Reaches only the conversation surface, and only that
|
|
424
|
+
* user's own rows — the server enforces both.
|
|
425
|
+
*/
|
|
426
|
+
export declare function createUserClient(options: ClientOptions): AgentClient;
|
|
427
|
+
export {};
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Base for everything this SDK throws, so `catch (e) { if (e instanceof
|
|
2
|
+
* AgentError) }` covers both an HTTP failure and a connection that never got
|
|
3
|
+
* there. */
|
|
4
|
+
export declare class AgentError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/** The server answered, and said no. */
|
|
8
|
+
export declare class AgentApiError extends AgentError {
|
|
9
|
+
readonly status: number;
|
|
10
|
+
/** Server's `x-request-id`, when present. Worth quoting in a bug report. */
|
|
11
|
+
readonly requestId: string | null;
|
|
12
|
+
/** The response body, verbatim and untruncated. Some routes explain the
|
|
13
|
+
* failure in there (an MCP probe's reason, a rejected cron) in a form worth
|
|
14
|
+
* showing the user; `message` only carries a truncated preview. */
|
|
15
|
+
readonly body: string;
|
|
16
|
+
constructor(message: string, status: number, requestId?: string | null, body?: string);
|
|
17
|
+
/** The body parsed as JSON, or `undefined` when it isn't. */
|
|
18
|
+
json<T = unknown>(): T | undefined;
|
|
19
|
+
/** The token was rejected. The client already retried once with a fresh one,
|
|
20
|
+
* so seeing this means `getToken` is handing back something unusable. */
|
|
21
|
+
get isAuthError(): boolean;
|
|
22
|
+
get isNotFound(): boolean;
|
|
23
|
+
/** The request clashed with current state — a slug already taken, a
|
|
24
|
+
* conversation that belongs to a channel, a user already blocked. */
|
|
25
|
+
get isConflict(): boolean;
|
|
26
|
+
/** Worth retrying after a pause: the server is overloaded or briefly down. */
|
|
27
|
+
get isRetryable(): boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The client was constructed wrong — a `baseUrl` with no scheme, most often.
|
|
31
|
+
* Thrown at construction, not on the first call, so the stack points at the
|
|
32
|
+
* mistake.
|
|
33
|
+
*/
|
|
34
|
+
export declare class AgentConfigError extends AgentError {
|
|
35
|
+
constructor(message: string);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The request never produced a response: DNS, TLS, a refused connection, CORS,
|
|
39
|
+
* or the timeout below.
|
|
40
|
+
*
|
|
41
|
+
* Without this, `fetch` rejects with a bare `TypeError: fetch failed` and the
|
|
42
|
+
* caller cannot tell a wrong `baseUrl` from a server that said 500 — the two
|
|
43
|
+
* need completely different fixes.
|
|
44
|
+
*/
|
|
45
|
+
export declare class AgentNetworkError extends AgentError {
|
|
46
|
+
/** Whatever `fetch` (or the abort) threw. */
|
|
47
|
+
readonly cause: unknown;
|
|
48
|
+
/** True when the SDK's own timeout fired rather than the network failing. */
|
|
49
|
+
readonly timedOut: boolean;
|
|
50
|
+
constructor(message: string, cause: unknown, timedOut?: boolean);
|
|
51
|
+
}
|
|
52
|
+
export declare function raiseForStatus(res: Response, fallback: string): Promise<void>;
|