@aomi-labs/client 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,484 @@
1
+ // src/sse.ts
2
+ function extractSseData(rawEvent) {
3
+ const dataLines = rawEvent.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart());
4
+ if (!dataLines.length) return null;
5
+ return dataLines.join("\n");
6
+ }
7
+ async function readSseStream(stream, signal, onMessage) {
8
+ const reader = stream.getReader();
9
+ const decoder = new TextDecoder();
10
+ let buffer = "";
11
+ try {
12
+ while (!signal.aborted) {
13
+ const { value, done } = await reader.read();
14
+ if (done) break;
15
+ buffer += decoder.decode(value, { stream: true });
16
+ buffer = buffer.replace(/\r/g, "");
17
+ let separatorIndex = buffer.indexOf("\n\n");
18
+ while (separatorIndex >= 0) {
19
+ const rawEvent = buffer.slice(0, separatorIndex);
20
+ buffer = buffer.slice(separatorIndex + 2);
21
+ const data = extractSseData(rawEvent);
22
+ if (data) {
23
+ onMessage(data);
24
+ }
25
+ separatorIndex = buffer.indexOf("\n\n");
26
+ }
27
+ }
28
+ } finally {
29
+ reader.releaseLock();
30
+ }
31
+ }
32
+ function createSseSubscriber({
33
+ backendUrl,
34
+ getHeaders,
35
+ logger
36
+ }) {
37
+ const subscriptions = /* @__PURE__ */ new Map();
38
+ const subscribe = (sessionId, onUpdate, onError) => {
39
+ const existing = subscriptions.get(sessionId);
40
+ const listener = { onUpdate, onError };
41
+ if (existing) {
42
+ existing.listeners.add(listener);
43
+ logger == null ? void 0 : logger.debug("[aomi][sse] listener added", {
44
+ sessionId,
45
+ listeners: existing.listeners.size
46
+ });
47
+ return () => {
48
+ existing.listeners.delete(listener);
49
+ logger == null ? void 0 : logger.debug("[aomi][sse] listener removed", {
50
+ sessionId,
51
+ listeners: existing.listeners.size
52
+ });
53
+ if (existing.listeners.size === 0) {
54
+ existing.stop("unsubscribe");
55
+ if (subscriptions.get(sessionId) === existing) {
56
+ subscriptions.delete(sessionId);
57
+ }
58
+ }
59
+ };
60
+ }
61
+ const subscription = {
62
+ abortController: null,
63
+ retries: 0,
64
+ retryTimer: null,
65
+ stopped: false,
66
+ listeners: /* @__PURE__ */ new Set([listener]),
67
+ stop: (reason) => {
68
+ var _a;
69
+ subscription.stopped = true;
70
+ if (subscription.retryTimer) {
71
+ clearTimeout(subscription.retryTimer);
72
+ subscription.retryTimer = null;
73
+ }
74
+ (_a = subscription.abortController) == null ? void 0 : _a.abort();
75
+ subscription.abortController = null;
76
+ logger == null ? void 0 : logger.debug("[aomi][sse] stop", {
77
+ sessionId,
78
+ reason,
79
+ retries: subscription.retries
80
+ });
81
+ }
82
+ };
83
+ const scheduleRetry = () => {
84
+ if (subscription.stopped) return;
85
+ subscription.retries += 1;
86
+ const delayMs = Math.min(500 * 2 ** (subscription.retries - 1), 1e4);
87
+ logger == null ? void 0 : logger.debug("[aomi][sse] retry scheduled", {
88
+ sessionId,
89
+ delayMs,
90
+ retries: subscription.retries
91
+ });
92
+ subscription.retryTimer = setTimeout(() => {
93
+ void open();
94
+ }, delayMs);
95
+ };
96
+ const open = async () => {
97
+ var _a;
98
+ if (subscription.stopped) return;
99
+ if (subscription.retryTimer) {
100
+ clearTimeout(subscription.retryTimer);
101
+ subscription.retryTimer = null;
102
+ }
103
+ const controller = new AbortController();
104
+ subscription.abortController = controller;
105
+ const openedAt = Date.now();
106
+ try {
107
+ const response = await fetch(`${backendUrl}/api/updates`, {
108
+ headers: getHeaders(sessionId),
109
+ signal: controller.signal
110
+ });
111
+ if (!response.ok) {
112
+ throw new Error(
113
+ `SSE HTTP ${response.status}: ${response.statusText}`
114
+ );
115
+ }
116
+ if (!response.body) {
117
+ throw new Error("SSE response missing body");
118
+ }
119
+ subscription.retries = 0;
120
+ await readSseStream(response.body, controller.signal, (data) => {
121
+ var _a2, _b;
122
+ let parsed;
123
+ try {
124
+ parsed = JSON.parse(data);
125
+ } catch (error) {
126
+ for (const item of subscription.listeners) {
127
+ (_a2 = item.onError) == null ? void 0 : _a2.call(item, error);
128
+ }
129
+ return;
130
+ }
131
+ for (const item of subscription.listeners) {
132
+ try {
133
+ item.onUpdate(parsed);
134
+ } catch (error) {
135
+ (_b = item.onError) == null ? void 0 : _b.call(item, error);
136
+ }
137
+ }
138
+ });
139
+ logger == null ? void 0 : logger.debug("[aomi][sse] stream ended", {
140
+ sessionId,
141
+ aborted: controller.signal.aborted,
142
+ stopped: subscription.stopped,
143
+ durationMs: Date.now() - openedAt
144
+ });
145
+ } catch (error) {
146
+ if (!controller.signal.aborted && !subscription.stopped) {
147
+ for (const item of subscription.listeners) {
148
+ (_a = item.onError) == null ? void 0 : _a.call(item, error);
149
+ }
150
+ }
151
+ }
152
+ if (!subscription.stopped) {
153
+ scheduleRetry();
154
+ }
155
+ };
156
+ subscriptions.set(sessionId, subscription);
157
+ void open();
158
+ return () => {
159
+ subscription.listeners.delete(listener);
160
+ logger == null ? void 0 : logger.debug("[aomi][sse] listener removed", {
161
+ sessionId,
162
+ listeners: subscription.listeners.size
163
+ });
164
+ if (subscription.listeners.size === 0) {
165
+ subscription.stop("unsubscribe");
166
+ if (subscriptions.get(sessionId) === subscription) {
167
+ subscriptions.delete(sessionId);
168
+ }
169
+ }
170
+ };
171
+ };
172
+ return { subscribe };
173
+ }
174
+
175
+ // src/client.ts
176
+ var SESSION_ID_HEADER = "X-Session-Id";
177
+ var API_KEY_HEADER = "X-API-Key";
178
+ function toQueryString(payload) {
179
+ const params = new URLSearchParams();
180
+ for (const [key, value] of Object.entries(payload)) {
181
+ if (value === void 0 || value === null) continue;
182
+ params.set(key, String(value));
183
+ }
184
+ const qs = params.toString();
185
+ return qs ? `?${qs}` : "";
186
+ }
187
+ function withSessionHeader(sessionId, init) {
188
+ const headers = new Headers(init);
189
+ headers.set(SESSION_ID_HEADER, sessionId);
190
+ return headers;
191
+ }
192
+ async function postState(baseUrl, path, payload, sessionId, apiKey) {
193
+ const query = toQueryString(payload);
194
+ const url = `${baseUrl}${path}${query}`;
195
+ const headers = new Headers(withSessionHeader(sessionId));
196
+ if (apiKey) {
197
+ headers.set(API_KEY_HEADER, apiKey);
198
+ }
199
+ const response = await fetch(url, {
200
+ method: "POST",
201
+ headers
202
+ });
203
+ if (!response.ok) {
204
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
205
+ }
206
+ return await response.json();
207
+ }
208
+ var AomiClient = class {
209
+ constructor(options) {
210
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
211
+ this.apiKey = options.apiKey;
212
+ this.logger = options.logger;
213
+ this.sseSubscriber = createSseSubscriber({
214
+ backendUrl: this.baseUrl,
215
+ getHeaders: (sessionId) => withSessionHeader(sessionId, { Accept: "text/event-stream" }),
216
+ logger: this.logger
217
+ });
218
+ }
219
+ // ===========================================================================
220
+ // Chat & State
221
+ // ===========================================================================
222
+ /**
223
+ * Fetch current session state (messages, processing status, title).
224
+ */
225
+ async fetchState(sessionId, userState) {
226
+ const url = new URL("/api/state", this.baseUrl);
227
+ if (userState) {
228
+ url.searchParams.set("user_state", JSON.stringify(userState));
229
+ }
230
+ const response = await fetch(url.toString(), {
231
+ headers: withSessionHeader(sessionId)
232
+ });
233
+ if (!response.ok) {
234
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
235
+ }
236
+ return await response.json();
237
+ }
238
+ /**
239
+ * Send a chat message and return updated session state.
240
+ */
241
+ async sendMessage(sessionId, message, options) {
242
+ var _a, _b;
243
+ const namespace = (_a = options == null ? void 0 : options.namespace) != null ? _a : "default";
244
+ const apiKey = (_b = options == null ? void 0 : options.apiKey) != null ? _b : this.apiKey;
245
+ const payload = { message, namespace };
246
+ if (options == null ? void 0 : options.publicKey) {
247
+ payload.public_key = options.publicKey;
248
+ }
249
+ if (options == null ? void 0 : options.userState) {
250
+ payload.user_state = JSON.stringify(options.userState);
251
+ }
252
+ return postState(
253
+ this.baseUrl,
254
+ "/api/chat",
255
+ payload,
256
+ sessionId,
257
+ apiKey
258
+ );
259
+ }
260
+ /**
261
+ * Send a system-level message (e.g. wallet state changes, context switches).
262
+ */
263
+ async sendSystemMessage(sessionId, message) {
264
+ return postState(
265
+ this.baseUrl,
266
+ "/api/system",
267
+ { message },
268
+ sessionId
269
+ );
270
+ }
271
+ /**
272
+ * Interrupt the AI's current response.
273
+ */
274
+ async interrupt(sessionId) {
275
+ return postState(
276
+ this.baseUrl,
277
+ "/api/interrupt",
278
+ {},
279
+ sessionId
280
+ );
281
+ }
282
+ // ===========================================================================
283
+ // SSE (Real-time Updates)
284
+ // ===========================================================================
285
+ /**
286
+ * Subscribe to real-time SSE updates for a session.
287
+ * Automatically reconnects with exponential backoff on disconnects.
288
+ * Returns an unsubscribe function.
289
+ */
290
+ subscribeSSE(sessionId, onUpdate, onError) {
291
+ return this.sseSubscriber.subscribe(sessionId, onUpdate, onError);
292
+ }
293
+ // ===========================================================================
294
+ // Thread / Session Management
295
+ // ===========================================================================
296
+ /**
297
+ * List all threads for a wallet address.
298
+ */
299
+ async listThreads(publicKey) {
300
+ const url = `${this.baseUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;
301
+ const response = await fetch(url);
302
+ if (!response.ok) {
303
+ throw new Error(`Failed to fetch threads: HTTP ${response.status}`);
304
+ }
305
+ return await response.json();
306
+ }
307
+ /**
308
+ * Get a single thread by ID.
309
+ */
310
+ async getThread(sessionId) {
311
+ const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
312
+ const response = await fetch(url, {
313
+ headers: withSessionHeader(sessionId)
314
+ });
315
+ if (!response.ok) {
316
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
317
+ }
318
+ return await response.json();
319
+ }
320
+ /**
321
+ * Create a new thread. The client generates the session ID.
322
+ */
323
+ async createThread(threadId, publicKey) {
324
+ const body = {};
325
+ if (publicKey) body.public_key = publicKey;
326
+ const url = `${this.baseUrl}/api/sessions`;
327
+ const response = await fetch(url, {
328
+ method: "POST",
329
+ headers: withSessionHeader(threadId, {
330
+ "Content-Type": "application/json"
331
+ }),
332
+ body: JSON.stringify(body)
333
+ });
334
+ if (!response.ok) {
335
+ throw new Error(`Failed to create thread: HTTP ${response.status}`);
336
+ }
337
+ return await response.json();
338
+ }
339
+ /**
340
+ * Delete a thread by ID.
341
+ */
342
+ async deleteThread(sessionId) {
343
+ const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
344
+ const response = await fetch(url, {
345
+ method: "DELETE",
346
+ headers: withSessionHeader(sessionId)
347
+ });
348
+ if (!response.ok) {
349
+ throw new Error(`Failed to delete thread: HTTP ${response.status}`);
350
+ }
351
+ }
352
+ /**
353
+ * Rename a thread.
354
+ */
355
+ async renameThread(sessionId, newTitle) {
356
+ const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
357
+ const response = await fetch(url, {
358
+ method: "PATCH",
359
+ headers: withSessionHeader(sessionId, {
360
+ "Content-Type": "application/json"
361
+ }),
362
+ body: JSON.stringify({ title: newTitle })
363
+ });
364
+ if (!response.ok) {
365
+ throw new Error(`Failed to rename thread: HTTP ${response.status}`);
366
+ }
367
+ }
368
+ /**
369
+ * Archive a thread.
370
+ */
371
+ async archiveThread(sessionId) {
372
+ const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;
373
+ const response = await fetch(url, {
374
+ method: "POST",
375
+ headers: withSessionHeader(sessionId)
376
+ });
377
+ if (!response.ok) {
378
+ throw new Error(`Failed to archive thread: HTTP ${response.status}`);
379
+ }
380
+ }
381
+ /**
382
+ * Unarchive a thread.
383
+ */
384
+ async unarchiveThread(sessionId) {
385
+ const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;
386
+ const response = await fetch(url, {
387
+ method: "POST",
388
+ headers: withSessionHeader(sessionId)
389
+ });
390
+ if (!response.ok) {
391
+ throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);
392
+ }
393
+ }
394
+ // ===========================================================================
395
+ // System Events
396
+ // ===========================================================================
397
+ /**
398
+ * Get system events for a session.
399
+ */
400
+ async getSystemEvents(sessionId, count) {
401
+ const url = new URL("/api/events", this.baseUrl);
402
+ if (count !== void 0) {
403
+ url.searchParams.set("count", String(count));
404
+ }
405
+ const response = await fetch(url.toString(), {
406
+ headers: withSessionHeader(sessionId)
407
+ });
408
+ if (!response.ok) {
409
+ if (response.status === 404) return [];
410
+ throw new Error(`Failed to get system events: HTTP ${response.status}`);
411
+ }
412
+ return await response.json();
413
+ }
414
+ // ===========================================================================
415
+ // Control API
416
+ // ===========================================================================
417
+ /**
418
+ * Get available namespaces.
419
+ */
420
+ async getNamespaces(sessionId, options) {
421
+ var _a;
422
+ const url = new URL("/api/control/namespaces", this.baseUrl);
423
+ if (options == null ? void 0 : options.publicKey) {
424
+ url.searchParams.set("public_key", options.publicKey);
425
+ }
426
+ const apiKey = (_a = options == null ? void 0 : options.apiKey) != null ? _a : this.apiKey;
427
+ const headers = new Headers(withSessionHeader(sessionId));
428
+ if (apiKey) {
429
+ headers.set(API_KEY_HEADER, apiKey);
430
+ }
431
+ const response = await fetch(url.toString(), { headers });
432
+ if (!response.ok) {
433
+ throw new Error(`Failed to get namespaces: HTTP ${response.status}`);
434
+ }
435
+ return await response.json();
436
+ }
437
+ /**
438
+ * Get available models.
439
+ */
440
+ async getModels(sessionId) {
441
+ const url = new URL("/api/control/models", this.baseUrl);
442
+ const response = await fetch(url.toString(), {
443
+ headers: withSessionHeader(sessionId)
444
+ });
445
+ if (!response.ok) {
446
+ throw new Error(`Failed to get models: HTTP ${response.status}`);
447
+ }
448
+ return await response.json();
449
+ }
450
+ /**
451
+ * Set the model for a session.
452
+ */
453
+ async setModel(sessionId, rig, options) {
454
+ var _a;
455
+ const apiKey = (_a = options == null ? void 0 : options.apiKey) != null ? _a : this.apiKey;
456
+ const payload = { rig };
457
+ if (options == null ? void 0 : options.namespace) {
458
+ payload.namespace = options.namespace;
459
+ }
460
+ return postState(this.baseUrl, "/api/control/model", payload, sessionId, apiKey);
461
+ }
462
+ };
463
+
464
+ // src/types.ts
465
+ function isInlineCall(event) {
466
+ return "InlineCall" in event;
467
+ }
468
+ function isSystemNotice(event) {
469
+ return "SystemNotice" in event;
470
+ }
471
+ function isSystemError(event) {
472
+ return "SystemError" in event;
473
+ }
474
+ function isAsyncCallback(event) {
475
+ return "AsyncCallback" in event;
476
+ }
477
+ export {
478
+ AomiClient,
479
+ isAsyncCallback,
480
+ isInlineCall,
481
+ isSystemError,
482
+ isSystemNotice
483
+ };
484
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sse.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["import type { ApiSSEEvent, Logger } from \"./types\";\n\nexport type SseSubscriber = {\n subscribe: (\n sessionId: string,\n onUpdate: (event: ApiSSEEvent) => void,\n onError?: (error: unknown) => void,\n ) => () => void;\n};\n\nexport type SseSubscriberOptions = {\n backendUrl: string;\n getHeaders: (sessionId: string) => HeadersInit;\n logger?: Logger;\n};\n\ntype SseSubscription = {\n abortController: AbortController | null;\n retries: number;\n retryTimer: ReturnType<typeof setTimeout> | null;\n stopped: boolean;\n listeners: Set<SseListener>;\n stop: (reason?: string) => void;\n};\n\ntype SseListener = {\n onUpdate: (event: ApiSSEEvent) => void;\n onError?: (error: unknown) => void;\n};\n\nfunction extractSseData(rawEvent: string): string | null {\n const dataLines = rawEvent\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"data:\"))\n .map((line) => line.slice(5).trimStart());\n if (!dataLines.length) return null;\n return dataLines.join(\"\\n\");\n}\n\nasync function readSseStream(\n stream: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n onMessage: (data: string) => void,\n): Promise<void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (!signal.aborted) {\n const { value, done } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n buffer = buffer.replace(/\\r/g, \"\");\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\");\n while (separatorIndex >= 0) {\n const rawEvent = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + 2);\n const data = extractSseData(rawEvent);\n if (data) {\n onMessage(data);\n }\n separatorIndex = buffer.indexOf(\"\\n\\n\");\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function createSseSubscriber({\n backendUrl,\n getHeaders,\n logger,\n}: SseSubscriberOptions): SseSubscriber {\n const subscriptions = new Map<string, SseSubscription>();\n\n const subscribe: SseSubscriber[\"subscribe\"] = (\n sessionId,\n onUpdate,\n onError,\n ) => {\n const existing = subscriptions.get(sessionId);\n const listener: SseListener = { onUpdate, onError };\n if (existing) {\n existing.listeners.add(listener);\n logger?.debug(\"[aomi][sse] listener added\", {\n sessionId,\n listeners: existing.listeners.size,\n });\n return () => {\n existing.listeners.delete(listener);\n logger?.debug(\"[aomi][sse] listener removed\", {\n sessionId,\n listeners: existing.listeners.size,\n });\n if (existing.listeners.size === 0) {\n existing.stop(\"unsubscribe\");\n if (subscriptions.get(sessionId) === existing) {\n subscriptions.delete(sessionId);\n }\n }\n };\n }\n\n const subscription: SseSubscription = {\n abortController: null,\n retries: 0,\n retryTimer: null,\n stopped: false,\n listeners: new Set([listener]),\n stop: (reason?: string) => {\n subscription.stopped = true;\n if (subscription.retryTimer) {\n clearTimeout(subscription.retryTimer);\n subscription.retryTimer = null;\n }\n subscription.abortController?.abort();\n subscription.abortController = null;\n logger?.debug(\"[aomi][sse] stop\", {\n sessionId,\n reason,\n retries: subscription.retries,\n });\n },\n };\n\n const scheduleRetry = () => {\n if (subscription.stopped) return;\n subscription.retries += 1;\n const delayMs = Math.min(500 * 2 ** (subscription.retries - 1), 10000);\n logger?.debug(\"[aomi][sse] retry scheduled\", {\n sessionId,\n delayMs,\n retries: subscription.retries,\n });\n subscription.retryTimer = setTimeout(() => {\n void open();\n }, delayMs);\n };\n\n const open = async () => {\n if (subscription.stopped) return;\n if (subscription.retryTimer) {\n clearTimeout(subscription.retryTimer);\n subscription.retryTimer = null;\n }\n\n const controller = new AbortController();\n subscription.abortController = controller;\n const openedAt = Date.now();\n\n try {\n const response = await fetch(`${backendUrl}/api/updates`, {\n headers: getHeaders(sessionId),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(\n `SSE HTTP ${response.status}: ${response.statusText}`,\n );\n }\n\n if (!response.body) {\n throw new Error(\"SSE response missing body\");\n }\n\n subscription.retries = 0;\n\n await readSseStream(response.body, controller.signal, (data) => {\n let parsed: ApiSSEEvent;\n try {\n parsed = JSON.parse(data) as ApiSSEEvent;\n } catch (error) {\n for (const item of subscription.listeners) {\n item.onError?.(error);\n }\n return;\n }\n\n for (const item of subscription.listeners) {\n try {\n item.onUpdate(parsed);\n } catch (error) {\n item.onError?.(error);\n }\n }\n });\n logger?.debug(\"[aomi][sse] stream ended\", {\n sessionId,\n aborted: controller.signal.aborted,\n stopped: subscription.stopped,\n durationMs: Date.now() - openedAt,\n });\n } catch (error) {\n if (!controller.signal.aborted && !subscription.stopped) {\n for (const item of subscription.listeners) {\n item.onError?.(error);\n }\n }\n }\n\n if (!subscription.stopped) {\n scheduleRetry();\n }\n };\n\n subscriptions.set(sessionId, subscription);\n void open();\n\n return () => {\n subscription.listeners.delete(listener);\n logger?.debug(\"[aomi][sse] listener removed\", {\n sessionId,\n listeners: subscription.listeners.size,\n });\n if (subscription.listeners.size === 0) {\n subscription.stop(\"unsubscribe\");\n if (subscriptions.get(sessionId) === subscription) {\n subscriptions.delete(sessionId);\n }\n }\n };\n };\n\n return { subscribe };\n}\n","import type {\n AomiClientOptions,\n AomiMessage,\n ApiChatResponse,\n ApiCreateThreadResponse,\n ApiInterruptResponse,\n ApiSSEEvent,\n ApiStateResponse,\n ApiSystemEvent,\n ApiSystemResponse,\n ApiThread,\n Logger,\n UserState,\n} from \"./types\";\nimport { createSseSubscriber, type SseSubscriber } from \"./sse\";\n\n// =============================================================================\n// Internal helpers\n// =============================================================================\n\nconst SESSION_ID_HEADER = \"X-Session-Id\";\nconst API_KEY_HEADER = \"X-API-Key\";\n\nfunction toQueryString(payload: Record<string, unknown>): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(payload)) {\n if (value === undefined || value === null) continue;\n params.set(key, String(value));\n }\n const qs = params.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nfunction withSessionHeader(\n sessionId: string,\n init?: HeadersInit,\n): HeadersInit {\n const headers = new Headers(init);\n headers.set(SESSION_ID_HEADER, sessionId);\n return headers;\n}\n\nasync function postState<T>(\n baseUrl: string,\n path: string,\n payload: Record<string, unknown>,\n sessionId: string,\n apiKey?: string,\n): Promise<T> {\n const query = toQueryString(payload);\n const url = `${baseUrl}${path}${query}`;\n\n const headers = new Headers(withSessionHeader(sessionId));\n if (apiKey) {\n headers.set(API_KEY_HEADER, apiKey);\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as T;\n}\n\n// =============================================================================\n// AomiClient\n// =============================================================================\n\nexport class AomiClient {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly logger?: Logger;\n private readonly sseSubscriber: SseSubscriber;\n\n constructor(options: AomiClientOptions) {\n // Strip trailing slash\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n this.logger = options.logger;\n\n this.sseSubscriber = createSseSubscriber({\n backendUrl: this.baseUrl,\n getHeaders: (sessionId) =>\n withSessionHeader(sessionId, { Accept: \"text/event-stream\" }),\n logger: this.logger,\n });\n }\n\n // ===========================================================================\n // Chat & State\n // ===========================================================================\n\n /**\n * Fetch current session state (messages, processing status, title).\n */\n async fetchState(\n sessionId: string,\n userState?: UserState,\n ): Promise<ApiStateResponse> {\n const url = new URL(\"/api/state\", this.baseUrl);\n if (userState) {\n url.searchParams.set(\"user_state\", JSON.stringify(userState));\n }\n\n const response = await fetch(url.toString(), {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as ApiStateResponse;\n }\n\n /**\n * Send a chat message and return updated session state.\n */\n async sendMessage(\n sessionId: string,\n message: string,\n options?: {\n namespace?: string;\n publicKey?: string;\n apiKey?: string;\n userState?: UserState;\n },\n ): Promise<ApiChatResponse> {\n const namespace = options?.namespace ?? \"default\";\n const apiKey = options?.apiKey ?? this.apiKey;\n\n const payload: Record<string, unknown> = { message, namespace };\n if (options?.publicKey) {\n payload.public_key = options.publicKey;\n }\n if (options?.userState) {\n payload.user_state = JSON.stringify(options.userState);\n }\n\n return postState<ApiChatResponse>(\n this.baseUrl,\n \"/api/chat\",\n payload,\n sessionId,\n apiKey,\n );\n }\n\n /**\n * Send a system-level message (e.g. wallet state changes, context switches).\n */\n async sendSystemMessage(\n sessionId: string,\n message: string,\n ): Promise<ApiSystemResponse> {\n return postState<ApiSystemResponse>(\n this.baseUrl,\n \"/api/system\",\n { message },\n sessionId,\n );\n }\n\n /**\n * Interrupt the AI's current response.\n */\n async interrupt(sessionId: string): Promise<ApiInterruptResponse> {\n return postState<ApiInterruptResponse>(\n this.baseUrl,\n \"/api/interrupt\",\n {},\n sessionId,\n );\n }\n\n // ===========================================================================\n // SSE (Real-time Updates)\n // ===========================================================================\n\n /**\n * Subscribe to real-time SSE updates for a session.\n * Automatically reconnects with exponential backoff on disconnects.\n * Returns an unsubscribe function.\n */\n subscribeSSE(\n sessionId: string,\n onUpdate: (event: ApiSSEEvent) => void,\n onError?: (error: unknown) => void,\n ): () => void {\n return this.sseSubscriber.subscribe(sessionId, onUpdate, onError);\n }\n\n // ===========================================================================\n // Thread / Session Management\n // ===========================================================================\n\n /**\n * List all threads for a wallet address.\n */\n async listThreads(publicKey: string): Promise<ApiThread[]> {\n const url = `${this.baseUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch threads: HTTP ${response.status}`);\n }\n\n return (await response.json()) as ApiThread[];\n }\n\n /**\n * Get a single thread by ID.\n */\n async getThread(sessionId: string): Promise<ApiThread> {\n const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n const response = await fetch(url, {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as ApiThread;\n }\n\n /**\n * Create a new thread. The client generates the session ID.\n */\n async createThread(\n threadId: string,\n publicKey?: string,\n ): Promise<ApiCreateThreadResponse> {\n const body: Record<string, string> = {};\n if (publicKey) body.public_key = publicKey;\n\n const url = `${this.baseUrl}/api/sessions`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(threadId, {\n \"Content-Type\": \"application/json\",\n }),\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create thread: HTTP ${response.status}`);\n }\n\n return (await response.json()) as ApiCreateThreadResponse;\n }\n\n /**\n * Delete a thread by ID.\n */\n async deleteThread(sessionId: string): Promise<void> {\n const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n const response = await fetch(url, {\n method: \"DELETE\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to delete thread: HTTP ${response.status}`);\n }\n }\n\n /**\n * Rename a thread.\n */\n async renameThread(sessionId: string, newTitle: string): Promise<void> {\n const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;\n const response = await fetch(url, {\n method: \"PATCH\",\n headers: withSessionHeader(sessionId, {\n \"Content-Type\": \"application/json\",\n }),\n body: JSON.stringify({ title: newTitle }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to rename thread: HTTP ${response.status}`);\n }\n }\n\n /**\n * Archive a thread.\n */\n async archiveThread(sessionId: string): Promise<void> {\n const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to archive thread: HTTP ${response.status}`);\n }\n }\n\n /**\n * Unarchive a thread.\n */\n async unarchiveThread(sessionId: string): Promise<void> {\n const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to unarchive thread: HTTP ${response.status}`);\n }\n }\n\n // ===========================================================================\n // System Events\n // ===========================================================================\n\n /**\n * Get system events for a session.\n */\n async getSystemEvents(\n sessionId: string,\n count?: number,\n ): Promise<ApiSystemEvent[]> {\n const url = new URL(\"/api/events\", this.baseUrl);\n if (count !== undefined) {\n url.searchParams.set(\"count\", String(count));\n }\n const response = await fetch(url.toString(), {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n if (response.status === 404) return [];\n throw new Error(`Failed to get system events: HTTP ${response.status}`);\n }\n\n return (await response.json()) as ApiSystemEvent[];\n }\n\n // ===========================================================================\n // Control API\n // ===========================================================================\n\n /**\n * Get available namespaces.\n */\n async getNamespaces(\n sessionId: string,\n options?: { publicKey?: string; apiKey?: string },\n ): Promise<string[]> {\n const url = new URL(\"/api/control/namespaces\", this.baseUrl);\n if (options?.publicKey) {\n url.searchParams.set(\"public_key\", options.publicKey);\n }\n\n const apiKey = options?.apiKey ?? this.apiKey;\n const headers = new Headers(withSessionHeader(sessionId));\n if (apiKey) {\n headers.set(API_KEY_HEADER, apiKey);\n }\n\n const response = await fetch(url.toString(), { headers });\n\n if (!response.ok) {\n throw new Error(`Failed to get namespaces: HTTP ${response.status}`);\n }\n\n return (await response.json()) as string[];\n }\n\n /**\n * Get available models.\n */\n async getModels(sessionId: string): Promise<string[]> {\n const url = new URL(\"/api/control/models\", this.baseUrl);\n\n const response = await fetch(url.toString(), {\n headers: withSessionHeader(sessionId),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get models: HTTP ${response.status}`);\n }\n\n return (await response.json()) as string[];\n }\n\n /**\n * Set the model for a session.\n */\n async setModel(\n sessionId: string,\n rig: string,\n options?: { namespace?: string; apiKey?: string },\n ): Promise<{\n success: boolean;\n rig: string;\n baml: string;\n created: boolean;\n }> {\n const apiKey = options?.apiKey ?? this.apiKey;\n const payload: Record<string, unknown> = { rig };\n if (options?.namespace) {\n payload.namespace = options.namespace;\n }\n\n return postState<{\n success: boolean;\n rig: string;\n baml: string;\n created: boolean;\n }>(this.baseUrl, \"/api/control/model\", payload, sessionId, apiKey);\n }\n}\n","// =============================================================================\n// User State\n// =============================================================================\n\n/**\n * Client-side user state synced with the backend.\n * Typically wallet connection info, but can be any key-value data.\n */\nexport type UserState = Record<string, unknown>;\n\n// =============================================================================\n// Logger\n// =============================================================================\n\n/**\n * Optional logger for debug output. Pass `console` or any compatible object.\n */\nexport type Logger = {\n debug: (...args: unknown[]) => void;\n};\n\n// =============================================================================\n// Client Options\n// =============================================================================\n\nexport type AomiClientOptions = {\n /** Base URL of the Aomi backend (e.g. \"https://aomi.dev\") */\n baseUrl: string;\n /** Default API key for non-default namespaces */\n apiKey?: string;\n /** Optional logger for debug output (default: silent) */\n logger?: Logger;\n};\n\n// =============================================================================\n// Base Types\n// =============================================================================\n\nexport interface AomiMessage {\n sender?: \"user\" | \"agent\" | \"system\" | string;\n content?: string;\n timestamp?: string;\n is_streaming?: boolean;\n tool_result?: [string, string] | null;\n}\n\n// =============================================================================\n// API Response Types\n// =============================================================================\n\n/**\n * GET /api/state\n * Fetches current session state including messages and processing status\n */\nexport interface ApiStateResponse {\n messages?: AomiMessage[] | null;\n system_events?: ApiSystemEvent[] | null;\n title?: string | null;\n is_processing?: boolean;\n}\n\n/**\n * POST /api/chat\n * Sends a chat message and returns updated session state\n */\nexport interface ApiChatResponse {\n messages?: AomiMessage[] | null;\n system_events?: ApiSystemEvent[] | null;\n title?: string | null;\n is_processing?: boolean;\n}\n\n/**\n * POST /api/system\n * Sends a system message and returns the response message\n */\nexport interface ApiSystemResponse {\n res?: AomiMessage | null;\n}\n\n/**\n * POST /api/interrupt\n * Interrupts current processing and returns updated session state\n */\nexport type ApiInterruptResponse = ApiChatResponse;\n\n/**\n * GET /api/sessions\n * Returns array of ApiThread\n */\nexport interface ApiThread {\n session_id: string;\n title: string;\n is_archived?: boolean;\n}\n\n/**\n * POST /api/sessions\n * Creates a new thread/session\n */\nexport interface ApiCreateThreadResponse {\n session_id: string;\n title?: string;\n}\n\n// =============================================================================\n// SSE Event Types (/api/updates)\n// =============================================================================\n\n/**\n * Base SSE event - all events have session_id and type\n */\nexport type ApiSSEEvent = {\n type:\n | \"title_changed\"\n | \"tool_update\"\n | \"tool_complete\"\n | \"system_notice\"\n | string;\n session_id: string;\n new_title?: string;\n [key: string]: unknown;\n};\n\nexport type ApiSSEEventType =\n | \"title_changed\"\n | \"tool_update\"\n | \"tool_complete\"\n | \"system_notice\";\n\n// =============================================================================\n// System Events (/api/events)\n// =============================================================================\n\n/**\n * Backend SystemEvent enum serializes as tagged JSON:\n * - InlineCall: {\"InlineCall\": {\"type\": \"wallet_tx_request\", \"payload\": {...}}}\n * - SystemNotice: {\"SystemNotice\": \"message\"}\n * - SystemError: {\"SystemError\": \"message\"}\n * - AsyncCallback: {\"AsyncCallback\": {...}} (not sent over HTTP)\n */\nexport type ApiSystemEvent =\n | { InlineCall: { type: string; payload?: unknown; [key: string]: unknown } }\n | { SystemNotice: string }\n | { SystemError: string }\n | { AsyncCallback: Record<string, unknown> };\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\nexport function isInlineCall(\n event: ApiSystemEvent,\n): event is { InlineCall: { type: string; payload?: unknown } } {\n return \"InlineCall\" in event;\n}\n\nexport function isSystemNotice(\n event: ApiSystemEvent,\n): event is { SystemNotice: string } {\n return \"SystemNotice\" in event;\n}\n\nexport function isSystemError(\n event: ApiSystemEvent,\n): event is { SystemError: string } {\n return \"SystemError\" in event;\n}\n\nexport function isAsyncCallback(\n event: ApiSystemEvent,\n): event is { AsyncCallback: Record<string, unknown> } {\n return \"AsyncCallback\" in event;\n}\n"],"mappings":"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","names":["_a"]}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@aomi-labs/client",
3
+ "version": "0.1.0",
4
+ "description": "Platform-agnostic TypeScript client for the Aomi backend API",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "clean:dist": "rm -rf dist"
27
+ }
28
+ }