ql-agent-sdk 1.0.1 → 1.0.2

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.cjs CHANGED
@@ -23,6 +23,7 @@ __export(index_exports, {
23
23
  API_ERROR_CODES: () => API_ERROR_CODES,
24
24
  AgentsApi: () => AgentsApi,
25
25
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
26
+ ImagesApi: () => ImagesApi,
26
27
  QLClient: () => QLClient,
27
28
  QLError: () => QLError,
28
29
  TaskHandle: () => TaskHandle,
@@ -476,6 +477,19 @@ var TasksApi = class {
476
477
  return new TaskHandle(this.t, taskId);
477
478
  }
478
479
  };
480
+ var ImagesApi = class {
481
+ constructor(t) {
482
+ this.t = t;
483
+ }
484
+ /** GET /api/v1/images/models — list tiered image models + runtime availability. */
485
+ listModels() {
486
+ return this.t.json("GET", "/api/v1/images/models");
487
+ }
488
+ /** POST /api/v1/agents/:agentId/images — generate image(s) via a tiered model. */
489
+ generate(agentId, input) {
490
+ return this.t.json("POST", `/api/v1/agents/${encodeURIComponent(agentId)}/images`, { body: input });
491
+ }
492
+ };
479
493
  function readEnvBaseUrl() {
480
494
  try {
481
495
  if (typeof process !== "undefined" && process?.env) {
@@ -497,6 +511,7 @@ var QLClient = class {
497
511
  this.agents = new AgentsApi(this.transport);
498
512
  this.workflows = new WorkflowsApi(this.transport);
499
513
  this.tasks = new TasksApi(this.transport);
514
+ this.images = new ImagesApi(this.transport);
500
515
  }
501
516
  /** The normalized base URL in use (not secret). */
502
517
  get baseUrl() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/sse.ts","../src/task.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["/**\n * ql-agent-sdk — TypeScript SDK for the Quanton Labs agent platform API (v1).\n *\n * Quick start:\n * import { QLClient } from \"ql-agent-sdk\";\n * const ql = new QLClient({ apiKey: process.env.QL_API_KEY! });\n * const agents = await ql.agents.list();\n */\n\nexport { QLClient, WorkspaceApi, AgentsApi, WorkflowsApi, TasksApi, DEFAULT_BASE_URL } from \"./client.js\";\nexport type { QLClientOptions } from \"./client.js\";\n\nexport { QLError } from \"./errors.js\";\nexport type { QLErrorContext } from \"./errors.js\";\n\nexport { TaskHandle, isTerminalTaskStatus } from \"./task.js\";\n\nexport { API_ERROR_CODES } from \"./types.js\";\nexport type {\n ApiErrorCode,\n ChatMessage,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n StreamOptions,\n MessageItem,\n HistoryPage,\n HistoryParams,\n AgentSummary,\n AgentListResult,\n CapParamKind,\n CapabilityParam,\n CapabilityTemplate,\n CapabilityInfo,\n AgentDetail,\n CapabilitiesResult,\n RunCapabilityInput,\n CapabilityResult,\n RunCapabilityResult,\n Workspace,\n WorkflowRunInput,\n WorkflowRunStart,\n WorkflowRunStatus,\n WorkflowRun,\n TaskPriority,\n TaskCreateInput,\n TaskCreated,\n TaskStatus,\n Task,\n WaitOptions,\n} from \"./types.js\";\n","import type { ApiErrorCode } from \"./types.js\";\n\nexport interface QLErrorContext {\n method?: string;\n url?: string;\n}\n\n/**\n * Error thrown by the SDK for any failed API interaction.\n *\n * - `status`: HTTP status code (when the failure came from an HTTP response).\n * - `code`: stable API error code when provided by the backend, otherwise a\n * synthesized one derived from the status, or a synthetic transport\n * code such as \"aborted\" / \"timeout\" / \"network\".\n * - `message`: human-readable description. The API key is never included.\n */\nexport class QLError extends Error {\n readonly status?: number;\n readonly code: string;\n readonly method?: string;\n readonly url?: string;\n /** The raw parsed error body (if any), for advanced inspection. */\n readonly details?: unknown;\n\n constructor(message: string, opts: { status?: number; code: string; context?: QLErrorContext; details?: unknown } = { code: \"internal_error\" }) {\n super(message);\n this.name = \"QLError\";\n this.status = opts.status;\n this.code = opts.code;\n this.method = opts.context?.method;\n this.url = opts.context?.url;\n this.details = opts.details;\n // Restore prototype chain (required when targeting ES5-ish runtimes).\n Object.setPrototypeOf(this, QLError.prototype);\n }\n\n /** True for 401/403 or unauthorized/forbidden codes. */\n get isAuthError(): boolean {\n return this.code === \"unauthorized\" || this.code === \"forbidden\" || this.status === 401 || this.status === 403;\n }\n\n /** True when the request was aborted by the caller. */\n get isAborted(): boolean {\n return this.code === \"aborted\";\n }\n\n /** True when a wait() call exceeded its timeout. */\n get isTimeout(): boolean {\n return this.code === \"timeout\";\n }\n\n /** True for transient network failures (no HTTP response received). */\n get isNetworkError(): boolean {\n return this.code === \"network\";\n }\n}\n\n/** Map an HTTP status to a stable API error code when the body has none. */\nexport function codeFromStatus(status: number): ApiErrorCode | \"conflict\" {\n switch (status) {\n case 400:\n return \"validation_error\";\n case 401:\n return \"unauthorized\";\n case 403:\n return \"forbidden\";\n case 404:\n return \"not_found\";\n case 409:\n return \"conflict\";\n default:\n return status >= 500 ? \"internal_error\" : \"validation_error\";\n }\n}\n\ninterface ParsedErrorBody {\n ok?: boolean;\n error?: { code?: string; message?: string } | string;\n message?: string;\n}\n\n/** Build a QLError from a non-2xx HTTP response. Never includes the API key. */\nexport function toHttpError(status: number, text: string | undefined, ctx: QLErrorContext): QLError {\n let parsed: ParsedErrorBody | null = null;\n if (text) {\n try {\n const j = JSON.parse(text);\n if (j && typeof j === \"object\") parsed = j as ParsedErrorBody;\n } catch {\n parsed = null;\n }\n }\n\n const bodyErr = parsed?.error;\n let code: string | undefined;\n let message: string | undefined;\n if (typeof bodyErr === \"string\") {\n message = bodyErr;\n } else if (bodyErr && typeof bodyErr === \"object\") {\n code = typeof bodyErr.code === \"string\" ? bodyErr.code : undefined;\n message = typeof bodyErr.message === \"string\" ? bodyErr.message : undefined;\n }\n if (!code) code = codeFromStatus(status);\n if (!message) message = (typeof parsed?.message === \"string\" ? parsed.message : undefined) ?? `Request failed with status ${status}`;\n\n return new QLError(message, { status, code, context: ctx, details: parsed ?? undefined });\n}\n\n/** Wrap a low-level fetch/network failure (no HTTP response). */\nexport function toNetworkError(cause: unknown, ctx: QLErrorContext): QLError {\n const aborted = isAbortCause(cause);\n if (aborted) {\n return new QLError(\"Request aborted\", { code: \"aborted\", context: ctx });\n }\n const msg = cause instanceof Error ? cause.message : String(cause);\n return new QLError(`Network error: ${msg}`, { code: \"network\", context: ctx, details: cause });\n}\n\nfunction isAbortCause(cause: unknown): boolean {\n if (!cause) return false;\n if (typeof cause === \"object\") {\n const c = cause as { name?: string; type?: string };\n if (c.name === \"AbortError\" || c.type === \"aborted\") return true;\n }\n return false;\n}\n\n/** Build an abort error for wait()/stream cancellation. */\nexport function abortError(): QLError {\n return new QLError(\"Operation aborted\", { code: \"aborted\" });\n}\n\n/** Build a timeout error for wait(). */\nexport function timeoutError(timeoutMs: number): QLError {\n return new QLError(`Timed out after ${timeoutMs}ms`, { code: \"timeout\" });\n}\n","import { QLError, toHttpError, toNetworkError } from \"./errors.js\";\nimport type { ApiErrorCode } from \"./types.js\";\n\nexport interface TransportOptions {\n apiKey: string;\n baseUrl: string;\n fetchImpl: typeof fetch;\n}\n\nexport interface JsonRequestOptions {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\n/**\n * Internal transport used by the API namespaces. Keeps the API key inside a\n * closure (never exposed) and normalizes responses/errors for the caller.\n */\nexport interface Transport {\n /** Perform a JSON request and return the unwrapped `data` payload. */\n json<T>(method: string, path: string, opts?: JsonRequestOptions): Promise<T>;\n /**\n * Perform a request expected to stream SSE. Returns the response body stream\n * after verifying a 2xx + text/event-stream; throws QLError otherwise.\n */\n stream(method: string, path: string, opts?: JsonRequestOptions & { acceptStream?: boolean }): Promise<ReadableStream<Uint8Array>>;\n}\n\nexport function createTransport(opts: TransportOptions): Transport {\n const { apiKey, baseUrl, fetchImpl } = opts;\n\n return {\n async json<T>(method: string, path: string, reqOpts: JsonRequestOptions = {}) {\n const res = await doFetch(method, path, reqOpts);\n const text = await res.text();\n if (!res.ok) throw toHttpError(res.status, text, { method, url: res.url });\n return unwrap<T>(text, { method, url: res.url });\n },\n\n async stream(method, path, reqOpts = {}) {\n const res = await doFetch(method, path, {\n ...reqOpts,\n headers: { accept: \"text/event-stream\", ...(reqOpts.headers ?? {}) },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => undefined);\n throw toHttpError(res.status, text, { method, url: res.url });\n }\n const ctype = (res.headers.get(\"content-type\") || \"\").toLowerCase();\n if (!ctype.includes(\"text/event-stream\")) {\n // The endpoint returned a non-SSE body (e.g. an error envelope). Surface it.\n const text = await res.text().catch(() => undefined);\n throw new QLError(`Expected text/event-stream but got \"${ctype || \"unknown\"}\"`, {\n status: res.status,\n code: \"internal_error\",\n context: { method, url: res.url },\n details: safeParse(text),\n });\n }\n if (!res.body) throw new QLError(\"Response has no readable body stream\", { code: \"network\", context: { method, url: res.url } });\n return res.body;\n },\n };\n\n function doFetch(method: string, path: string, reqOpts: JsonRequestOptions): Promise<Response> {\n const url = buildUrl(baseUrl, path, reqOpts.query);\n const headers: Record<string, string> = {\n authorization: `Bearer ${apiKey}`,\n accept: \"application/json\",\n ...(reqOpts.body !== undefined ? { \"content-type\": \"application/json\" } : {}),\n ...(reqOpts.headers ?? {}),\n };\n return fetchImpl(url, {\n method,\n headers,\n body: reqOpts.body !== undefined ? JSON.stringify(reqOpts.body) : undefined,\n signal: reqOpts.signal,\n }).catch((err) => {\n throw toNetworkError(err, { method, url });\n });\n }\n}\n\nfunction unwrap<T>(text: string, ctx: { method?: string; url?: string }): T {\n const parsed = safeParse(text);\n if (parsed && typeof parsed === \"object\" && \"ok\" in (parsed as Record<string, unknown>)) {\n const env = parsed as { ok: boolean; data?: unknown; error?: { code?: string; message?: string } };\n if (env.ok === true) return env.data as T;\n // ok:false on a 2xx — treat as an application error.\n throw new QLError(env.error?.message || \"Request failed\", {\n code: (env.error?.code as ApiErrorCode) || \"internal_error\",\n context: ctx,\n details: env,\n });\n }\n // Non-enveloped payload (legacy shapes): return as-is.\n return parsed as T;\n}\n\nfunction safeParse(text?: string): unknown {\n if (!text) return null;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\n/** Join base + path and append a query string (skipping undefined values). */\nexport function buildUrl(baseUrl: string, path: string, query?: Record<string, string | number | undefined>): string {\n const base = baseUrl.replace(/\\/+$/, \"\");\n const p = path.startsWith(\"/\") ? path : `/${path}`;\n let url = `${base}${p}`;\n if (query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n }\n return url;\n}\n\n/** Normalize a base URL: trim whitespace and drop any trailing slash. */\nexport function normalizeUrl(url: string): string {\n return url.trim().replace(/\\/+$/, \"\");\n}\n","/**\n * Minimal, dependency-free Server-Sent Events reader built on Web Streams.\n *\n * Handles the cases that commonly break naive parsers:\n * - a `data:` line split across two TCP chunks (chunk boundaries)\n * - multiple events arriving in a single chunk\n * - both CRLF and LF line endings (and lone CR)\n * - a final event that is not terminated by a trailing newline\n * - the `[DONE]` terminator\n * - abort signals\n */\n\nexport interface SSEEvent {\n /** The concatenated `data:` payload for this event (trimmed of the leading space). */\n data: string;\n}\n\ninterface ReadOptions {\n signal?: AbortSignal;\n /** When true, stop after the first `[DONE]` data value. Default true. */\n stopOnDone?: boolean;\n}\n\n/**\n * Read raw SSE events from a `ReadableStream<Uint8Array>`.\n * Yields one object per event with its combined `data` payload.\n */\nexport async function* readSSEEvents(\n body: ReadableStream<Uint8Array>,\n opts: ReadOptions = {},\n): AsyncGenerator<SSEEvent, void, unknown> {\n const stopOnDone = opts.stopOnDone ?? true;\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let dataLines: string[] = [];\n\n // Abort wiring: cancel the underlying stream promptly when the signal fires.\n const onAbort = () => {\n void reader.cancel().catch(() => {});\n };\n if (opts.signal) {\n if (opts.signal.aborted) {\n await reader.cancel().catch(() => {});\n return;\n }\n opts.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const dispatch = (): SSEEvent | null => {\n if (dataLines.length === 0) return null;\n const data = dataLines.join(\"\\n\");\n dataLines = [];\n return { data };\n };\n\n const processLine = (line: string): SSEEvent | null => {\n if (line === \"\") return dispatch(); // blank line = event boundary\n if (line.startsWith(\":\")) return null; // comment\n if (line.startsWith(\"data:\")) {\n let value = line.slice(5);\n if (value.startsWith(\" \")) value = value.slice(1);\n dataLines.push(value);\n return null;\n }\n // Ignore event:/id:/retry: and unknown fields.\n return null;\n };\n\n try {\n for (;;) {\n if (opts.signal?.aborted) break;\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let s = splitFirstLine(buffer);\n while (s !== null) {\n const ev = processLine(s.line);\n if (ev) {\n if (stopOnDone && ev.data.trim() === \"[DONE]\") return;\n yield ev;\n }\n buffer = s.rest;\n s = splitFirstLine(buffer);\n }\n }\n\n // Flush any bytes still held by the decoder.\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const ev = processLine(buffer);\n if (ev && !(stopOnDone && ev.data.trim() === \"[DONE]\")) yield ev;\n }\n // Flush a final event that had no terminating blank line.\n const tail = dispatch();\n if (tail && !(stopOnDone && tail.data.trim() === \"[DONE]\")) yield tail;\n } finally {\n if (opts.signal) opts.signal.removeEventListener(\"abort\", onAbort);\n try {\n reader.releaseLock();\n } catch {\n /* already released */\n }\n }\n}\n\n/** Split the first complete line (LF, CRLF, or lone CR) out of `buf`. */\nfunction splitFirstLine(buf: string): { line: string; rest: string } | null {\n const nl = buf.indexOf(\"\\n\");\n const cr = buf.indexOf(\"\\r\");\n let end = -1;\n let termLen = 0;\n if (nl !== -1 && (cr === -1 || nl < cr)) {\n end = nl;\n termLen = 1;\n } else if (cr !== -1) {\n end = cr;\n termLen = buf[cr + 1] === \"\\n\" ? 2 : 1;\n }\n if (end === -1) return null;\n return { line: buf.slice(0, end), rest: buf.slice(end + termLen) };\n}\n\n/** Parse a single SSE `data` payload as JSON, returning null on failure. */\nexport function parseSSEData<T = unknown>(data: string): T | null {\n const trimmed = data.trim();\n if (trimmed === \"\" || trimmed === \"[DONE]\") return null;\n try {\n return JSON.parse(trimmed) as T;\n } catch {\n return null; // malformed JSON is skipped, not fatal\n }\n}\n","import type { Transport } from \"./http.js\";\nimport { abortError, timeoutError } from \"./errors.js\";\nimport type { Task, WaitOptions } from \"./types.js\";\n\n/** Statuses at which a task will not change again. */\nconst TERMINAL_TASK_STATUSES = new Set([\"completed\", \"failed\", \"cancelled\"]);\n\nexport function isTerminalTaskStatus(status: string): boolean {\n return TERMINAL_TASK_STATUSES.has(status);\n}\n\n/**\n * A handle to a background task created via `tasks.create`.\n *\n * NOTE on execution: creating a task only enqueues it. It may stay in the\n * `queued` state until an existing worker/execution mechanism processes it —\n * this SDK does not trigger execution. `wait()` simply polls until the task\n * reaches a terminal status (or you time out / abort).\n */\nexport class TaskHandle {\n constructor(\n private readonly transport: Transport,\n public readonly taskId: string,\n ) {}\n\n /** Fetch the current task snapshot (single request). */\n get(signal?: AbortSignal): Promise<Task> {\n return this.transport.json<Task>(\"GET\", `/api/v1/tasks/${this.taskId}`, { signal });\n }\n\n /** Alias of `get()` — perform one poll and return the latest snapshot. */\n poll(signal?: AbortSignal): Promise<Task> {\n return this.get(signal);\n }\n\n /**\n * Poll until the task reaches a terminal status.\n *\n * - Uses exponential-ish backoff from `intervalMs` up to `maxIntervalMs`.\n * - Throws a QLError with code \"timeout\" if `timeoutMs` elapses first.\n * - Throws a QLError with code \"aborted\" if `signal` aborts.\n */\n async wait(opts: WaitOptions = {}): Promise<Task> {\n const intervalMs = opts.intervalMs ?? 2000;\n const maxIntervalMs = opts.maxIntervalMs ?? 15000;\n const signal = opts.signal;\n const startedAt = Date.now();\n let delay = intervalMs;\n\n for (;;) {\n if (signal?.aborted) throw abortError();\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n const task = await this.get(signal);\n opts.onTick?.(task);\n if (isTerminalTaskStatus(task.status)) return task;\n\n // Recompute timeout after the poll so a slow request doesn't overshoot silently.\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n await sleep(delay, signal);\n delay = Math.min(maxIntervalMs, Math.round(delay * 1.5));\n }\n }\n}\n\n/** Abort-aware sleep. Rejects with an abort error if `signal` fires first. */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(abortError());\n return;\n }\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n cleanup();\n reject(abortError());\n };\n const cleanup = () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n };\n if (signal) signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n","import { createTransport, normalizeUrl, type Transport } from \"./http.js\";\nimport { QLError } from \"./errors.js\";\nimport { readSSEEvents, parseSSEData } from \"./sse.js\";\nimport { TaskHandle } from \"./task.js\";\nimport type {\n AgentDetail,\n AgentListResult,\n CapabilitiesResult,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n HistoryPage,\n HistoryParams,\n RunCapabilityInput,\n RunCapabilityResult,\n StreamOptions,\n Task,\n TaskCreateInput,\n TaskCreated,\n WorkflowRun,\n WorkflowRunInput,\n WorkflowRunStart,\n Workspace,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://app.quantonlabs.com\";\n\nexport interface QLClientOptions {\n /** Your Quanton Labs API key (Bearer). Never logged or exposed. */\n apiKey: string;\n /** API base URL. Defaults to `QL_BASE_URL` if set, else https://app.quantonlabs.com. */\n baseUrl?: string;\n /** Override the global fetch (for tests, proxies, or custom runtimes). */\n fetch?: typeof fetch;\n}\n\n/** Workspace namespace. */\nexport class WorkspaceApi {\n constructor(private readonly t: Transport) {}\n /** GET /api/v1/workspace */\n get(): Promise<Workspace> {\n return this.t.json<Workspace>(\"GET\", \"/api/v1/workspace\");\n }\n}\n\n/** Agents namespace. */\nexport class AgentsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/agents — list the global agent registry. */\n list(): Promise<AgentListResult> {\n return this.t.json<AgentListResult>(\"GET\", \"/api/v1/agents\");\n }\n\n /** GET /api/v1/agents/:agentId — agent detail + capabilities. */\n get(agentId: string): Promise<AgentDetail> {\n return this.t.json<AgentDetail>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}`);\n }\n\n /** GET /api/v1/agents/:agentId/capabilities */\n capabilities(agentId: string): Promise<CapabilitiesResult> {\n return this.t.json<CapabilitiesResult>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities`);\n }\n\n /** POST /api/v1/agents/:agentId/capabilities/run — run a feature. */\n runCapability(agentId: string, input: RunCapabilityInput): Promise<RunCapabilityResult> {\n return this.t.json<RunCapabilityResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities/run`, {\n body: { capId: input.capId, params: input.params ?? {} },\n });\n }\n\n /** POST /api/v1/agents/chat — non-streaming chat. */\n chat(input: ChatInput): Promise<ChatResult> {\n return this.t.json<ChatResult>(\"POST\", \"/api/v1/agents/chat\", { body: input });\n }\n\n /**\n * POST /api/v1/agents/chat/stream — streaming chat as an async iterable.\n *\n * Yields incremental `delta` events (text and/or reasoning) followed by a\n * single `done` event with the fully accumulated text. Stop early by passing\n * an `AbortSignal` (see StreamOptions) or breaking out of the loop.\n */\n chatStream(input: ChatInput, opts: StreamOptions = {}): AsyncIterable<ChatStreamEvent> {\n return this.chatStreamImpl(input, opts);\n }\n\n /** GET /api/v1/agents/:agentId/messages — paginated history (newest first). */\n history(agentId: string, params: HistoryParams = {}): Promise<HistoryPage> {\n return this.t.json<HistoryPage>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/messages`, {\n query: { limit: params.limit, before: params.before, userId: params.userId },\n });\n }\n\n private async *chatStreamImpl(input: ChatInput, opts: StreamOptions): AsyncGenerator<ChatStreamEvent> {\n const body = await this.t.stream(\"POST\", \"/api/v1/agents/chat/stream\", { body: input, signal: opts.signal });\n let content = \"\";\n let reasoning = \"\";\n for await (const ev of readSSEEvents(body, { signal: opts.signal })) {\n const payload = parseSSEData<{ choices?: { delta?: { content?: string; reasoning?: string; reasoning_content?: string } }[] }>(ev.data);\n if (!payload) continue; // [DONE] or malformed chunk\n const delta = payload.choices?.[0]?.delta;\n const text = typeof delta?.content === \"string\" ? delta.content : undefined;\n const reason =\n typeof delta?.reasoning === \"string\"\n ? delta.reasoning\n : typeof delta?.reasoning_content === \"string\"\n ? delta.reasoning_content\n : undefined;\n if (text) content += text;\n if (reason) reasoning += reason;\n if (text || reason) yield { type: \"delta\", content: text, reasoning: reason };\n }\n yield { type: \"done\", content, reasoning: reasoning || undefined };\n }\n}\n\n/** Workflows namespace. */\nexport class WorkflowsApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/workflows/:id/run — start a run (returns immediately, HTTP 202). */\n run(workflowId: string, input: WorkflowRunInput = {}): Promise<WorkflowRunStart> {\n return this.t.json<WorkflowRunStart>(\"POST\", `/api/v1/workflows/${encodeURIComponent(workflowId)}/run`, { body: input });\n }\n\n /** GET /api/v1/workflow-runs/:runId — poll a run. */\n getRun(runId: string): Promise<WorkflowRun> {\n return this.t.json<WorkflowRun>(\"GET\", `/api/v1/workflow-runs/${encodeURIComponent(runId)}`);\n }\n}\n\n/** Tasks namespace. */\nexport class TasksApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/tasks — create (enqueue) a background task. Does NOT trigger execution. */\n create(input: TaskCreateInput): Promise<TaskCreated> {\n return this.t.json<TaskCreated>(\"POST\", \"/api/v1/tasks\", { body: input });\n }\n\n /** GET /api/v1/tasks/:taskId — fetch the current snapshot. */\n get(taskId: string, signal?: AbortSignal): Promise<Task> {\n return this.t.json<Task>(\"GET\", `/api/v1/tasks/${encodeURIComponent(taskId)}`, { signal });\n }\n\n /** Get a handle for polling / waiting on a task (poll(), wait()). */\n handle(taskId: string): TaskHandle {\n return new TaskHandle(this.t, taskId);\n }\n}\n\nfunction readEnvBaseUrl(): string | undefined {\n try {\n if (typeof process !== \"undefined\" && process?.env) {\n return process.env.QL_BASE_URL || undefined;\n }\n } catch {\n /* non-Node runtime */\n }\n return undefined;\n}\n\n/**\n * The public client. Example:\n * const ql = new QLClient({ apiKey: process.env.QL_API_KEY });\n * const agents = await ql.agents.list();\n */\nexport class QLClient {\n readonly workspace: WorkspaceApi;\n readonly agents: AgentsApi;\n readonly workflows: WorkflowsApi;\n readonly tasks: TasksApi;\n\n private readonly transport: Transport;\n private readonly base: string;\n\n constructor(opts: QLClientOptions) {\n if (!opts || typeof opts.apiKey !== \"string\" || opts.apiKey.length === 0) {\n throw new QLError(\"apiKey is required\", { code: \"validation_error\" });\n }\n this.base = normalizeUrl(opts.baseUrl ?? readEnvBaseUrl() ?? DEFAULT_BASE_URL);\n const fetchImpl = (opts.fetch ?? globalThis.fetch).bind(globalThis);\n this.transport = createTransport({ apiKey: opts.apiKey, baseUrl: this.base, fetchImpl });\n this.workspace = new WorkspaceApi(this.transport);\n this.agents = new AgentsApi(this.transport);\n this.workflows = new WorkflowsApi(this.transport);\n this.tasks = new TasksApi(this.transport);\n }\n\n /** The normalized base URL in use (not secret). */\n get baseUrl(): string {\n return this.base;\n }\n}\n","/**\n * Public request/response types for the Quanton Labs agent platform API (v1).\n *\n * These mirror the verified Phase 1 endpoints. The public surface is enveloped:\n * success -> { ok: true, data }\n * error -> { ok: false, error: { code, message } }\n * The SDK unwraps `data` for you and surfaces errors as a typed QLError.\n */\n\n/** Stable API error codes emitted by the backend. */\nexport const API_ERROR_CODES = {\n unauthorized: \"unauthorized\",\n forbidden: \"forbidden\",\n notFound: \"not_found\",\n validationError: \"validation_error\",\n conflict: \"conflict\",\n internalError: \"internal_error\",\n} as const;\n\nexport type ApiErrorCode = (typeof API_ERROR_CODES)[keyof typeof API_ERROR_CODES];\n\n/** A single message in a chat conversation. */\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\n/** Input for `agents.chat` and `agents.chatStream`. */\nexport interface ChatInput {\n agentId: string;\n messages: ChatMessage[];\n /** Optional internal user id; defaults to the key's workspace when omitted. */\n userId?: string;\n /** Optional OpenRouter response-format hint (e.g. `{ type: \"json_object\" }`). */\n response_format?: Record<string, unknown>;\n}\n\n/** Result of a non-streaming chat call. */\nexport interface ChatResult {\n content: string;\n toolCalls: number;\n iterations: number;\n /** Human-readable duration string, e.g. \"2.91s\". */\n duration: string;\n}\n\n/**\n * A single event yielded by `agents.chatStream`.\n * - `delta`: an incremental piece of the streamed response (text and/or reasoning).\n * - `done`: emitted once at the end with the fully accumulated text.\n */\nexport type ChatStreamEvent =\n | { type: \"delta\"; content?: string; reasoning?: string }\n | { type: \"done\"; content: string; reasoning?: string };\n\n/** Options accepted by streaming methods. */\nexport interface StreamOptions {\n /** Abort the in-flight request/stream at any time. */\n signal?: AbortSignal;\n}\n\n/** A conversation-history page (newest first). */\nexport interface MessageItem {\n id: string;\n role: string;\n content: string | null;\n reasoning?: string;\n toolCalls: unknown[];\n status: string;\n timestamp: string | Date;\n}\n\nexport interface HistoryPage {\n agentId: string;\n limit: number;\n /** Cursor for the next page (pass as `before`); null when exhausted. */\n nextBefore: string | null;\n items: MessageItem[];\n}\n\n/** Query params for `agents.history`. */\nexport interface HistoryParams {\n /** Page size, 1..100 (default 20 server-side). */\n limit?: number;\n /** Cursor = id of the last item on the previous page. */\n before?: string;\n /** Optional internal user id filter. */\n userId?: string;\n}\n\n/** Agent summary as returned by `agents.list`. */\nexport interface AgentSummary {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n capabilityCount: number;\n}\n\nexport interface AgentListResult {\n agents: AgentSummary[];\n}\n\n/** A schema-driven capability parameter (rendered as a form field in the UI). */\nexport type CapParamKind = \"text\" | \"textarea\" | \"number\" | \"select\" | \"boolean\" | \"json\";\n\nexport interface CapabilityParam {\n key: string;\n label: string;\n kind: CapParamKind;\n placeholder?: string;\n options?: { value: string; label: string }[];\n required?: boolean;\n hint?: string;\n rows?: number;\n [key: string]: unknown;\n}\n\n/** A pre-filled example input set (suggestion chip). */\nexport interface CapabilityTemplate {\n label: string;\n values: Record<string, unknown>;\n}\n\n/** A client-safe capability descriptor (the server-side `run` is stripped). */\nexport interface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n category: string;\n icon?: string;\n badge?: string;\n params: CapabilityParam[];\n templates?: CapabilityTemplate[];\n metrics?: string[];\n tableKey?: string;\n outputHint?: string;\n [key: string]: unknown;\n}\n\n/** Agent detail + its capabilities, as returned by `agents.get`. */\nexport interface AgentDetail {\n agent: {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n };\n capabilities: CapabilityInfo[];\n}\n\n/** Result of `agents.capabilities`. */\nexport interface CapabilitiesResult {\n agentId: string;\n capabilities: CapabilityInfo[];\n}\n\n/** Input for `agents.runCapability`. */\nexport interface RunCapabilityInput {\n capId: string;\n /** Capability-specific parameters (see the capability's `params`). */\n params?: Record<string, unknown>;\n}\n\n/**\n * The result of running a capability. A discriminated union matching the\n * backend — a feature can return text, structured JSON, HTML, or a file URL.\n */\nexport type CapabilityResult =\n | { type: \"text\"; content: string }\n | { type: \"json\"; data: unknown }\n | { type: \"html\"; html: string }\n | { type: \"file\"; url: string; filename: string; mime: string };\n\n/** Result envelope for `agents.runCapability`. */\nexport interface RunCapabilityResult {\n result: CapabilityResult;\n}\n\n/** The workspace object as returned by the public API (redacted). */\nexport interface Workspace {\n _id: string;\n name: string;\n plan?: string;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n}\n\n/** Input for `workflows.run`. */\nexport interface WorkflowRunInput {\n /** Optional workflow input payload. */\n input?: Record<string, unknown>;\n}\n\n/** Returned immediately when a workflow run is started (HTTP 202). */\nexport interface WorkflowRunStart {\n runId: string;\n status: \"running\";\n}\n\nexport type WorkflowRunStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | (string & {});\n\n/** A workflow run snapshot, as returned by `workflows.getRun`. */\nexport interface WorkflowRun {\n runId: string;\n status: WorkflowRunStatus;\n output: unknown | null;\n error?: string;\n durationMs?: number;\n startedAt: string | Date;\n finishedAt: string | Date | null;\n}\n\nexport type TaskPriority = \"low\" | \"medium\" | \"high\" | \"urgent\";\n\n/** Input for `tasks.create`. */\nexport interface TaskCreateInput {\n agentId: string;\n title: string;\n description?: string;\n /** Arbitrary payload handed to the agent. */\n input?: unknown;\n priority?: TaskPriority;\n}\n\n/** Returned when a task is created (HTTP 201). */\nexport interface TaskCreated {\n taskId: string;\n status: TaskStatus;\n}\n\nexport type TaskStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"retrying\"\n | (string & {});\n\n/** A task snapshot, as returned by `tasks.get`. */\nexport interface Task {\n taskId: string;\n status: TaskStatus;\n title: string;\n progress?: unknown;\n result?: unknown;\n output?: unknown;\n error?: string;\n createdAt: string | Date;\n completedAt: string | Date | null;\n}\n\n/** Options for polling / waiting on a task. */\nexport interface WaitOptions {\n /** Base delay between polls in ms (default 2000). Grows with backoff up to `maxIntervalMs`. */\n intervalMs?: number;\n /** Upper bound for the backoff delay in ms (default 15000). */\n maxIntervalMs?: number;\n /** Stop waiting after this many ms and throw a timeout error. Omit to wait until terminal or abort. */\n timeoutMs?: number;\n /** Abort polling at any time. */\n signal?: AbortSignal;\n /** Called after each poll with the latest task snapshot. */\n onTick?: (task: Task) => void;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/sse.ts","../src/task.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["/**\n * ql-agent-sdk — TypeScript SDK for the Quanton Labs agent platform API (v1).\n *\n * Quick start:\n * import { QLClient } from \"ql-agent-sdk\";\n * const ql = new QLClient({ apiKey: process.env.QL_API_KEY! });\n * const agents = await ql.agents.list();\n */\n\nexport { QLClient, WorkspaceApi, AgentsApi, WorkflowsApi, TasksApi, ImagesApi, DEFAULT_BASE_URL } from \"./client.js\";\nexport type { QLClientOptions } from \"./client.js\";\n\nexport { QLError } from \"./errors.js\";\nexport type { QLErrorContext } from \"./errors.js\";\n\nexport { TaskHandle, isTerminalTaskStatus } from \"./task.js\";\n\nexport { API_ERROR_CODES } from \"./types.js\";\nexport type {\n ApiErrorCode,\n ChatMessage,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n StreamOptions,\n MessageItem,\n HistoryPage,\n HistoryParams,\n AgentSummary,\n AgentListResult,\n CapParamKind,\n CapabilityParam,\n CapabilityTemplate,\n CapabilityInfo,\n AgentDetail,\n CapabilitiesResult,\n RunCapabilityInput,\n CapabilityResult,\n RunCapabilityResult,\n Workspace,\n WorkflowRunInput,\n WorkflowRunStart,\n WorkflowRunStatus,\n WorkflowRun,\n ImageTier,\n ImagePricingEntry,\n ImageModelInfo,\n ImageModelsResult,\n ImageReferenceInput,\n ImageGenerateInput,\n GeneratedImage,\n ImageUsage,\n ImageGenerateResult,\n TaskPriority,\n TaskCreateInput,\n TaskCreated,\n TaskStatus,\n Task,\n WaitOptions,\n} from \"./types.js\";\n","import type { ApiErrorCode } from \"./types.js\";\n\nexport interface QLErrorContext {\n method?: string;\n url?: string;\n}\n\n/**\n * Error thrown by the SDK for any failed API interaction.\n *\n * - `status`: HTTP status code (when the failure came from an HTTP response).\n * - `code`: stable API error code when provided by the backend, otherwise a\n * synthesized one derived from the status, or a synthetic transport\n * code such as \"aborted\" / \"timeout\" / \"network\".\n * - `message`: human-readable description. The API key is never included.\n */\nexport class QLError extends Error {\n readonly status?: number;\n readonly code: string;\n readonly method?: string;\n readonly url?: string;\n /** The raw parsed error body (if any), for advanced inspection. */\n readonly details?: unknown;\n\n constructor(message: string, opts: { status?: number; code: string; context?: QLErrorContext; details?: unknown } = { code: \"internal_error\" }) {\n super(message);\n this.name = \"QLError\";\n this.status = opts.status;\n this.code = opts.code;\n this.method = opts.context?.method;\n this.url = opts.context?.url;\n this.details = opts.details;\n // Restore prototype chain (required when targeting ES5-ish runtimes).\n Object.setPrototypeOf(this, QLError.prototype);\n }\n\n /** True for 401/403 or unauthorized/forbidden codes. */\n get isAuthError(): boolean {\n return this.code === \"unauthorized\" || this.code === \"forbidden\" || this.status === 401 || this.status === 403;\n }\n\n /** True when the request was aborted by the caller. */\n get isAborted(): boolean {\n return this.code === \"aborted\";\n }\n\n /** True when a wait() call exceeded its timeout. */\n get isTimeout(): boolean {\n return this.code === \"timeout\";\n }\n\n /** True for transient network failures (no HTTP response received). */\n get isNetworkError(): boolean {\n return this.code === \"network\";\n }\n}\n\n/** Map an HTTP status to a stable API error code when the body has none. */\nexport function codeFromStatus(status: number): ApiErrorCode | \"conflict\" {\n switch (status) {\n case 400:\n return \"validation_error\";\n case 401:\n return \"unauthorized\";\n case 403:\n return \"forbidden\";\n case 404:\n return \"not_found\";\n case 409:\n return \"conflict\";\n default:\n return status >= 500 ? \"internal_error\" : \"validation_error\";\n }\n}\n\ninterface ParsedErrorBody {\n ok?: boolean;\n error?: { code?: string; message?: string } | string;\n message?: string;\n}\n\n/** Build a QLError from a non-2xx HTTP response. Never includes the API key. */\nexport function toHttpError(status: number, text: string | undefined, ctx: QLErrorContext): QLError {\n let parsed: ParsedErrorBody | null = null;\n if (text) {\n try {\n const j = JSON.parse(text);\n if (j && typeof j === \"object\") parsed = j as ParsedErrorBody;\n } catch {\n parsed = null;\n }\n }\n\n const bodyErr = parsed?.error;\n let code: string | undefined;\n let message: string | undefined;\n if (typeof bodyErr === \"string\") {\n message = bodyErr;\n } else if (bodyErr && typeof bodyErr === \"object\") {\n code = typeof bodyErr.code === \"string\" ? bodyErr.code : undefined;\n message = typeof bodyErr.message === \"string\" ? bodyErr.message : undefined;\n }\n if (!code) code = codeFromStatus(status);\n if (!message) message = (typeof parsed?.message === \"string\" ? parsed.message : undefined) ?? `Request failed with status ${status}`;\n\n return new QLError(message, { status, code, context: ctx, details: parsed ?? undefined });\n}\n\n/** Wrap a low-level fetch/network failure (no HTTP response). */\nexport function toNetworkError(cause: unknown, ctx: QLErrorContext): QLError {\n const aborted = isAbortCause(cause);\n if (aborted) {\n return new QLError(\"Request aborted\", { code: \"aborted\", context: ctx });\n }\n const msg = cause instanceof Error ? cause.message : String(cause);\n return new QLError(`Network error: ${msg}`, { code: \"network\", context: ctx, details: cause });\n}\n\nfunction isAbortCause(cause: unknown): boolean {\n if (!cause) return false;\n if (typeof cause === \"object\") {\n const c = cause as { name?: string; type?: string };\n if (c.name === \"AbortError\" || c.type === \"aborted\") return true;\n }\n return false;\n}\n\n/** Build an abort error for wait()/stream cancellation. */\nexport function abortError(): QLError {\n return new QLError(\"Operation aborted\", { code: \"aborted\" });\n}\n\n/** Build a timeout error for wait(). */\nexport function timeoutError(timeoutMs: number): QLError {\n return new QLError(`Timed out after ${timeoutMs}ms`, { code: \"timeout\" });\n}\n","import { QLError, toHttpError, toNetworkError } from \"./errors.js\";\nimport type { ApiErrorCode } from \"./types.js\";\n\nexport interface TransportOptions {\n apiKey: string;\n baseUrl: string;\n fetchImpl: typeof fetch;\n}\n\nexport interface JsonRequestOptions {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\n/**\n * Internal transport used by the API namespaces. Keeps the API key inside a\n * closure (never exposed) and normalizes responses/errors for the caller.\n */\nexport interface Transport {\n /** Perform a JSON request and return the unwrapped `data` payload. */\n json<T>(method: string, path: string, opts?: JsonRequestOptions): Promise<T>;\n /**\n * Perform a request expected to stream SSE. Returns the response body stream\n * after verifying a 2xx + text/event-stream; throws QLError otherwise.\n */\n stream(method: string, path: string, opts?: JsonRequestOptions & { acceptStream?: boolean }): Promise<ReadableStream<Uint8Array>>;\n}\n\nexport function createTransport(opts: TransportOptions): Transport {\n const { apiKey, baseUrl, fetchImpl } = opts;\n\n return {\n async json<T>(method: string, path: string, reqOpts: JsonRequestOptions = {}) {\n const res = await doFetch(method, path, reqOpts);\n const text = await res.text();\n if (!res.ok) throw toHttpError(res.status, text, { method, url: res.url });\n return unwrap<T>(text, { method, url: res.url });\n },\n\n async stream(method, path, reqOpts = {}) {\n const res = await doFetch(method, path, {\n ...reqOpts,\n headers: { accept: \"text/event-stream\", ...(reqOpts.headers ?? {}) },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => undefined);\n throw toHttpError(res.status, text, { method, url: res.url });\n }\n const ctype = (res.headers.get(\"content-type\") || \"\").toLowerCase();\n if (!ctype.includes(\"text/event-stream\")) {\n // The endpoint returned a non-SSE body (e.g. an error envelope). Surface it.\n const text = await res.text().catch(() => undefined);\n throw new QLError(`Expected text/event-stream but got \"${ctype || \"unknown\"}\"`, {\n status: res.status,\n code: \"internal_error\",\n context: { method, url: res.url },\n details: safeParse(text),\n });\n }\n if (!res.body) throw new QLError(\"Response has no readable body stream\", { code: \"network\", context: { method, url: res.url } });\n return res.body;\n },\n };\n\n function doFetch(method: string, path: string, reqOpts: JsonRequestOptions): Promise<Response> {\n const url = buildUrl(baseUrl, path, reqOpts.query);\n const headers: Record<string, string> = {\n authorization: `Bearer ${apiKey}`,\n accept: \"application/json\",\n ...(reqOpts.body !== undefined ? { \"content-type\": \"application/json\" } : {}),\n ...(reqOpts.headers ?? {}),\n };\n return fetchImpl(url, {\n method,\n headers,\n body: reqOpts.body !== undefined ? JSON.stringify(reqOpts.body) : undefined,\n signal: reqOpts.signal,\n }).catch((err) => {\n throw toNetworkError(err, { method, url });\n });\n }\n}\n\nfunction unwrap<T>(text: string, ctx: { method?: string; url?: string }): T {\n const parsed = safeParse(text);\n if (parsed && typeof parsed === \"object\" && \"ok\" in (parsed as Record<string, unknown>)) {\n const env = parsed as { ok: boolean; data?: unknown; error?: { code?: string; message?: string } };\n if (env.ok === true) return env.data as T;\n // ok:false on a 2xx — treat as an application error.\n throw new QLError(env.error?.message || \"Request failed\", {\n code: (env.error?.code as ApiErrorCode) || \"internal_error\",\n context: ctx,\n details: env,\n });\n }\n // Non-enveloped payload (legacy shapes): return as-is.\n return parsed as T;\n}\n\nfunction safeParse(text?: string): unknown {\n if (!text) return null;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\n/** Join base + path and append a query string (skipping undefined values). */\nexport function buildUrl(baseUrl: string, path: string, query?: Record<string, string | number | undefined>): string {\n const base = baseUrl.replace(/\\/+$/, \"\");\n const p = path.startsWith(\"/\") ? path : `/${path}`;\n let url = `${base}${p}`;\n if (query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n }\n return url;\n}\n\n/** Normalize a base URL: trim whitespace and drop any trailing slash. */\nexport function normalizeUrl(url: string): string {\n return url.trim().replace(/\\/+$/, \"\");\n}\n","/**\n * Minimal, dependency-free Server-Sent Events reader built on Web Streams.\n *\n * Handles the cases that commonly break naive parsers:\n * - a `data:` line split across two TCP chunks (chunk boundaries)\n * - multiple events arriving in a single chunk\n * - both CRLF and LF line endings (and lone CR)\n * - a final event that is not terminated by a trailing newline\n * - the `[DONE]` terminator\n * - abort signals\n */\n\nexport interface SSEEvent {\n /** The concatenated `data:` payload for this event (trimmed of the leading space). */\n data: string;\n}\n\ninterface ReadOptions {\n signal?: AbortSignal;\n /** When true, stop after the first `[DONE]` data value. Default true. */\n stopOnDone?: boolean;\n}\n\n/**\n * Read raw SSE events from a `ReadableStream<Uint8Array>`.\n * Yields one object per event with its combined `data` payload.\n */\nexport async function* readSSEEvents(\n body: ReadableStream<Uint8Array>,\n opts: ReadOptions = {},\n): AsyncGenerator<SSEEvent, void, unknown> {\n const stopOnDone = opts.stopOnDone ?? true;\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let dataLines: string[] = [];\n\n // Abort wiring: cancel the underlying stream promptly when the signal fires.\n const onAbort = () => {\n void reader.cancel().catch(() => {});\n };\n if (opts.signal) {\n if (opts.signal.aborted) {\n await reader.cancel().catch(() => {});\n return;\n }\n opts.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const dispatch = (): SSEEvent | null => {\n if (dataLines.length === 0) return null;\n const data = dataLines.join(\"\\n\");\n dataLines = [];\n return { data };\n };\n\n const processLine = (line: string): SSEEvent | null => {\n if (line === \"\") return dispatch(); // blank line = event boundary\n if (line.startsWith(\":\")) return null; // comment\n if (line.startsWith(\"data:\")) {\n let value = line.slice(5);\n if (value.startsWith(\" \")) value = value.slice(1);\n dataLines.push(value);\n return null;\n }\n // Ignore event:/id:/retry: and unknown fields.\n return null;\n };\n\n try {\n for (;;) {\n if (opts.signal?.aborted) break;\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let s = splitFirstLine(buffer);\n while (s !== null) {\n const ev = processLine(s.line);\n if (ev) {\n if (stopOnDone && ev.data.trim() === \"[DONE]\") return;\n yield ev;\n }\n buffer = s.rest;\n s = splitFirstLine(buffer);\n }\n }\n\n // Flush any bytes still held by the decoder.\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const ev = processLine(buffer);\n if (ev && !(stopOnDone && ev.data.trim() === \"[DONE]\")) yield ev;\n }\n // Flush a final event that had no terminating blank line.\n const tail = dispatch();\n if (tail && !(stopOnDone && tail.data.trim() === \"[DONE]\")) yield tail;\n } finally {\n if (opts.signal) opts.signal.removeEventListener(\"abort\", onAbort);\n try {\n reader.releaseLock();\n } catch {\n /* already released */\n }\n }\n}\n\n/** Split the first complete line (LF, CRLF, or lone CR) out of `buf`. */\nfunction splitFirstLine(buf: string): { line: string; rest: string } | null {\n const nl = buf.indexOf(\"\\n\");\n const cr = buf.indexOf(\"\\r\");\n let end = -1;\n let termLen = 0;\n if (nl !== -1 && (cr === -1 || nl < cr)) {\n end = nl;\n termLen = 1;\n } else if (cr !== -1) {\n end = cr;\n termLen = buf[cr + 1] === \"\\n\" ? 2 : 1;\n }\n if (end === -1) return null;\n return { line: buf.slice(0, end), rest: buf.slice(end + termLen) };\n}\n\n/** Parse a single SSE `data` payload as JSON, returning null on failure. */\nexport function parseSSEData<T = unknown>(data: string): T | null {\n const trimmed = data.trim();\n if (trimmed === \"\" || trimmed === \"[DONE]\") return null;\n try {\n return JSON.parse(trimmed) as T;\n } catch {\n return null; // malformed JSON is skipped, not fatal\n }\n}\n","import type { Transport } from \"./http.js\";\nimport { abortError, timeoutError } from \"./errors.js\";\nimport type { Task, WaitOptions } from \"./types.js\";\n\n/** Statuses at which a task will not change again. */\nconst TERMINAL_TASK_STATUSES = new Set([\"completed\", \"failed\", \"cancelled\"]);\n\nexport function isTerminalTaskStatus(status: string): boolean {\n return TERMINAL_TASK_STATUSES.has(status);\n}\n\n/**\n * A handle to a background task created via `tasks.create`.\n *\n * NOTE on execution: creating a task only enqueues it. It may stay in the\n * `queued` state until an existing worker/execution mechanism processes it —\n * this SDK does not trigger execution. `wait()` simply polls until the task\n * reaches a terminal status (or you time out / abort).\n */\nexport class TaskHandle {\n constructor(\n private readonly transport: Transport,\n public readonly taskId: string,\n ) {}\n\n /** Fetch the current task snapshot (single request). */\n get(signal?: AbortSignal): Promise<Task> {\n return this.transport.json<Task>(\"GET\", `/api/v1/tasks/${this.taskId}`, { signal });\n }\n\n /** Alias of `get()` — perform one poll and return the latest snapshot. */\n poll(signal?: AbortSignal): Promise<Task> {\n return this.get(signal);\n }\n\n /**\n * Poll until the task reaches a terminal status.\n *\n * - Uses exponential-ish backoff from `intervalMs` up to `maxIntervalMs`.\n * - Throws a QLError with code \"timeout\" if `timeoutMs` elapses first.\n * - Throws a QLError with code \"aborted\" if `signal` aborts.\n */\n async wait(opts: WaitOptions = {}): Promise<Task> {\n const intervalMs = opts.intervalMs ?? 2000;\n const maxIntervalMs = opts.maxIntervalMs ?? 15000;\n const signal = opts.signal;\n const startedAt = Date.now();\n let delay = intervalMs;\n\n for (;;) {\n if (signal?.aborted) throw abortError();\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n const task = await this.get(signal);\n opts.onTick?.(task);\n if (isTerminalTaskStatus(task.status)) return task;\n\n // Recompute timeout after the poll so a slow request doesn't overshoot silently.\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n await sleep(delay, signal);\n delay = Math.min(maxIntervalMs, Math.round(delay * 1.5));\n }\n }\n}\n\n/** Abort-aware sleep. Rejects with an abort error if `signal` fires first. */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(abortError());\n return;\n }\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n cleanup();\n reject(abortError());\n };\n const cleanup = () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n };\n if (signal) signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n","import { createTransport, normalizeUrl, type Transport } from \"./http.js\";\nimport { QLError } from \"./errors.js\";\nimport { readSSEEvents, parseSSEData } from \"./sse.js\";\nimport { TaskHandle } from \"./task.js\";\nimport type {\n AgentDetail,\n AgentListResult,\n CapabilitiesResult,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n HistoryPage,\n HistoryParams,\n GeneratedImage,\n ImageGenerateInput,\n ImageGenerateResult,\n ImageModelInfo,\n ImageModelsResult,\n ImageReferenceInput,\n ImageTier,\n ImageUsage,\n RunCapabilityInput,\n RunCapabilityResult,\n StreamOptions,\n Task,\n TaskCreateInput,\n TaskCreated,\n WorkflowRun,\n WorkflowRunInput,\n WorkflowRunStart,\n Workspace,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://app.quantonlabs.com\";\n\nexport interface QLClientOptions {\n /** Your Quanton Labs API key (Bearer). Never logged or exposed. */\n apiKey: string;\n /** API base URL. Defaults to `QL_BASE_URL` if set, else https://app.quantonlabs.com. */\n baseUrl?: string;\n /** Override the global fetch (for tests, proxies, or custom runtimes). */\n fetch?: typeof fetch;\n}\n\n/** Workspace namespace. */\nexport class WorkspaceApi {\n constructor(private readonly t: Transport) {}\n /** GET /api/v1/workspace */\n get(): Promise<Workspace> {\n return this.t.json<Workspace>(\"GET\", \"/api/v1/workspace\");\n }\n}\n\n/** Agents namespace. */\nexport class AgentsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/agents — list the global agent registry. */\n list(): Promise<AgentListResult> {\n return this.t.json<AgentListResult>(\"GET\", \"/api/v1/agents\");\n }\n\n /** GET /api/v1/agents/:agentId — agent detail + capabilities. */\n get(agentId: string): Promise<AgentDetail> {\n return this.t.json<AgentDetail>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}`);\n }\n\n /** GET /api/v1/agents/:agentId/capabilities */\n capabilities(agentId: string): Promise<CapabilitiesResult> {\n return this.t.json<CapabilitiesResult>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities`);\n }\n\n /** POST /api/v1/agents/:agentId/capabilities/run — run a feature. */\n runCapability(agentId: string, input: RunCapabilityInput): Promise<RunCapabilityResult> {\n return this.t.json<RunCapabilityResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities/run`, {\n body: { capId: input.capId, params: input.params ?? {} },\n });\n }\n\n /** POST /api/v1/agents/chat — non-streaming chat. */\n chat(input: ChatInput): Promise<ChatResult> {\n return this.t.json<ChatResult>(\"POST\", \"/api/v1/agents/chat\", { body: input });\n }\n\n /**\n * POST /api/v1/agents/chat/stream — streaming chat as an async iterable.\n *\n * Yields incremental `delta` events (text and/or reasoning) followed by a\n * single `done` event with the fully accumulated text. Stop early by passing\n * an `AbortSignal` (see StreamOptions) or breaking out of the loop.\n */\n chatStream(input: ChatInput, opts: StreamOptions = {}): AsyncIterable<ChatStreamEvent> {\n return this.chatStreamImpl(input, opts);\n }\n\n /** GET /api/v1/agents/:agentId/messages — paginated history (newest first). */\n history(agentId: string, params: HistoryParams = {}): Promise<HistoryPage> {\n return this.t.json<HistoryPage>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/messages`, {\n query: { limit: params.limit, before: params.before, userId: params.userId },\n });\n }\n\n private async *chatStreamImpl(input: ChatInput, opts: StreamOptions): AsyncGenerator<ChatStreamEvent> {\n const body = await this.t.stream(\"POST\", \"/api/v1/agents/chat/stream\", { body: input, signal: opts.signal });\n let content = \"\";\n let reasoning = \"\";\n for await (const ev of readSSEEvents(body, { signal: opts.signal })) {\n const payload = parseSSEData<{ choices?: { delta?: { content?: string; reasoning?: string; reasoning_content?: string } }[] }>(ev.data);\n if (!payload) continue; // [DONE] or malformed chunk\n const delta = payload.choices?.[0]?.delta;\n const text = typeof delta?.content === \"string\" ? delta.content : undefined;\n const reason =\n typeof delta?.reasoning === \"string\"\n ? delta.reasoning\n : typeof delta?.reasoning_content === \"string\"\n ? delta.reasoning_content\n : undefined;\n if (text) content += text;\n if (reason) reasoning += reason;\n if (text || reason) yield { type: \"delta\", content: text, reasoning: reason };\n }\n yield { type: \"done\", content, reasoning: reasoning || undefined };\n }\n}\n\n/** Workflows namespace. */\nexport class WorkflowsApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/workflows/:id/run — start a run (returns immediately, HTTP 202). */\n run(workflowId: string, input: WorkflowRunInput = {}): Promise<WorkflowRunStart> {\n return this.t.json<WorkflowRunStart>(\"POST\", `/api/v1/workflows/${encodeURIComponent(workflowId)}/run`, { body: input });\n }\n\n /** GET /api/v1/workflow-runs/:runId — poll a run. */\n getRun(runId: string): Promise<WorkflowRun> {\n return this.t.json<WorkflowRun>(\"GET\", `/api/v1/workflow-runs/${encodeURIComponent(runId)}`);\n }\n}\n\n/** Tasks namespace. */\nexport class TasksApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/tasks — create (enqueue) a background task. Does NOT trigger execution. */\n create(input: TaskCreateInput): Promise<TaskCreated> {\n return this.t.json<TaskCreated>(\"POST\", \"/api/v1/tasks\", { body: input });\n }\n\n /** GET /api/v1/tasks/:taskId — fetch the current snapshot. */\n get(taskId: string, signal?: AbortSignal): Promise<Task> {\n return this.t.json<Task>(\"GET\", `/api/v1/tasks/${encodeURIComponent(taskId)}`, { signal });\n }\n\n /** Get a handle for polling / waiting on a task (poll(), wait()). */\n handle(taskId: string): TaskHandle {\n return new TaskHandle(this.t, taskId);\n }\n}\n\n/** Images namespace (tiered image generation). */\nexport class ImagesApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/images/models — list tiered image models + runtime availability. */\n listModels(): Promise<ImageModelsResult> {\n return this.t.json<ImageModelsResult>(\"GET\", \"/api/v1/images/models\");\n }\n\n /** POST /api/v1/agents/:agentId/images — generate image(s) via a tiered model. */\n generate(agentId: string, input: ImageGenerateInput): Promise<ImageGenerateResult> {\n return this.t.json<ImageGenerateResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/images`, { body: input });\n }\n}\n\nfunction readEnvBaseUrl(): string | undefined {\n try {\n if (typeof process !== \"undefined\" && process?.env) {\n return process.env.QL_BASE_URL || undefined;\n }\n } catch {\n /* non-Node runtime */\n }\n return undefined;\n}\n\n/**\n * The public client. Example:\n * const ql = new QLClient({ apiKey: process.env.QL_API_KEY });\n * const agents = await ql.agents.list();\n */\nexport class QLClient {\n readonly workspace: WorkspaceApi;\n readonly agents: AgentsApi;\n readonly workflows: WorkflowsApi;\n readonly tasks: TasksApi;\n readonly images: ImagesApi;\n\n private readonly transport: Transport;\n private readonly base: string;\n\n constructor(opts: QLClientOptions) {\n if (!opts || typeof opts.apiKey !== \"string\" || opts.apiKey.length === 0) {\n throw new QLError(\"apiKey is required\", { code: \"validation_error\" });\n }\n this.base = normalizeUrl(opts.baseUrl ?? readEnvBaseUrl() ?? DEFAULT_BASE_URL);\n const fetchImpl = (opts.fetch ?? globalThis.fetch).bind(globalThis);\n this.transport = createTransport({ apiKey: opts.apiKey, baseUrl: this.base, fetchImpl });\n this.workspace = new WorkspaceApi(this.transport);\n this.agents = new AgentsApi(this.transport);\n this.workflows = new WorkflowsApi(this.transport);\n this.tasks = new TasksApi(this.transport);\n this.images = new ImagesApi(this.transport);\n }\n\n /** The normalized base URL in use (not secret). */\n get baseUrl(): string {\n return this.base;\n }\n}\n","/**\n * Public request/response types for the Quanton Labs agent platform API (v1).\n *\n * These mirror the verified Phase 1 endpoints. The public surface is enveloped:\n * success -> { ok: true, data }\n * error -> { ok: false, error: { code, message } }\n * The SDK unwraps `data` for you and surfaces errors as a typed QLError.\n */\n\n/** Stable API error codes emitted by the backend. */\nexport const API_ERROR_CODES = {\n unauthorized: \"unauthorized\",\n forbidden: \"forbidden\",\n notFound: \"not_found\",\n validationError: \"validation_error\",\n conflict: \"conflict\",\n internalError: \"internal_error\",\n} as const;\n\nexport type ApiErrorCode = (typeof API_ERROR_CODES)[keyof typeof API_ERROR_CODES];\n\n/** A single message in a chat conversation. */\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\n/** Input for `agents.chat` and `agents.chatStream`. */\nexport interface ChatInput {\n agentId: string;\n messages: ChatMessage[];\n /** Optional internal user id; defaults to the key's workspace when omitted. */\n userId?: string;\n /** Optional OpenRouter response-format hint (e.g. `{ type: \"json_object\" }`). */\n response_format?: Record<string, unknown>;\n}\n\n/** Result of a non-streaming chat call. */\nexport interface ChatResult {\n content: string;\n toolCalls: number;\n iterations: number;\n /** Human-readable duration string, e.g. \"2.91s\". */\n duration: string;\n}\n\n/**\n * A single event yielded by `agents.chatStream`.\n * - `delta`: an incremental piece of the streamed response (text and/or reasoning).\n * - `done`: emitted once at the end with the fully accumulated text.\n */\nexport type ChatStreamEvent =\n | { type: \"delta\"; content?: string; reasoning?: string }\n | { type: \"done\"; content: string; reasoning?: string };\n\n/** Options accepted by streaming methods. */\nexport interface StreamOptions {\n /** Abort the in-flight request/stream at any time. */\n signal?: AbortSignal;\n}\n\n/** A conversation-history page (newest first). */\nexport interface MessageItem {\n id: string;\n role: string;\n content: string | null;\n reasoning?: string;\n toolCalls: unknown[];\n status: string;\n timestamp: string | Date;\n}\n\nexport interface HistoryPage {\n agentId: string;\n limit: number;\n /** Cursor for the next page (pass as `before`); null when exhausted. */\n nextBefore: string | null;\n items: MessageItem[];\n}\n\n/** Query params for `agents.history`. */\nexport interface HistoryParams {\n /** Page size, 1..100 (default 20 server-side). */\n limit?: number;\n /** Cursor = id of the last item on the previous page. */\n before?: string;\n /** Optional internal user id filter. */\n userId?: string;\n}\n\n/** Agent summary as returned by `agents.list`. */\nexport interface AgentSummary {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n capabilityCount: number;\n}\n\nexport interface AgentListResult {\n agents: AgentSummary[];\n}\n\n/** A schema-driven capability parameter (rendered as a form field in the UI). */\nexport type CapParamKind = \"text\" | \"textarea\" | \"number\" | \"select\" | \"boolean\" | \"json\";\n\nexport interface CapabilityParam {\n key: string;\n label: string;\n kind: CapParamKind;\n placeholder?: string;\n options?: { value: string; label: string }[];\n required?: boolean;\n hint?: string;\n rows?: number;\n [key: string]: unknown;\n}\n\n/** A pre-filled example input set (suggestion chip). */\nexport interface CapabilityTemplate {\n label: string;\n values: Record<string, unknown>;\n}\n\n/** A client-safe capability descriptor (the server-side `run` is stripped). */\nexport interface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n category: string;\n icon?: string;\n badge?: string;\n params: CapabilityParam[];\n templates?: CapabilityTemplate[];\n metrics?: string[];\n tableKey?: string;\n outputHint?: string;\n [key: string]: unknown;\n}\n\n/** Agent detail + its capabilities, as returned by `agents.get`. */\nexport interface AgentDetail {\n agent: {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n };\n capabilities: CapabilityInfo[];\n}\n\n/** Result of `agents.capabilities`. */\nexport interface CapabilitiesResult {\n agentId: string;\n capabilities: CapabilityInfo[];\n}\n\n/** Input for `agents.runCapability`. */\nexport interface RunCapabilityInput {\n capId: string;\n /** Capability-specific parameters (see the capability's `params`). */\n params?: Record<string, unknown>;\n}\n\n/**\n * The result of running a capability. A discriminated union matching the\n * backend — a feature can return text, structured JSON, HTML, or a file URL.\n */\nexport type CapabilityResult =\n | { type: \"text\"; content: string }\n | { type: \"json\"; data: unknown }\n | { type: \"html\"; html: string }\n | { type: \"file\"; url: string; filename: string; mime: string };\n\n/** Result envelope for `agents.runCapability`. */\nexport interface RunCapabilityResult {\n result: CapabilityResult;\n}\n\n/** The workspace object as returned by the public API (redacted). */\nexport interface Workspace {\n _id: string;\n name: string;\n plan?: string;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n}\n\n/** Input for `workflows.run`. */\nexport interface WorkflowRunInput {\n /** Optional workflow input payload. */\n input?: Record<string, unknown>;\n}\n\n/** Returned immediately when a workflow run is started (HTTP 202). */\nexport interface WorkflowRunStart {\n runId: string;\n status: \"running\";\n}\n\nexport type WorkflowRunStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | (string & {});\n\n/** A workflow run snapshot, as returned by `workflows.getRun`. */\nexport interface WorkflowRun {\n runId: string;\n status: WorkflowRunStatus;\n output: unknown | null;\n error?: string;\n durationMs?: number;\n startedAt: string | Date;\n finishedAt: string | Date | null;\n}\n\nexport type TaskPriority = \"low\" | \"medium\" | \"high\" | \"urgent\";\n\n/** Input for `tasks.create`. */\nexport interface TaskCreateInput {\n agentId: string;\n title: string;\n description?: string;\n /** Arbitrary payload handed to the agent. */\n input?: unknown;\n priority?: TaskPriority;\n}\n\n/** Returned when a task is created (HTTP 201). */\nexport interface TaskCreated {\n taskId: string;\n status: TaskStatus;\n}\n\nexport type TaskStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"retrying\"\n | (string & {});\n\n/** A task snapshot, as returned by `tasks.get`. */\nexport interface Task {\n taskId: string;\n status: TaskStatus;\n title: string;\n progress?: unknown;\n result?: unknown;\n output?: unknown;\n error?: string;\n createdAt: string | Date;\n completedAt: string | Date | null;\n}\n\n/** Options for polling / waiting on a task. */\nexport interface WaitOptions {\n /** Base delay between polls in ms (default 2000). Grows with backoff up to `maxIntervalMs`. */\n intervalMs?: number;\n /** Upper bound for the backoff delay in ms (default 15000). */\n maxIntervalMs?: number;\n /** Stop waiting after this many ms and throw a timeout error. Omit to wait until terminal or abort. */\n timeoutMs?: number;\n /** Abort polling at any time. */\n signal?: AbortSignal;\n /** Called after each poll with the latest task snapshot. */\n onTick?: (task: Task) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Images — tiered image generation\n// ---------------------------------------------------------------------------\n\nexport type ImageTier = \"standard\" | \"professional\" | \"advanced\";\n\n/** A single pricing entry for an image model. */\nexport interface ImagePricingEntry {\n /** What is billed, e.g. \"output_image\" / \"input_image\". */\n billable: string;\n /** Billing unit: flat per image, or per output-image token. */\n unit: \"image\" | \"token\";\n costUsd: number;\n /** Optional sub-variant (e.g. a resolution tier or quality variant). */\n variant?: string;\n}\n\n/** A tiered image-generation model as returned by `images.listModels`. */\nexport interface ImageModelInfo {\n id: string;\n name: string;\n tier: ImageTier;\n description: string;\n /** Short best-use-case label for UI copy. */\n bestFor: string;\n referenceImageSupport: boolean;\n maxReferenceImages: number;\n /** Empty array = the model does not accept a resolution parameter. */\n supportedResolutions: string[];\n supportedAspectRatios: string[];\n /** Max value for the `n` (images per request) parameter. */\n maxImages: number;\n pricing: {\n /** Human-readable summary, e.g. \"$0.018 / image\". */\n summary: string;\n entries: ImagePricingEntry[];\n };\n recommended: boolean;\n /** Static registry flag (always reflects the shipped registry). */\n enabled: boolean;\n /** Runtime availability — live when `verified` is true. */\n available: boolean;\n /** Whether `available` reflects a live OpenRouter check. */\n verified: boolean;\n}\n\n/** Result of `images.listModels`. */\nexport interface ImageModelsResult {\n models: ImageModelInfo[];\n availability: {\n /** True when the availability values came from a fresh OpenRouter check. */\n fresh: boolean;\n verifiedAt: string | Date | null;\n };\n}\n\n/** A reference image for generation. */\nexport interface ImageReferenceInput {\n /** Base64 data URL, e.g. \"data:image/png;base64,...\". */\n dataUrl: string;\n /** Optional instruction on how this reference should influence the output. */\n description?: string;\n}\n\n/** Input for `images.generate`. */\nexport interface ImageGenerateInput {\n prompt: string;\n /** Explicit OpenRouter model id (wins over `tier`). */\n model?: string;\n /** Tier to resolve a model from (used when `model` is omitted). */\n tier?: ImageTier | string;\n references?: ImageReferenceInput[];\n resolution?: string;\n aspect_ratio?: string;\n n?: number;\n}\n\n/** A single generated image. */\nexport interface GeneratedImage {\n /** Base64-encoded image bytes (no data-URL prefix). */\n b64Json: string;\n mediaType: string;\n}\n\n/** Token + cost usage for a generation, as reported by the provider. */\nexport interface ImageUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n /** Actual cost in USD. */\n cost: number;\n}\n\n/** Result of `images.generate`. */\nexport interface ImageGenerateResult {\n images: GeneratedImage[];\n usage: ImageUsage | null;\n model: string;\n tier: string;\n latencyMs: number;\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -270,6 +270,95 @@ interface WaitOptions {
270
270
  /** Called after each poll with the latest task snapshot. */
271
271
  onTick?: (task: Task) => void;
272
272
  }
273
+ type ImageTier = "standard" | "professional" | "advanced";
274
+ /** A single pricing entry for an image model. */
275
+ interface ImagePricingEntry {
276
+ /** What is billed, e.g. "output_image" / "input_image". */
277
+ billable: string;
278
+ /** Billing unit: flat per image, or per output-image token. */
279
+ unit: "image" | "token";
280
+ costUsd: number;
281
+ /** Optional sub-variant (e.g. a resolution tier or quality variant). */
282
+ variant?: string;
283
+ }
284
+ /** A tiered image-generation model as returned by `images.listModels`. */
285
+ interface ImageModelInfo {
286
+ id: string;
287
+ name: string;
288
+ tier: ImageTier;
289
+ description: string;
290
+ /** Short best-use-case label for UI copy. */
291
+ bestFor: string;
292
+ referenceImageSupport: boolean;
293
+ maxReferenceImages: number;
294
+ /** Empty array = the model does not accept a resolution parameter. */
295
+ supportedResolutions: string[];
296
+ supportedAspectRatios: string[];
297
+ /** Max value for the `n` (images per request) parameter. */
298
+ maxImages: number;
299
+ pricing: {
300
+ /** Human-readable summary, e.g. "$0.018 / image". */
301
+ summary: string;
302
+ entries: ImagePricingEntry[];
303
+ };
304
+ recommended: boolean;
305
+ /** Static registry flag (always reflects the shipped registry). */
306
+ enabled: boolean;
307
+ /** Runtime availability — live when `verified` is true. */
308
+ available: boolean;
309
+ /** Whether `available` reflects a live OpenRouter check. */
310
+ verified: boolean;
311
+ }
312
+ /** Result of `images.listModels`. */
313
+ interface ImageModelsResult {
314
+ models: ImageModelInfo[];
315
+ availability: {
316
+ /** True when the availability values came from a fresh OpenRouter check. */
317
+ fresh: boolean;
318
+ verifiedAt: string | Date | null;
319
+ };
320
+ }
321
+ /** A reference image for generation. */
322
+ interface ImageReferenceInput {
323
+ /** Base64 data URL, e.g. "data:image/png;base64,...". */
324
+ dataUrl: string;
325
+ /** Optional instruction on how this reference should influence the output. */
326
+ description?: string;
327
+ }
328
+ /** Input for `images.generate`. */
329
+ interface ImageGenerateInput {
330
+ prompt: string;
331
+ /** Explicit OpenRouter model id (wins over `tier`). */
332
+ model?: string;
333
+ /** Tier to resolve a model from (used when `model` is omitted). */
334
+ tier?: ImageTier | string;
335
+ references?: ImageReferenceInput[];
336
+ resolution?: string;
337
+ aspect_ratio?: string;
338
+ n?: number;
339
+ }
340
+ /** A single generated image. */
341
+ interface GeneratedImage {
342
+ /** Base64-encoded image bytes (no data-URL prefix). */
343
+ b64Json: string;
344
+ mediaType: string;
345
+ }
346
+ /** Token + cost usage for a generation, as reported by the provider. */
347
+ interface ImageUsage {
348
+ promptTokens: number;
349
+ completionTokens: number;
350
+ totalTokens: number;
351
+ /** Actual cost in USD. */
352
+ cost: number;
353
+ }
354
+ /** Result of `images.generate`. */
355
+ interface ImageGenerateResult {
356
+ images: GeneratedImage[];
357
+ usage: ImageUsage | null;
358
+ model: string;
359
+ tier: string;
360
+ latencyMs: number;
361
+ }
273
362
 
274
363
  declare function isTerminalTaskStatus(status: string): boolean;
275
364
  /**
@@ -360,6 +449,15 @@ declare class TasksApi {
360
449
  /** Get a handle for polling / waiting on a task (poll(), wait()). */
361
450
  handle(taskId: string): TaskHandle;
362
451
  }
452
+ /** Images namespace (tiered image generation). */
453
+ declare class ImagesApi {
454
+ private readonly t;
455
+ constructor(t: Transport);
456
+ /** GET /api/v1/images/models — list tiered image models + runtime availability. */
457
+ listModels(): Promise<ImageModelsResult>;
458
+ /** POST /api/v1/agents/:agentId/images — generate image(s) via a tiered model. */
459
+ generate(agentId: string, input: ImageGenerateInput): Promise<ImageGenerateResult>;
460
+ }
363
461
  /**
364
462
  * The public client. Example:
365
463
  * const ql = new QLClient({ apiKey: process.env.QL_API_KEY });
@@ -370,6 +468,7 @@ declare class QLClient {
370
468
  readonly agents: AgentsApi;
371
469
  readonly workflows: WorkflowsApi;
372
470
  readonly tasks: TasksApi;
471
+ readonly images: ImagesApi;
373
472
  private readonly transport;
374
473
  private readonly base;
375
474
  constructor(opts: QLClientOptions);
@@ -413,4 +512,4 @@ declare class QLError extends Error {
413
512
  get isNetworkError(): boolean;
414
513
  }
415
514
 
416
- export { API_ERROR_CODES, type AgentDetail, type AgentListResult, type AgentSummary, AgentsApi, type ApiErrorCode, type CapParamKind, type CapabilitiesResult, type CapabilityInfo, type CapabilityParam, type CapabilityResult, type CapabilityTemplate, type ChatInput, type ChatMessage, type ChatResult, type ChatStreamEvent, DEFAULT_BASE_URL, type HistoryPage, type HistoryParams, type MessageItem, QLClient, type QLClientOptions, QLError, type QLErrorContext, type RunCapabilityInput, type RunCapabilityResult, type StreamOptions, type Task, type TaskCreateInput, type TaskCreated, TaskHandle, type TaskPriority, type TaskStatus, TasksApi, type WaitOptions, type WorkflowRun, type WorkflowRunInput, type WorkflowRunStart, type WorkflowRunStatus, WorkflowsApi, type Workspace, WorkspaceApi, isTerminalTaskStatus };
515
+ export { API_ERROR_CODES, type AgentDetail, type AgentListResult, type AgentSummary, AgentsApi, type ApiErrorCode, type CapParamKind, type CapabilitiesResult, type CapabilityInfo, type CapabilityParam, type CapabilityResult, type CapabilityTemplate, type ChatInput, type ChatMessage, type ChatResult, type ChatStreamEvent, DEFAULT_BASE_URL, type GeneratedImage, type HistoryPage, type HistoryParams, type ImageGenerateInput, type ImageGenerateResult, type ImageModelInfo, type ImageModelsResult, type ImagePricingEntry, type ImageReferenceInput, type ImageTier, type ImageUsage, ImagesApi, type MessageItem, QLClient, type QLClientOptions, QLError, type QLErrorContext, type RunCapabilityInput, type RunCapabilityResult, type StreamOptions, type Task, type TaskCreateInput, type TaskCreated, TaskHandle, type TaskPriority, type TaskStatus, TasksApi, type WaitOptions, type WorkflowRun, type WorkflowRunInput, type WorkflowRunStart, type WorkflowRunStatus, WorkflowsApi, type Workspace, WorkspaceApi, isTerminalTaskStatus };
package/dist/index.d.ts CHANGED
@@ -270,6 +270,95 @@ interface WaitOptions {
270
270
  /** Called after each poll with the latest task snapshot. */
271
271
  onTick?: (task: Task) => void;
272
272
  }
273
+ type ImageTier = "standard" | "professional" | "advanced";
274
+ /** A single pricing entry for an image model. */
275
+ interface ImagePricingEntry {
276
+ /** What is billed, e.g. "output_image" / "input_image". */
277
+ billable: string;
278
+ /** Billing unit: flat per image, or per output-image token. */
279
+ unit: "image" | "token";
280
+ costUsd: number;
281
+ /** Optional sub-variant (e.g. a resolution tier or quality variant). */
282
+ variant?: string;
283
+ }
284
+ /** A tiered image-generation model as returned by `images.listModels`. */
285
+ interface ImageModelInfo {
286
+ id: string;
287
+ name: string;
288
+ tier: ImageTier;
289
+ description: string;
290
+ /** Short best-use-case label for UI copy. */
291
+ bestFor: string;
292
+ referenceImageSupport: boolean;
293
+ maxReferenceImages: number;
294
+ /** Empty array = the model does not accept a resolution parameter. */
295
+ supportedResolutions: string[];
296
+ supportedAspectRatios: string[];
297
+ /** Max value for the `n` (images per request) parameter. */
298
+ maxImages: number;
299
+ pricing: {
300
+ /** Human-readable summary, e.g. "$0.018 / image". */
301
+ summary: string;
302
+ entries: ImagePricingEntry[];
303
+ };
304
+ recommended: boolean;
305
+ /** Static registry flag (always reflects the shipped registry). */
306
+ enabled: boolean;
307
+ /** Runtime availability — live when `verified` is true. */
308
+ available: boolean;
309
+ /** Whether `available` reflects a live OpenRouter check. */
310
+ verified: boolean;
311
+ }
312
+ /** Result of `images.listModels`. */
313
+ interface ImageModelsResult {
314
+ models: ImageModelInfo[];
315
+ availability: {
316
+ /** True when the availability values came from a fresh OpenRouter check. */
317
+ fresh: boolean;
318
+ verifiedAt: string | Date | null;
319
+ };
320
+ }
321
+ /** A reference image for generation. */
322
+ interface ImageReferenceInput {
323
+ /** Base64 data URL, e.g. "data:image/png;base64,...". */
324
+ dataUrl: string;
325
+ /** Optional instruction on how this reference should influence the output. */
326
+ description?: string;
327
+ }
328
+ /** Input for `images.generate`. */
329
+ interface ImageGenerateInput {
330
+ prompt: string;
331
+ /** Explicit OpenRouter model id (wins over `tier`). */
332
+ model?: string;
333
+ /** Tier to resolve a model from (used when `model` is omitted). */
334
+ tier?: ImageTier | string;
335
+ references?: ImageReferenceInput[];
336
+ resolution?: string;
337
+ aspect_ratio?: string;
338
+ n?: number;
339
+ }
340
+ /** A single generated image. */
341
+ interface GeneratedImage {
342
+ /** Base64-encoded image bytes (no data-URL prefix). */
343
+ b64Json: string;
344
+ mediaType: string;
345
+ }
346
+ /** Token + cost usage for a generation, as reported by the provider. */
347
+ interface ImageUsage {
348
+ promptTokens: number;
349
+ completionTokens: number;
350
+ totalTokens: number;
351
+ /** Actual cost in USD. */
352
+ cost: number;
353
+ }
354
+ /** Result of `images.generate`. */
355
+ interface ImageGenerateResult {
356
+ images: GeneratedImage[];
357
+ usage: ImageUsage | null;
358
+ model: string;
359
+ tier: string;
360
+ latencyMs: number;
361
+ }
273
362
 
274
363
  declare function isTerminalTaskStatus(status: string): boolean;
275
364
  /**
@@ -360,6 +449,15 @@ declare class TasksApi {
360
449
  /** Get a handle for polling / waiting on a task (poll(), wait()). */
361
450
  handle(taskId: string): TaskHandle;
362
451
  }
452
+ /** Images namespace (tiered image generation). */
453
+ declare class ImagesApi {
454
+ private readonly t;
455
+ constructor(t: Transport);
456
+ /** GET /api/v1/images/models — list tiered image models + runtime availability. */
457
+ listModels(): Promise<ImageModelsResult>;
458
+ /** POST /api/v1/agents/:agentId/images — generate image(s) via a tiered model. */
459
+ generate(agentId: string, input: ImageGenerateInput): Promise<ImageGenerateResult>;
460
+ }
363
461
  /**
364
462
  * The public client. Example:
365
463
  * const ql = new QLClient({ apiKey: process.env.QL_API_KEY });
@@ -370,6 +468,7 @@ declare class QLClient {
370
468
  readonly agents: AgentsApi;
371
469
  readonly workflows: WorkflowsApi;
372
470
  readonly tasks: TasksApi;
471
+ readonly images: ImagesApi;
373
472
  private readonly transport;
374
473
  private readonly base;
375
474
  constructor(opts: QLClientOptions);
@@ -413,4 +512,4 @@ declare class QLError extends Error {
413
512
  get isNetworkError(): boolean;
414
513
  }
415
514
 
416
- export { API_ERROR_CODES, type AgentDetail, type AgentListResult, type AgentSummary, AgentsApi, type ApiErrorCode, type CapParamKind, type CapabilitiesResult, type CapabilityInfo, type CapabilityParam, type CapabilityResult, type CapabilityTemplate, type ChatInput, type ChatMessage, type ChatResult, type ChatStreamEvent, DEFAULT_BASE_URL, type HistoryPage, type HistoryParams, type MessageItem, QLClient, type QLClientOptions, QLError, type QLErrorContext, type RunCapabilityInput, type RunCapabilityResult, type StreamOptions, type Task, type TaskCreateInput, type TaskCreated, TaskHandle, type TaskPriority, type TaskStatus, TasksApi, type WaitOptions, type WorkflowRun, type WorkflowRunInput, type WorkflowRunStart, type WorkflowRunStatus, WorkflowsApi, type Workspace, WorkspaceApi, isTerminalTaskStatus };
515
+ export { API_ERROR_CODES, type AgentDetail, type AgentListResult, type AgentSummary, AgentsApi, type ApiErrorCode, type CapParamKind, type CapabilitiesResult, type CapabilityInfo, type CapabilityParam, type CapabilityResult, type CapabilityTemplate, type ChatInput, type ChatMessage, type ChatResult, type ChatStreamEvent, DEFAULT_BASE_URL, type GeneratedImage, type HistoryPage, type HistoryParams, type ImageGenerateInput, type ImageGenerateResult, type ImageModelInfo, type ImageModelsResult, type ImagePricingEntry, type ImageReferenceInput, type ImageTier, type ImageUsage, ImagesApi, type MessageItem, QLClient, type QLClientOptions, QLError, type QLErrorContext, type RunCapabilityInput, type RunCapabilityResult, type StreamOptions, type Task, type TaskCreateInput, type TaskCreated, TaskHandle, type TaskPriority, type TaskStatus, TasksApi, type WaitOptions, type WorkflowRun, type WorkflowRunInput, type WorkflowRunStart, type WorkflowRunStatus, WorkflowsApi, type Workspace, WorkspaceApi, isTerminalTaskStatus };
package/dist/index.js CHANGED
@@ -441,6 +441,19 @@ var TasksApi = class {
441
441
  return new TaskHandle(this.t, taskId);
442
442
  }
443
443
  };
444
+ var ImagesApi = class {
445
+ constructor(t) {
446
+ this.t = t;
447
+ }
448
+ /** GET /api/v1/images/models — list tiered image models + runtime availability. */
449
+ listModels() {
450
+ return this.t.json("GET", "/api/v1/images/models");
451
+ }
452
+ /** POST /api/v1/agents/:agentId/images — generate image(s) via a tiered model. */
453
+ generate(agentId, input) {
454
+ return this.t.json("POST", `/api/v1/agents/${encodeURIComponent(agentId)}/images`, { body: input });
455
+ }
456
+ };
444
457
  function readEnvBaseUrl() {
445
458
  try {
446
459
  if (typeof process !== "undefined" && process?.env) {
@@ -462,6 +475,7 @@ var QLClient = class {
462
475
  this.agents = new AgentsApi(this.transport);
463
476
  this.workflows = new WorkflowsApi(this.transport);
464
477
  this.tasks = new TasksApi(this.transport);
478
+ this.images = new ImagesApi(this.transport);
465
479
  }
466
480
  /** The normalized base URL in use (not secret). */
467
481
  get baseUrl() {
@@ -482,6 +496,7 @@ export {
482
496
  API_ERROR_CODES,
483
497
  AgentsApi,
484
498
  DEFAULT_BASE_URL,
499
+ ImagesApi,
485
500
  QLClient,
486
501
  QLError,
487
502
  TaskHandle,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/sse.ts","../src/task.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["import type { ApiErrorCode } from \"./types.js\";\n\nexport interface QLErrorContext {\n method?: string;\n url?: string;\n}\n\n/**\n * Error thrown by the SDK for any failed API interaction.\n *\n * - `status`: HTTP status code (when the failure came from an HTTP response).\n * - `code`: stable API error code when provided by the backend, otherwise a\n * synthesized one derived from the status, or a synthetic transport\n * code such as \"aborted\" / \"timeout\" / \"network\".\n * - `message`: human-readable description. The API key is never included.\n */\nexport class QLError extends Error {\n readonly status?: number;\n readonly code: string;\n readonly method?: string;\n readonly url?: string;\n /** The raw parsed error body (if any), for advanced inspection. */\n readonly details?: unknown;\n\n constructor(message: string, opts: { status?: number; code: string; context?: QLErrorContext; details?: unknown } = { code: \"internal_error\" }) {\n super(message);\n this.name = \"QLError\";\n this.status = opts.status;\n this.code = opts.code;\n this.method = opts.context?.method;\n this.url = opts.context?.url;\n this.details = opts.details;\n // Restore prototype chain (required when targeting ES5-ish runtimes).\n Object.setPrototypeOf(this, QLError.prototype);\n }\n\n /** True for 401/403 or unauthorized/forbidden codes. */\n get isAuthError(): boolean {\n return this.code === \"unauthorized\" || this.code === \"forbidden\" || this.status === 401 || this.status === 403;\n }\n\n /** True when the request was aborted by the caller. */\n get isAborted(): boolean {\n return this.code === \"aborted\";\n }\n\n /** True when a wait() call exceeded its timeout. */\n get isTimeout(): boolean {\n return this.code === \"timeout\";\n }\n\n /** True for transient network failures (no HTTP response received). */\n get isNetworkError(): boolean {\n return this.code === \"network\";\n }\n}\n\n/** Map an HTTP status to a stable API error code when the body has none. */\nexport function codeFromStatus(status: number): ApiErrorCode | \"conflict\" {\n switch (status) {\n case 400:\n return \"validation_error\";\n case 401:\n return \"unauthorized\";\n case 403:\n return \"forbidden\";\n case 404:\n return \"not_found\";\n case 409:\n return \"conflict\";\n default:\n return status >= 500 ? \"internal_error\" : \"validation_error\";\n }\n}\n\ninterface ParsedErrorBody {\n ok?: boolean;\n error?: { code?: string; message?: string } | string;\n message?: string;\n}\n\n/** Build a QLError from a non-2xx HTTP response. Never includes the API key. */\nexport function toHttpError(status: number, text: string | undefined, ctx: QLErrorContext): QLError {\n let parsed: ParsedErrorBody | null = null;\n if (text) {\n try {\n const j = JSON.parse(text);\n if (j && typeof j === \"object\") parsed = j as ParsedErrorBody;\n } catch {\n parsed = null;\n }\n }\n\n const bodyErr = parsed?.error;\n let code: string | undefined;\n let message: string | undefined;\n if (typeof bodyErr === \"string\") {\n message = bodyErr;\n } else if (bodyErr && typeof bodyErr === \"object\") {\n code = typeof bodyErr.code === \"string\" ? bodyErr.code : undefined;\n message = typeof bodyErr.message === \"string\" ? bodyErr.message : undefined;\n }\n if (!code) code = codeFromStatus(status);\n if (!message) message = (typeof parsed?.message === \"string\" ? parsed.message : undefined) ?? `Request failed with status ${status}`;\n\n return new QLError(message, { status, code, context: ctx, details: parsed ?? undefined });\n}\n\n/** Wrap a low-level fetch/network failure (no HTTP response). */\nexport function toNetworkError(cause: unknown, ctx: QLErrorContext): QLError {\n const aborted = isAbortCause(cause);\n if (aborted) {\n return new QLError(\"Request aborted\", { code: \"aborted\", context: ctx });\n }\n const msg = cause instanceof Error ? cause.message : String(cause);\n return new QLError(`Network error: ${msg}`, { code: \"network\", context: ctx, details: cause });\n}\n\nfunction isAbortCause(cause: unknown): boolean {\n if (!cause) return false;\n if (typeof cause === \"object\") {\n const c = cause as { name?: string; type?: string };\n if (c.name === \"AbortError\" || c.type === \"aborted\") return true;\n }\n return false;\n}\n\n/** Build an abort error for wait()/stream cancellation. */\nexport function abortError(): QLError {\n return new QLError(\"Operation aborted\", { code: \"aborted\" });\n}\n\n/** Build a timeout error for wait(). */\nexport function timeoutError(timeoutMs: number): QLError {\n return new QLError(`Timed out after ${timeoutMs}ms`, { code: \"timeout\" });\n}\n","import { QLError, toHttpError, toNetworkError } from \"./errors.js\";\nimport type { ApiErrorCode } from \"./types.js\";\n\nexport interface TransportOptions {\n apiKey: string;\n baseUrl: string;\n fetchImpl: typeof fetch;\n}\n\nexport interface JsonRequestOptions {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\n/**\n * Internal transport used by the API namespaces. Keeps the API key inside a\n * closure (never exposed) and normalizes responses/errors for the caller.\n */\nexport interface Transport {\n /** Perform a JSON request and return the unwrapped `data` payload. */\n json<T>(method: string, path: string, opts?: JsonRequestOptions): Promise<T>;\n /**\n * Perform a request expected to stream SSE. Returns the response body stream\n * after verifying a 2xx + text/event-stream; throws QLError otherwise.\n */\n stream(method: string, path: string, opts?: JsonRequestOptions & { acceptStream?: boolean }): Promise<ReadableStream<Uint8Array>>;\n}\n\nexport function createTransport(opts: TransportOptions): Transport {\n const { apiKey, baseUrl, fetchImpl } = opts;\n\n return {\n async json<T>(method: string, path: string, reqOpts: JsonRequestOptions = {}) {\n const res = await doFetch(method, path, reqOpts);\n const text = await res.text();\n if (!res.ok) throw toHttpError(res.status, text, { method, url: res.url });\n return unwrap<T>(text, { method, url: res.url });\n },\n\n async stream(method, path, reqOpts = {}) {\n const res = await doFetch(method, path, {\n ...reqOpts,\n headers: { accept: \"text/event-stream\", ...(reqOpts.headers ?? {}) },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => undefined);\n throw toHttpError(res.status, text, { method, url: res.url });\n }\n const ctype = (res.headers.get(\"content-type\") || \"\").toLowerCase();\n if (!ctype.includes(\"text/event-stream\")) {\n // The endpoint returned a non-SSE body (e.g. an error envelope). Surface it.\n const text = await res.text().catch(() => undefined);\n throw new QLError(`Expected text/event-stream but got \"${ctype || \"unknown\"}\"`, {\n status: res.status,\n code: \"internal_error\",\n context: { method, url: res.url },\n details: safeParse(text),\n });\n }\n if (!res.body) throw new QLError(\"Response has no readable body stream\", { code: \"network\", context: { method, url: res.url } });\n return res.body;\n },\n };\n\n function doFetch(method: string, path: string, reqOpts: JsonRequestOptions): Promise<Response> {\n const url = buildUrl(baseUrl, path, reqOpts.query);\n const headers: Record<string, string> = {\n authorization: `Bearer ${apiKey}`,\n accept: \"application/json\",\n ...(reqOpts.body !== undefined ? { \"content-type\": \"application/json\" } : {}),\n ...(reqOpts.headers ?? {}),\n };\n return fetchImpl(url, {\n method,\n headers,\n body: reqOpts.body !== undefined ? JSON.stringify(reqOpts.body) : undefined,\n signal: reqOpts.signal,\n }).catch((err) => {\n throw toNetworkError(err, { method, url });\n });\n }\n}\n\nfunction unwrap<T>(text: string, ctx: { method?: string; url?: string }): T {\n const parsed = safeParse(text);\n if (parsed && typeof parsed === \"object\" && \"ok\" in (parsed as Record<string, unknown>)) {\n const env = parsed as { ok: boolean; data?: unknown; error?: { code?: string; message?: string } };\n if (env.ok === true) return env.data as T;\n // ok:false on a 2xx — treat as an application error.\n throw new QLError(env.error?.message || \"Request failed\", {\n code: (env.error?.code as ApiErrorCode) || \"internal_error\",\n context: ctx,\n details: env,\n });\n }\n // Non-enveloped payload (legacy shapes): return as-is.\n return parsed as T;\n}\n\nfunction safeParse(text?: string): unknown {\n if (!text) return null;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\n/** Join base + path and append a query string (skipping undefined values). */\nexport function buildUrl(baseUrl: string, path: string, query?: Record<string, string | number | undefined>): string {\n const base = baseUrl.replace(/\\/+$/, \"\");\n const p = path.startsWith(\"/\") ? path : `/${path}`;\n let url = `${base}${p}`;\n if (query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n }\n return url;\n}\n\n/** Normalize a base URL: trim whitespace and drop any trailing slash. */\nexport function normalizeUrl(url: string): string {\n return url.trim().replace(/\\/+$/, \"\");\n}\n","/**\n * Minimal, dependency-free Server-Sent Events reader built on Web Streams.\n *\n * Handles the cases that commonly break naive parsers:\n * - a `data:` line split across two TCP chunks (chunk boundaries)\n * - multiple events arriving in a single chunk\n * - both CRLF and LF line endings (and lone CR)\n * - a final event that is not terminated by a trailing newline\n * - the `[DONE]` terminator\n * - abort signals\n */\n\nexport interface SSEEvent {\n /** The concatenated `data:` payload for this event (trimmed of the leading space). */\n data: string;\n}\n\ninterface ReadOptions {\n signal?: AbortSignal;\n /** When true, stop after the first `[DONE]` data value. Default true. */\n stopOnDone?: boolean;\n}\n\n/**\n * Read raw SSE events from a `ReadableStream<Uint8Array>`.\n * Yields one object per event with its combined `data` payload.\n */\nexport async function* readSSEEvents(\n body: ReadableStream<Uint8Array>,\n opts: ReadOptions = {},\n): AsyncGenerator<SSEEvent, void, unknown> {\n const stopOnDone = opts.stopOnDone ?? true;\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let dataLines: string[] = [];\n\n // Abort wiring: cancel the underlying stream promptly when the signal fires.\n const onAbort = () => {\n void reader.cancel().catch(() => {});\n };\n if (opts.signal) {\n if (opts.signal.aborted) {\n await reader.cancel().catch(() => {});\n return;\n }\n opts.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const dispatch = (): SSEEvent | null => {\n if (dataLines.length === 0) return null;\n const data = dataLines.join(\"\\n\");\n dataLines = [];\n return { data };\n };\n\n const processLine = (line: string): SSEEvent | null => {\n if (line === \"\") return dispatch(); // blank line = event boundary\n if (line.startsWith(\":\")) return null; // comment\n if (line.startsWith(\"data:\")) {\n let value = line.slice(5);\n if (value.startsWith(\" \")) value = value.slice(1);\n dataLines.push(value);\n return null;\n }\n // Ignore event:/id:/retry: and unknown fields.\n return null;\n };\n\n try {\n for (;;) {\n if (opts.signal?.aborted) break;\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let s = splitFirstLine(buffer);\n while (s !== null) {\n const ev = processLine(s.line);\n if (ev) {\n if (stopOnDone && ev.data.trim() === \"[DONE]\") return;\n yield ev;\n }\n buffer = s.rest;\n s = splitFirstLine(buffer);\n }\n }\n\n // Flush any bytes still held by the decoder.\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const ev = processLine(buffer);\n if (ev && !(stopOnDone && ev.data.trim() === \"[DONE]\")) yield ev;\n }\n // Flush a final event that had no terminating blank line.\n const tail = dispatch();\n if (tail && !(stopOnDone && tail.data.trim() === \"[DONE]\")) yield tail;\n } finally {\n if (opts.signal) opts.signal.removeEventListener(\"abort\", onAbort);\n try {\n reader.releaseLock();\n } catch {\n /* already released */\n }\n }\n}\n\n/** Split the first complete line (LF, CRLF, or lone CR) out of `buf`. */\nfunction splitFirstLine(buf: string): { line: string; rest: string } | null {\n const nl = buf.indexOf(\"\\n\");\n const cr = buf.indexOf(\"\\r\");\n let end = -1;\n let termLen = 0;\n if (nl !== -1 && (cr === -1 || nl < cr)) {\n end = nl;\n termLen = 1;\n } else if (cr !== -1) {\n end = cr;\n termLen = buf[cr + 1] === \"\\n\" ? 2 : 1;\n }\n if (end === -1) return null;\n return { line: buf.slice(0, end), rest: buf.slice(end + termLen) };\n}\n\n/** Parse a single SSE `data` payload as JSON, returning null on failure. */\nexport function parseSSEData<T = unknown>(data: string): T | null {\n const trimmed = data.trim();\n if (trimmed === \"\" || trimmed === \"[DONE]\") return null;\n try {\n return JSON.parse(trimmed) as T;\n } catch {\n return null; // malformed JSON is skipped, not fatal\n }\n}\n","import type { Transport } from \"./http.js\";\nimport { abortError, timeoutError } from \"./errors.js\";\nimport type { Task, WaitOptions } from \"./types.js\";\n\n/** Statuses at which a task will not change again. */\nconst TERMINAL_TASK_STATUSES = new Set([\"completed\", \"failed\", \"cancelled\"]);\n\nexport function isTerminalTaskStatus(status: string): boolean {\n return TERMINAL_TASK_STATUSES.has(status);\n}\n\n/**\n * A handle to a background task created via `tasks.create`.\n *\n * NOTE on execution: creating a task only enqueues it. It may stay in the\n * `queued` state until an existing worker/execution mechanism processes it —\n * this SDK does not trigger execution. `wait()` simply polls until the task\n * reaches a terminal status (or you time out / abort).\n */\nexport class TaskHandle {\n constructor(\n private readonly transport: Transport,\n public readonly taskId: string,\n ) {}\n\n /** Fetch the current task snapshot (single request). */\n get(signal?: AbortSignal): Promise<Task> {\n return this.transport.json<Task>(\"GET\", `/api/v1/tasks/${this.taskId}`, { signal });\n }\n\n /** Alias of `get()` — perform one poll and return the latest snapshot. */\n poll(signal?: AbortSignal): Promise<Task> {\n return this.get(signal);\n }\n\n /**\n * Poll until the task reaches a terminal status.\n *\n * - Uses exponential-ish backoff from `intervalMs` up to `maxIntervalMs`.\n * - Throws a QLError with code \"timeout\" if `timeoutMs` elapses first.\n * - Throws a QLError with code \"aborted\" if `signal` aborts.\n */\n async wait(opts: WaitOptions = {}): Promise<Task> {\n const intervalMs = opts.intervalMs ?? 2000;\n const maxIntervalMs = opts.maxIntervalMs ?? 15000;\n const signal = opts.signal;\n const startedAt = Date.now();\n let delay = intervalMs;\n\n for (;;) {\n if (signal?.aborted) throw abortError();\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n const task = await this.get(signal);\n opts.onTick?.(task);\n if (isTerminalTaskStatus(task.status)) return task;\n\n // Recompute timeout after the poll so a slow request doesn't overshoot silently.\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n await sleep(delay, signal);\n delay = Math.min(maxIntervalMs, Math.round(delay * 1.5));\n }\n }\n}\n\n/** Abort-aware sleep. Rejects with an abort error if `signal` fires first. */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(abortError());\n return;\n }\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n cleanup();\n reject(abortError());\n };\n const cleanup = () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n };\n if (signal) signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n","import { createTransport, normalizeUrl, type Transport } from \"./http.js\";\nimport { QLError } from \"./errors.js\";\nimport { readSSEEvents, parseSSEData } from \"./sse.js\";\nimport { TaskHandle } from \"./task.js\";\nimport type {\n AgentDetail,\n AgentListResult,\n CapabilitiesResult,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n HistoryPage,\n HistoryParams,\n RunCapabilityInput,\n RunCapabilityResult,\n StreamOptions,\n Task,\n TaskCreateInput,\n TaskCreated,\n WorkflowRun,\n WorkflowRunInput,\n WorkflowRunStart,\n Workspace,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://app.quantonlabs.com\";\n\nexport interface QLClientOptions {\n /** Your Quanton Labs API key (Bearer). Never logged or exposed. */\n apiKey: string;\n /** API base URL. Defaults to `QL_BASE_URL` if set, else https://app.quantonlabs.com. */\n baseUrl?: string;\n /** Override the global fetch (for tests, proxies, or custom runtimes). */\n fetch?: typeof fetch;\n}\n\n/** Workspace namespace. */\nexport class WorkspaceApi {\n constructor(private readonly t: Transport) {}\n /** GET /api/v1/workspace */\n get(): Promise<Workspace> {\n return this.t.json<Workspace>(\"GET\", \"/api/v1/workspace\");\n }\n}\n\n/** Agents namespace. */\nexport class AgentsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/agents — list the global agent registry. */\n list(): Promise<AgentListResult> {\n return this.t.json<AgentListResult>(\"GET\", \"/api/v1/agents\");\n }\n\n /** GET /api/v1/agents/:agentId — agent detail + capabilities. */\n get(agentId: string): Promise<AgentDetail> {\n return this.t.json<AgentDetail>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}`);\n }\n\n /** GET /api/v1/agents/:agentId/capabilities */\n capabilities(agentId: string): Promise<CapabilitiesResult> {\n return this.t.json<CapabilitiesResult>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities`);\n }\n\n /** POST /api/v1/agents/:agentId/capabilities/run — run a feature. */\n runCapability(agentId: string, input: RunCapabilityInput): Promise<RunCapabilityResult> {\n return this.t.json<RunCapabilityResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities/run`, {\n body: { capId: input.capId, params: input.params ?? {} },\n });\n }\n\n /** POST /api/v1/agents/chat — non-streaming chat. */\n chat(input: ChatInput): Promise<ChatResult> {\n return this.t.json<ChatResult>(\"POST\", \"/api/v1/agents/chat\", { body: input });\n }\n\n /**\n * POST /api/v1/agents/chat/stream — streaming chat as an async iterable.\n *\n * Yields incremental `delta` events (text and/or reasoning) followed by a\n * single `done` event with the fully accumulated text. Stop early by passing\n * an `AbortSignal` (see StreamOptions) or breaking out of the loop.\n */\n chatStream(input: ChatInput, opts: StreamOptions = {}): AsyncIterable<ChatStreamEvent> {\n return this.chatStreamImpl(input, opts);\n }\n\n /** GET /api/v1/agents/:agentId/messages — paginated history (newest first). */\n history(agentId: string, params: HistoryParams = {}): Promise<HistoryPage> {\n return this.t.json<HistoryPage>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/messages`, {\n query: { limit: params.limit, before: params.before, userId: params.userId },\n });\n }\n\n private async *chatStreamImpl(input: ChatInput, opts: StreamOptions): AsyncGenerator<ChatStreamEvent> {\n const body = await this.t.stream(\"POST\", \"/api/v1/agents/chat/stream\", { body: input, signal: opts.signal });\n let content = \"\";\n let reasoning = \"\";\n for await (const ev of readSSEEvents(body, { signal: opts.signal })) {\n const payload = parseSSEData<{ choices?: { delta?: { content?: string; reasoning?: string; reasoning_content?: string } }[] }>(ev.data);\n if (!payload) continue; // [DONE] or malformed chunk\n const delta = payload.choices?.[0]?.delta;\n const text = typeof delta?.content === \"string\" ? delta.content : undefined;\n const reason =\n typeof delta?.reasoning === \"string\"\n ? delta.reasoning\n : typeof delta?.reasoning_content === \"string\"\n ? delta.reasoning_content\n : undefined;\n if (text) content += text;\n if (reason) reasoning += reason;\n if (text || reason) yield { type: \"delta\", content: text, reasoning: reason };\n }\n yield { type: \"done\", content, reasoning: reasoning || undefined };\n }\n}\n\n/** Workflows namespace. */\nexport class WorkflowsApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/workflows/:id/run — start a run (returns immediately, HTTP 202). */\n run(workflowId: string, input: WorkflowRunInput = {}): Promise<WorkflowRunStart> {\n return this.t.json<WorkflowRunStart>(\"POST\", `/api/v1/workflows/${encodeURIComponent(workflowId)}/run`, { body: input });\n }\n\n /** GET /api/v1/workflow-runs/:runId — poll a run. */\n getRun(runId: string): Promise<WorkflowRun> {\n return this.t.json<WorkflowRun>(\"GET\", `/api/v1/workflow-runs/${encodeURIComponent(runId)}`);\n }\n}\n\n/** Tasks namespace. */\nexport class TasksApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/tasks — create (enqueue) a background task. Does NOT trigger execution. */\n create(input: TaskCreateInput): Promise<TaskCreated> {\n return this.t.json<TaskCreated>(\"POST\", \"/api/v1/tasks\", { body: input });\n }\n\n /** GET /api/v1/tasks/:taskId — fetch the current snapshot. */\n get(taskId: string, signal?: AbortSignal): Promise<Task> {\n return this.t.json<Task>(\"GET\", `/api/v1/tasks/${encodeURIComponent(taskId)}`, { signal });\n }\n\n /** Get a handle for polling / waiting on a task (poll(), wait()). */\n handle(taskId: string): TaskHandle {\n return new TaskHandle(this.t, taskId);\n }\n}\n\nfunction readEnvBaseUrl(): string | undefined {\n try {\n if (typeof process !== \"undefined\" && process?.env) {\n return process.env.QL_BASE_URL || undefined;\n }\n } catch {\n /* non-Node runtime */\n }\n return undefined;\n}\n\n/**\n * The public client. Example:\n * const ql = new QLClient({ apiKey: process.env.QL_API_KEY });\n * const agents = await ql.agents.list();\n */\nexport class QLClient {\n readonly workspace: WorkspaceApi;\n readonly agents: AgentsApi;\n readonly workflows: WorkflowsApi;\n readonly tasks: TasksApi;\n\n private readonly transport: Transport;\n private readonly base: string;\n\n constructor(opts: QLClientOptions) {\n if (!opts || typeof opts.apiKey !== \"string\" || opts.apiKey.length === 0) {\n throw new QLError(\"apiKey is required\", { code: \"validation_error\" });\n }\n this.base = normalizeUrl(opts.baseUrl ?? readEnvBaseUrl() ?? DEFAULT_BASE_URL);\n const fetchImpl = (opts.fetch ?? globalThis.fetch).bind(globalThis);\n this.transport = createTransport({ apiKey: opts.apiKey, baseUrl: this.base, fetchImpl });\n this.workspace = new WorkspaceApi(this.transport);\n this.agents = new AgentsApi(this.transport);\n this.workflows = new WorkflowsApi(this.transport);\n this.tasks = new TasksApi(this.transport);\n }\n\n /** The normalized base URL in use (not secret). */\n get baseUrl(): string {\n return this.base;\n }\n}\n","/**\n * Public request/response types for the Quanton Labs agent platform API (v1).\n *\n * These mirror the verified Phase 1 endpoints. The public surface is enveloped:\n * success -> { ok: true, data }\n * error -> { ok: false, error: { code, message } }\n * The SDK unwraps `data` for you and surfaces errors as a typed QLError.\n */\n\n/** Stable API error codes emitted by the backend. */\nexport const API_ERROR_CODES = {\n unauthorized: \"unauthorized\",\n forbidden: \"forbidden\",\n notFound: \"not_found\",\n validationError: \"validation_error\",\n conflict: \"conflict\",\n internalError: \"internal_error\",\n} as const;\n\nexport type ApiErrorCode = (typeof API_ERROR_CODES)[keyof typeof API_ERROR_CODES];\n\n/** A single message in a chat conversation. */\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\n/** Input for `agents.chat` and `agents.chatStream`. */\nexport interface ChatInput {\n agentId: string;\n messages: ChatMessage[];\n /** Optional internal user id; defaults to the key's workspace when omitted. */\n userId?: string;\n /** Optional OpenRouter response-format hint (e.g. `{ type: \"json_object\" }`). */\n response_format?: Record<string, unknown>;\n}\n\n/** Result of a non-streaming chat call. */\nexport interface ChatResult {\n content: string;\n toolCalls: number;\n iterations: number;\n /** Human-readable duration string, e.g. \"2.91s\". */\n duration: string;\n}\n\n/**\n * A single event yielded by `agents.chatStream`.\n * - `delta`: an incremental piece of the streamed response (text and/or reasoning).\n * - `done`: emitted once at the end with the fully accumulated text.\n */\nexport type ChatStreamEvent =\n | { type: \"delta\"; content?: string; reasoning?: string }\n | { type: \"done\"; content: string; reasoning?: string };\n\n/** Options accepted by streaming methods. */\nexport interface StreamOptions {\n /** Abort the in-flight request/stream at any time. */\n signal?: AbortSignal;\n}\n\n/** A conversation-history page (newest first). */\nexport interface MessageItem {\n id: string;\n role: string;\n content: string | null;\n reasoning?: string;\n toolCalls: unknown[];\n status: string;\n timestamp: string | Date;\n}\n\nexport interface HistoryPage {\n agentId: string;\n limit: number;\n /** Cursor for the next page (pass as `before`); null when exhausted. */\n nextBefore: string | null;\n items: MessageItem[];\n}\n\n/** Query params for `agents.history`. */\nexport interface HistoryParams {\n /** Page size, 1..100 (default 20 server-side). */\n limit?: number;\n /** Cursor = id of the last item on the previous page. */\n before?: string;\n /** Optional internal user id filter. */\n userId?: string;\n}\n\n/** Agent summary as returned by `agents.list`. */\nexport interface AgentSummary {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n capabilityCount: number;\n}\n\nexport interface AgentListResult {\n agents: AgentSummary[];\n}\n\n/** A schema-driven capability parameter (rendered as a form field in the UI). */\nexport type CapParamKind = \"text\" | \"textarea\" | \"number\" | \"select\" | \"boolean\" | \"json\";\n\nexport interface CapabilityParam {\n key: string;\n label: string;\n kind: CapParamKind;\n placeholder?: string;\n options?: { value: string; label: string }[];\n required?: boolean;\n hint?: string;\n rows?: number;\n [key: string]: unknown;\n}\n\n/** A pre-filled example input set (suggestion chip). */\nexport interface CapabilityTemplate {\n label: string;\n values: Record<string, unknown>;\n}\n\n/** A client-safe capability descriptor (the server-side `run` is stripped). */\nexport interface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n category: string;\n icon?: string;\n badge?: string;\n params: CapabilityParam[];\n templates?: CapabilityTemplate[];\n metrics?: string[];\n tableKey?: string;\n outputHint?: string;\n [key: string]: unknown;\n}\n\n/** Agent detail + its capabilities, as returned by `agents.get`. */\nexport interface AgentDetail {\n agent: {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n };\n capabilities: CapabilityInfo[];\n}\n\n/** Result of `agents.capabilities`. */\nexport interface CapabilitiesResult {\n agentId: string;\n capabilities: CapabilityInfo[];\n}\n\n/** Input for `agents.runCapability`. */\nexport interface RunCapabilityInput {\n capId: string;\n /** Capability-specific parameters (see the capability's `params`). */\n params?: Record<string, unknown>;\n}\n\n/**\n * The result of running a capability. A discriminated union matching the\n * backend — a feature can return text, structured JSON, HTML, or a file URL.\n */\nexport type CapabilityResult =\n | { type: \"text\"; content: string }\n | { type: \"json\"; data: unknown }\n | { type: \"html\"; html: string }\n | { type: \"file\"; url: string; filename: string; mime: string };\n\n/** Result envelope for `agents.runCapability`. */\nexport interface RunCapabilityResult {\n result: CapabilityResult;\n}\n\n/** The workspace object as returned by the public API (redacted). */\nexport interface Workspace {\n _id: string;\n name: string;\n plan?: string;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n}\n\n/** Input for `workflows.run`. */\nexport interface WorkflowRunInput {\n /** Optional workflow input payload. */\n input?: Record<string, unknown>;\n}\n\n/** Returned immediately when a workflow run is started (HTTP 202). */\nexport interface WorkflowRunStart {\n runId: string;\n status: \"running\";\n}\n\nexport type WorkflowRunStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | (string & {});\n\n/** A workflow run snapshot, as returned by `workflows.getRun`. */\nexport interface WorkflowRun {\n runId: string;\n status: WorkflowRunStatus;\n output: unknown | null;\n error?: string;\n durationMs?: number;\n startedAt: string | Date;\n finishedAt: string | Date | null;\n}\n\nexport type TaskPriority = \"low\" | \"medium\" | \"high\" | \"urgent\";\n\n/** Input for `tasks.create`. */\nexport interface TaskCreateInput {\n agentId: string;\n title: string;\n description?: string;\n /** Arbitrary payload handed to the agent. */\n input?: unknown;\n priority?: TaskPriority;\n}\n\n/** Returned when a task is created (HTTP 201). */\nexport interface TaskCreated {\n taskId: string;\n status: TaskStatus;\n}\n\nexport type TaskStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"retrying\"\n | (string & {});\n\n/** A task snapshot, as returned by `tasks.get`. */\nexport interface Task {\n taskId: string;\n status: TaskStatus;\n title: string;\n progress?: unknown;\n result?: unknown;\n output?: unknown;\n error?: string;\n createdAt: string | Date;\n completedAt: string | Date | null;\n}\n\n/** Options for polling / waiting on a task. */\nexport interface WaitOptions {\n /** Base delay between polls in ms (default 2000). Grows with backoff up to `maxIntervalMs`. */\n intervalMs?: number;\n /** Upper bound for the backoff delay in ms (default 15000). */\n maxIntervalMs?: number;\n /** Stop waiting after this many ms and throw a timeout error. Omit to wait until terminal or abort. */\n timeoutMs?: number;\n /** Abort polling at any time. */\n signal?: AbortSignal;\n /** Called after each poll with the latest task snapshot. */\n onTick?: (task: Task) => void;\n}\n"],"mappings":";AAgBO,IAAM,UAAN,MAAM,iBAAgB,MAAM;AAAA,EAQjC,YAAY,SAAiB,OAAuF,EAAE,MAAM,iBAAiB,GAAG;AAC9I,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS,KAAK;AACnB,SAAK,OAAO,KAAK;AACjB,SAAK,SAAS,KAAK,SAAS;AAC5B,SAAK,MAAM,KAAK,SAAS;AACzB,SAAK,UAAU,KAAK;AAEpB,WAAO,eAAe,MAAM,SAAQ,SAAS;AAAA,EAC/C;AAAA;AAAA,EAGA,IAAI,cAAuB;AACzB,WAAO,KAAK,SAAS,kBAAkB,KAAK,SAAS,eAAe,KAAK,WAAW,OAAO,KAAK,WAAW;AAAA,EAC7G;AAAA;AAAA,EAGA,IAAI,YAAqB;AACvB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,YAAqB;AACvB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,iBAA0B;AAC5B,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAGO,SAAS,eAAe,QAA2C;AACxE,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,UAAU,MAAM,mBAAmB;AAAA,EAC9C;AACF;AASO,SAAS,YAAY,QAAgB,MAA0B,KAA8B;AAClG,MAAI,SAAiC;AACrC,MAAI,MAAM;AACR,QAAI;AACF,YAAM,IAAI,KAAK,MAAM,IAAI;AACzB,UAAI,KAAK,OAAO,MAAM,SAAU,UAAS;AAAA,IAC3C,QAAQ;AACN,eAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ;AACxB,MAAI;AACJ,MAAI;AACJ,MAAI,OAAO,YAAY,UAAU;AAC/B,cAAU;AAAA,EACZ,WAAW,WAAW,OAAO,YAAY,UAAU;AACjD,WAAO,OAAO,QAAQ,SAAS,WAAW,QAAQ,OAAO;AACzD,cAAU,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAAA,EACpE;AACA,MAAI,CAAC,KAAM,QAAO,eAAe,MAAM;AACvC,MAAI,CAAC,QAAS,YAAW,OAAO,QAAQ,YAAY,WAAW,OAAO,UAAU,WAAc,8BAA8B,MAAM;AAElI,SAAO,IAAI,QAAQ,SAAS,EAAE,QAAQ,MAAM,SAAS,KAAK,SAAS,UAAU,OAAU,CAAC;AAC1F;AAGO,SAAS,eAAe,OAAgB,KAA8B;AAC3E,QAAM,UAAU,aAAa,KAAK;AAClC,MAAI,SAAS;AACX,WAAO,IAAI,QAAQ,mBAAmB,EAAE,MAAM,WAAW,SAAS,IAAI,CAAC;AAAA,EACzE;AACA,QAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,SAAO,IAAI,QAAQ,kBAAkB,GAAG,IAAI,EAAE,MAAM,WAAW,SAAS,KAAK,SAAS,MAAM,CAAC;AAC/F;AAEA,SAAS,aAAa,OAAyB;AAC7C,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI;AACV,QAAI,EAAE,SAAS,gBAAgB,EAAE,SAAS,UAAW,QAAO;AAAA,EAC9D;AACA,SAAO;AACT;AAGO,SAAS,aAAsB;AACpC,SAAO,IAAI,QAAQ,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAC7D;AAGO,SAAS,aAAa,WAA4B;AACvD,SAAO,IAAI,QAAQ,mBAAmB,SAAS,MAAM,EAAE,MAAM,UAAU,CAAC;AAC1E;;;ACzGO,SAAS,gBAAgB,MAAmC;AACjE,QAAM,EAAE,QAAQ,SAAS,UAAU,IAAI;AAEvC,SAAO;AAAA,IACL,MAAM,KAAQ,QAAgB,MAAc,UAA8B,CAAC,GAAG;AAC5E,YAAM,MAAM,MAAM,QAAQ,QAAQ,MAAM,OAAO;AAC/C,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,CAAC,IAAI,GAAI,OAAM,YAAY,IAAI,QAAQ,MAAM,EAAE,QAAQ,KAAK,IAAI,IAAI,CAAC;AACzE,aAAO,OAAU,MAAM,EAAE,QAAQ,KAAK,IAAI,IAAI,CAAC;AAAA,IACjD;AAAA,IAEA,MAAM,OAAO,QAAQ,MAAM,UAAU,CAAC,GAAG;AACvC,YAAM,MAAM,MAAM,QAAQ,QAAQ,MAAM;AAAA,QACtC,GAAG;AAAA,QACH,SAAS,EAAE,QAAQ,qBAAqB,GAAI,QAAQ,WAAW,CAAC,EAAG;AAAA,MACrE,CAAC;AACD,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AACnD,cAAM,YAAY,IAAI,QAAQ,MAAM,EAAE,QAAQ,KAAK,IAAI,IAAI,CAAC;AAAA,MAC9D;AACA,YAAM,SAAS,IAAI,QAAQ,IAAI,cAAc,KAAK,IAAI,YAAY;AAClE,UAAI,CAAC,MAAM,SAAS,mBAAmB,GAAG;AAExC,cAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AACnD,cAAM,IAAI,QAAQ,uCAAuC,SAAS,SAAS,KAAK;AAAA,UAC9E,QAAQ,IAAI;AAAA,UACZ,MAAM;AAAA,UACN,SAAS,EAAE,QAAQ,KAAK,IAAI,IAAI;AAAA,UAChC,SAAS,UAAU,IAAI;AAAA,QACzB,CAAC;AAAA,MACH;AACA,UAAI,CAAC,IAAI,KAAM,OAAM,IAAI,QAAQ,wCAAwC,EAAE,MAAM,WAAW,SAAS,EAAE,QAAQ,KAAK,IAAI,IAAI,EAAE,CAAC;AAC/H,aAAO,IAAI;AAAA,IACb;AAAA,EACF;AAEA,WAAS,QAAQ,QAAgB,MAAc,SAAgD;AAC7F,UAAM,MAAM,SAAS,SAAS,MAAM,QAAQ,KAAK;AACjD,UAAM,UAAkC;AAAA,MACtC,eAAe,UAAU,MAAM;AAAA,MAC/B,QAAQ;AAAA,MACR,GAAI,QAAQ,SAAS,SAAY,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,MAC3E,GAAI,QAAQ,WAAW,CAAC;AAAA,IAC1B;AACA,WAAO,UAAU,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA,MAAM,QAAQ,SAAS,SAAY,KAAK,UAAU,QAAQ,IAAI,IAAI;AAAA,MAClE,QAAQ,QAAQ;AAAA,IAClB,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,YAAM,eAAe,KAAK,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,CAAC;AAAA,EACH;AACF;AAEA,SAAS,OAAU,MAAc,KAA2C;AAC1E,QAAM,SAAS,UAAU,IAAI;AAC7B,MAAI,UAAU,OAAO,WAAW,YAAY,QAAS,QAAoC;AACvF,UAAM,MAAM;AACZ,QAAI,IAAI,OAAO,KAAM,QAAO,IAAI;AAEhC,UAAM,IAAI,QAAQ,IAAI,OAAO,WAAW,kBAAkB;AAAA,MACxD,MAAO,IAAI,OAAO,QAAyB;AAAA,MAC3C,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,UAAU,MAAwB;AACzC,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,SAAS,SAAiB,MAAc,OAA6D;AACnH,QAAM,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AACvC,QAAM,IAAI,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAChD,MAAI,MAAM,GAAG,IAAI,GAAG,CAAC;AACrB,MAAI,OAAO;AACT,UAAM,SAAS,IAAI,gBAAgB;AACnC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAI,UAAU,UAAa,UAAU,KAAM,QAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAC1E;AACA,UAAM,KAAK,OAAO,SAAS;AAC3B,QAAI,GAAI,QAAO,IAAI,EAAE;AAAA,EACvB;AACA,SAAO;AACT;AAGO,SAAS,aAAa,KAAqB;AAChD,SAAO,IAAI,KAAK,EAAE,QAAQ,QAAQ,EAAE;AACtC;;;ACtGA,gBAAuB,cACrB,MACA,OAAoB,CAAC,GACoB;AACzC,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AACb,MAAI,YAAsB,CAAC;AAG3B,QAAM,UAAU,MAAM;AACpB,SAAK,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACrC;AACA,MAAI,KAAK,QAAQ;AACf,QAAI,KAAK,OAAO,SAAS;AACvB,YAAM,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACpC;AAAA,IACF;AACA,SAAK,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EAC/D;AAEA,QAAM,WAAW,MAAuB;AACtC,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,UAAM,OAAO,UAAU,KAAK,IAAI;AAChC,gBAAY,CAAC;AACb,WAAO,EAAE,KAAK;AAAA,EAChB;AAEA,QAAM,cAAc,CAAC,SAAkC;AACrD,QAAI,SAAS,GAAI,QAAO,SAAS;AACjC,QAAI,KAAK,WAAW,GAAG,EAAG,QAAO;AACjC,QAAI,KAAK,WAAW,OAAO,GAAG;AAC5B,UAAI,QAAQ,KAAK,MAAM,CAAC;AACxB,UAAI,MAAM,WAAW,GAAG,EAAG,SAAQ,MAAM,MAAM,CAAC;AAChD,gBAAU,KAAK,KAAK;AACpB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,eAAS;AACP,UAAI,KAAK,QAAQ,QAAS;AAC1B,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAEhD,UAAI,IAAI,eAAe,MAAM;AAC7B,aAAO,MAAM,MAAM;AACjB,cAAM,KAAK,YAAY,EAAE,IAAI;AAC7B,YAAI,IAAI;AACN,cAAI,cAAc,GAAG,KAAK,KAAK,MAAM,SAAU;AAC/C,gBAAM;AAAA,QACR;AACA,iBAAS,EAAE;AACX,YAAI,eAAe,MAAM;AAAA,MAC3B;AAAA,IACF;AAGA,cAAU,QAAQ,OAAO;AACzB,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,KAAK,YAAY,MAAM;AAC7B,UAAI,MAAM,EAAE,cAAc,GAAG,KAAK,KAAK,MAAM,UAAW,OAAM;AAAA,IAChE;AAEA,UAAM,OAAO,SAAS;AACtB,QAAI,QAAQ,EAAE,cAAc,KAAK,KAAK,KAAK,MAAM,UAAW,OAAM;AAAA,EACpE,UAAE;AACA,QAAI,KAAK,OAAQ,MAAK,OAAO,oBAAoB,SAAS,OAAO;AACjE,QAAI;AACF,aAAO,YAAY;AAAA,IACrB,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAGA,SAAS,eAAe,KAAoD;AAC1E,QAAM,KAAK,IAAI,QAAQ,IAAI;AAC3B,QAAM,KAAK,IAAI,QAAQ,IAAI;AAC3B,MAAI,MAAM;AACV,MAAI,UAAU;AACd,MAAI,OAAO,OAAO,OAAO,MAAM,KAAK,KAAK;AACvC,UAAM;AACN,cAAU;AAAA,EACZ,WAAW,OAAO,IAAI;AACpB,UAAM;AACN,cAAU,IAAI,KAAK,CAAC,MAAM,OAAO,IAAI;AAAA,EACvC;AACA,MAAI,QAAQ,GAAI,QAAO;AACvB,SAAO,EAAE,MAAM,IAAI,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,MAAM,MAAM,OAAO,EAAE;AACnE;AAGO,SAAS,aAA0B,MAAwB;AAChE,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,YAAY,MAAM,YAAY,SAAU,QAAO;AACnD,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AChIA,IAAM,yBAAyB,oBAAI,IAAI,CAAC,aAAa,UAAU,WAAW,CAAC;AAEpE,SAAS,qBAAqB,QAAyB;AAC5D,SAAO,uBAAuB,IAAI,MAAM;AAC1C;AAUO,IAAM,aAAN,MAAiB;AAAA,EACtB,YACmB,WACD,QAChB;AAFiB;AACD;AAAA,EACf;AAAA;AAAA,EAGH,IAAI,QAAqC;AACvC,WAAO,KAAK,UAAU,KAAW,OAAO,iBAAiB,KAAK,MAAM,IAAI,EAAE,OAAO,CAAC;AAAA,EACpF;AAAA;AAAA,EAGA,KAAK,QAAqC;AACxC,WAAO,KAAK,IAAI,MAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KAAK,OAAoB,CAAC,GAAkB;AAChD,UAAM,aAAa,KAAK,cAAc;AACtC,UAAM,gBAAgB,KAAK,iBAAiB;AAC5C,UAAM,SAAS,KAAK;AACpB,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI,QAAQ;AAEZ,eAAS;AACP,UAAI,QAAQ,QAAS,OAAM,WAAW;AACtC,UAAI,KAAK,cAAc,UAAa,KAAK,IAAI,IAAI,aAAa,KAAK,WAAW;AAC5E,cAAM,aAAa,KAAK,SAAS;AAAA,MACnC;AAEA,YAAM,OAAO,MAAM,KAAK,IAAI,MAAM;AAClC,WAAK,SAAS,IAAI;AAClB,UAAI,qBAAqB,KAAK,MAAM,EAAG,QAAO;AAG9C,UAAI,KAAK,cAAc,UAAa,KAAK,IAAI,IAAI,aAAa,KAAK,WAAW;AAC5E,cAAM,aAAa,KAAK,SAAS;AAAA,MACnC;AAEA,YAAM,MAAM,OAAO,MAAM;AACzB,cAAQ,KAAK,IAAI,eAAe,KAAK,MAAM,QAAQ,GAAG,CAAC;AAAA,IACzD;AAAA,EACF;AACF;AAGA,SAAS,MAAM,IAAY,QAAqC;AAC9D,SAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,QAAI,QAAQ,SAAS;AACnB,aAAO,WAAW,CAAC;AACnB;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,MAAM;AAC7B,cAAQ;AACR,cAAQ;AAAA,IACV,GAAG,EAAE;AACL,UAAM,UAAU,MAAM;AACpB,mBAAa,KAAK;AAClB,cAAQ;AACR,aAAO,WAAW,CAAC;AAAA,IACrB;AACA,UAAM,UAAU,MAAM;AACpB,UAAI,OAAQ,QAAO,oBAAoB,SAAS,OAAO;AAAA,IACzD;AACA,QAAI,OAAQ,QAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EACtE,CAAC;AACH;;;AClEO,IAAM,mBAAmB;AAYzB,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAE5C,MAA0B;AACxB,WAAO,KAAK,EAAE,KAAgB,OAAO,mBAAmB;AAAA,EAC1D;AACF;AAGO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,OAAiC;AAC/B,WAAO,KAAK,EAAE,KAAsB,OAAO,gBAAgB;AAAA,EAC7D;AAAA;AAAA,EAGA,IAAI,SAAuC;AACzC,WAAO,KAAK,EAAE,KAAkB,OAAO,kBAAkB,mBAAmB,OAAO,CAAC,EAAE;AAAA,EACxF;AAAA;AAAA,EAGA,aAAa,SAA8C;AACzD,WAAO,KAAK,EAAE,KAAyB,OAAO,kBAAkB,mBAAmB,OAAO,CAAC,eAAe;AAAA,EAC5G;AAAA;AAAA,EAGA,cAAc,SAAiB,OAAyD;AACtF,WAAO,KAAK,EAAE,KAA0B,QAAQ,kBAAkB,mBAAmB,OAAO,CAAC,qBAAqB;AAAA,MAChH,MAAM,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,UAAU,CAAC,EAAE;AAAA,IACzD,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,KAAK,OAAuC;AAC1C,WAAO,KAAK,EAAE,KAAiB,QAAQ,uBAAuB,EAAE,MAAM,MAAM,CAAC;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,OAAkB,OAAsB,CAAC,GAAmC;AACrF,WAAO,KAAK,eAAe,OAAO,IAAI;AAAA,EACxC;AAAA;AAAA,EAGA,QAAQ,SAAiB,SAAwB,CAAC,GAAyB;AACzE,WAAO,KAAK,EAAE,KAAkB,OAAO,kBAAkB,mBAAmB,OAAO,CAAC,aAAa;AAAA,MAC/F,OAAO,EAAE,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,OAAO;AAAA,IAC7E,CAAC;AAAA,EACH;AAAA,EAEA,OAAe,eAAe,OAAkB,MAAsD;AACpG,UAAM,OAAO,MAAM,KAAK,EAAE,OAAO,QAAQ,8BAA8B,EAAE,MAAM,OAAO,QAAQ,KAAK,OAAO,CAAC;AAC3G,QAAI,UAAU;AACd,QAAI,YAAY;AAChB,qBAAiB,MAAM,cAAc,MAAM,EAAE,QAAQ,KAAK,OAAO,CAAC,GAAG;AACnE,YAAM,UAAU,aAA+G,GAAG,IAAI;AACtI,UAAI,CAAC,QAAS;AACd,YAAM,QAAQ,QAAQ,UAAU,CAAC,GAAG;AACpC,YAAM,OAAO,OAAO,OAAO,YAAY,WAAW,MAAM,UAAU;AAClE,YAAM,SACJ,OAAO,OAAO,cAAc,WACxB,MAAM,YACN,OAAO,OAAO,sBAAsB,WAClC,MAAM,oBACN;AACR,UAAI,KAAM,YAAW;AACrB,UAAI,OAAQ,cAAa;AACzB,UAAI,QAAQ,OAAQ,OAAM,EAAE,MAAM,SAAS,SAAS,MAAM,WAAW,OAAO;AAAA,IAC9E;AACA,UAAM,EAAE,MAAM,QAAQ,SAAS,WAAW,aAAa,OAAU;AAAA,EACnE;AACF;AAGO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,IAAI,YAAoB,QAA0B,CAAC,GAA8B;AAC/E,WAAO,KAAK,EAAE,KAAuB,QAAQ,qBAAqB,mBAAmB,UAAU,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAC;AAAA,EACzH;AAAA;AAAA,EAGA,OAAO,OAAqC;AAC1C,WAAO,KAAK,EAAE,KAAkB,OAAO,yBAAyB,mBAAmB,KAAK,CAAC,EAAE;AAAA,EAC7F;AACF;AAGO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,OAAO,OAA8C;AACnD,WAAO,KAAK,EAAE,KAAkB,QAAQ,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,IAAI,QAAgB,QAAqC;AACvD,WAAO,KAAK,EAAE,KAAW,OAAO,iBAAiB,mBAAmB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;AAAA,EAC3F;AAAA;AAAA,EAGA,OAAO,QAA4B;AACjC,WAAO,IAAI,WAAW,KAAK,GAAG,MAAM;AAAA,EACtC;AACF;AAEA,SAAS,iBAAqC;AAC5C,MAAI;AACF,QAAI,OAAO,YAAY,eAAe,SAAS,KAAK;AAClD,aAAO,QAAQ,IAAI,eAAe;AAAA,IACpC;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAOO,IAAM,WAAN,MAAe;AAAA,EASpB,YAAY,MAAuB;AACjC,QAAI,CAAC,QAAQ,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,WAAW,GAAG;AACxE,YAAM,IAAI,QAAQ,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAAA,IACtE;AACA,SAAK,OAAO,aAAa,KAAK,WAAW,eAAe,KAAK,gBAAgB;AAC7E,UAAM,aAAa,KAAK,SAAS,WAAW,OAAO,KAAK,UAAU;AAClE,SAAK,YAAY,gBAAgB,EAAE,QAAQ,KAAK,QAAQ,SAAS,KAAK,MAAM,UAAU,CAAC;AACvF,SAAK,YAAY,IAAI,aAAa,KAAK,SAAS;AAChD,SAAK,SAAS,IAAI,UAAU,KAAK,SAAS;AAC1C,SAAK,YAAY,IAAI,aAAa,KAAK,SAAS;AAChD,SAAK,QAAQ,IAAI,SAAS,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA,EAGA,IAAI,UAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AACF;;;ACxLO,IAAM,kBAAkB;AAAA,EAC7B,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,eAAe;AACjB;","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/sse.ts","../src/task.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["import type { ApiErrorCode } from \"./types.js\";\n\nexport interface QLErrorContext {\n method?: string;\n url?: string;\n}\n\n/**\n * Error thrown by the SDK for any failed API interaction.\n *\n * - `status`: HTTP status code (when the failure came from an HTTP response).\n * - `code`: stable API error code when provided by the backend, otherwise a\n * synthesized one derived from the status, or a synthetic transport\n * code such as \"aborted\" / \"timeout\" / \"network\".\n * - `message`: human-readable description. The API key is never included.\n */\nexport class QLError extends Error {\n readonly status?: number;\n readonly code: string;\n readonly method?: string;\n readonly url?: string;\n /** The raw parsed error body (if any), for advanced inspection. */\n readonly details?: unknown;\n\n constructor(message: string, opts: { status?: number; code: string; context?: QLErrorContext; details?: unknown } = { code: \"internal_error\" }) {\n super(message);\n this.name = \"QLError\";\n this.status = opts.status;\n this.code = opts.code;\n this.method = opts.context?.method;\n this.url = opts.context?.url;\n this.details = opts.details;\n // Restore prototype chain (required when targeting ES5-ish runtimes).\n Object.setPrototypeOf(this, QLError.prototype);\n }\n\n /** True for 401/403 or unauthorized/forbidden codes. */\n get isAuthError(): boolean {\n return this.code === \"unauthorized\" || this.code === \"forbidden\" || this.status === 401 || this.status === 403;\n }\n\n /** True when the request was aborted by the caller. */\n get isAborted(): boolean {\n return this.code === \"aborted\";\n }\n\n /** True when a wait() call exceeded its timeout. */\n get isTimeout(): boolean {\n return this.code === \"timeout\";\n }\n\n /** True for transient network failures (no HTTP response received). */\n get isNetworkError(): boolean {\n return this.code === \"network\";\n }\n}\n\n/** Map an HTTP status to a stable API error code when the body has none. */\nexport function codeFromStatus(status: number): ApiErrorCode | \"conflict\" {\n switch (status) {\n case 400:\n return \"validation_error\";\n case 401:\n return \"unauthorized\";\n case 403:\n return \"forbidden\";\n case 404:\n return \"not_found\";\n case 409:\n return \"conflict\";\n default:\n return status >= 500 ? \"internal_error\" : \"validation_error\";\n }\n}\n\ninterface ParsedErrorBody {\n ok?: boolean;\n error?: { code?: string; message?: string } | string;\n message?: string;\n}\n\n/** Build a QLError from a non-2xx HTTP response. Never includes the API key. */\nexport function toHttpError(status: number, text: string | undefined, ctx: QLErrorContext): QLError {\n let parsed: ParsedErrorBody | null = null;\n if (text) {\n try {\n const j = JSON.parse(text);\n if (j && typeof j === \"object\") parsed = j as ParsedErrorBody;\n } catch {\n parsed = null;\n }\n }\n\n const bodyErr = parsed?.error;\n let code: string | undefined;\n let message: string | undefined;\n if (typeof bodyErr === \"string\") {\n message = bodyErr;\n } else if (bodyErr && typeof bodyErr === \"object\") {\n code = typeof bodyErr.code === \"string\" ? bodyErr.code : undefined;\n message = typeof bodyErr.message === \"string\" ? bodyErr.message : undefined;\n }\n if (!code) code = codeFromStatus(status);\n if (!message) message = (typeof parsed?.message === \"string\" ? parsed.message : undefined) ?? `Request failed with status ${status}`;\n\n return new QLError(message, { status, code, context: ctx, details: parsed ?? undefined });\n}\n\n/** Wrap a low-level fetch/network failure (no HTTP response). */\nexport function toNetworkError(cause: unknown, ctx: QLErrorContext): QLError {\n const aborted = isAbortCause(cause);\n if (aborted) {\n return new QLError(\"Request aborted\", { code: \"aborted\", context: ctx });\n }\n const msg = cause instanceof Error ? cause.message : String(cause);\n return new QLError(`Network error: ${msg}`, { code: \"network\", context: ctx, details: cause });\n}\n\nfunction isAbortCause(cause: unknown): boolean {\n if (!cause) return false;\n if (typeof cause === \"object\") {\n const c = cause as { name?: string; type?: string };\n if (c.name === \"AbortError\" || c.type === \"aborted\") return true;\n }\n return false;\n}\n\n/** Build an abort error for wait()/stream cancellation. */\nexport function abortError(): QLError {\n return new QLError(\"Operation aborted\", { code: \"aborted\" });\n}\n\n/** Build a timeout error for wait(). */\nexport function timeoutError(timeoutMs: number): QLError {\n return new QLError(`Timed out after ${timeoutMs}ms`, { code: \"timeout\" });\n}\n","import { QLError, toHttpError, toNetworkError } from \"./errors.js\";\nimport type { ApiErrorCode } from \"./types.js\";\n\nexport interface TransportOptions {\n apiKey: string;\n baseUrl: string;\n fetchImpl: typeof fetch;\n}\n\nexport interface JsonRequestOptions {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\n/**\n * Internal transport used by the API namespaces. Keeps the API key inside a\n * closure (never exposed) and normalizes responses/errors for the caller.\n */\nexport interface Transport {\n /** Perform a JSON request and return the unwrapped `data` payload. */\n json<T>(method: string, path: string, opts?: JsonRequestOptions): Promise<T>;\n /**\n * Perform a request expected to stream SSE. Returns the response body stream\n * after verifying a 2xx + text/event-stream; throws QLError otherwise.\n */\n stream(method: string, path: string, opts?: JsonRequestOptions & { acceptStream?: boolean }): Promise<ReadableStream<Uint8Array>>;\n}\n\nexport function createTransport(opts: TransportOptions): Transport {\n const { apiKey, baseUrl, fetchImpl } = opts;\n\n return {\n async json<T>(method: string, path: string, reqOpts: JsonRequestOptions = {}) {\n const res = await doFetch(method, path, reqOpts);\n const text = await res.text();\n if (!res.ok) throw toHttpError(res.status, text, { method, url: res.url });\n return unwrap<T>(text, { method, url: res.url });\n },\n\n async stream(method, path, reqOpts = {}) {\n const res = await doFetch(method, path, {\n ...reqOpts,\n headers: { accept: \"text/event-stream\", ...(reqOpts.headers ?? {}) },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => undefined);\n throw toHttpError(res.status, text, { method, url: res.url });\n }\n const ctype = (res.headers.get(\"content-type\") || \"\").toLowerCase();\n if (!ctype.includes(\"text/event-stream\")) {\n // The endpoint returned a non-SSE body (e.g. an error envelope). Surface it.\n const text = await res.text().catch(() => undefined);\n throw new QLError(`Expected text/event-stream but got \"${ctype || \"unknown\"}\"`, {\n status: res.status,\n code: \"internal_error\",\n context: { method, url: res.url },\n details: safeParse(text),\n });\n }\n if (!res.body) throw new QLError(\"Response has no readable body stream\", { code: \"network\", context: { method, url: res.url } });\n return res.body;\n },\n };\n\n function doFetch(method: string, path: string, reqOpts: JsonRequestOptions): Promise<Response> {\n const url = buildUrl(baseUrl, path, reqOpts.query);\n const headers: Record<string, string> = {\n authorization: `Bearer ${apiKey}`,\n accept: \"application/json\",\n ...(reqOpts.body !== undefined ? { \"content-type\": \"application/json\" } : {}),\n ...(reqOpts.headers ?? {}),\n };\n return fetchImpl(url, {\n method,\n headers,\n body: reqOpts.body !== undefined ? JSON.stringify(reqOpts.body) : undefined,\n signal: reqOpts.signal,\n }).catch((err) => {\n throw toNetworkError(err, { method, url });\n });\n }\n}\n\nfunction unwrap<T>(text: string, ctx: { method?: string; url?: string }): T {\n const parsed = safeParse(text);\n if (parsed && typeof parsed === \"object\" && \"ok\" in (parsed as Record<string, unknown>)) {\n const env = parsed as { ok: boolean; data?: unknown; error?: { code?: string; message?: string } };\n if (env.ok === true) return env.data as T;\n // ok:false on a 2xx — treat as an application error.\n throw new QLError(env.error?.message || \"Request failed\", {\n code: (env.error?.code as ApiErrorCode) || \"internal_error\",\n context: ctx,\n details: env,\n });\n }\n // Non-enveloped payload (legacy shapes): return as-is.\n return parsed as T;\n}\n\nfunction safeParse(text?: string): unknown {\n if (!text) return null;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\n/** Join base + path and append a query string (skipping undefined values). */\nexport function buildUrl(baseUrl: string, path: string, query?: Record<string, string | number | undefined>): string {\n const base = baseUrl.replace(/\\/+$/, \"\");\n const p = path.startsWith(\"/\") ? path : `/${path}`;\n let url = `${base}${p}`;\n if (query) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n }\n return url;\n}\n\n/** Normalize a base URL: trim whitespace and drop any trailing slash. */\nexport function normalizeUrl(url: string): string {\n return url.trim().replace(/\\/+$/, \"\");\n}\n","/**\n * Minimal, dependency-free Server-Sent Events reader built on Web Streams.\n *\n * Handles the cases that commonly break naive parsers:\n * - a `data:` line split across two TCP chunks (chunk boundaries)\n * - multiple events arriving in a single chunk\n * - both CRLF and LF line endings (and lone CR)\n * - a final event that is not terminated by a trailing newline\n * - the `[DONE]` terminator\n * - abort signals\n */\n\nexport interface SSEEvent {\n /** The concatenated `data:` payload for this event (trimmed of the leading space). */\n data: string;\n}\n\ninterface ReadOptions {\n signal?: AbortSignal;\n /** When true, stop after the first `[DONE]` data value. Default true. */\n stopOnDone?: boolean;\n}\n\n/**\n * Read raw SSE events from a `ReadableStream<Uint8Array>`.\n * Yields one object per event with its combined `data` payload.\n */\nexport async function* readSSEEvents(\n body: ReadableStream<Uint8Array>,\n opts: ReadOptions = {},\n): AsyncGenerator<SSEEvent, void, unknown> {\n const stopOnDone = opts.stopOnDone ?? true;\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let dataLines: string[] = [];\n\n // Abort wiring: cancel the underlying stream promptly when the signal fires.\n const onAbort = () => {\n void reader.cancel().catch(() => {});\n };\n if (opts.signal) {\n if (opts.signal.aborted) {\n await reader.cancel().catch(() => {});\n return;\n }\n opts.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const dispatch = (): SSEEvent | null => {\n if (dataLines.length === 0) return null;\n const data = dataLines.join(\"\\n\");\n dataLines = [];\n return { data };\n };\n\n const processLine = (line: string): SSEEvent | null => {\n if (line === \"\") return dispatch(); // blank line = event boundary\n if (line.startsWith(\":\")) return null; // comment\n if (line.startsWith(\"data:\")) {\n let value = line.slice(5);\n if (value.startsWith(\" \")) value = value.slice(1);\n dataLines.push(value);\n return null;\n }\n // Ignore event:/id:/retry: and unknown fields.\n return null;\n };\n\n try {\n for (;;) {\n if (opts.signal?.aborted) break;\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let s = splitFirstLine(buffer);\n while (s !== null) {\n const ev = processLine(s.line);\n if (ev) {\n if (stopOnDone && ev.data.trim() === \"[DONE]\") return;\n yield ev;\n }\n buffer = s.rest;\n s = splitFirstLine(buffer);\n }\n }\n\n // Flush any bytes still held by the decoder.\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const ev = processLine(buffer);\n if (ev && !(stopOnDone && ev.data.trim() === \"[DONE]\")) yield ev;\n }\n // Flush a final event that had no terminating blank line.\n const tail = dispatch();\n if (tail && !(stopOnDone && tail.data.trim() === \"[DONE]\")) yield tail;\n } finally {\n if (opts.signal) opts.signal.removeEventListener(\"abort\", onAbort);\n try {\n reader.releaseLock();\n } catch {\n /* already released */\n }\n }\n}\n\n/** Split the first complete line (LF, CRLF, or lone CR) out of `buf`. */\nfunction splitFirstLine(buf: string): { line: string; rest: string } | null {\n const nl = buf.indexOf(\"\\n\");\n const cr = buf.indexOf(\"\\r\");\n let end = -1;\n let termLen = 0;\n if (nl !== -1 && (cr === -1 || nl < cr)) {\n end = nl;\n termLen = 1;\n } else if (cr !== -1) {\n end = cr;\n termLen = buf[cr + 1] === \"\\n\" ? 2 : 1;\n }\n if (end === -1) return null;\n return { line: buf.slice(0, end), rest: buf.slice(end + termLen) };\n}\n\n/** Parse a single SSE `data` payload as JSON, returning null on failure. */\nexport function parseSSEData<T = unknown>(data: string): T | null {\n const trimmed = data.trim();\n if (trimmed === \"\" || trimmed === \"[DONE]\") return null;\n try {\n return JSON.parse(trimmed) as T;\n } catch {\n return null; // malformed JSON is skipped, not fatal\n }\n}\n","import type { Transport } from \"./http.js\";\nimport { abortError, timeoutError } from \"./errors.js\";\nimport type { Task, WaitOptions } from \"./types.js\";\n\n/** Statuses at which a task will not change again. */\nconst TERMINAL_TASK_STATUSES = new Set([\"completed\", \"failed\", \"cancelled\"]);\n\nexport function isTerminalTaskStatus(status: string): boolean {\n return TERMINAL_TASK_STATUSES.has(status);\n}\n\n/**\n * A handle to a background task created via `tasks.create`.\n *\n * NOTE on execution: creating a task only enqueues it. It may stay in the\n * `queued` state until an existing worker/execution mechanism processes it —\n * this SDK does not trigger execution. `wait()` simply polls until the task\n * reaches a terminal status (or you time out / abort).\n */\nexport class TaskHandle {\n constructor(\n private readonly transport: Transport,\n public readonly taskId: string,\n ) {}\n\n /** Fetch the current task snapshot (single request). */\n get(signal?: AbortSignal): Promise<Task> {\n return this.transport.json<Task>(\"GET\", `/api/v1/tasks/${this.taskId}`, { signal });\n }\n\n /** Alias of `get()` — perform one poll and return the latest snapshot. */\n poll(signal?: AbortSignal): Promise<Task> {\n return this.get(signal);\n }\n\n /**\n * Poll until the task reaches a terminal status.\n *\n * - Uses exponential-ish backoff from `intervalMs` up to `maxIntervalMs`.\n * - Throws a QLError with code \"timeout\" if `timeoutMs` elapses first.\n * - Throws a QLError with code \"aborted\" if `signal` aborts.\n */\n async wait(opts: WaitOptions = {}): Promise<Task> {\n const intervalMs = opts.intervalMs ?? 2000;\n const maxIntervalMs = opts.maxIntervalMs ?? 15000;\n const signal = opts.signal;\n const startedAt = Date.now();\n let delay = intervalMs;\n\n for (;;) {\n if (signal?.aborted) throw abortError();\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n const task = await this.get(signal);\n opts.onTick?.(task);\n if (isTerminalTaskStatus(task.status)) return task;\n\n // Recompute timeout after the poll so a slow request doesn't overshoot silently.\n if (opts.timeoutMs !== undefined && Date.now() - startedAt >= opts.timeoutMs) {\n throw timeoutError(opts.timeoutMs);\n }\n\n await sleep(delay, signal);\n delay = Math.min(maxIntervalMs, Math.round(delay * 1.5));\n }\n }\n}\n\n/** Abort-aware sleep. Rejects with an abort error if `signal` fires first. */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(abortError());\n return;\n }\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n cleanup();\n reject(abortError());\n };\n const cleanup = () => {\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n };\n if (signal) signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n","import { createTransport, normalizeUrl, type Transport } from \"./http.js\";\nimport { QLError } from \"./errors.js\";\nimport { readSSEEvents, parseSSEData } from \"./sse.js\";\nimport { TaskHandle } from \"./task.js\";\nimport type {\n AgentDetail,\n AgentListResult,\n CapabilitiesResult,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n HistoryPage,\n HistoryParams,\n GeneratedImage,\n ImageGenerateInput,\n ImageGenerateResult,\n ImageModelInfo,\n ImageModelsResult,\n ImageReferenceInput,\n ImageTier,\n ImageUsage,\n RunCapabilityInput,\n RunCapabilityResult,\n StreamOptions,\n Task,\n TaskCreateInput,\n TaskCreated,\n WorkflowRun,\n WorkflowRunInput,\n WorkflowRunStart,\n Workspace,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://app.quantonlabs.com\";\n\nexport interface QLClientOptions {\n /** Your Quanton Labs API key (Bearer). Never logged or exposed. */\n apiKey: string;\n /** API base URL. Defaults to `QL_BASE_URL` if set, else https://app.quantonlabs.com. */\n baseUrl?: string;\n /** Override the global fetch (for tests, proxies, or custom runtimes). */\n fetch?: typeof fetch;\n}\n\n/** Workspace namespace. */\nexport class WorkspaceApi {\n constructor(private readonly t: Transport) {}\n /** GET /api/v1/workspace */\n get(): Promise<Workspace> {\n return this.t.json<Workspace>(\"GET\", \"/api/v1/workspace\");\n }\n}\n\n/** Agents namespace. */\nexport class AgentsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/agents — list the global agent registry. */\n list(): Promise<AgentListResult> {\n return this.t.json<AgentListResult>(\"GET\", \"/api/v1/agents\");\n }\n\n /** GET /api/v1/agents/:agentId — agent detail + capabilities. */\n get(agentId: string): Promise<AgentDetail> {\n return this.t.json<AgentDetail>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}`);\n }\n\n /** GET /api/v1/agents/:agentId/capabilities */\n capabilities(agentId: string): Promise<CapabilitiesResult> {\n return this.t.json<CapabilitiesResult>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities`);\n }\n\n /** POST /api/v1/agents/:agentId/capabilities/run — run a feature. */\n runCapability(agentId: string, input: RunCapabilityInput): Promise<RunCapabilityResult> {\n return this.t.json<RunCapabilityResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/capabilities/run`, {\n body: { capId: input.capId, params: input.params ?? {} },\n });\n }\n\n /** POST /api/v1/agents/chat — non-streaming chat. */\n chat(input: ChatInput): Promise<ChatResult> {\n return this.t.json<ChatResult>(\"POST\", \"/api/v1/agents/chat\", { body: input });\n }\n\n /**\n * POST /api/v1/agents/chat/stream — streaming chat as an async iterable.\n *\n * Yields incremental `delta` events (text and/or reasoning) followed by a\n * single `done` event with the fully accumulated text. Stop early by passing\n * an `AbortSignal` (see StreamOptions) or breaking out of the loop.\n */\n chatStream(input: ChatInput, opts: StreamOptions = {}): AsyncIterable<ChatStreamEvent> {\n return this.chatStreamImpl(input, opts);\n }\n\n /** GET /api/v1/agents/:agentId/messages — paginated history (newest first). */\n history(agentId: string, params: HistoryParams = {}): Promise<HistoryPage> {\n return this.t.json<HistoryPage>(\"GET\", `/api/v1/agents/${encodeURIComponent(agentId)}/messages`, {\n query: { limit: params.limit, before: params.before, userId: params.userId },\n });\n }\n\n private async *chatStreamImpl(input: ChatInput, opts: StreamOptions): AsyncGenerator<ChatStreamEvent> {\n const body = await this.t.stream(\"POST\", \"/api/v1/agents/chat/stream\", { body: input, signal: opts.signal });\n let content = \"\";\n let reasoning = \"\";\n for await (const ev of readSSEEvents(body, { signal: opts.signal })) {\n const payload = parseSSEData<{ choices?: { delta?: { content?: string; reasoning?: string; reasoning_content?: string } }[] }>(ev.data);\n if (!payload) continue; // [DONE] or malformed chunk\n const delta = payload.choices?.[0]?.delta;\n const text = typeof delta?.content === \"string\" ? delta.content : undefined;\n const reason =\n typeof delta?.reasoning === \"string\"\n ? delta.reasoning\n : typeof delta?.reasoning_content === \"string\"\n ? delta.reasoning_content\n : undefined;\n if (text) content += text;\n if (reason) reasoning += reason;\n if (text || reason) yield { type: \"delta\", content: text, reasoning: reason };\n }\n yield { type: \"done\", content, reasoning: reasoning || undefined };\n }\n}\n\n/** Workflows namespace. */\nexport class WorkflowsApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/workflows/:id/run — start a run (returns immediately, HTTP 202). */\n run(workflowId: string, input: WorkflowRunInput = {}): Promise<WorkflowRunStart> {\n return this.t.json<WorkflowRunStart>(\"POST\", `/api/v1/workflows/${encodeURIComponent(workflowId)}/run`, { body: input });\n }\n\n /** GET /api/v1/workflow-runs/:runId — poll a run. */\n getRun(runId: string): Promise<WorkflowRun> {\n return this.t.json<WorkflowRun>(\"GET\", `/api/v1/workflow-runs/${encodeURIComponent(runId)}`);\n }\n}\n\n/** Tasks namespace. */\nexport class TasksApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/tasks — create (enqueue) a background task. Does NOT trigger execution. */\n create(input: TaskCreateInput): Promise<TaskCreated> {\n return this.t.json<TaskCreated>(\"POST\", \"/api/v1/tasks\", { body: input });\n }\n\n /** GET /api/v1/tasks/:taskId — fetch the current snapshot. */\n get(taskId: string, signal?: AbortSignal): Promise<Task> {\n return this.t.json<Task>(\"GET\", `/api/v1/tasks/${encodeURIComponent(taskId)}`, { signal });\n }\n\n /** Get a handle for polling / waiting on a task (poll(), wait()). */\n handle(taskId: string): TaskHandle {\n return new TaskHandle(this.t, taskId);\n }\n}\n\n/** Images namespace (tiered image generation). */\nexport class ImagesApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/images/models — list tiered image models + runtime availability. */\n listModels(): Promise<ImageModelsResult> {\n return this.t.json<ImageModelsResult>(\"GET\", \"/api/v1/images/models\");\n }\n\n /** POST /api/v1/agents/:agentId/images — generate image(s) via a tiered model. */\n generate(agentId: string, input: ImageGenerateInput): Promise<ImageGenerateResult> {\n return this.t.json<ImageGenerateResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/images`, { body: input });\n }\n}\n\nfunction readEnvBaseUrl(): string | undefined {\n try {\n if (typeof process !== \"undefined\" && process?.env) {\n return process.env.QL_BASE_URL || undefined;\n }\n } catch {\n /* non-Node runtime */\n }\n return undefined;\n}\n\n/**\n * The public client. Example:\n * const ql = new QLClient({ apiKey: process.env.QL_API_KEY });\n * const agents = await ql.agents.list();\n */\nexport class QLClient {\n readonly workspace: WorkspaceApi;\n readonly agents: AgentsApi;\n readonly workflows: WorkflowsApi;\n readonly tasks: TasksApi;\n readonly images: ImagesApi;\n\n private readonly transport: Transport;\n private readonly base: string;\n\n constructor(opts: QLClientOptions) {\n if (!opts || typeof opts.apiKey !== \"string\" || opts.apiKey.length === 0) {\n throw new QLError(\"apiKey is required\", { code: \"validation_error\" });\n }\n this.base = normalizeUrl(opts.baseUrl ?? readEnvBaseUrl() ?? DEFAULT_BASE_URL);\n const fetchImpl = (opts.fetch ?? globalThis.fetch).bind(globalThis);\n this.transport = createTransport({ apiKey: opts.apiKey, baseUrl: this.base, fetchImpl });\n this.workspace = new WorkspaceApi(this.transport);\n this.agents = new AgentsApi(this.transport);\n this.workflows = new WorkflowsApi(this.transport);\n this.tasks = new TasksApi(this.transport);\n this.images = new ImagesApi(this.transport);\n }\n\n /** The normalized base URL in use (not secret). */\n get baseUrl(): string {\n return this.base;\n }\n}\n","/**\n * Public request/response types for the Quanton Labs agent platform API (v1).\n *\n * These mirror the verified Phase 1 endpoints. The public surface is enveloped:\n * success -> { ok: true, data }\n * error -> { ok: false, error: { code, message } }\n * The SDK unwraps `data` for you and surfaces errors as a typed QLError.\n */\n\n/** Stable API error codes emitted by the backend. */\nexport const API_ERROR_CODES = {\n unauthorized: \"unauthorized\",\n forbidden: \"forbidden\",\n notFound: \"not_found\",\n validationError: \"validation_error\",\n conflict: \"conflict\",\n internalError: \"internal_error\",\n} as const;\n\nexport type ApiErrorCode = (typeof API_ERROR_CODES)[keyof typeof API_ERROR_CODES];\n\n/** A single message in a chat conversation. */\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\n/** Input for `agents.chat` and `agents.chatStream`. */\nexport interface ChatInput {\n agentId: string;\n messages: ChatMessage[];\n /** Optional internal user id; defaults to the key's workspace when omitted. */\n userId?: string;\n /** Optional OpenRouter response-format hint (e.g. `{ type: \"json_object\" }`). */\n response_format?: Record<string, unknown>;\n}\n\n/** Result of a non-streaming chat call. */\nexport interface ChatResult {\n content: string;\n toolCalls: number;\n iterations: number;\n /** Human-readable duration string, e.g. \"2.91s\". */\n duration: string;\n}\n\n/**\n * A single event yielded by `agents.chatStream`.\n * - `delta`: an incremental piece of the streamed response (text and/or reasoning).\n * - `done`: emitted once at the end with the fully accumulated text.\n */\nexport type ChatStreamEvent =\n | { type: \"delta\"; content?: string; reasoning?: string }\n | { type: \"done\"; content: string; reasoning?: string };\n\n/** Options accepted by streaming methods. */\nexport interface StreamOptions {\n /** Abort the in-flight request/stream at any time. */\n signal?: AbortSignal;\n}\n\n/** A conversation-history page (newest first). */\nexport interface MessageItem {\n id: string;\n role: string;\n content: string | null;\n reasoning?: string;\n toolCalls: unknown[];\n status: string;\n timestamp: string | Date;\n}\n\nexport interface HistoryPage {\n agentId: string;\n limit: number;\n /** Cursor for the next page (pass as `before`); null when exhausted. */\n nextBefore: string | null;\n items: MessageItem[];\n}\n\n/** Query params for `agents.history`. */\nexport interface HistoryParams {\n /** Page size, 1..100 (default 20 server-side). */\n limit?: number;\n /** Cursor = id of the last item on the previous page. */\n before?: string;\n /** Optional internal user id filter. */\n userId?: string;\n}\n\n/** Agent summary as returned by `agents.list`. */\nexport interface AgentSummary {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n capabilityCount: number;\n}\n\nexport interface AgentListResult {\n agents: AgentSummary[];\n}\n\n/** A schema-driven capability parameter (rendered as a form field in the UI). */\nexport type CapParamKind = \"text\" | \"textarea\" | \"number\" | \"select\" | \"boolean\" | \"json\";\n\nexport interface CapabilityParam {\n key: string;\n label: string;\n kind: CapParamKind;\n placeholder?: string;\n options?: { value: string; label: string }[];\n required?: boolean;\n hint?: string;\n rows?: number;\n [key: string]: unknown;\n}\n\n/** A pre-filled example input set (suggestion chip). */\nexport interface CapabilityTemplate {\n label: string;\n values: Record<string, unknown>;\n}\n\n/** A client-safe capability descriptor (the server-side `run` is stripped). */\nexport interface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n category: string;\n icon?: string;\n badge?: string;\n params: CapabilityParam[];\n templates?: CapabilityTemplate[];\n metrics?: string[];\n tableKey?: string;\n outputHint?: string;\n [key: string]: unknown;\n}\n\n/** Agent detail + its capabilities, as returned by `agents.get`. */\nexport interface AgentDetail {\n agent: {\n id: string;\n name: string;\n domain: string;\n description: string;\n icon: string;\n tags: string[];\n };\n capabilities: CapabilityInfo[];\n}\n\n/** Result of `agents.capabilities`. */\nexport interface CapabilitiesResult {\n agentId: string;\n capabilities: CapabilityInfo[];\n}\n\n/** Input for `agents.runCapability`. */\nexport interface RunCapabilityInput {\n capId: string;\n /** Capability-specific parameters (see the capability's `params`). */\n params?: Record<string, unknown>;\n}\n\n/**\n * The result of running a capability. A discriminated union matching the\n * backend — a feature can return text, structured JSON, HTML, or a file URL.\n */\nexport type CapabilityResult =\n | { type: \"text\"; content: string }\n | { type: \"json\"; data: unknown }\n | { type: \"html\"; html: string }\n | { type: \"file\"; url: string; filename: string; mime: string };\n\n/** Result envelope for `agents.runCapability`. */\nexport interface RunCapabilityResult {\n result: CapabilityResult;\n}\n\n/** The workspace object as returned by the public API (redacted). */\nexport interface Workspace {\n _id: string;\n name: string;\n plan?: string;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n}\n\n/** Input for `workflows.run`. */\nexport interface WorkflowRunInput {\n /** Optional workflow input payload. */\n input?: Record<string, unknown>;\n}\n\n/** Returned immediately when a workflow run is started (HTTP 202). */\nexport interface WorkflowRunStart {\n runId: string;\n status: \"running\";\n}\n\nexport type WorkflowRunStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | (string & {});\n\n/** A workflow run snapshot, as returned by `workflows.getRun`. */\nexport interface WorkflowRun {\n runId: string;\n status: WorkflowRunStatus;\n output: unknown | null;\n error?: string;\n durationMs?: number;\n startedAt: string | Date;\n finishedAt: string | Date | null;\n}\n\nexport type TaskPriority = \"low\" | \"medium\" | \"high\" | \"urgent\";\n\n/** Input for `tasks.create`. */\nexport interface TaskCreateInput {\n agentId: string;\n title: string;\n description?: string;\n /** Arbitrary payload handed to the agent. */\n input?: unknown;\n priority?: TaskPriority;\n}\n\n/** Returned when a task is created (HTTP 201). */\nexport interface TaskCreated {\n taskId: string;\n status: TaskStatus;\n}\n\nexport type TaskStatus =\n | \"queued\"\n | \"running\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"retrying\"\n | (string & {});\n\n/** A task snapshot, as returned by `tasks.get`. */\nexport interface Task {\n taskId: string;\n status: TaskStatus;\n title: string;\n progress?: unknown;\n result?: unknown;\n output?: unknown;\n error?: string;\n createdAt: string | Date;\n completedAt: string | Date | null;\n}\n\n/** Options for polling / waiting on a task. */\nexport interface WaitOptions {\n /** Base delay between polls in ms (default 2000). Grows with backoff up to `maxIntervalMs`. */\n intervalMs?: number;\n /** Upper bound for the backoff delay in ms (default 15000). */\n maxIntervalMs?: number;\n /** Stop waiting after this many ms and throw a timeout error. Omit to wait until terminal or abort. */\n timeoutMs?: number;\n /** Abort polling at any time. */\n signal?: AbortSignal;\n /** Called after each poll with the latest task snapshot. */\n onTick?: (task: Task) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Images — tiered image generation\n// ---------------------------------------------------------------------------\n\nexport type ImageTier = \"standard\" | \"professional\" | \"advanced\";\n\n/** A single pricing entry for an image model. */\nexport interface ImagePricingEntry {\n /** What is billed, e.g. \"output_image\" / \"input_image\". */\n billable: string;\n /** Billing unit: flat per image, or per output-image token. */\n unit: \"image\" | \"token\";\n costUsd: number;\n /** Optional sub-variant (e.g. a resolution tier or quality variant). */\n variant?: string;\n}\n\n/** A tiered image-generation model as returned by `images.listModels`. */\nexport interface ImageModelInfo {\n id: string;\n name: string;\n tier: ImageTier;\n description: string;\n /** Short best-use-case label for UI copy. */\n bestFor: string;\n referenceImageSupport: boolean;\n maxReferenceImages: number;\n /** Empty array = the model does not accept a resolution parameter. */\n supportedResolutions: string[];\n supportedAspectRatios: string[];\n /** Max value for the `n` (images per request) parameter. */\n maxImages: number;\n pricing: {\n /** Human-readable summary, e.g. \"$0.018 / image\". */\n summary: string;\n entries: ImagePricingEntry[];\n };\n recommended: boolean;\n /** Static registry flag (always reflects the shipped registry). */\n enabled: boolean;\n /** Runtime availability — live when `verified` is true. */\n available: boolean;\n /** Whether `available` reflects a live OpenRouter check. */\n verified: boolean;\n}\n\n/** Result of `images.listModels`. */\nexport interface ImageModelsResult {\n models: ImageModelInfo[];\n availability: {\n /** True when the availability values came from a fresh OpenRouter check. */\n fresh: boolean;\n verifiedAt: string | Date | null;\n };\n}\n\n/** A reference image for generation. */\nexport interface ImageReferenceInput {\n /** Base64 data URL, e.g. \"data:image/png;base64,...\". */\n dataUrl: string;\n /** Optional instruction on how this reference should influence the output. */\n description?: string;\n}\n\n/** Input for `images.generate`. */\nexport interface ImageGenerateInput {\n prompt: string;\n /** Explicit OpenRouter model id (wins over `tier`). */\n model?: string;\n /** Tier to resolve a model from (used when `model` is omitted). */\n tier?: ImageTier | string;\n references?: ImageReferenceInput[];\n resolution?: string;\n aspect_ratio?: string;\n n?: number;\n}\n\n/** A single generated image. */\nexport interface GeneratedImage {\n /** Base64-encoded image bytes (no data-URL prefix). */\n b64Json: string;\n mediaType: string;\n}\n\n/** Token + cost usage for a generation, as reported by the provider. */\nexport interface ImageUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n /** Actual cost in USD. */\n cost: number;\n}\n\n/** Result of `images.generate`. */\nexport interface ImageGenerateResult {\n images: GeneratedImage[];\n usage: ImageUsage | null;\n model: string;\n tier: string;\n latencyMs: number;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ql-agent-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "TypeScript SDK for the Quanton Labs agent platform API (v1).",
5
5
  "keywords": [
6
6
  "quanton",