@almadar/sdk 0.1.0-alpha.4 → 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/client/index.d.ts +3 -3
- package/dist/client/index.js +25 -11
- package/dist/client/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +25 -21
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +7 -5
- package/dist/react/index.js +3 -10
- package/dist/react/index.js.map +1 -1
- package/dist/server/express.d.ts +39 -0
- package/dist/server/express.js +472 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/hono.d.ts +33 -0
- package/dist/server/hono.js +417 -0
- package/dist/server/hono.js.map +1 -0
- package/dist/server/index.d.ts +14 -11
- package/dist/server/index.js +102 -46
- package/dist/server/index.js.map +1 -1
- package/dist/{types-BfWDIOGm.d.ts → types-D-q0c5Yt.d.ts} +26 -64
- package/package.json +15 -13
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { parseOrbitalSchema } from '@almadar/core';
|
|
2
|
+
|
|
3
|
+
// src/client/AlmadarClient.ts
|
|
4
|
+
|
|
1
5
|
// src/client/errors.ts
|
|
2
6
|
var AlmadarError = class extends Error {
|
|
3
7
|
code;
|
|
@@ -124,7 +128,11 @@ var AlmadarClient = class {
|
|
|
124
128
|
prompt: input.prompt,
|
|
125
129
|
endUserId: input.endUserId,
|
|
126
130
|
appId: input.appId,
|
|
127
|
-
async: true
|
|
131
|
+
async: true,
|
|
132
|
+
provider: input.provider,
|
|
133
|
+
model: input.model,
|
|
134
|
+
catalogMode: input.catalogMode,
|
|
135
|
+
stdAllowList: input.stdAllowList
|
|
128
136
|
});
|
|
129
137
|
assertString(handle.jobId, "AsyncJobHandle.jobId");
|
|
130
138
|
assertString(handle.statusUrl, "AsyncJobHandle.statusUrl");
|
|
@@ -158,20 +166,28 @@ var AlmadarClient = class {
|
|
|
158
166
|
body: JSON.stringify({
|
|
159
167
|
prompt: input.prompt,
|
|
160
168
|
endUserId: input.endUserId,
|
|
161
|
-
appId: input.appId
|
|
169
|
+
appId: input.appId,
|
|
170
|
+
provider: input.provider,
|
|
171
|
+
model: input.model,
|
|
172
|
+
catalogMode: input.catalogMode,
|
|
173
|
+
stdAllowList: input.stdAllowList
|
|
162
174
|
})
|
|
163
175
|
});
|
|
164
176
|
if (!res.ok) throw await this.errorFromResponse(res);
|
|
165
177
|
if (res.body === null) throw new Error("AlmadarClient.generate: server returned no body");
|
|
166
178
|
let final = null;
|
|
167
179
|
for await (const raw of parseSSE(res.body)) {
|
|
168
|
-
const event =
|
|
180
|
+
const event = parseSseEvent(raw.data);
|
|
169
181
|
if (event === null) continue;
|
|
170
182
|
input.onEvent?.(event);
|
|
171
183
|
if (event.type === "complete") {
|
|
172
|
-
|
|
184
|
+
if (event.data.schema === void 0) {
|
|
185
|
+
throw new ServerError({ code: 500, message: "`complete` event did not contain a schema" });
|
|
186
|
+
}
|
|
187
|
+
const schema = parseOrbitalSchema(event.data.schema);
|
|
188
|
+
final = { schema, appId: event.data.appId };
|
|
173
189
|
} else if (event.type === "error") {
|
|
174
|
-
throw errorFromBody({ code:
|
|
190
|
+
throw errorFromBody({ code: 500, message: event.data.error });
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
if (final === null) {
|
|
@@ -254,7 +270,7 @@ var AlmadarClient = class {
|
|
|
254
270
|
return err;
|
|
255
271
|
}
|
|
256
272
|
};
|
|
257
|
-
function
|
|
273
|
+
function parseSseEvent(dataLine) {
|
|
258
274
|
if (dataLine === "") return null;
|
|
259
275
|
let payload;
|
|
260
276
|
try {
|
|
@@ -262,11 +278,9 @@ function parseAgentEvent(eventName, dataLine) {
|
|
|
262
278
|
} catch {
|
|
263
279
|
return null;
|
|
264
280
|
}
|
|
265
|
-
if (payload === null || typeof payload !== "object") return null;
|
|
266
|
-
if (typeof payload.type
|
|
267
|
-
|
|
268
|
-
const synthesized = Object.assign(payload, { type: eventName });
|
|
269
|
-
return synthesized;
|
|
281
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
282
|
+
if (typeof payload.type !== "string" || typeof payload.timestamp !== "number") return null;
|
|
283
|
+
return payload;
|
|
270
284
|
}
|
|
271
285
|
function assertString(v, name) {
|
|
272
286
|
if (typeof v !== "string" || v === "") {
|
|
@@ -280,68 +294,110 @@ function sleep(ms) {
|
|
|
280
294
|
// src/server/index.ts
|
|
281
295
|
function resolveEndUserId(opts, req) {
|
|
282
296
|
if (opts.endUserId) return opts.endUserId(req);
|
|
283
|
-
const header = req.headers
|
|
297
|
+
const header = req.headers.get("x-user-id");
|
|
284
298
|
return typeof header === "string" && header.length > 0 ? header : void 0;
|
|
285
299
|
}
|
|
286
|
-
function
|
|
287
|
-
|
|
300
|
+
function encodeSseEvent(event) {
|
|
301
|
+
return `data: ${JSON.stringify(event)}
|
|
288
302
|
|
|
289
|
-
|
|
303
|
+
`;
|
|
290
304
|
}
|
|
291
305
|
function createGenerateHandler(opts) {
|
|
292
|
-
return async (
|
|
293
|
-
|
|
306
|
+
return async (request) => {
|
|
307
|
+
let body;
|
|
308
|
+
try {
|
|
309
|
+
body = await request.json();
|
|
310
|
+
} catch {
|
|
311
|
+
return new Response(JSON.stringify({ error: "invalid JSON body" }), {
|
|
312
|
+
status: 400,
|
|
313
|
+
headers: { "content-type": "application/json" }
|
|
314
|
+
});
|
|
315
|
+
}
|
|
294
316
|
const rawPrompt = body.prompt ?? body.message;
|
|
295
317
|
const prompt = typeof rawPrompt === "string" ? rawPrompt : "";
|
|
296
318
|
if (!prompt) {
|
|
297
|
-
|
|
298
|
-
|
|
319
|
+
return new Response(JSON.stringify({ error: "prompt or message is required" }), {
|
|
320
|
+
status: 400,
|
|
321
|
+
headers: { "content-type": "application/json" }
|
|
322
|
+
});
|
|
299
323
|
}
|
|
300
324
|
const bodyEndUserId = typeof body.endUserId === "string" ? body.endUserId : void 0;
|
|
301
|
-
const endUserId = bodyEndUserId ?? resolveEndUserId(opts,
|
|
325
|
+
const endUserId = bodyEndUserId ?? resolveEndUserId(opts, request);
|
|
302
326
|
const appId = typeof body.appId === "string" ? body.appId : void 0;
|
|
303
|
-
res.setHeader("Content-Type", "text/event-stream");
|
|
304
|
-
res.setHeader("Cache-Control", "no-cache");
|
|
305
|
-
res.setHeader("Connection", "keep-alive");
|
|
306
327
|
const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
328
|
+
const stream = new ReadableStream({
|
|
329
|
+
async start(controller) {
|
|
330
|
+
const encoder = new TextEncoder();
|
|
331
|
+
try {
|
|
332
|
+
await client.generate({
|
|
333
|
+
prompt,
|
|
334
|
+
endUserId,
|
|
335
|
+
appId,
|
|
336
|
+
onEvent: (event) => {
|
|
337
|
+
controller.enqueue(encoder.encode(encodeSseEvent(event)));
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
} catch (err) {
|
|
341
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
342
|
+
const errorEvent = {
|
|
343
|
+
type: "error",
|
|
344
|
+
timestamp: Date.now(),
|
|
345
|
+
data: { error: message }
|
|
346
|
+
};
|
|
347
|
+
controller.enqueue(encoder.encode(encodeSseEvent(errorEvent)));
|
|
348
|
+
} finally {
|
|
349
|
+
controller.close();
|
|
314
350
|
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
return new Response(stream, {
|
|
354
|
+
status: 200,
|
|
355
|
+
headers: {
|
|
356
|
+
"content-type": "text/event-stream",
|
|
357
|
+
"cache-control": "no-cache",
|
|
358
|
+
connection: "keep-alive"
|
|
359
|
+
}
|
|
360
|
+
});
|
|
323
361
|
};
|
|
324
362
|
}
|
|
325
363
|
function createEditHandler(opts) {
|
|
326
|
-
return async (
|
|
327
|
-
|
|
364
|
+
return async (request) => {
|
|
365
|
+
let body;
|
|
366
|
+
try {
|
|
367
|
+
body = await request.json();
|
|
368
|
+
} catch {
|
|
369
|
+
return new Response(JSON.stringify({ error: "invalid JSON body" }), {
|
|
370
|
+
status: 400,
|
|
371
|
+
headers: { "content-type": "application/json" }
|
|
372
|
+
});
|
|
373
|
+
}
|
|
328
374
|
const appId = typeof body.appId === "string" ? body.appId : "";
|
|
329
375
|
if (!appId) {
|
|
330
|
-
|
|
331
|
-
|
|
376
|
+
return new Response(JSON.stringify({ error: "appId is required" }), {
|
|
377
|
+
status: 400,
|
|
378
|
+
headers: { "content-type": "application/json" }
|
|
379
|
+
});
|
|
332
380
|
}
|
|
333
381
|
const patch = body.patch;
|
|
334
382
|
if (patch === void 0 || patch === null || typeof patch !== "object") {
|
|
335
|
-
|
|
336
|
-
|
|
383
|
+
return new Response(JSON.stringify({ error: "patch is required" }), {
|
|
384
|
+
status: 400,
|
|
385
|
+
headers: { "content-type": "application/json" }
|
|
386
|
+
});
|
|
337
387
|
}
|
|
338
388
|
const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });
|
|
339
389
|
try {
|
|
340
390
|
const schema = await client.editSchema(appId, patch);
|
|
341
|
-
|
|
391
|
+
return new Response(JSON.stringify(schema), {
|
|
392
|
+
status: 200,
|
|
393
|
+
headers: { "content-type": "application/json" }
|
|
394
|
+
});
|
|
342
395
|
} catch (err) {
|
|
343
396
|
const message = err instanceof Error ? err.message : String(err);
|
|
344
|
-
|
|
397
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
398
|
+
status: 500,
|
|
399
|
+
headers: { "content-type": "application/json" }
|
|
400
|
+
});
|
|
345
401
|
}
|
|
346
402
|
};
|
|
347
403
|
}
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/errors.ts","../../src/client/sseParser.ts","../../src/client/AlmadarClient.ts","../../src/server/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Typed SDK errors. Server emits a structured `ApiErrorBody`; the HTTP layer\n * maps the `code` to one of these subclasses. Customers `catch` by class.\n */\n\nimport type { ApiErrorBody } from '../types';\n\nexport class AlmadarError extends Error {\n readonly code: number;\n readonly details?: ApiErrorBody['details'];\n constructor(body: ApiErrorBody) {\n super(body.message);\n this.name = 'AlmadarError';\n this.code = body.code;\n this.details = body.details;\n }\n}\n\n/** 4001 — invalid, revoked, or missing API key. */\nexport class ApiKeyError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ApiKeyError';\n }\n}\n\n/** 4029 — team cap (feature counter) exceeded. Retry after a billing cycle. */\nexport class RateLimitedError extends AlmadarError {\n readonly retryAfterSeconds?: number;\n constructor(body: ApiErrorBody, retryAfterSeconds?: number) {\n super(body);\n this.name = 'RateLimitedError';\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\n/** 4040 — the team's behavior catalog (subset/replace mode) cannot serve the request. */\nexport class CatalogOutOfScopeError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'CatalogOutOfScopeError';\n }\n}\n\n/** Anything else from the server with a recognized envelope but no specific subclass. */\nexport class ServerError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ServerError';\n }\n}\n\nexport function errorFromBody(body: ApiErrorBody): AlmadarError {\n switch (body.code) {\n case 4001:\n return new ApiKeyError(body);\n case 4029:\n return new RateLimitedError(body);\n case 4040:\n return new CatalogOutOfScopeError(body);\n default:\n return new ServerError(body);\n }\n}\n","/**\n * Minimal Server-Sent Events parser. Reads a `ReadableStream<Uint8Array>`\n * (the body of a `fetch` Response) and yields decoded events. Universal:\n * works in browser, Node 18+, Deno, Bun.\n *\n * Spec subset implemented:\n * - `event:` and `data:` fields\n * - dispatch on blank line\n * - newline-tolerant (CRLF + LF)\n * - skips comments (`:`-prefixed lines)\n *\n * Not implemented (we don't need them):\n * - `id:` / `retry:` fields\n * - reconnection / last-event-id\n */\n\nexport interface RawSseEvent {\n /** `event:` field value. Empty string when absent — matches the spec default. */\n event: string;\n /** Concatenated `data:` lines, joined by newlines. */\n data: string;\n}\n\nexport async function* parseSSE(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<RawSseEvent, void, void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let currentEvent = '';\n let currentData = '';\n\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let newlineIdx: number;\n while ((newlineIdx = indexOfNewline(buffer)) !== -1) {\n const rawLine = buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + (buffer[newlineIdx] === '\\r' && buffer[newlineIdx + 1] === '\\n' ? 2 : 1));\n\n if (rawLine === '') {\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n currentEvent = '';\n currentData = '';\n }\n continue;\n }\n if (rawLine.startsWith(':')) continue;\n\n const colon = rawLine.indexOf(':');\n const field = colon === -1 ? rawLine : rawLine.slice(0, colon);\n const rawValue = colon === -1 ? '' : rawLine.slice(colon + 1);\n const value2 = rawValue.startsWith(' ') ? rawValue.slice(1) : rawValue;\n\n if (field === 'event') {\n currentEvent = value2;\n } else if (field === 'data') {\n currentData = currentData === '' ? value2 : `${currentData}\\n${value2}`;\n }\n }\n }\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction indexOfNewline(s: string): number {\n for (let i = 0; i < s.length; i += 1) {\n const c = s[i];\n if (c === '\\n' || c === '\\r') return i;\n }\n return -1;\n}\n","/**\n * `AlmadarClient` — server / Node-side HTTP client targeting `/api/v1/agent/*`.\n * Authenticates with a team-bound API key (`sk_*`) issued from\n * Studio's `/settings/sdk` panel. See `docs/Almadar_Studio_SDK.md` §5.\n *\n * Never instantiate this in a browser bundle — `apiKey` must never leave\n * the customer's server.\n */\n\nimport type { OrbitalSchema } from '@almadar/core';\nimport type {\n AgentEvent,\n AlmadarClientOptions,\n ApiErrorBody,\n AsyncJobHandle,\n CompileOptions,\n CompileResult,\n EditSchemaPatch,\n GenerateOptions,\n GenerateResult,\n} from '../types';\nimport { errorFromBody, ServerError } from './errors';\nimport { parseSSE } from './sseParser';\n\nconst DEFAULT_BASE_URL = 'https://studio.almadar.io';\nconst POLL_BACKOFF_MS: readonly number[] = [1000, 2000, 5000, 10_000, 30_000];\n\ninterface JobStatus {\n state: 'pending' | 'complete' | 'error';\n events?: readonly AgentEvent[];\n result?: GenerateResult;\n errorCode?: number;\n errorMessage?: string;\n}\n\nexport class AlmadarClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(opts: AlmadarClientOptions) {\n if (!opts.apiKey || typeof opts.apiKey !== 'string') {\n throw new Error('AlmadarClient: opts.apiKey is required');\n }\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (typeof this.fetchImpl !== 'function') {\n throw new Error('AlmadarClient: no fetch available — pass opts.fetch for Node <18');\n }\n }\n\n async generate(input: GenerateOptions): Promise<GenerateResult> {\n if (input.async === true) {\n const handle = await this.requestJson<AsyncJobHandle>('POST', '/api/v1/agent/generate', {\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n async: true,\n });\n assertString(handle.jobId, 'AsyncJobHandle.jobId');\n assertString(handle.statusUrl, 'AsyncJobHandle.statusUrl');\n return this.pollUntilComplete(handle, input.onEvent);\n }\n return this.streamGenerate(input);\n }\n\n async editSchema(appId: string, patch: EditSchemaPatch): Promise<OrbitalSchema> {\n if (!appId) throw new Error('AlmadarClient.editSchema: appId is required');\n const schema = await this.requestJson<OrbitalSchema>('PUT', '/api/v1/agent/edit-schema', {\n appId,\n patch,\n });\n assertString(schema.name, 'OrbitalSchema.name');\n return schema;\n }\n\n async compileToApp(schema: OrbitalSchema, opts?: CompileOptions): Promise<CompileResult> {\n const result = await this.requestJson<CompileResult>('POST', '/api/v1/agent/compile', {\n schema,\n target: opts?.target,\n shell: opts?.shell,\n });\n assertString(result.downloadUrl, 'CompileResult.downloadUrl');\n assertString(result.expiresAt, 'CompileResult.expiresAt');\n return result;\n }\n\n private async streamGenerate(input: GenerateOptions): Promise<GenerateResult> {\n const res = await this.fetchImpl(`${this.baseUrl}/api/v1/agent/generate`, {\n method: 'POST',\n headers: this.headers({ accept: 'text/event-stream', contentType: 'application/json' }, input.endUserId),\n body: JSON.stringify({\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n }),\n });\n if (!res.ok) throw await this.errorFromResponse(res);\n if (res.body === null) throw new Error('AlmadarClient.generate: server returned no body');\n\n let final: GenerateResult | null = null;\n for await (const raw of parseSSE(res.body)) {\n const event = parseAgentEvent(raw.event, raw.data);\n if (event === null) continue;\n input.onEvent?.(event);\n if (event.type === 'complete') {\n final = { schema: event.schema, appId: event.appId };\n } else if (event.type === 'error') {\n throw errorFromBody({ code: event.code ?? 500, message: event.message });\n }\n }\n if (final === null) {\n throw new ServerError({ code: 500, message: 'SSE stream ended without `complete` event' });\n }\n return final;\n }\n\n private async pollUntilComplete(\n handle: AsyncJobHandle,\n onEvent: GenerateOptions['onEvent'],\n ): Promise<GenerateResult> {\n let attempt = 0;\n for (;;) {\n const delay = POLL_BACKOFF_MS[Math.min(attempt, POLL_BACKOFF_MS.length - 1)];\n await sleep(delay);\n attempt += 1;\n const status = await this.requestJson<JobStatus>('GET', handle.statusUrl);\n assertString(status.state, 'JobStatus.state');\n if (status.events !== undefined && onEvent !== undefined) {\n for (const e of status.events) onEvent(e);\n }\n if (status.state === 'complete') {\n if (status.result === undefined) {\n throw new ServerError({ code: 500, message: 'Job complete but no result returned' });\n }\n return status.result;\n }\n if (status.state === 'error') {\n throw errorFromBody({\n code: status.errorCode ?? 500,\n message: status.errorMessage ?? 'Job failed',\n });\n }\n }\n }\n\n private async requestJson<T>(method: string, path: string, body?: object): Promise<T> {\n const isAbsolute = path.startsWith('http://') || path.startsWith('https://');\n const url = isAbsolute ? path : `${this.baseUrl}${path}`;\n const init: RequestInit = {\n method,\n headers: this.headers({\n accept: 'application/json',\n contentType: body !== undefined ? 'application/json' : undefined,\n }),\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await this.fetchImpl(url, init);\n if (!res.ok) throw await this.errorFromResponse(res);\n const text = await res.text();\n if (text === '') {\n throw new ServerError({ code: 500, message: 'Empty response body' });\n }\n const parsed: T = JSON.parse(text);\n return parsed;\n }\n\n private headers(\n opts: { accept?: string; contentType?: string },\n endUserId?: string,\n ): Record<string, string> {\n const h: Record<string, string> = { authorization: `Bearer ${this.apiKey}` };\n if (opts.accept !== undefined) h['accept'] = opts.accept;\n if (opts.contentType !== undefined) h['content-type'] = opts.contentType;\n if (endUserId !== undefined && endUserId !== '') h['x-end-user-id'] = endUserId;\n return h;\n }\n\n private async errorFromResponse(res: Response): Promise<Error> {\n const text = await res.text();\n let body: ApiErrorBody;\n try {\n const parsed: ApiErrorBody | null = text === '' ? null : JSON.parse(text);\n body = parsed !== null && typeof parsed.code === 'number' && typeof parsed.message === 'string'\n ? parsed\n : {\n code: res.status,\n message: res.statusText !== '' ? res.statusText : 'HTTP error',\n };\n } catch {\n body = { code: res.status, message: text !== '' ? text : res.statusText };\n }\n const retryAfter = res.headers.get('retry-after');\n const err = errorFromBody(body);\n if (err.name === 'RateLimitedError' && retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n Object.defineProperty(err, 'retryAfterSeconds', { value: seconds, enumerable: true });\n }\n }\n return err;\n }\n}\n\nfunction parseAgentEvent(eventName: string, dataLine: string): AgentEvent | null {\n if (dataLine === '') return null;\n let payload: AgentEvent | null;\n try {\n payload = JSON.parse(dataLine);\n } catch {\n return null;\n }\n if (payload === null || typeof payload !== 'object') return null;\n if (typeof payload.type === 'string') return payload;\n if (eventName === '') return null;\n // Server sent only an `event:` field name — write `type` onto the payload.\n // Mutating the parsed result is safe because we own it.\n const synthesized: AgentEvent & { type: string } = Object.assign(payload, { type: eventName });\n return synthesized;\n}\n\nfunction assertString(v: string | undefined, name: string): asserts v is string {\n if (typeof v !== 'string' || v === '') {\n throw new ServerError({ code: 500, message: `Malformed server response: ${name} is not a string` });\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * `@almadar/sdk/server` — Express handler factories for the Almadar agent.\n *\n * Node-only. Never import this from browser or React code.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server';\n */\n\nimport type { Request, Response } from 'express';\nimport type { OrbitalSchema } from '@almadar/core';\nimport { AlmadarClient } from '../client/AlmadarClient';\nimport type { AgentEvent, EditSchemaRequest, EditSchemaPatch, GenerateRequest } from '../types';\n\n// ============================================================================\n// Public option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** API key issued from Studio's /settings/sdk panel. */\n apiKey: string;\n /** Defaults to https://studio.almadar.io. */\n baseUrl?: string;\n /** Derive a stable end-user id from the request. */\n endUserId?: (req: Request) => string;\n}\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\nfunction resolveEndUserId(opts: GenerateHandlerOptions, req: Request): string | undefined {\n if (opts.endUserId) return opts.endUserId(req);\n const header = req.headers['x-user-id'];\n return typeof header === 'string' && header.length > 0 ? header : undefined;\n}\n\nfunction writeSseEvent(res: Response, event: AgentEvent): void {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n}\n\n// ============================================================================\n// createGenerateHandler\n// ============================================================================\n\n/**\n * Returns an Express route handler that streams a generate call as SSE.\n *\n * Body shape accepted: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport function createGenerateHandler(\n opts: GenerateHandlerOptions,\n): (req: Request, res: Response) => Promise<void> {\n return async (req: Request, res: Response): Promise<void> => {\n const body = req.body as GenerateRequest;\n const rawPrompt = body.prompt ?? body.message;\n const prompt = typeof rawPrompt === 'string' ? rawPrompt : '';\n\n if (!prompt) {\n res.status(400).json({ error: 'prompt or message is required' });\n return;\n }\n\n const bodyEndUserId = typeof body.endUserId === 'string' ? body.endUserId : undefined;\n const endUserId = bodyEndUserId ?? resolveEndUserId(opts, req);\n const appId = typeof body.appId === 'string' ? body.appId : undefined;\n\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n try {\n await client.generate({\n prompt,\n endUserId,\n appId,\n onEvent: (event: AgentEvent) => {\n writeSseEvent(res, event);\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const errorEvent: AgentEvent = { type: 'error', message };\n writeSseEvent(res, errorEvent);\n } finally {\n res.end();\n }\n };\n}\n\n// ============================================================================\n// createEditHandler\n// ============================================================================\n\n/**\n * Returns an Express route handler that calls `editSchema` and returns JSON.\n *\n * Body shape accepted: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport function createEditHandler(\n opts: GenerateHandlerOptions,\n): (req: Request, res: Response) => Promise<void> {\n return async (req: Request, res: Response): Promise<void> => {\n const body = req.body as EditSchemaRequest;\n const appId = typeof body.appId === 'string' ? body.appId : '';\n\n if (!appId) {\n res.status(400).json({ error: 'appId is required' });\n return;\n }\n\n const patch: EditSchemaPatch | undefined = body.patch;\n if (patch === undefined || patch === null || typeof patch !== 'object') {\n res.status(400).json({ error: 'patch is required' });\n return;\n }\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n try {\n const schema: OrbitalSchema = await client.editSchema(appId, patch);\n res.json(schema);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n res.status(500).json({ error: message });\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/client/errors.ts","../../src/client/sseParser.ts","../../src/client/AlmadarClient.ts","../../src/server/index.ts"],"names":[],"mappings":";;;;;AAOO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA,EAC7B,IAAA;AAAA,EACA,OAAA;AAAA,EACT,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACtB;AACF,CAAA;AAGO,IAAM,WAAA,GAAN,cAA0B,YAAA,CAAa;AAAA,EAC5C,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AACF,CAAA;AAGO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAA,EACxC,iBAAA;AAAA,EACT,WAAA,CAAY,MAAoB,iBAAA,EAA4B;AAC1D,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,IAAA,CAAK,iBAAA,GAAoB,iBAAA;AAAA,EAC3B;AACF,CAAA;AAGO,IAAM,sBAAA,GAAN,cAAqC,YAAA,CAAa;AAAA,EACvD,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EACd;AACF,CAAA;AAGO,IAAM,WAAA,GAAN,cAA0B,YAAA,CAAa;AAAA,EAC5C,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AAAA,EACd;AACF,CAAA;AAEO,SAAS,cAAc,IAAA,EAAkC;AAC9D,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,IAAA;AACH,MAAA,OAAO,IAAI,YAAY,IAAI,CAAA;AAAA,IAC7B,KAAK,IAAA;AACH,MAAA,OAAO,IAAI,iBAAiB,IAAI,CAAA;AAAA,IAClC,KAAK,IAAA;AACH,MAAA,OAAO,IAAI,uBAAuB,IAAI,CAAA;AAAA,IACxC;AACE,MAAA,OAAO,IAAI,YAAY,IAAI,CAAA;AAAA;AAEjC;;;ACxCA,gBAAuB,SACrB,MAAA,EACyC;AACzC,EAAA,MAAM,MAAA,GAAS,OAAO,SAAA,EAAU;AAChC,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,CAAY,OAAO,CAAA;AACvC,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,IAAI,YAAA,GAAe,EAAA;AACnB,EAAA,IAAI,WAAA,GAAc,EAAA;AAElB,EAAA,IAAI;AACF,IAAA,WAAS;AACP,MAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,MAAA,IAAI,IAAA,EAAM;AACV,MAAA,MAAA,IAAU,QAAQ,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAEhD,MAAA,IAAI,UAAA;AACJ,MAAA,OAAA,CAAQ,UAAA,GAAa,cAAA,CAAe,MAAM,CAAA,MAAO,CAAA,CAAA,EAAI;AACnD,QAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA;AAC1C,QAAA,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,UAAA,IAAc,MAAA,CAAO,UAAU,CAAA,KAAM,IAAA,IAAQ,MAAA,CAAO,UAAA,GAAa,CAAC,CAAA,KAAM,IAAA,GAAO,IAAI,CAAA,CAAE,CAAA;AAE3G,QAAA,IAAI,YAAY,EAAA,EAAI;AAClB,UAAA,IAAI,WAAA,KAAgB,EAAA,IAAM,YAAA,KAAiB,EAAA,EAAI;AAC7C,YAAA,MAAM,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,WAAA,EAAY;AAC/C,YAAA,YAAA,GAAe,EAAA;AACf,YAAA,WAAA,GAAc,EAAA;AAAA,UAChB;AACA,UAAA;AAAA,QACF;AACA,QAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAE7B,QAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,CAAQ,GAAG,CAAA;AACjC,QAAA,MAAM,QAAQ,KAAA,KAAU,CAAA,CAAA,GAAK,UAAU,OAAA,CAAQ,KAAA,CAAM,GAAG,KAAK,CAAA;AAC7D,QAAA,MAAM,WAAW,KAAA,KAAU,CAAA,CAAA,GAAK,KAAK,OAAA,CAAQ,KAAA,CAAM,QAAQ,CAAC,CAAA;AAC5D,QAAA,MAAM,MAAA,GAAS,SAAS,UAAA,CAAW,GAAG,IAAI,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,GAAI,QAAA;AAE9D,QAAA,IAAI,UAAU,OAAA,EAAS;AACrB,UAAA,YAAA,GAAe,MAAA;AAAA,QACjB,CAAA,MAAA,IAAW,UAAU,MAAA,EAAQ;AAC3B,UAAA,WAAA,GAAc,WAAA,KAAgB,EAAA,GAAK,MAAA,GAAS,CAAA,EAAG,WAAW;AAAA,EAAK,MAAM,CAAA,CAAA;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,WAAA,KAAgB,EAAA,IAAM,YAAA,KAAiB,EAAA,EAAI;AAC7C,MAAA,MAAM,EAAE,KAAA,EAAO,YAAA,EAAc,IAAA,EAAM,WAAA,EAAY;AAAA,IACjD;AAAA,EACF,CAAA,SAAE;AACA,IAAA,MAAA,CAAO,WAAA,EAAY;AAAA,EACrB;AACF;AAEA,SAAS,eAAe,CAAA,EAAmB;AACzC,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,KAAK,CAAA,EAAG;AACpC,IAAA,MAAM,CAAA,GAAI,EAAE,CAAC,CAAA;AACb,IAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,IAAA,EAAM,OAAO,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,EAAA;AACT;;;ACxDA,IAAM,gBAAA,GAAmB,2BAAA;AACzB,IAAM,kBAAqC,CAAC,GAAA,EAAM,GAAA,EAAM,GAAA,EAAM,KAAQ,GAAM,CAAA;AAUrE,IAAM,gBAAN,MAAoB;AAAA,EACR,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,IAAA,EAA4B;AACtC,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,OAAO,IAAA,CAAK,WAAW,QAAA,EAAU;AACnD,MAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,IAC1D;AACA,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACnE,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,KAAA,IAAS,UAAA,CAAW,KAAA;AAC1C,IAAA,IAAI,OAAO,IAAA,CAAK,SAAA,KAAc,UAAA,EAAY;AACxC,MAAA,MAAM,IAAI,MAAM,uEAAkE,CAAA;AAAA,IACpF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,KAAA,EAAiD;AAC9D,IAAA,IAAI,KAAA,CAAM,UAAU,IAAA,EAAM;AACxB,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,WAAA,CAA4B,QAAQ,wBAAA,EAA0B;AAAA,QACtF,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,KAAA,EAAO,IAAA;AAAA,QACP,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,aAAa,KAAA,CAAM,WAAA;AAAA,QACnB,cAAc,KAAA,CAAM;AAAA,OACrB,CAAA;AACD,MAAA,YAAA,CAAa,MAAA,CAAO,OAAO,sBAAsB,CAAA;AACjD,MAAA,YAAA,CAAa,MAAA,CAAO,WAAW,0BAA0B,CAAA;AACzD,MAAA,OAAO,IAAA,CAAK,iBAAA,CAAkB,MAAA,EAAQ,KAAA,CAAM,OAAO,CAAA;AAAA,IACrD;AACA,IAAA,OAAO,IAAA,CAAK,eAAe,KAAK,CAAA;AAAA,EAClC;AAAA,EAEA,MAAM,UAAA,CAAW,KAAA,EAAe,KAAA,EAAgD;AAC9E,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,MAAM,6CAA6C,CAAA;AACzE,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,WAAA,CAA2B,OAAO,2BAAA,EAA6B;AAAA,MACvF,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,YAAA,CAAa,MAAA,CAAO,MAAM,oBAAoB,CAAA;AAC9C,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAM,YAAA,CAAa,MAAA,EAAuB,IAAA,EAA+C;AACvF,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,WAAA,CAA2B,QAAQ,uBAAA,EAAyB;AAAA,MACpF,MAAA;AAAA,MACA,QAAQ,IAAA,EAAM,MAAA;AAAA,MACd,OAAO,IAAA,EAAM;AAAA,KACd,CAAA;AACD,IAAA,YAAA,CAAa,MAAA,CAAO,aAAa,2BAA2B,CAAA;AAC5D,IAAA,YAAA,CAAa,MAAA,CAAO,WAAW,yBAAyB,CAAA;AACxD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAc,eAAe,KAAA,EAAiD;AAC5E,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,UAAU,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,sBAAA,CAAA,EAA0B;AAAA,MACxE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,EAAE,MAAA,EAAQ,qBAAqB,WAAA,EAAa,kBAAA,EAAmB,EAAG,KAAA,CAAM,SAAS,CAAA;AAAA,MACvG,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,WAAW,KAAA,CAAM,SAAA;AAAA,QACjB,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,aAAa,KAAA,CAAM,WAAA;AAAA,QACnB,cAAc,KAAA,CAAM;AAAA,OACrB;AAAA,KACF,CAAA;AACD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,QAAU,MAAM,IAAA,CAAK,kBAAkB,GAAG,CAAA;AACnD,IAAA,IAAI,IAAI,IAAA,KAAS,IAAA,EAAM,MAAM,IAAI,MAAM,iDAAiD,CAAA;AAExF,IAAA,IAAI,KAAA,GAA+B,IAAA;AACnC,IAAA,WAAA,MAAiB,GAAA,IAAO,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAG;AAC1C,MAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA;AACpC,MAAA,IAAI,UAAU,IAAA,EAAM;AACpB,MAAA,KAAA,CAAM,UAAU,KAAK,CAAA;AACrB,MAAA,IAAI,KAAA,CAAM,SAAS,UAAA,EAAY;AAC7B,QAAA,IAAI,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,MAAA,EAAW;AACnC,UAAA,MAAM,IAAI,WAAA,CAAY,EAAE,MAAM,GAAA,EAAK,OAAA,EAAS,6CAA6C,CAAA;AAAA,QAC3F;AACA,QAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA;AACnD,QAAA,KAAA,GAAQ,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAA,CAAM,KAAK,KAAA,EAAM;AAAA,MAC5C,CAAA,MAAA,IAAW,KAAA,CAAM,IAAA,KAAS,OAAA,EAAS;AACjC,QAAA,MAAM,aAAA,CAAc,EAAE,IAAA,EAAM,GAAA,EAAK,SAAS,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9D;AAAA,IACF;AACA,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,MAAM,IAAI,WAAA,CAAY,EAAE,MAAM,GAAA,EAAK,OAAA,EAAS,6CAA6C,CAAA;AAAA,IAC3F;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAc,iBAAA,CACZ,MAAA,EACA,OAAA,EACyB;AACzB,IAAA,IAAI,OAAA,GAAU,CAAA;AACd,IAAA,WAAS;AACP,MAAA,MAAM,KAAA,GAAQ,gBAAgB,IAAA,CAAK,GAAA,CAAI,SAAS,eAAA,CAAgB,MAAA,GAAS,CAAC,CAAC,CAAA;AAC3E,MAAA,MAAM,MAAM,KAAK,CAAA;AACjB,MAAA,OAAA,IAAW,CAAA;AACX,MAAA,MAAM,SAAS,MAAM,IAAA,CAAK,WAAA,CAAuB,KAAA,EAAO,OAAO,SAAS,CAAA;AACxE,MAAA,YAAA,CAAa,MAAA,CAAO,OAAO,iBAAiB,CAAA;AAC5C,MAAA,IAAI,MAAA,CAAO,MAAA,KAAW,MAAA,IAAa,OAAA,KAAY,MAAA,EAAW;AACxD,QAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,EAAQ,OAAA,CAAQ,CAAC,CAAA;AAAA,MAC1C;AACA,MAAA,IAAI,MAAA,CAAO,UAAU,UAAA,EAAY;AAC/B,QAAA,IAAI,MAAA,CAAO,WAAW,MAAA,EAAW;AAC/B,UAAA,MAAM,IAAI,WAAA,CAAY,EAAE,MAAM,GAAA,EAAK,OAAA,EAAS,uCAAuC,CAAA;AAAA,QACrF;AACA,QAAA,OAAO,MAAA,CAAO,MAAA;AAAA,MAChB;AACA,MAAA,IAAI,MAAA,CAAO,UAAU,OAAA,EAAS;AAC5B,QAAA,MAAM,aAAA,CAAc;AAAA,UAClB,IAAA,EAAM,OAAO,SAAA,IAAa,GAAA;AAAA,UAC1B,OAAA,EAAS,OAAO,YAAA,IAAgB;AAAA,SACjC,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,WAAA,CAAe,MAAA,EAAgB,IAAA,EAAc,IAAA,EAA2B;AACpF,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA,CAAW,SAAS,CAAA,IAAK,IAAA,CAAK,WAAW,UAAU,CAAA;AAC3E,IAAA,MAAM,MAAM,UAAA,GAAa,IAAA,GAAO,GAAG,IAAA,CAAK,OAAO,GAAG,IAAI,CAAA,CAAA;AACtD,IAAA,MAAM,IAAA,GAAoB;AAAA,MACxB,MAAA;AAAA,MACA,OAAA,EAAS,KAAK,OAAA,CAAQ;AAAA,QACpB,MAAA,EAAQ,kBAAA;AAAA,QACR,WAAA,EAAa,IAAA,KAAS,MAAA,GAAY,kBAAA,GAAqB;AAAA,OACxD;AAAA,KACH;AACA,IAAA,IAAI,SAAS,MAAA,EAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AACvD,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAA;AAC1C,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,QAAU,MAAM,IAAA,CAAK,kBAAkB,GAAG,CAAA;AACnD,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,MAAM,IAAI,WAAA,CAAY,EAAE,MAAM,GAAA,EAAK,OAAA,EAAS,uBAAuB,CAAA;AAAA,IACrE;AACA,IAAA,MAAM,MAAA,GAAY,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AACjC,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,OAAA,CACN,MACA,SAAA,EACwB;AACxB,IAAA,MAAM,IAA4B,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA,EAAG;AAC3E,IAAA,IAAI,KAAK,MAAA,KAAW,MAAA,EAAW,CAAA,CAAE,QAAQ,IAAI,IAAA,CAAK,MAAA;AAClD,IAAA,IAAI,KAAK,WAAA,KAAgB,MAAA,EAAW,CAAA,CAAE,cAAc,IAAI,IAAA,CAAK,WAAA;AAC7D,IAAA,IAAI,cAAc,MAAA,IAAa,SAAA,KAAc,EAAA,EAAI,CAAA,CAAE,eAAe,CAAA,GAAI,SAAA;AACtE,IAAA,OAAO,CAAA;AAAA,EACT;AAAA,EAEA,MAAc,kBAAkB,GAAA,EAA+B;AAC7D,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,SAA8B,IAAA,KAAS,EAAA,GAAK,IAAA,GAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AACxE,MAAA,IAAA,GAAO,MAAA,KAAW,IAAA,IAAQ,OAAO,MAAA,CAAO,IAAA,KAAS,YAAY,OAAO,MAAA,CAAO,OAAA,KAAY,QAAA,GACnF,MAAA,GACA;AAAA,QACE,MAAM,GAAA,CAAI,MAAA;AAAA,QACV,OAAA,EAAS,GAAA,CAAI,UAAA,KAAe,EAAA,GAAK,IAAI,UAAA,GAAa;AAAA,OACpD;AAAA,IACN,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,GAAO,EAAE,MAAM,GAAA,CAAI,MAAA,EAAQ,SAAS,IAAA,KAAS,EAAA,GAAK,IAAA,GAAO,GAAA,CAAI,UAAA,EAAW;AAAA,IAC1E;AACA,IAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAChD,IAAA,MAAM,GAAA,GAAM,cAAc,IAAI,CAAA;AAC9B,IAAA,IAAI,GAAA,CAAI,IAAA,KAAS,kBAAA,IAAsB,UAAA,KAAe,IAAA,EAAM;AAC1D,MAAA,MAAM,OAAA,GAAU,OAAO,UAAU,CAAA;AACjC,MAAA,IAAI,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,EAAG;AAC5B,QAAA,MAAA,CAAO,cAAA,CAAe,KAAK,mBAAA,EAAqB,EAAE,OAAO,OAAA,EAAS,UAAA,EAAY,MAAM,CAAA;AAAA,MACtF;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;AAQA,SAAS,cAAc,QAAA,EAAmC;AACxD,EAAA,IAAI,QAAA,KAAa,IAAI,OAAO,IAAA;AAC5B,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,IAAA,CAAK,MAAM,QAAQ,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAA,KAAY,QAAQ,OAAO,OAAA,KAAY,YAAY,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG,OAAO,IAAA;AACtF,EAAA,IAAI,OAAO,QAAQ,IAAA,KAAS,QAAA,IAAY,OAAO,OAAA,CAAQ,SAAA,KAAc,UAAU,OAAO,IAAA;AACtF,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,YAAA,CAAa,GAAuB,IAAA,EAAmC;AAC9E,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,EAAA,EAAI;AACrC,IAAA,MAAM,IAAI,YAAY,EAAE,IAAA,EAAM,KAAK,OAAA,EAAS,CAAA,2BAAA,EAA8B,IAAI,CAAA,gBAAA,CAAA,EAAoB,CAAA;AAAA,EACpG;AACF;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;;;AC/MA,SAAS,gBAAA,CAAiB,MAA8B,GAAA,EAAkC;AACxF,EAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAO,IAAA,CAAK,UAAU,GAAG,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,WAAW,CAAA;AAC1C,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,CAAO,MAAA,GAAS,IAAI,MAAA,GAAS,MAAA;AACpE;AAEA,SAAS,eAAe,KAAA,EAAyB;AAC/C,EAAA,OAAO,CAAA,MAAA,EAAS,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC;;AAAA,CAAA;AACvC;AAWO,SAAS,sBACd,IAAA,EACyC;AACzC,EAAA,OAAO,OAAO,OAAA,KAAwC;AACpD,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAQ,MAAM,QAAQ,IAAA,EAAK;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mBAAA,EAAqB,CAAA,EAAG;AAAA,QAClE,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,OAAA;AACtC,IAAA,MAAM,MAAA,GAAS,OAAO,SAAA,KAAc,QAAA,GAAW,SAAA,GAAY,EAAA;AAE3D,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,+BAAA,EAAiC,CAAA,EAAG;AAAA,QAC9E,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,gBAAgB,OAAO,IAAA,CAAK,SAAA,KAAc,QAAA,GAAW,KAAK,SAAA,GAAY,MAAA;AAC5E,IAAA,MAAM,SAAA,GAAY,aAAA,IAAiB,gBAAA,CAAiB,IAAA,EAAM,OAAO,CAAA;AACjE,IAAA,MAAM,QAAQ,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GAAW,KAAK,KAAA,GAAQ,MAAA;AAE5D,IAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc,EAAE,MAAA,EAAQ,KAAK,MAAA,EAAQ,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,CAAA;AAE/E,IAAA,MAAM,MAAA,GAAS,IAAI,cAAA,CAA2B;AAAA,MAC5C,MAAM,MAAM,UAAA,EAAY;AACtB,QAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,QAAA,IAAI;AACF,UAAA,MAAM,OAAO,QAAA,CAAS;AAAA,YACpB,MAAA;AAAA,YACA,SAAA;AAAA,YACA,KAAA;AAAA,YACA,OAAA,EAAS,CAAC,KAAA,KAAoB;AAC5B,cAAA,UAAA,CAAW,QAAQ,OAAA,CAAQ,MAAA,CAAO,cAAA,CAAe,KAAK,CAAC,CAAC,CAAA;AAAA,YAC1D;AAAA,WACD,CAAA;AAAA,QACH,SAAS,GAAA,EAAK;AACZ,UAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,UAAA,MAAM,UAAA,GAAuB;AAAA,YAC3B,IAAA,EAAM,OAAA;AAAA,YACN,SAAA,EAAW,KAAK,GAAA,EAAI;AAAA,YACpB,IAAA,EAAM,EAAE,KAAA,EAAO,OAAA;AAAQ,WACzB;AACA,UAAA,UAAA,CAAW,QAAQ,OAAA,CAAQ,MAAA,CAAO,cAAA,CAAe,UAAU,CAAC,CAAC,CAAA;AAAA,QAC/D,CAAA,SAAE;AACA,UAAA,UAAA,CAAW,KAAA,EAAM;AAAA,QACnB;AAAA,MACF;AAAA,KACD,CAAA;AAED,IAAA,OAAO,IAAI,SAAS,MAAA,EAAQ;AAAA,MAC1B,MAAA,EAAQ,GAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,mBAAA;AAAA,QAChB,eAAA,EAAiB,UAAA;AAAA,QACjB,UAAA,EAAY;AAAA;AACd,KACD,CAAA;AAAA,EACH,CAAA;AACF;AAWO,SAAS,kBACd,IAAA,EACyC;AACzC,EAAA,OAAO,OAAO,OAAA,KAAwC;AACpD,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAQ,MAAM,QAAQ,IAAA,EAAK;AAAA,IAC7B,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mBAAA,EAAqB,CAAA,EAAG;AAAA,QAClE,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,QAAQ,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GAAW,KAAK,KAAA,GAAQ,EAAA;AAC5D,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mBAAA,EAAqB,CAAA,EAAG;AAAA,QAClE,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,QAAqC,IAAA,CAAK,KAAA;AAChD,IAAA,IAAI,UAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,OAAO,UAAU,QAAA,EAAU;AACtE,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,mBAAA,EAAqB,CAAA,EAAG;AAAA,QAClE,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,aAAA,CAAc,EAAE,MAAA,EAAQ,KAAK,MAAA,EAAQ,OAAA,EAAS,IAAA,CAAK,OAAA,EAAS,CAAA;AAE/E,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAwB,MAAM,MAAA,CAAO,UAAA,CAAW,OAAO,KAAK,CAAA;AAClE,MAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA,EAAG;AAAA,QAC1C,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,MAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG;AAAA,QACtD,MAAA,EAAQ,GAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,OAC/C,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACF","file":"index.js","sourcesContent":["/**\n * Typed SDK errors. Server emits a structured `ApiErrorBody`; the HTTP layer\n * maps the `code` to one of these subclasses. Customers `catch` by class.\n */\n\nimport type { ApiErrorBody } from '../types';\n\nexport class AlmadarError extends Error {\n readonly code: number;\n readonly details?: ApiErrorBody['details'];\n constructor(body: ApiErrorBody) {\n super(body.message);\n this.name = 'AlmadarError';\n this.code = body.code;\n this.details = body.details;\n }\n}\n\n/** 4001 — invalid, revoked, or missing API key. */\nexport class ApiKeyError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ApiKeyError';\n }\n}\n\n/** 4029 — team cap (feature counter) exceeded. Retry after a billing cycle. */\nexport class RateLimitedError extends AlmadarError {\n readonly retryAfterSeconds?: number;\n constructor(body: ApiErrorBody, retryAfterSeconds?: number) {\n super(body);\n this.name = 'RateLimitedError';\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\n/** 4040 — the team's behavior catalog (subset/replace mode) cannot serve the request. */\nexport class CatalogOutOfScopeError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'CatalogOutOfScopeError';\n }\n}\n\n/** Anything else from the server with a recognized envelope but no specific subclass. */\nexport class ServerError extends AlmadarError {\n constructor(body: ApiErrorBody) {\n super(body);\n this.name = 'ServerError';\n }\n}\n\nexport function errorFromBody(body: ApiErrorBody): AlmadarError {\n switch (body.code) {\n case 4001:\n return new ApiKeyError(body);\n case 4029:\n return new RateLimitedError(body);\n case 4040:\n return new CatalogOutOfScopeError(body);\n default:\n return new ServerError(body);\n }\n}\n","/**\n * Minimal Server-Sent Events parser. Reads a `ReadableStream<Uint8Array>`\n * (the body of a `fetch` Response) and yields decoded events. Universal:\n * works in browser, Node 18+, Deno, Bun.\n *\n * Spec subset implemented:\n * - `event:` and `data:` fields\n * - dispatch on blank line\n * - newline-tolerant (CRLF + LF)\n * - skips comments (`:`-prefixed lines)\n *\n * Not implemented (we don't need them):\n * - `id:` / `retry:` fields\n * - reconnection / last-event-id\n */\n\nexport interface RawSseEvent {\n /** `event:` field value. Empty string when absent — matches the spec default. */\n event: string;\n /** Concatenated `data:` lines, joined by newlines. */\n data: string;\n}\n\nexport async function* parseSSE(\n stream: ReadableStream<Uint8Array>,\n): AsyncGenerator<RawSseEvent, void, void> {\n const reader = stream.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let currentEvent = '';\n let currentData = '';\n\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let newlineIdx: number;\n while ((newlineIdx = indexOfNewline(buffer)) !== -1) {\n const rawLine = buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + (buffer[newlineIdx] === '\\r' && buffer[newlineIdx + 1] === '\\n' ? 2 : 1));\n\n if (rawLine === '') {\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n currentEvent = '';\n currentData = '';\n }\n continue;\n }\n if (rawLine.startsWith(':')) continue;\n\n const colon = rawLine.indexOf(':');\n const field = colon === -1 ? rawLine : rawLine.slice(0, colon);\n const rawValue = colon === -1 ? '' : rawLine.slice(colon + 1);\n const value2 = rawValue.startsWith(' ') ? rawValue.slice(1) : rawValue;\n\n if (field === 'event') {\n currentEvent = value2;\n } else if (field === 'data') {\n currentData = currentData === '' ? value2 : `${currentData}\\n${value2}`;\n }\n }\n }\n if (currentData !== '' || currentEvent !== '') {\n yield { event: currentEvent, data: currentData };\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction indexOfNewline(s: string): number {\n for (let i = 0; i < s.length; i += 1) {\n const c = s[i];\n if (c === '\\n' || c === '\\r') return i;\n }\n return -1;\n}\n","/**\n * `AlmadarClient` — server / Node-side HTTP client targeting `/api/v1/agent/*`.\n * Authenticates with a team-bound API key (`sk_*`) issued from\n * Studio's `/settings/sdk` panel. See `docs/Almadar_Studio_SDK.md` §5.\n *\n * Never instantiate this in a browser bundle — `apiKey` must never leave\n * the customer's server.\n */\n\nimport { parseOrbitalSchema, type OrbitalSchema, type SSEEvent } from '@almadar/core';\nimport type {\n AlmadarClientOptions,\n ApiErrorBody,\n AsyncJobHandle,\n CompileOptions,\n CompileResult,\n EditSchemaPatch,\n GenerateOptions,\n GenerateResult,\n} from '../types';\nimport { errorFromBody, ServerError } from './errors';\nimport { parseSSE } from './sseParser';\n\nconst DEFAULT_BASE_URL = 'https://studio.almadar.io';\nconst POLL_BACKOFF_MS: readonly number[] = [1000, 2000, 5000, 10_000, 30_000];\n\ninterface JobStatus {\n state: 'pending' | 'complete' | 'error';\n events?: readonly SSEEvent[];\n result?: GenerateResult;\n errorCode?: number;\n errorMessage?: string;\n}\n\nexport class AlmadarClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(opts: AlmadarClientOptions) {\n if (!opts.apiKey || typeof opts.apiKey !== 'string') {\n throw new Error('AlmadarClient: opts.apiKey is required');\n }\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (typeof this.fetchImpl !== 'function') {\n throw new Error('AlmadarClient: no fetch available — pass opts.fetch for Node <18');\n }\n }\n\n async generate(input: GenerateOptions): Promise<GenerateResult> {\n if (input.async === true) {\n const handle = await this.requestJson<AsyncJobHandle>('POST', '/api/v1/agent/generate', {\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n async: true,\n provider: input.provider,\n model: input.model,\n catalogMode: input.catalogMode,\n stdAllowList: input.stdAllowList,\n });\n assertString(handle.jobId, 'AsyncJobHandle.jobId');\n assertString(handle.statusUrl, 'AsyncJobHandle.statusUrl');\n return this.pollUntilComplete(handle, input.onEvent);\n }\n return this.streamGenerate(input);\n }\n\n async editSchema(appId: string, patch: EditSchemaPatch): Promise<OrbitalSchema> {\n if (!appId) throw new Error('AlmadarClient.editSchema: appId is required');\n const schema = await this.requestJson<OrbitalSchema>('PUT', '/api/v1/agent/edit-schema', {\n appId,\n patch,\n });\n assertString(schema.name, 'OrbitalSchema.name');\n return schema;\n }\n\n async compileToApp(schema: OrbitalSchema, opts?: CompileOptions): Promise<CompileResult> {\n const result = await this.requestJson<CompileResult>('POST', '/api/v1/agent/compile', {\n schema,\n target: opts?.target,\n shell: opts?.shell,\n });\n assertString(result.downloadUrl, 'CompileResult.downloadUrl');\n assertString(result.expiresAt, 'CompileResult.expiresAt');\n return result;\n }\n\n private async streamGenerate(input: GenerateOptions): Promise<GenerateResult> {\n const res = await this.fetchImpl(`${this.baseUrl}/api/v1/agent/generate`, {\n method: 'POST',\n headers: this.headers({ accept: 'text/event-stream', contentType: 'application/json' }, input.endUserId),\n body: JSON.stringify({\n prompt: input.prompt,\n endUserId: input.endUserId,\n appId: input.appId,\n provider: input.provider,\n model: input.model,\n catalogMode: input.catalogMode,\n stdAllowList: input.stdAllowList,\n }),\n });\n if (!res.ok) throw await this.errorFromResponse(res);\n if (res.body === null) throw new Error('AlmadarClient.generate: server returned no body');\n\n let final: GenerateResult | null = null;\n for await (const raw of parseSSE(res.body)) {\n const event = parseSseEvent(raw.data);\n if (event === null) continue;\n input.onEvent?.(event);\n if (event.type === 'complete') {\n if (event.data.schema === undefined) {\n throw new ServerError({ code: 500, message: '`complete` event did not contain a schema' });\n }\n const schema = parseOrbitalSchema(event.data.schema);\n final = { schema, appId: event.data.appId };\n } else if (event.type === 'error') {\n throw errorFromBody({ code: 500, message: event.data.error });\n }\n }\n if (final === null) {\n throw new ServerError({ code: 500, message: 'SSE stream ended without `complete` event' });\n }\n return final;\n }\n\n private async pollUntilComplete(\n handle: AsyncJobHandle,\n onEvent: GenerateOptions['onEvent'],\n ): Promise<GenerateResult> {\n let attempt = 0;\n for (;;) {\n const delay = POLL_BACKOFF_MS[Math.min(attempt, POLL_BACKOFF_MS.length - 1)];\n await sleep(delay);\n attempt += 1;\n const status = await this.requestJson<JobStatus>('GET', handle.statusUrl);\n assertString(status.state, 'JobStatus.state');\n if (status.events !== undefined && onEvent !== undefined) {\n for (const e of status.events) onEvent(e);\n }\n if (status.state === 'complete') {\n if (status.result === undefined) {\n throw new ServerError({ code: 500, message: 'Job complete but no result returned' });\n }\n return status.result;\n }\n if (status.state === 'error') {\n throw errorFromBody({\n code: status.errorCode ?? 500,\n message: status.errorMessage ?? 'Job failed',\n });\n }\n }\n }\n\n private async requestJson<T>(method: string, path: string, body?: object): Promise<T> {\n const isAbsolute = path.startsWith('http://') || path.startsWith('https://');\n const url = isAbsolute ? path : `${this.baseUrl}${path}`;\n const init: RequestInit = {\n method,\n headers: this.headers({\n accept: 'application/json',\n contentType: body !== undefined ? 'application/json' : undefined,\n }),\n };\n if (body !== undefined) init.body = JSON.stringify(body);\n const res = await this.fetchImpl(url, init);\n if (!res.ok) throw await this.errorFromResponse(res);\n const text = await res.text();\n if (text === '') {\n throw new ServerError({ code: 500, message: 'Empty response body' });\n }\n const parsed: T = JSON.parse(text);\n return parsed;\n }\n\n private headers(\n opts: { accept?: string; contentType?: string },\n endUserId?: string,\n ): Record<string, string> {\n const h: Record<string, string> = { authorization: `Bearer ${this.apiKey}` };\n if (opts.accept !== undefined) h['accept'] = opts.accept;\n if (opts.contentType !== undefined) h['content-type'] = opts.contentType;\n if (endUserId !== undefined && endUserId !== '') h['x-end-user-id'] = endUserId;\n return h;\n }\n\n private async errorFromResponse(res: Response): Promise<Error> {\n const text = await res.text();\n let body: ApiErrorBody;\n try {\n const parsed: ApiErrorBody | null = text === '' ? null : JSON.parse(text);\n body = parsed !== null && typeof parsed.code === 'number' && typeof parsed.message === 'string'\n ? parsed\n : {\n code: res.status,\n message: res.statusText !== '' ? res.statusText : 'HTTP error',\n };\n } catch {\n body = { code: res.status, message: text !== '' ? text : res.statusText };\n }\n const retryAfter = res.headers.get('retry-after');\n const err = errorFromBody(body);\n if (err.name === 'RateLimitedError' && retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n Object.defineProperty(err, 'retryAfterSeconds', { value: seconds, enumerable: true });\n }\n }\n return err;\n }\n}\n\n/**\n * Parse one SSE `data:` line into the canonical `SSEEvent` union.\n * The server is the trusted emitter, so we validate only the envelope\n * (object with string `type` and numeric `timestamp`) and cast to the\n * discriminated union. Malformed lines are ignored.\n */\nfunction parseSseEvent(dataLine: string): SSEEvent | null {\n if (dataLine === '') return null;\n let payload;\n try {\n payload = JSON.parse(dataLine);\n } catch {\n return null;\n }\n if (payload === null || typeof payload !== 'object' || Array.isArray(payload)) return null;\n if (typeof payload.type !== 'string' || typeof payload.timestamp !== 'number') return null;\n return payload as SSEEvent;\n}\n\nfunction assertString(v: string | undefined, name: string): asserts v is string {\n if (typeof v !== 'string' || v === '') {\n throw new ServerError({ code: 500, message: `Malformed server response: ${name} is not a string` });\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * `@almadar/sdk/server` — Framework-agnostic Web-standard Fetch handlers for\n * the Almadar agent proxy. Node-only; never import from browser or React code.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server';\n * const handler = createGenerateHandler({ apiKey: process.env.ALMADAR_API_KEY! });\n * // handler: (request: Request) => Promise<Response>\n *\n * For framework adapters see `@almadar/sdk/server/express` and `@almadar/sdk/server/hono`.\n */\n\nimport type { OrbitalSchema } from '@almadar/core';\nimport { AlmadarClient } from '../client/AlmadarClient';\nimport type { EditSchemaRequest, EditSchemaPatch, GenerateRequest, SSEEvent } from '../types';\n\n// ============================================================================\n// Public option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** API key issued from Studio's /settings/sdk panel. */\n apiKey: string;\n /** Defaults to https://studio.almadar.io. */\n baseUrl?: string;\n /**\n * Derive a stable end-user id from the incoming Web Request.\n * Falls back to the `x-user-id` request header when omitted.\n */\n endUserId?: (req: Request) => string;\n}\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\nfunction resolveEndUserId(opts: GenerateHandlerOptions, req: Request): string | undefined {\n if (opts.endUserId) return opts.endUserId(req);\n const header = req.headers.get('x-user-id');\n return typeof header === 'string' && header.length > 0 ? header : undefined;\n}\n\nfunction encodeSseEvent(event: SSEEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n// ============================================================================\n// createGenerateHandler\n// ============================================================================\n\n/**\n * Returns a Web-standard Fetch handler that streams a generate call as SSE.\n *\n * Body shape accepted: `{ prompt: string; endUserId?: string; appId?: string }`\n */\nexport function createGenerateHandler(\n opts: GenerateHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let body: GenerateRequest;\n try {\n body = (await request.json()) as GenerateRequest;\n } catch {\n return new Response(JSON.stringify({ error: 'invalid JSON body' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const rawPrompt = body.prompt ?? body.message;\n const prompt = typeof rawPrompt === 'string' ? rawPrompt : '';\n\n if (!prompt) {\n return new Response(JSON.stringify({ error: 'prompt or message is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const bodyEndUserId = typeof body.endUserId === 'string' ? body.endUserId : undefined;\n const endUserId = bodyEndUserId ?? resolveEndUserId(opts, request);\n const appId = typeof body.appId === 'string' ? body.appId : undefined;\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n const encoder = new TextEncoder();\n try {\n await client.generate({\n prompt,\n endUserId,\n appId,\n onEvent: (event: SSEEvent) => {\n controller.enqueue(encoder.encode(encodeSseEvent(event)));\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const errorEvent: SSEEvent = {\n type: 'error',\n timestamp: Date.now(),\n data: { error: message },\n };\n controller.enqueue(encoder.encode(encodeSseEvent(errorEvent)));\n } finally {\n controller.close();\n }\n },\n });\n\n return new Response(stream, {\n status: 200,\n headers: {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n },\n });\n };\n}\n\n// ============================================================================\n// createEditHandler\n// ============================================================================\n\n/**\n * Returns a Web-standard Fetch handler that calls `editSchema` and returns JSON.\n *\n * Body shape accepted: `{ appId: string; patch: EditSchemaPatch }`\n */\nexport function createEditHandler(\n opts: GenerateHandlerOptions,\n): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n let body: EditSchemaRequest;\n try {\n body = (await request.json()) as EditSchemaRequest;\n } catch {\n return new Response(JSON.stringify({ error: 'invalid JSON body' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const appId = typeof body.appId === 'string' ? body.appId : '';\n if (!appId) {\n return new Response(JSON.stringify({ error: 'appId is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const patch: EditSchemaPatch | undefined = body.patch;\n if (patch === undefined || patch === null || typeof patch !== 'object') {\n return new Response(JSON.stringify({ error: 'patch is required' }), {\n status: 400,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n const client = new AlmadarClient({ apiKey: opts.apiKey, baseUrl: opts.baseUrl });\n\n try {\n const schema: OrbitalSchema = await client.editSchema(appId, patch);\n return new Response(JSON.stringify(schema), {\n status: 200,\n headers: { 'content-type': 'application/json' },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return new Response(JSON.stringify({ error: message }), {\n status: 500,\n headers: { 'content-type': 'application/json' },\n });\n }\n };\n}\n"]}
|
|
@@ -1,65 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SSEEvent, OrbitalSchema, EventPayload, EntityData } from '@almadar/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Public SDK types. Canonical schema / payload types come from `@almadar/core`;
|
|
5
|
-
* the SDK adds the
|
|
5
|
+
* the SDK adds the HTTP-layer option shapes and re-exports the canonical SSE
|
|
6
|
+
* event union.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
|
-
/**
|
|
9
|
-
* Canonical JSON value type — the closure of every value that survives a
|
|
10
|
-
* `JSON.parse(JSON.stringify(x))` round-trip. Used as the JSON-parse output
|
|
11
|
-
* type so we never widen to `unknown` at HTTP boundaries.
|
|
12
|
-
*
|
|
13
|
-
* Mirrors `packages/almadar-agent/src/api-types.ts:25-31`.
|
|
14
|
-
*/
|
|
15
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
16
|
-
[key: string]: JsonValue;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Lifecycle events emitted by the agent during a `generate()` call. Mirrors
|
|
20
|
-
* the SSE event types from
|
|
21
|
-
* `apps/builder/packages/server/src/routes/agent/deepagent.ts` — keep in sync
|
|
22
|
-
* when new events are added on the server.
|
|
23
|
-
*/
|
|
24
|
-
type AgentEvent = {
|
|
25
|
-
type: 'start';
|
|
26
|
-
threadId: string;
|
|
27
|
-
workDir: string;
|
|
28
|
-
} | {
|
|
29
|
-
type: 'plan_committed';
|
|
30
|
-
orbitals: readonly string[];
|
|
31
|
-
} | {
|
|
32
|
-
type: 'orbital_added';
|
|
33
|
-
orbital: string;
|
|
34
|
-
} | {
|
|
35
|
-
type: 'schema_update';
|
|
36
|
-
schema: OrbitalSchema;
|
|
37
|
-
} | {
|
|
38
|
-
type: 'app_created';
|
|
39
|
-
appId: string;
|
|
40
|
-
name: string;
|
|
41
|
-
} | {
|
|
42
|
-
type: 'subagent_start';
|
|
43
|
-
subagent: string;
|
|
44
|
-
} | {
|
|
45
|
-
type: 'subagent_progress';
|
|
46
|
-
subagent: string;
|
|
47
|
-
message: string;
|
|
48
|
-
} | {
|
|
49
|
-
type: 'subagent_complete';
|
|
50
|
-
subagent: string;
|
|
51
|
-
} | {
|
|
52
|
-
type: 'coordinator_decision';
|
|
53
|
-
decision: string;
|
|
54
|
-
} | {
|
|
55
|
-
type: 'complete';
|
|
56
|
-
schema: OrbitalSchema;
|
|
57
|
-
appId?: string;
|
|
58
|
-
} | {
|
|
59
|
-
type: 'error';
|
|
60
|
-
message: string;
|
|
61
|
-
code?: number;
|
|
62
|
-
};
|
|
63
9
|
/**
|
|
64
10
|
* Server-emitted error envelope. `code` maps to the SDK error subclasses:
|
|
65
11
|
* 4001 → ApiKeyError, 4029 → RateLimitedError, 4040 → CatalogOutOfScopeError.
|
|
@@ -81,13 +27,33 @@ interface GenerateOptions {
|
|
|
81
27
|
prompt: string;
|
|
82
28
|
endUserId?: string;
|
|
83
29
|
appId?: string;
|
|
84
|
-
/** Streaming callback for SSE events. */
|
|
85
|
-
onEvent?: (event:
|
|
30
|
+
/** Streaming callback for canonical SSE events. */
|
|
31
|
+
onEvent?: (event: SSEEvent) => void;
|
|
86
32
|
/**
|
|
87
33
|
* When true, server responds with an `AsyncJobHandle` immediately and the
|
|
88
34
|
* client polls. Useful for generations expected to exceed proxy SSE timeouts.
|
|
89
35
|
*/
|
|
90
36
|
async?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Agent provider override (e.g. 'deepseek', 'openai').
|
|
39
|
+
* Omit to use the server's default.
|
|
40
|
+
*/
|
|
41
|
+
provider?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Agent model override (e.g. 'deepseek-chat').
|
|
44
|
+
* Omit to use the server's default.
|
|
45
|
+
*/
|
|
46
|
+
model?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Behavior catalog mode — 'subset' narrows generation to stdAllowList.
|
|
49
|
+
* Server-specific; omit if the agent does not support it.
|
|
50
|
+
*/
|
|
51
|
+
catalogMode?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Allow-list of std behavior names. Requires a server that supports catalog
|
|
54
|
+
* narrowing (e.g. the builder Rabit/Studio agent).
|
|
55
|
+
*/
|
|
56
|
+
stdAllowList?: string[];
|
|
91
57
|
}
|
|
92
58
|
interface GenerateResult {
|
|
93
59
|
schema: OrbitalSchema;
|
|
@@ -136,10 +102,6 @@ interface AlmadarAppProps {
|
|
|
136
102
|
initialPagePath?: string;
|
|
137
103
|
height?: string;
|
|
138
104
|
className?: string;
|
|
139
|
-
theme?: 'copper' | 'wireframe' | 'default';
|
|
140
|
-
}
|
|
141
|
-
interface AlmadarAppRef {
|
|
142
|
-
emit(eventName: string, payload?: EventPayload): void;
|
|
143
105
|
}
|
|
144
106
|
|
|
145
|
-
export type {
|
|
107
|
+
export type { AlmadarAppProps as A, CompileOptions as C, EditSchemaPatch as E, GenerateOptions as G, AlmadarClientOptions as a, ApiErrorBody as b, AsyncJobHandle as c, CompileResult as d, GenerateResult as e };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/sdk",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Almadar SDK — embed agent-generated orbital schemas in your React app. AlmadarApp component + AlmadarClient HTTP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,6 +22,14 @@
|
|
|
22
22
|
"./server": {
|
|
23
23
|
"types": "./dist/server/index.d.ts",
|
|
24
24
|
"import": "./dist/server/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./server/express": {
|
|
27
|
+
"types": "./dist/server/express.d.ts",
|
|
28
|
+
"import": "./dist/server/express.js"
|
|
29
|
+
},
|
|
30
|
+
"./server/hono": {
|
|
31
|
+
"types": "./dist/server/hono.d.ts",
|
|
32
|
+
"import": "./dist/server/hono.js"
|
|
25
33
|
}
|
|
26
34
|
},
|
|
27
35
|
"files": [
|
|
@@ -29,24 +37,17 @@
|
|
|
29
37
|
"README.md",
|
|
30
38
|
"LICENSE"
|
|
31
39
|
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@almadar/core": "^10.11.0",
|
|
42
|
+
"@almadar/runtime": "^6.17.0",
|
|
43
|
+
"@almadar/ui": "^5.76.7"
|
|
44
|
+
},
|
|
32
45
|
"peerDependencies": {
|
|
33
|
-
"@almadar/core": ">=10",
|
|
34
|
-
"@almadar/runtime": ">=6.13",
|
|
35
|
-
"@almadar/ui": ">=5.32",
|
|
36
|
-
"express": ">=4.0.0",
|
|
37
46
|
"react": ">=18.0.0",
|
|
38
47
|
"react-dom": ">=18.0.0"
|
|
39
48
|
},
|
|
40
|
-
"peerDependenciesMeta": {
|
|
41
|
-
"express": {
|
|
42
|
-
"optional": true
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
49
|
"devDependencies": {
|
|
46
|
-
"@almadar/core": ">=10",
|
|
47
50
|
"@almadar/eslint-plugin": ">=2.7.0",
|
|
48
|
-
"@almadar/runtime": ">=6.13",
|
|
49
|
-
"@almadar/ui": ">=5.32",
|
|
50
51
|
"@testing-library/react": "^16.1.0",
|
|
51
52
|
"@types/express": "^4.17.21",
|
|
52
53
|
"@types/react": "^18.3.12",
|
|
@@ -55,6 +56,7 @@
|
|
|
55
56
|
"eslint": "10.0.0",
|
|
56
57
|
"express": "^4.21.0",
|
|
57
58
|
"happy-dom": "^15.11.7",
|
|
59
|
+
"hono": "^4.12.27",
|
|
58
60
|
"react": "^18.3.1",
|
|
59
61
|
"react-dom": "^18.3.1",
|
|
60
62
|
"tsup": "^8.3.5",
|