ql-agent-sdk 1.3.3 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -13
- package/dist/index.cjs +145 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +546 -1
- package/dist/index.d.ts +546 -1
- package/dist/index.js +145 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -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, ImagesApi, VideosApi, AudioApi, FilesApi, 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, VideoTaskHandle, isTerminalTaskStatus } from \"./task.js\";\n\nexport { API_ERROR_CODES } from \"./types.js\";\nexport type {\n ApiErrorCode,\n CreateKeyInput,\n CreateKeyResult,\n DeleteKeyResult,\n DiscardedKey,\n MintedKey,\n ChatMessage,\n ChatInput,\n ChatFile,\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 VideoTier,\n VideoPricingEntry,\n VideoModelInfo,\n VideoModelsResult,\n VideoGenerateInput,\n VideoTaskCreated,\n VideoTaskStatus,\n VideoTask,\n VideoWaitOptions,\n TtsInput,\n TtsResult,\n VoiceInfo,\n VoicesResult,\n UploadedFile,\n FileUploadOptions,\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\nexport interface FormRequestOptions {\n form: FormData;\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 /** Perform a multipart/form-data request and return the unwrapped `data` payload. */\n form<T>(path: string, opts: FormRequestOptions): 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 form<T>(path: string, reqOpts: FormRequestOptions) {\n const res = await doFormFetch(path, reqOpts);\n const text = await res.text();\n if (!res.ok) throw toHttpError(res.status, text, { method: \"POST\", url: res.url });\n return unwrap<T>(text, { method: \"POST\", 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 function doFormFetch(path: string, reqOpts: FormRequestOptions): Promise<Response> {\n const url = buildUrl(baseUrl, path);\n // No content-type header here — fetch sets the multipart boundary itself.\n const headers: Record<string, string> = {\n authorization: `Bearer ${apiKey}`,\n accept: \"application/json\",\n ...(reqOpts.headers ?? {}),\n };\n return fetchImpl(url, {\n method: \"POST\",\n headers,\n body: reqOpts.form,\n signal: reqOpts.signal,\n }).catch((err) => {\n throw toNetworkError(err, { method: \"POST\", 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, VideoTask, VideoWaitOptions } from \"./types.js\";\n\n/** Statuses at which a job will not change again (shared by tasks and video jobs). */\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\ninterface PollOptions {\n intervalMs?: number;\n maxIntervalMs?: number;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\n/**\n * Shared polling loop used by TaskHandle.wait() and VideoTaskHandle.wait().\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 */\nasync function pollUntilTerminal<T>(\n fetchSnapshot: (signal?: AbortSignal) => Promise<T>,\n isTerminal: (snapshot: T) => boolean,\n onTick: ((snapshot: T) => void) | undefined,\n opts: PollOptions,\n): Promise<T> {\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 snapshot = await fetchSnapshot(signal);\n onTick?.(snapshot);\n if (isTerminal(snapshot)) return snapshot;\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 * 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 /** Poll until the task reaches a terminal status (see pollUntilTerminal for semantics). */\n async wait(opts: WaitOptions = {}): Promise<Task> {\n return pollUntilTerminal(\n (signal) => this.get(signal),\n (task) => isTerminalTaskStatus(task.status),\n opts.onTick,\n opts,\n );\n }\n}\n\n/**\n * A handle to a video job created via `videos.generate`.\n * Polls the video-tasks endpoint until the job reaches a terminal status.\n */\nexport class VideoTaskHandle {\n constructor(\n private readonly transport: Transport,\n public readonly taskId: string,\n ) {}\n\n /** Fetch the current job snapshot (single request). */\n get(signal?: AbortSignal): Promise<VideoTask> {\n return this.transport.json<VideoTask>(\"GET\", `/api/v1/video-tasks/${encodeURIComponent(this.taskId)}`, { signal });\n }\n\n /** Alias of `get()` — perform one poll and return the latest snapshot. */\n poll(signal?: AbortSignal): Promise<VideoTask> {\n return this.get(signal);\n }\n\n /** Poll until the job reaches a terminal status (completed/failed/cancelled). */\n async wait(opts: VideoWaitOptions = {}): Promise<VideoTask> {\n return pollUntilTerminal(\n (signal) => this.get(signal),\n (task) => isTerminalTaskStatus(task.status),\n opts.onTick,\n opts,\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, VideoTaskHandle } from \"./task.js\";\nimport type {\n AgentDetail,\n AgentListResult,\n CatalogResult,\n CapabilitiesResult,\n CreateKeyInput,\n CreateKeyResult,\n DeleteKeyResult,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n HistoryPage,\n HistoryParams,\n ImageGenerateInput,\n ImageGenerateResult,\n ImageModelsResult,\n KeysResult,\n RunCapabilityInput,\n RunCapabilityResult,\n StreamOptions,\n Task,\n TaskCreateInput,\n TaskCreated,\n TtsInput,\n TtsResult,\n UploadedFile,\n FileUploadOptions,\n WorkflowRun,\n WorkflowRunInput,\n WorkflowRunStart,\n Workspace,\n VerifyKeyResult,\n VideoGenerateInput,\n VideoModelsResult,\n VideoTask,\n VideoTaskCreated,\n VoicesResult,\n WorkspaceModelsResult,\n WorkspaceModelsUpdateInput,\n WorkspaceUpdateInput,\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 /** GET /api/v1/workspace/models — current model config (OpenRouter key masked). */\n getModels(): Promise<WorkspaceModelsResult> {\n return this.t.json<WorkspaceModelsResult>(\"GET\", \"/api/v1/workspace/models\");\n }\n\n /** PATCH /api/v1/workspace — update the workspace name and/or OpenRouter model config (partial). */\n update(input: WorkspaceUpdateInput): Promise<Workspace> {\n return this.t.json<Workspace>(\"PATCH\", \"/api/v1/workspace\", { body: input });\n }\n\n /** PATCH /api/v1/workspace — convenience wrapper that only touches `config.openrouter`. */\n updateModels(input: WorkspaceModelsUpdateInput): Promise<Workspace> {\n return this.t.json<Workspace>(\"PATCH\", \"/api/v1/workspace\", { body: { config: { openrouter: input } } });\n }\n\n /** GET /api/v1/workspace/models/catalog — OpenRouter model catalog (server-side cached). */\n listCatalogModels(): Promise<CatalogResult> {\n return this.t.json<CatalogResult>(\"GET\", \"/api/v1/workspace/models/catalog\");\n }\n\n /** POST /api/v1/workspace/models/verify — check an OpenRouter key with a 1-token completion. */\n verifyOpenRouterKey(key: string, model?: string, baseUrl?: string): Promise<VerifyKeyResult> {\n return this.t.json<VerifyKeyResult>(\"POST\", \"/api/v1/workspace/models/verify\", { body: { key, model, baseUrl } });\n }\n\n /** GET /api/v1/workspace/keys — API keys with rotation metadata (rotatesAt, daysLeft). */\n listKeys(): Promise<KeysResult> {\n return this.t.json<KeysResult>(\"GET\", \"/api/v1/workspace/keys\");\n }\n\n /**\n * POST /api/v1/workspace/keys — mint a new API key for the workspace.\n * All expired, non-revoked keys (issued and legacy) are discarded first, so a\n * rotation is one call. The raw `secret` is returned exactly once.\n */\n createKey(input?: CreateKeyInput): Promise<CreateKeyResult> {\n return this.t.json<CreateKeyResult>(\"POST\", \"/api/v1/workspace/keys\", { body: input ?? {} });\n }\n\n /** DELETE /api/v1/workspace/keys/:keyId — delete an issued or legacy key. */\n deleteKey(keyId: string): Promise<DeleteKeyResult> {\n return this.t.json<DeleteKeyResult>(\"DELETE\", `/api/v1/workspace/keys/${encodeURIComponent(keyId)}`);\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<{ type?: string; stage?: string; detail?: string; choices?: { delta?: { content?: string; reasoning?: string; reasoning_content?: string } }[] }>(ev.data);\n if (!payload) continue; // [DONE] or malformed chunk\n if (payload.type === \"progress\") {\n yield { type: \"progress\", stage: payload.stage, detail: payload.detail };\n continue;\n }\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\n/** Videos namespace (tiered video generation: submit → poll). */\nexport class VideosApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/videos/models — list tiered video models + engine availability. */\n listModels(): Promise<VideoModelsResult> {\n return this.t.json<VideoModelsResult>(\"GET\", \"/api/v1/videos/models\");\n }\n\n /** POST /api/v1/agents/:agentId/videos — start a video job (returns the queued task, HTTP 202). */\n generate(agentId: string, input: VideoGenerateInput): Promise<VideoTaskCreated> {\n return this.t.json<VideoTaskCreated>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/videos`, { body: input });\n }\n\n /** GET /api/v1/video-tasks/:taskId — fetch the current job snapshot. */\n getTask(taskId: string, signal?: AbortSignal): Promise<VideoTask> {\n return this.t.json<VideoTask>(\"GET\", `/api/v1/video-tasks/${encodeURIComponent(taskId)}`, { signal });\n }\n\n /** DELETE /api/v1/video-tasks/:taskId — cancel a queued/rendering job (409 if already terminal). */\n cancelTask(taskId: string): Promise<VideoTask> {\n return this.t.json<VideoTask>(\"DELETE\", `/api/v1/video-tasks/${encodeURIComponent(taskId)}`);\n }\n\n /** Get a handle for polling / waiting on a video job (poll(), wait()). */\n handle(taskId: string): VideoTaskHandle {\n return new VideoTaskHandle(this.t, taskId);\n }\n}\n\n/** Audio namespace (text-to-speech). */\nexport class AudioApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/audio/voices — list available TTS voices. */\n voices(): Promise<VoicesResult> {\n return this.t.json<VoicesResult>(\"GET\", \"/api/v1/audio/voices\");\n }\n\n /** POST /api/v1/agents/:agentId/tts — synthesize speech (synchronous). */\n textToSpeech(agentId: string, input: TtsInput): Promise<TtsResult> {\n return this.t.json<TtsResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/tts`, { body: input });\n }\n}\n\n/** Files namespace (media uploads). */\nexport class FilesApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/files — upload a media file (multipart field \"file\"). */\n async upload(file: Blob, opts: FileUploadOptions = {}): Promise<UploadedFile> {\n const form = new FormData();\n if (opts.filename !== undefined) {\n form.append(\"file\", file, opts.filename);\n } else {\n form.append(\"file\", file);\n }\n // Coarse progress only: fetch does not expose upload byte progress.\n opts.onProgress?.(0);\n const result = await this.t.form<UploadedFile>(\"/api/v1/files\", { form });\n opts.onProgress?.(100);\n return result;\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 readonly videos: VideosApi;\n readonly audio: AudioApi;\n readonly files: FilesApi;\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 this.videos = new VideosApi(this.transport);\n this.audio = new AudioApi(this.transport);\n this.files = new FilesApi(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 model id override — wins over the workspace director-panel default. */\n modelId?: string;\n /** Optional OpenRouter response-format hint (e.g. `{ type: \"json_object\" }`). */\n response_format?: Record<string, unknown>;\n /**\n * CSV/TSV attachments (base64 payloads). The backend parses them and hands\n * the rows to the agent's tool loop as structured data for batch processing.\n */\n files?: ChatFile[];\n}\n\n/** A file attachment sent with a chat request (base64 payload; CSV/TSV only). */\nexport interface ChatFile {\n name: string;\n mime?: string;\n dataBase64: string;\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 * - `progress`: tool-loop progress frames (e.g. which tools ran) for long jobs.\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: \"progress\"; stage?: string; detail?: 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 registry model id override (wins over `model`, the workspace default, and `tier`). */\n modelId?: 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\n// ---------------------------------------------------------------------------\n// Videos — tiered video generation (async: submit → poll)\n// ---------------------------------------------------------------------------\n\nexport type VideoTier = \"standard\" | \"professional\" | \"advanced\";\n\n/** A single pricing entry for a video model. */\nexport interface VideoPricingEntry {\n /** What is billed, e.g. \"output_video\" / \"voiceover\". */\n billable: string;\n /** Billing unit: per rendered second, or flat per request. */\n unit: \"second\" | \"request\";\n costUsd: number;\n}\n\n/** A tiered video-generation model as returned by `videos.listModels`. */\nexport interface VideoModelInfo {\n id: string;\n name: string;\n tier: VideoTier;\n description: string;\n /** Short best-use-case label for UI copy. */\n bestFor: string;\n /** Execution engine (e.g. \"motion-graphics\"). */\n engine: string;\n supportsProductImages: boolean;\n maxReferenceImages: number;\n supportsReferenceVideos: boolean;\n maxReferenceVideos: number;\n supportedAspectRatios: string[];\n supportedResolutions: string[];\n /** Inclusive [min, max] duration in seconds. */\n durationRange: [number, number];\n voiceoverSupport: boolean;\n pricing: {\n summary: string;\n entries: VideoPricingEntry[];\n };\n recommended: boolean;\n enabled: boolean;\n /** Runtime engine availability (render toolchain present). */\n available: boolean;\n}\n\n/** Result of `videos.listModels`. */\n/** An OpenRouter AI video model (from the public GET /api/v1/videos/models catalog). */\nexport interface OrVideoModel {\n id: string;\n canonical_slug?: string | null;\n hugging_face_id?: string | null;\n name: string;\n created?: number;\n description?: string;\n /** e.g. [\"480p\",\"720p\"] — null when the provider does not publish it. */\n supported_resolutions?: string[] | null;\n /** e.g. [\"16:9\",\"9:16\"] — null when the model decides. */\n supported_aspect_ratios?: string[] | null;\n /** e.g. [\"854x480\",\"1280x720\"]. */\n supported_sizes?: string[] | null;\n /** Discrete list of allowed durations in seconds (e.g. [3,5] or [1..15]). */\n supported_durations?: number[] | null;\n supported_frame_images?: (\"first_frame\" | \"last_frame\")[] | null;\n upscale_factor?: number | null;\n creativity?: number | null;\n /** Native audio generation (null = model decides / unknown). */\n generate_audio?: boolean | null;\n seed?: boolean | null;\n /** Per-SKU price strings — \"cents_*\" keys are in cents, the rest in USD. */\n pricing_skus?: Record<string, string> | null;\n allowed_passthrough_parameters?: string[];\n}\n\nexport interface VideoModelsResult {\n models: VideoModelInfo[];\n engine: {\n available: boolean;\n detail: string;\n };\n /** Live OpenRouter AI video catalog (may be empty when the upstream is unreachable). */\n openrouterModels?: OrVideoModel[];\n}\n\n/** Input for `videos.generate`. */\nexport interface VideoGenerateInput {\n /** The creative brief / script for the video. */\n prompt: string;\n /** Explicit registry model id override (wins over `model`, the workspace default, and `tier`). */\n modelId?: string;\n /** Explicit registry model id (wins over `tier`). */\n model?: string;\n /** Tier to resolve a model from (used when `model` is omitted). */\n tier?: VideoTier | string;\n /** Product/reference images — base64 data URLs or https URLs. Order defines IMG_0..N. */\n images_list?: string[];\n /** Reference (style) videos — https URLs only (upload local files via `files.upload`). */\n video_files?: string[];\n /** e.g. \"16:9\", \"9:16\", \"1:1\". Default \"16:9\". */\n aspect_ratio?: string;\n /** Duration in seconds (must be within the model's durationRange). */\n duration?: number;\n /** e.g. \"720p\" | \"1080p\". Default \"720p\". */\n resolution?: string;\n /** Bake an ElevenLabs voiceover into the render (requires `narration`). */\n generate_audio?: boolean;\n /** Voiceover text (used when `generate_audio` is true). Max 3000 chars. */\n narration?: string;\n}\n\n/** Returned when a video job is created (HTTP 202). */\nexport interface VideoTaskCreated {\n taskId: string;\n status: \"queued\";\n}\n\nexport type VideoTaskStatus =\n | \"queued\"\n | \"rendering\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | (string & {});\n\n/** A video job snapshot, as returned by `videos.getTask`. */\nexport interface VideoTask {\n taskId: string;\n status: VideoTaskStatus;\n progress?: {\n current: number;\n total: number;\n message?: string;\n };\n /** Served media path (e.g. /generated/video-….mp4) once completed. */\n outputUrl?: string;\n mime?: string;\n ext?: string;\n /** Actual rendered duration in seconds. */\n durationSec?: number;\n error?: string;\n model?: string;\n tier?: string;\n latencyMs?: number;\n createdAt: string | Date;\n completedAt: string | Date | null;\n}\n\n/** Options for polling / waiting on a video job. */\nexport interface VideoWaitOptions {\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 job snapshot. */\n onTick?: (task: VideoTask) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Audio — text-to-speech\n// ---------------------------------------------------------------------------\n\n// ─── Workspace model configuration (director panel) ──────────────────────\n\n/** Per-role model defaults as configured in the director panel. */\nexport interface WorkspaceModelConfig {\n status: \"active\" | \"inactive\";\n /** Masked OpenRouter key — the raw key is never returned by the API. */\n keyMasked: string;\n /** Optional chat-completions base URL override (empty = public OpenRouter API). */\n baseUrl: string;\n reasoning: string;\n instruct: string;\n response: string;\n vision: string;\n image: string;\n video: string;\n /** Ordered per-role fallback model ids (max 3 each), tried on provider failure. */\n fallbacks: {\n reasoning: string[];\n instruct: string[];\n response: string[];\n vision: string[];\n image: string[];\n video: string[];\n };\n}\n\n/** Result of `workspace.getModels`. */\nexport interface WorkspaceModelsResult {\n openrouter: WorkspaceModelConfig;\n}\n\n/** Partial model-config update for `workspace.update` / `workspace.updateModels`. */\nexport interface WorkspaceModelsUpdateInput {\n status?: \"active\" | \"inactive\";\n /** Full OpenRouter API key to store/rotate. Omit to leave unchanged. */\n key?: string;\n /** Optional chat-completions base URL override (defaults to the public OpenRouter API). */\n baseUrl?: string;\n reasoning?: string;\n instruct?: string;\n response?: string;\n vision?: string;\n image?: string;\n video?: string;\n /** Ordered per-role fallback model ids (max 3 each). */\n fallbacks?: {\n reasoning?: string[];\n instruct?: string[];\n response?: string[];\n vision?: string[];\n image?: string[];\n video?: string[];\n };\n}\n\n/** Input for `workspace.update`. */\nexport interface WorkspaceUpdateInput {\n name?: string;\n config?: { openrouter?: WorkspaceModelsUpdateInput };\n}\n\n/** A single OpenRouter catalog model. */\nexport interface CatalogModel {\n id: string;\n name: string;\n contextLength: number | null;\n promptPrice: number | null;\n completionPrice: number | null;\n}\n\n/** Result of `workspace.listCatalogModels`. */\nexport interface CatalogResult {\n models: CatalogModel[];\n /** True when the upstream fetch failed and a cached snapshot was served. */\n stale?: boolean;\n}\n\n/** Result of `workspace.verifyOpenRouterKey`. */\nexport interface VerifyKeyResult {\n valid: boolean;\n error?: string;\n}\n\n/** A v1 API key with rotation metadata (hashes never leave the server). */\nexport interface ApiKeyInfo {\n _id: string;\n name: string;\n prefix: string;\n scopes: string[];\n createdAt: string | Date;\n lastUsedAt: string | Date | null;\n revokedAt: string | Date | null;\n /** When the key is auto-deleted (createdAt + lifetime). */\n rotatesAt: string | Date;\n /** Whole days remaining until rotation (0 when expired). */\n daysLeft: number;\n}\n\n/** Result of `workspace.listKeys`. */\nexport interface KeysResult {\n /** Key lifetime in days before auto-deletion. */\n lifetimeDays: number;\n keys: ApiKeyInfo[];\n}\n\n/** Input for `workspace.createKey`. */\nexport interface CreateKeyInput {\n /** Display name for the key (defaults to \"API Key\" server-side). */\n name?: string;\n}\n\n/** A freshly minted key. `secret` is the raw key — shown exactly once, never stored in plaintext. */\nexport interface MintedKey {\n id: string;\n name: string;\n prefix: string;\n secret: string;\n}\n\n/** An expired key that was discarded automatically when a new key was minted. */\nexport interface DiscardedKey {\n _id?: string;\n name: string;\n prefix: string;\n /** True when the key was embedded on the workspace document (pre-ApiKey-collection era). */\n legacy: boolean;\n}\n\n/** Result of `workspace.createKey`. */\nexport interface CreateKeyResult {\n key: MintedKey;\n /** Expired, non-revoked keys discarded as part of the rotation. */\n discarded: DiscardedKey[];\n}\n\n/** Result of `workspace.deleteKey`. */\nexport interface DeleteKeyResult {\n deleted: {\n id: string;\n name: string;\n prefix: string;\n legacy: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n\n/** Input for `audio.textToSpeech`. */\nexport interface TtsInput {\n /** Text to synthesize (max 3000 chars). */\n text: string;\n /** ElevenLabs voice id (list via `audio.voices`). Defaults to the platform voice. */\n voiceId?: string;\n /** Voice stability 0..1 (default 0.5). */\n stability?: number;\n /** Similarity boost 0..1 (default 0.75). */\n similarityBoost?: number;\n}\n\n/** Result of `audio.textToSpeech`. */\nexport interface TtsResult {\n /** Served audio path (e.g. /generated/tts-….mp3). */\n url: string;\n voiceId: string;\n modelId: string;\n bytes: number;\n latencyMs: number;\n}\n\n/** A single ElevenLabs voice as returned by `audio.voices`. */\nexport interface VoiceInfo {\n id: string;\n name: string;\n}\n\n/** Result of `audio.voices`. */\nexport interface VoicesResult {\n voices: VoiceInfo[];\n /** \"live\" = fetched from the provider; \"none\" = no provider key configured. */\n source: \"live\" | \"none\";\n note?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Files — media uploads\n// ---------------------------------------------------------------------------\n\n/** Result of `files.upload`. */\nexport interface UploadedFile {\n /** Stable served path (e.g. /uploads/<workspace>/<file>) usable as a media input URL. */\n url: string;\n filename: string;\n size: number;\n contentType: string;\n}\n\n/** Options for `files.upload`. */\nexport interface FileUploadOptions {\n /** Override the stored display name (extension is kept from the file). */\n filename?: string;\n /**\n * Coarse progress callback. Fetch does not expose upload byte progress, so this\n * reports 0 at start and 100 on completion.\n */\n onProgress?: (percent: number) => void;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACgBO,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;;;ACjGO,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,KAAQ,MAAc,SAA6B;AACvD,YAAM,MAAM,MAAM,YAAY,MAAM,OAAO;AAC3C,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI,CAAC,IAAI,GAAI,OAAM,YAAY,IAAI,QAAQ,MAAM,EAAE,QAAQ,QAAQ,KAAK,IAAI,IAAI,CAAC;AACjF,aAAO,OAAU,MAAM,EAAE,QAAQ,QAAQ,KAAK,IAAI,IAAI,CAAC;AAAA,IACzD;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;AAEA,WAAS,YAAY,MAAc,SAAgD;AACjF,UAAM,MAAM,SAAS,SAAS,IAAI;AAElC,UAAM,UAAkC;AAAA,MACtC,eAAe,UAAU,MAAM;AAAA,MAC/B,QAAQ;AAAA,MACR,GAAI,QAAQ,WAAW,CAAC;AAAA,IAC1B;AACA,WAAO,UAAU,KAAK;AAAA,MACpB,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,QAAQ;AAAA,MACd,QAAQ,QAAQ;AAAA,IAClB,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,YAAM,eAAe,KAAK,EAAE,QAAQ,QAAQ,IAAI,CAAC;AAAA,IACnD,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;;;ACvIA,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;AAgBA,eAAe,kBACb,eACA,YACA,QACA,MACY;AACZ,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAM,SAAS,KAAK;AACpB,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,QAAQ;AAEZ,aAAS;AACP,QAAI,QAAQ,QAAS,OAAM,WAAW;AACtC,QAAI,KAAK,cAAc,UAAa,KAAK,IAAI,IAAI,aAAa,KAAK,WAAW;AAC5E,YAAM,aAAa,KAAK,SAAS;AAAA,IACnC;AAEA,UAAM,WAAW,MAAM,cAAc,MAAM;AAC3C,aAAS,QAAQ;AACjB,QAAI,WAAW,QAAQ,EAAG,QAAO;AAGjC,QAAI,KAAK,cAAc,UAAa,KAAK,IAAI,IAAI,aAAa,KAAK,WAAW;AAC5E,YAAM,aAAa,KAAK,SAAS;AAAA,IACnC;AAEA,UAAM,MAAM,OAAO,MAAM;AACzB,YAAQ,KAAK,IAAI,eAAe,KAAK,MAAM,QAAQ,GAAG,CAAC;AAAA,EACzD;AACF;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,EAGA,MAAM,KAAK,OAAoB,CAAC,GAAkB;AAChD,WAAO;AAAA,MACL,CAAC,WAAW,KAAK,IAAI,MAAM;AAAA,MAC3B,CAAC,SAAS,qBAAqB,KAAK,MAAM;AAAA,MAC1C,KAAK;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YACmB,WACD,QAChB;AAFiB;AACD;AAAA,EACf;AAAA;AAAA,EAGH,IAAI,QAA0C;AAC5C,WAAO,KAAK,UAAU,KAAgB,OAAO,uBAAuB,mBAAmB,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;AAAA,EACnH;AAAA;AAAA,EAGA,KAAK,QAA0C;AAC7C,WAAO,KAAK,IAAI,MAAM;AAAA,EACxB;AAAA;AAAA,EAGA,MAAM,KAAK,OAAyB,CAAC,GAAuB;AAC1D,WAAO;AAAA,MACL,CAAC,WAAW,KAAK,IAAI,MAAM;AAAA,MAC3B,CAAC,SAAS,qBAAqB,KAAK,MAAM;AAAA,MAC1C,KAAK;AAAA,MACL;AAAA,IACF;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;;;AClGO,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;AAAA;AAAA,EAGA,YAA4C;AAC1C,WAAO,KAAK,EAAE,KAA4B,OAAO,0BAA0B;AAAA,EAC7E;AAAA;AAAA,EAGA,OAAO,OAAiD;AACtD,WAAO,KAAK,EAAE,KAAgB,SAAS,qBAAqB,EAAE,MAAM,MAAM,CAAC;AAAA,EAC7E;AAAA;AAAA,EAGA,aAAa,OAAuD;AAClE,WAAO,KAAK,EAAE,KAAgB,SAAS,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,MAAM,EAAE,EAAE,CAAC;AAAA,EACzG;AAAA;AAAA,EAGA,oBAA4C;AAC1C,WAAO,KAAK,EAAE,KAAoB,OAAO,kCAAkC;AAAA,EAC7E;AAAA;AAAA,EAGA,oBAAoB,KAAa,OAAgB,SAA4C;AAC3F,WAAO,KAAK,EAAE,KAAsB,QAAQ,mCAAmC,EAAE,MAAM,EAAE,KAAK,OAAO,QAAQ,EAAE,CAAC;AAAA,EAClH;AAAA;AAAA,EAGA,WAAgC;AAC9B,WAAO,KAAK,EAAE,KAAiB,OAAO,wBAAwB;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,OAAkD;AAC1D,WAAO,KAAK,EAAE,KAAsB,QAAQ,0BAA0B,EAAE,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,EAC7F;AAAA;AAAA,EAGA,UAAU,OAAyC;AACjD,WAAO,KAAK,EAAE,KAAsB,UAAU,0BAA0B,mBAAmB,KAAK,CAAC,EAAE;AAAA,EACrG;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+J,GAAG,IAAI;AACtL,UAAI,CAAC,QAAS;AACd,UAAI,QAAQ,SAAS,YAAY;AAC/B,cAAM,EAAE,MAAM,YAAY,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO;AACvE;AAAA,MACF;AACA,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;AAGO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,aAAyC;AACvC,WAAO,KAAK,EAAE,KAAwB,OAAO,uBAAuB;AAAA,EACtE;AAAA;AAAA,EAGA,SAAS,SAAiB,OAAyD;AACjF,WAAO,KAAK,EAAE,KAA0B,QAAQ,kBAAkB,mBAAmB,OAAO,CAAC,WAAW,EAAE,MAAM,MAAM,CAAC;AAAA,EACzH;AACF;AAGO,IAAM,YAAN,MAAgB;AAAA,EACrB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,aAAyC;AACvC,WAAO,KAAK,EAAE,KAAwB,OAAO,uBAAuB;AAAA,EACtE;AAAA;AAAA,EAGA,SAAS,SAAiB,OAAsD;AAC9E,WAAO,KAAK,EAAE,KAAuB,QAAQ,kBAAkB,mBAAmB,OAAO,CAAC,WAAW,EAAE,MAAM,MAAM,CAAC;AAAA,EACtH;AAAA;AAAA,EAGA,QAAQ,QAAgB,QAA0C;AAChE,WAAO,KAAK,EAAE,KAAgB,OAAO,uBAAuB,mBAAmB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;AAAA,EACtG;AAAA;AAAA,EAGA,WAAW,QAAoC;AAC7C,WAAO,KAAK,EAAE,KAAgB,UAAU,uBAAuB,mBAAmB,MAAM,CAAC,EAAE;AAAA,EAC7F;AAAA;AAAA,EAGA,OAAO,QAAiC;AACtC,WAAO,IAAI,gBAAgB,KAAK,GAAG,MAAM;AAAA,EAC3C;AACF;AAGO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,SAAgC;AAC9B,WAAO,KAAK,EAAE,KAAmB,OAAO,sBAAsB;AAAA,EAChE;AAAA;AAAA,EAGA,aAAa,SAAiB,OAAqC;AACjE,WAAO,KAAK,EAAE,KAAgB,QAAQ,kBAAkB,mBAAmB,OAAO,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAC;AAAA,EAC5G;AACF;AAGO,IAAM,WAAN,MAAe;AAAA,EACpB,YAA6B,GAAc;AAAd;AAAA,EAAe;AAAA;AAAA,EAG5C,MAAM,OAAO,MAAY,OAA0B,CAAC,GAA0B;AAC5E,UAAM,OAAO,IAAI,SAAS;AAC1B,QAAI,KAAK,aAAa,QAAW;AAC/B,WAAK,OAAO,QAAQ,MAAM,KAAK,QAAQ;AAAA,IACzC,OAAO;AACL,WAAK,OAAO,QAAQ,IAAI;AAAA,IAC1B;AAEA,SAAK,aAAa,CAAC;AACnB,UAAM,SAAS,MAAM,KAAK,EAAE,KAAmB,iBAAiB,EAAE,KAAK,CAAC;AACxE,SAAK,aAAa,GAAG;AACrB,WAAO;AAAA,EACT;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,EAapB,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;AACxC,SAAK,SAAS,IAAI,UAAU,KAAK,SAAS;AAC1C,SAAK,SAAS,IAAI,UAAU,KAAK,SAAS;AAC1C,SAAK,QAAQ,IAAI,SAAS,KAAK,SAAS;AACxC,SAAK,QAAQ,IAAI,SAAS,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA,EAGA,IAAI,UAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AACF;;;ACrVO,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/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, VideosApi, AudioApi, FilesApi, ApprovalsApi, PoliciesApi, EventsApi, SubagentsApi, SkillsApi, ExecutionsApi, 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, VideoTaskHandle, isTerminalTaskStatus } from \"./task.js\";\n\nexport { API_ERROR_CODES, APPROVAL_STATUSES, EXECUTION_STATUSES } from \"./types.js\";\nexport type {\n ApiErrorCode,\n CreateKeyInput,\n CreateKeyResult,\n DeleteKeyResult,\n DiscardedKey,\n MintedKey,\n ChatMessage,\n ChatInput,\n ChatFile,\n ChatResult,\n ChatStreamEvent,\n StreamOptions,\n MessageItem,\n HistoryPage,\n HistoryParams,\n AgentMessageKind,\n AgentMessageOutputFormat,\n AgentFeedToolCall,\n AgentMessageItem,\n AgentMessagesPage,\n AgentMessagesParams,\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 VideoTier,\n VideoPricingEntry,\n VideoModelInfo,\n VideoModelsResult,\n VideoGenerateInput,\n VideoTaskCreated,\n VideoTaskStatus,\n VideoTask,\n VideoWaitOptions,\n TtsInput,\n TtsResult,\n VoiceInfo,\n VoicesResult,\n UploadedFile,\n FileUploadOptions,\n TargetEntity,\n ApprovalPolicyResult,\n ApprovalSummary,\n ApprovalDetail,\n ApprovalStatus,\n ListApprovalsParams,\n ApprovalsListResult,\n DecideApprovalInput,\n DecideApprovalResult,\n ExecuteApprovalResult,\n PolicyRuleConditions,\n PolicyRule,\n PolicyPack,\n RoadmapPolicyPack,\n PoliciesResult,\n LedgerEvent,\n ListEventsParams,\n EventsPage,\n VerifyChainParams,\n VerifyChainResult,\n RetentionReport,\n AgentToolName,\n SubagentPermission,\n SubagentInputSpec,\n SubagentOutputSchema,\n SubagentExecutionConstraints,\n SubagentDefinition,\n SubagentStats,\n SubagentsListResult,\n SkillExecutionClass,\n SkillPermission,\n SkillProperty,\n SkillIOContract,\n SkillDefinition,\n SkillStats,\n SkillsListResult,\n SkillPolicyEvaluation,\n SkillRunInput,\n SkillRunResult,\n ExecutionStatus,\n ExecutionToolCall,\n ExecutionTokenUsage,\n ExecutionSummary,\n ListExecutionsParams,\n ExecutionsListResult,\n ExecutionDetail,\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\nexport interface FormRequestOptions {\n form: FormData;\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 /** Perform a multipart/form-data request and return the unwrapped `data` payload. */\n form<T>(path: string, opts: FormRequestOptions): 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 form<T>(path: string, reqOpts: FormRequestOptions) {\n const res = await doFormFetch(path, reqOpts);\n const text = await res.text();\n if (!res.ok) throw toHttpError(res.status, text, { method: \"POST\", url: res.url });\n return unwrap<T>(text, { method: \"POST\", 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 function doFormFetch(path: string, reqOpts: FormRequestOptions): Promise<Response> {\n const url = buildUrl(baseUrl, path);\n // No content-type header here — fetch sets the multipart boundary itself.\n const headers: Record<string, string> = {\n authorization: `Bearer ${apiKey}`,\n accept: \"application/json\",\n ...(reqOpts.headers ?? {}),\n };\n return fetchImpl(url, {\n method: \"POST\",\n headers,\n body: reqOpts.form,\n signal: reqOpts.signal,\n }).catch((err) => {\n throw toNetworkError(err, { method: \"POST\", 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, VideoTask, VideoWaitOptions } from \"./types.js\";\n\n/** Statuses at which a job will not change again (shared by tasks and video jobs). */\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\ninterface PollOptions {\n intervalMs?: number;\n maxIntervalMs?: number;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\n/**\n * Shared polling loop used by TaskHandle.wait() and VideoTaskHandle.wait().\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 */\nasync function pollUntilTerminal<T>(\n fetchSnapshot: (signal?: AbortSignal) => Promise<T>,\n isTerminal: (snapshot: T) => boolean,\n onTick: ((snapshot: T) => void) | undefined,\n opts: PollOptions,\n): Promise<T> {\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 snapshot = await fetchSnapshot(signal);\n onTick?.(snapshot);\n if (isTerminal(snapshot)) return snapshot;\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 * 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 /** Poll until the task reaches a terminal status (see pollUntilTerminal for semantics). */\n async wait(opts: WaitOptions = {}): Promise<Task> {\n return pollUntilTerminal(\n (signal) => this.get(signal),\n (task) => isTerminalTaskStatus(task.status),\n opts.onTick,\n opts,\n );\n }\n}\n\n/**\n * A handle to a video job created via `videos.generate`.\n * Polls the video-tasks endpoint until the job reaches a terminal status.\n */\nexport class VideoTaskHandle {\n constructor(\n private readonly transport: Transport,\n public readonly taskId: string,\n ) {}\n\n /** Fetch the current job snapshot (single request). */\n get(signal?: AbortSignal): Promise<VideoTask> {\n return this.transport.json<VideoTask>(\"GET\", `/api/v1/video-tasks/${encodeURIComponent(this.taskId)}`, { signal });\n }\n\n /** Alias of `get()` — perform one poll and return the latest snapshot. */\n poll(signal?: AbortSignal): Promise<VideoTask> {\n return this.get(signal);\n }\n\n /** Poll until the job reaches a terminal status (completed/failed/cancelled). */\n async wait(opts: VideoWaitOptions = {}): Promise<VideoTask> {\n return pollUntilTerminal(\n (signal) => this.get(signal),\n (task) => isTerminalTaskStatus(task.status),\n opts.onTick,\n opts,\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, VideoTaskHandle } from \"./task.js\";\nimport type {\n AgentDetail,\n AgentListResult,\n CatalogResult,\n CapabilitiesResult,\n CreateKeyInput,\n CreateKeyResult,\n DeleteKeyResult,\n ChatInput,\n ChatResult,\n ChatStreamEvent,\n HistoryPage,\n HistoryParams,\n AgentMessagesPage,\n AgentMessagesParams,\n ImageGenerateInput,\n ImageGenerateResult,\n ImageModelsResult,\n KeysResult,\n RunCapabilityInput,\n RunCapabilityResult,\n StreamOptions,\n Task,\n TaskCreateInput,\n TaskCreated,\n TtsInput,\n TtsResult,\n UploadedFile,\n FileUploadOptions,\n WorkflowRun,\n WorkflowRunInput,\n WorkflowRunStart,\n Workspace,\n VerifyKeyResult,\n VideoGenerateInput,\n VideoModelsResult,\n VideoTask,\n VideoTaskCreated,\n VoicesResult,\n WorkspaceModelsResult,\n WorkspaceModelsUpdateInput,\n WorkspaceUpdateInput,\n ApprovalsListResult,\n ApprovalDetail,\n DecideApprovalInput,\n DecideApprovalResult,\n ExecuteApprovalResult,\n ListApprovalsParams,\n PoliciesResult,\n EventsPage,\n ListEventsParams,\n RetentionReport,\n VerifyChainParams,\n VerifyChainResult,\n SubagentsListResult,\n SubagentDefinition,\n SkillsListResult,\n SkillDefinition,\n SkillRunInput,\n SkillRunResult,\n ExecutionsListResult,\n ExecutionDetail,\n ListExecutionsParams,\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 /** GET /api/v1/workspace/models — current model config (OpenRouter key masked). */\n getModels(): Promise<WorkspaceModelsResult> {\n return this.t.json<WorkspaceModelsResult>(\"GET\", \"/api/v1/workspace/models\");\n }\n\n /** PATCH /api/v1/workspace — update the workspace name and/or OpenRouter model config (partial). */\n update(input: WorkspaceUpdateInput): Promise<Workspace> {\n return this.t.json<Workspace>(\"PATCH\", \"/api/v1/workspace\", { body: input });\n }\n\n /** PATCH /api/v1/workspace — convenience wrapper that only touches `config.openrouter`. */\n updateModels(input: WorkspaceModelsUpdateInput): Promise<Workspace> {\n return this.t.json<Workspace>(\"PATCH\", \"/api/v1/workspace\", { body: { config: { openrouter: input } } });\n }\n\n /** GET /api/v1/workspace/models/catalog — OpenRouter model catalog (server-side cached). */\n listCatalogModels(): Promise<CatalogResult> {\n return this.t.json<CatalogResult>(\"GET\", \"/api/v1/workspace/models/catalog\");\n }\n\n /** POST /api/v1/workspace/models/verify — check an OpenRouter key with a 1-token completion. */\n verifyOpenRouterKey(key: string, model?: string, baseUrl?: string): Promise<VerifyKeyResult> {\n return this.t.json<VerifyKeyResult>(\"POST\", \"/api/v1/workspace/models/verify\", { body: { key, model, baseUrl } });\n }\n\n /** GET /api/v1/workspace/keys — API keys with rotation metadata (rotatesAt, daysLeft). */\n listKeys(): Promise<KeysResult> {\n return this.t.json<KeysResult>(\"GET\", \"/api/v1/workspace/keys\");\n }\n\n /**\n * POST /api/v1/workspace/keys — mint a new API key for the workspace.\n * All expired, non-revoked keys (issued and legacy) are discarded first, so a\n * rotation is one call. The raw `secret` is returned exactly once.\n */\n createKey(input?: CreateKeyInput): Promise<CreateKeyResult> {\n return this.t.json<CreateKeyResult>(\"POST\", \"/api/v1/workspace/keys\", { body: input ?? {} });\n }\n\n /** DELETE /api/v1/workspace/keys/:keyId — delete an issued or legacy key. */\n deleteKey(keyId: string): Promise<DeleteKeyResult> {\n return this.t.json<DeleteKeyResult>(\"DELETE\", `/api/v1/workspace/keys/${encodeURIComponent(keyId)}`);\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 /**\n * GET /api/v1/agents/messages — chronological message feed for a conversation.\n *\n * Returns the latest N entries in chronological order (omit `after`), or page\n * forward with `after` = id of the last item you received. Includes workflow\n * artifacts: tool results, step progress, and approval requests.\n */\n listMessages(params: AgentMessagesParams): Promise<AgentMessagesPage> {\n return this.t.json<AgentMessagesPage>(\"GET\", \"/api/v1/agents/messages\", {\n query: { agentId: params.agentId, after: params.after, limit: params.limit, 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<{ type?: string; stage?: string; detail?: string; choices?: { delta?: { content?: string; reasoning?: string; reasoning_content?: string } }[] }>(ev.data);\n if (!payload) continue; // [DONE] or malformed chunk\n if (payload.type === \"progress\") {\n yield { type: \"progress\", stage: payload.stage, detail: payload.detail };\n continue;\n }\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\n/** Videos namespace (tiered video generation: submit → poll). */\nexport class VideosApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/videos/models — list tiered video models + engine availability. */\n listModels(): Promise<VideoModelsResult> {\n return this.t.json<VideoModelsResult>(\"GET\", \"/api/v1/videos/models\");\n }\n\n /** POST /api/v1/agents/:agentId/videos — start a video job (returns the queued task, HTTP 202). */\n generate(agentId: string, input: VideoGenerateInput): Promise<VideoTaskCreated> {\n return this.t.json<VideoTaskCreated>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/videos`, { body: input });\n }\n\n /** GET /api/v1/video-tasks/:taskId — fetch the current job snapshot. */\n getTask(taskId: string, signal?: AbortSignal): Promise<VideoTask> {\n return this.t.json<VideoTask>(\"GET\", `/api/v1/video-tasks/${encodeURIComponent(taskId)}`, { signal });\n }\n\n /** DELETE /api/v1/video-tasks/:taskId — cancel a queued/rendering job (409 if already terminal). */\n cancelTask(taskId: string): Promise<VideoTask> {\n return this.t.json<VideoTask>(\"DELETE\", `/api/v1/video-tasks/${encodeURIComponent(taskId)}`);\n }\n\n /** Get a handle for polling / waiting on a video job (poll(), wait()). */\n handle(taskId: string): VideoTaskHandle {\n return new VideoTaskHandle(this.t, taskId);\n }\n}\n\n/** Audio namespace (text-to-speech). */\nexport class AudioApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/audio/voices — list available TTS voices. */\n voices(): Promise<VoicesResult> {\n return this.t.json<VoicesResult>(\"GET\", \"/api/v1/audio/voices\");\n }\n\n /** POST /api/v1/agents/:agentId/tts — synthesize speech (synchronous). */\n textToSpeech(agentId: string, input: TtsInput): Promise<TtsResult> {\n return this.t.json<TtsResult>(\"POST\", `/api/v1/agents/${encodeURIComponent(agentId)}/tts`, { body: input });\n }\n}\n\n/** Files namespace (media uploads). */\nexport class FilesApi {\n constructor(private readonly t: Transport) {}\n\n /** POST /api/v1/files — upload a media file (multipart field \"file\"). */\n async upload(file: Blob, opts: FileUploadOptions = {}): Promise<UploadedFile> {\n const form = new FormData();\n if (opts.filename !== undefined) {\n form.append(\"file\", file, opts.filename);\n } else {\n form.append(\"file\", file);\n }\n // Coarse progress only: fetch does not expose upload byte progress.\n opts.onProgress?.(0);\n const result = await this.t.form<UploadedFile>(\"/api/v1/files\", { form });\n opts.onProgress?.(100);\n return result;\n }\n}\n\n/** Approvals namespace (policy approval lifecycle). */\nexport class ApprovalsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/approvals — list policy approval requests (list-safe views, no payload). */\n list(params?: ListApprovalsParams): Promise<ApprovalsListResult> {\n return this.t.json<ApprovalsListResult>(\"GET\", \"/api/v1/approvals\", {\n query: {\n status: params?.status?.join(\",\"),\n limit: params?.limit,\n beforeCreatedAt: toIso(params?.beforeCreatedAt),\n },\n });\n }\n\n /** GET /api/v1/approvals/:id — full approval record incl. bound payload + evidence. */\n get(approvalId: string): Promise<ApprovalDetail> {\n return this.t.json<ApprovalDetail>(\"GET\", `/api/v1/approvals/${encodeURIComponent(approvalId)}`);\n }\n\n /** POST /api/v1/approvals/:id/decide — record an authorized workspace member's decision. */\n decide(approvalId: string, input: DecideApprovalInput): Promise<DecideApprovalResult> {\n return this.t.json<DecideApprovalResult>(\"POST\", `/api/v1/approvals/${encodeURIComponent(approvalId)}/decide`, { body: input });\n }\n\n /** POST /api/v1/approvals/:id/execute — execute the bound action of an approved approval, exactly once. */\n execute(approvalId: string): Promise<ExecuteApprovalResult> {\n return this.t.json<ExecuteApprovalResult>(\"POST\", `/api/v1/approvals/${encodeURIComponent(approvalId)}/execute`);\n }\n}\n\n/** Policies namespace (rule-pack registry). */\nexport class PoliciesApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/policies — active rule packs with their rules + documented roadmap packs. */\n get(): Promise<PoliciesResult> {\n return this.t.json<PoliciesResult>(\"GET\", \"/api/v1/policies\");\n }\n}\n\n/** Events namespace (hash-chained audit ledger). */\nexport class EventsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/events — paginated ledger read, newest first (`beforeSeq` pages backwards). */\n list(params?: ListEventsParams): Promise<EventsPage> {\n return this.t.json<EventsPage>(\"GET\", \"/api/v1/events\", {\n query: { limit: params?.limit, beforeSeq: params?.beforeSeq, types: params?.types?.join(\",\") },\n });\n }\n\n /** GET /api/v1/events/verify — recompute every hash and check each prevHash link (audit retrieval). */\n verify(params?: VerifyChainParams): Promise<VerifyChainResult> {\n return this.t.json<VerifyChainResult>(\"GET\", \"/api/v1/events/verify\", { query: { afterSeq: params?.afterSeq } });\n }\n\n /** GET /api/v1/events/retention — retention report (no automatic deletion runs). */\n retention(): Promise<RetentionReport> {\n return this.t.json<RetentionReport>(\"GET\", \"/api/v1/events/retention\");\n }\n}\n\n/** Subagents namespace (specialist subagent registry). */\nexport class SubagentsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/subagents — specialist definitions + honest stats (optionally filtered by owning agent). */\n list(agentId?: string): Promise<SubagentsListResult> {\n return this.t.json<SubagentsListResult>(\"GET\", \"/api/v1/subagents\", { query: { agentId } });\n }\n\n /** GET /api/v1/subagents/:id — one specialist definition. */\n get(subagentId: string): Promise<SubagentDefinition> {\n return this.t.json<SubagentDefinition>(\"GET\", `/api/v1/subagents/${encodeURIComponent(subagentId)}`);\n }\n}\n\n/** Skills namespace (shared skill registry + execution). */\nexport class SkillsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/skills — skill definitions (no implementation functions) + honest stats. */\n list(domain?: string): Promise<SkillsListResult> {\n return this.t.json<SkillsListResult>(\"GET\", \"/api/v1/skills\", { query: { domain } });\n }\n\n /** GET /api/v1/skills/:id — one skill definition. */\n get(skillId: string): Promise<SkillDefinition> {\n return this.t.json<SkillDefinition>(\"GET\", `/api/v1/skills/${encodeURIComponent(skillId)}`);\n }\n\n /** POST /api/v1/skills/run — run a skill through the full validation → authorization → policy → audit → execution pipeline. */\n run(input: SkillRunInput): Promise<SkillRunResult> {\n return this.t.json<SkillRunResult>(\"POST\", \"/api/v1/skills/run\", { body: input });\n }\n}\n\n/** Executions namespace (agent/subagent execution traces). */\nexport class ExecutionsApi {\n constructor(private readonly t: Transport) {}\n\n /** GET /api/v1/executions — execution history (list-safe views, no tool-call log). */\n list(params?: ListExecutionsParams): Promise<ExecutionsListResult> {\n return this.t.json<ExecutionsListResult>(\"GET\", \"/api/v1/executions\", {\n query: {\n agentId: params?.agentId,\n status: params?.status?.join(\",\"),\n limit: params?.limit,\n beforeCreatedAt: toIso(params?.beforeCreatedAt),\n },\n });\n }\n\n /** GET /api/v1/executions/:id — full execution trace incl. tool calls + direct children. */\n get(executionId: string): Promise<ExecutionDetail> {\n return this.t.json<ExecutionDetail>(\"GET\", `/api/v1/executions/${encodeURIComponent(executionId)}`);\n }\n}\n\nfunction toIso(value?: string | Date): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\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 readonly videos: VideosApi;\n readonly audio: AudioApi;\n readonly files: FilesApi;\n readonly approvals: ApprovalsApi;\n readonly policies: PoliciesApi;\n readonly events: EventsApi;\n readonly subagents: SubagentsApi;\n readonly skills: SkillsApi;\n readonly executions: ExecutionsApi;\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 this.videos = new VideosApi(this.transport);\n this.audio = new AudioApi(this.transport);\n this.approvals = new ApprovalsApi(this.transport);\n this.policies = new PoliciesApi(this.transport);\n this.events = new EventsApi(this.transport);\n this.subagents = new SubagentsApi(this.transport);\n this.skills = new SkillsApi(this.transport);\n this.executions = new ExecutionsApi(this.transport);\n this.files = new FilesApi(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 model id override — wins over the workspace director-panel default. */\n modelId?: string;\n /** Optional OpenRouter response-format hint (e.g. `{ type: \"json_object\" }`). */\n response_format?: Record<string, unknown>;\n /**\n * CSV/TSV attachments (base64 payloads). The backend parses them and hands\n * the rows to the agent's tool loop as structured data for batch processing.\n */\n files?: ChatFile[];\n}\n\n/** A file attachment sent with a chat request (base64 payload; CSV/TSV only). */\nexport interface ChatFile {\n name: string;\n mime?: string;\n dataBase64: string;\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 * - `progress`: tool-loop progress frames (e.g. which tools ran) for long jobs.\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: \"progress\"; stage?: string; detail?: 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/** Kinds of entries in the chronological agent message feed. */\nexport type AgentMessageKind = \"chat\" | \"tool_result\" | \"workflow\" | \"approval_request\";\n\n/** Declared output format of a feed message's content, when set. */\nexport type AgentMessageOutputFormat = \"text\" | \"json\" | \"html\";\n\n/** A tool call recorded on a feed message; `result` appears once the call completes (truncated server-side). */\nexport interface AgentFeedToolCall {\n name?: string;\n args?: unknown;\n status?: string;\n error?: string;\n result?: unknown;\n [key: string]: unknown;\n}\n\n/** One entry in the chronological agent message feed (GET /api/v1/agents/messages). */\nexport interface AgentMessageItem {\n id: string;\n role: string;\n kind: AgentMessageKind;\n content: string | null;\n reasoning?: string;\n toolCalls?: AgentFeedToolCall[];\n outputFormat?: AgentMessageOutputFormat;\n taskId?: string;\n status: string;\n timestamp: string | Date;\n}\n\n/** A page of the chronological agent message feed. */\nexport interface AgentMessagesPage {\n items: AgentMessageItem[];\n hasMore: boolean;\n /** Cursor for the next forward page (pass as `after`); undefined when exhausted. */\n nextAfter?: string;\n}\n\n/** Query params for `agents.listMessages`. */\nexport interface AgentMessagesParams {\n /** Platform slug or ObjectId of the agent. Required. */\n agentId: string;\n /** Cursor = id of the last item on the previous page (forward pagination). Omit for the latest N. */\n after?: string;\n /** Page size, 1..50 (default 20 server-side). */\n limit?: number;\n /** Optional internal user id filter (defaults to the workspace id server-side). */\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 registry model id override (wins over `model`, the workspace default, and `tier`). */\n modelId?: 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\n// ---------------------------------------------------------------------------\n// Videos — tiered video generation (async: submit → poll)\n// ---------------------------------------------------------------------------\n\nexport type VideoTier = \"standard\" | \"professional\" | \"advanced\";\n\n/** A single pricing entry for a video model. */\nexport interface VideoPricingEntry {\n /** What is billed, e.g. \"output_video\" / \"voiceover\". */\n billable: string;\n /** Billing unit: per rendered second, or flat per request. */\n unit: \"second\" | \"request\";\n costUsd: number;\n}\n\n/** A tiered video-generation model as returned by `videos.listModels`. */\nexport interface VideoModelInfo {\n id: string;\n name: string;\n tier: VideoTier;\n description: string;\n /** Short best-use-case label for UI copy. */\n bestFor: string;\n /** Execution engine (e.g. \"motion-graphics\"). */\n engine: string;\n supportsProductImages: boolean;\n maxReferenceImages: number;\n supportsReferenceVideos: boolean;\n maxReferenceVideos: number;\n supportedAspectRatios: string[];\n supportedResolutions: string[];\n /** Inclusive [min, max] duration in seconds. */\n durationRange: [number, number];\n voiceoverSupport: boolean;\n pricing: {\n summary: string;\n entries: VideoPricingEntry[];\n };\n recommended: boolean;\n enabled: boolean;\n /** Runtime engine availability (render toolchain present). */\n available: boolean;\n}\n\n/** Result of `videos.listModels`. */\n/** An OpenRouter AI video model (from the public GET /api/v1/videos/models catalog). */\nexport interface OrVideoModel {\n id: string;\n canonical_slug?: string | null;\n hugging_face_id?: string | null;\n name: string;\n created?: number;\n description?: string;\n /** e.g. [\"480p\",\"720p\"] — null when the provider does not publish it. */\n supported_resolutions?: string[] | null;\n /** e.g. [\"16:9\",\"9:16\"] — null when the model decides. */\n supported_aspect_ratios?: string[] | null;\n /** e.g. [\"854x480\",\"1280x720\"]. */\n supported_sizes?: string[] | null;\n /** Discrete list of allowed durations in seconds (e.g. [3,5] or [1..15]). */\n supported_durations?: number[] | null;\n supported_frame_images?: (\"first_frame\" | \"last_frame\")[] | null;\n upscale_factor?: number | null;\n creativity?: number | null;\n /** Native audio generation (null = model decides / unknown). */\n generate_audio?: boolean | null;\n seed?: boolean | null;\n /** Per-SKU price strings — \"cents_*\" keys are in cents, the rest in USD. */\n pricing_skus?: Record<string, string> | null;\n allowed_passthrough_parameters?: string[];\n}\n\nexport interface VideoModelsResult {\n models: VideoModelInfo[];\n engine: {\n available: boolean;\n detail: string;\n };\n /** Live OpenRouter AI video catalog (may be empty when the upstream is unreachable). */\n openrouterModels?: OrVideoModel[];\n}\n\n/** Input for `videos.generate`. */\nexport interface VideoGenerateInput {\n /** The creative brief / script for the video. */\n prompt: string;\n /** Explicit registry model id override (wins over `model`, the workspace default, and `tier`). */\n modelId?: string;\n /** Explicit registry model id (wins over `tier`). */\n model?: string;\n /** Tier to resolve a model from (used when `model` is omitted). */\n tier?: VideoTier | string;\n /** Product/reference images — base64 data URLs or https URLs. Order defines IMG_0..N. */\n images_list?: string[];\n /** Reference (style) videos — https URLs only (upload local files via `files.upload`). */\n video_files?: string[];\n /** e.g. \"16:9\", \"9:16\", \"1:1\". Default \"16:9\". */\n aspect_ratio?: string;\n /** Duration in seconds (must be within the model's durationRange). */\n duration?: number;\n /** e.g. \"720p\" | \"1080p\". Default \"720p\". */\n resolution?: string;\n /** Bake an ElevenLabs voiceover into the render (requires `narration`). */\n generate_audio?: boolean;\n /** Voiceover text (used when `generate_audio` is true). Max 3000 chars. */\n narration?: string;\n}\n\n/** Returned when a video job is created (HTTP 202). */\nexport interface VideoTaskCreated {\n taskId: string;\n status: \"queued\";\n}\n\nexport type VideoTaskStatus =\n | \"queued\"\n | \"rendering\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | (string & {});\n\n/** A video job snapshot, as returned by `videos.getTask`. */\nexport interface VideoTask {\n taskId: string;\n status: VideoTaskStatus;\n progress?: {\n current: number;\n total: number;\n message?: string;\n };\n /** Served media path (e.g. /generated/video-….mp4) once completed. */\n outputUrl?: string;\n mime?: string;\n ext?: string;\n /** Actual rendered duration in seconds. */\n durationSec?: number;\n error?: string;\n model?: string;\n tier?: string;\n latencyMs?: number;\n createdAt: string | Date;\n completedAt: string | Date | null;\n}\n\n/** Options for polling / waiting on a video job. */\nexport interface VideoWaitOptions {\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 job snapshot. */\n onTick?: (task: VideoTask) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Audio — text-to-speech\n// ---------------------------------------------------------------------------\n\n// ─── Workspace model configuration (director panel) ──────────────────────\n\n/** Per-role model defaults as configured in the director panel. */\nexport interface WorkspaceModelConfig {\n status: \"active\" | \"inactive\";\n /** Masked OpenRouter key — the raw key is never returned by the API. */\n keyMasked: string;\n /** Optional chat-completions base URL override (empty = public OpenRouter API). */\n baseUrl: string;\n reasoning: string;\n instruct: string;\n response: string;\n vision: string;\n image: string;\n video: string;\n /** Ordered per-role fallback model ids (max 3 each), tried on provider failure. */\n fallbacks: {\n reasoning: string[];\n instruct: string[];\n response: string[];\n vision: string[];\n image: string[];\n video: string[];\n };\n}\n\n/** Result of `workspace.getModels`. */\nexport interface WorkspaceModelsResult {\n openrouter: WorkspaceModelConfig;\n}\n\n/** Partial model-config update for `workspace.update` / `workspace.updateModels`. */\nexport interface WorkspaceModelsUpdateInput {\n status?: \"active\" | \"inactive\";\n /** Full OpenRouter API key to store/rotate. Omit to leave unchanged. */\n key?: string;\n /** Optional chat-completions base URL override (defaults to the public OpenRouter API). */\n baseUrl?: string;\n reasoning?: string;\n instruct?: string;\n response?: string;\n vision?: string;\n image?: string;\n video?: string;\n /** Ordered per-role fallback model ids (max 3 each). */\n fallbacks?: {\n reasoning?: string[];\n instruct?: string[];\n response?: string[];\n vision?: string[];\n image?: string[];\n video?: string[];\n };\n}\n\n/** Input for `workspace.update`. */\nexport interface WorkspaceUpdateInput {\n name?: string;\n config?: { openrouter?: WorkspaceModelsUpdateInput };\n}\n\n/** A single OpenRouter catalog model. */\nexport interface CatalogModel {\n id: string;\n name: string;\n contextLength: number | null;\n promptPrice: number | null;\n completionPrice: number | null;\n}\n\n/** Result of `workspace.listCatalogModels`. */\nexport interface CatalogResult {\n models: CatalogModel[];\n /** True when the upstream fetch failed and a cached snapshot was served. */\n stale?: boolean;\n}\n\n/** Result of `workspace.verifyOpenRouterKey`. */\nexport interface VerifyKeyResult {\n valid: boolean;\n error?: string;\n}\n\n/** A v1 API key with rotation metadata (hashes never leave the server). */\nexport interface ApiKeyInfo {\n _id: string;\n name: string;\n prefix: string;\n scopes: string[];\n createdAt: string | Date;\n lastUsedAt: string | Date | null;\n revokedAt: string | Date | null;\n /** When the key is auto-deleted (createdAt + lifetime). */\n rotatesAt: string | Date;\n /** Whole days remaining until rotation (0 when expired). */\n daysLeft: number;\n}\n\n/** Result of `workspace.listKeys`. */\nexport interface KeysResult {\n /** Key lifetime in days before auto-deletion. */\n lifetimeDays: number;\n keys: ApiKeyInfo[];\n}\n\n/** Input for `workspace.createKey`. */\nexport interface CreateKeyInput {\n /** Display name for the key (defaults to \"API Key\" server-side). */\n name?: string;\n}\n\n/** A freshly minted key. `secret` is the raw key — shown exactly once, never stored in plaintext. */\nexport interface MintedKey {\n id: string;\n name: string;\n prefix: string;\n secret: string;\n}\n\n/** An expired key that was discarded automatically when a new key was minted. */\nexport interface DiscardedKey {\n _id?: string;\n name: string;\n prefix: string;\n /** True when the key was embedded on the workspace document (pre-ApiKey-collection era). */\n legacy: boolean;\n}\n\n/** Result of `workspace.createKey`. */\nexport interface CreateKeyResult {\n key: MintedKey;\n /** Expired, non-revoked keys discarded as part of the rotation. */\n discarded: DiscardedKey[];\n}\n\n/** Result of `workspace.deleteKey`. */\nexport interface DeleteKeyResult {\n deleted: {\n id: string;\n name: string;\n prefix: string;\n legacy: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n\n/** Input for `audio.textToSpeech`. */\nexport interface TtsInput {\n /** Text to synthesize (max 3000 chars). */\n text: string;\n /** ElevenLabs voice id (list via `audio.voices`). Defaults to the platform voice. */\n voiceId?: string;\n /** Voice stability 0..1 (default 0.5). */\n stability?: number;\n /** Similarity boost 0..1 (default 0.75). */\n similarityBoost?: number;\n}\n\n/** Result of `audio.textToSpeech`. */\nexport interface TtsResult {\n /** Served audio path (e.g. /generated/tts-….mp3). */\n url: string;\n voiceId: string;\n modelId: string;\n bytes: number;\n latencyMs: number;\n}\n\n/** A single ElevenLabs voice as returned by `audio.voices`. */\nexport interface VoiceInfo {\n id: string;\n name: string;\n}\n\n/** Result of `audio.voices`. */\nexport interface VoicesResult {\n voices: VoiceInfo[];\n /** \"live\" = fetched from the provider; \"none\" = no provider key configured. */\n source: \"live\" | \"none\";\n note?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Files — media uploads\n// ---------------------------------------------------------------------------\n\n/** Result of `files.upload`. */\nexport interface UploadedFile {\n /** Stable served path (e.g. /uploads/<workspace>/<file>) usable as a media input URL. */\n url: string;\n filename: string;\n size: number;\n contentType: string;\n}\n\n/** Options for `files.upload`. */\nexport interface FileUploadOptions {\n /** Override the stored display name (extension is kept from the file). */\n filename?: string;\n /**\n * Coarse progress callback. Fetch does not expose upload byte progress, so this\n * reports 0 at start and 100 on completion.\n */\n onProgress?: (percent: number) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Architecture — approvals, policies, events, subagents, skills, executions\n// ---------------------------------------------------------------------------\n\n/** Approval lifecycle states (GET /api/v1/approvals `status` filter accepts these). */\nexport const APPROVAL_STATUSES = [\n \"pending\",\n \"approved\",\n \"rejected\",\n \"expired\",\n \"consumed\",\n \"invalidated\",\n \"cancelled\",\n] as const;\n\nexport type ApprovalStatus = (typeof APPROVAL_STATUSES)[number];\n\n/** A target entity an action is bound to (e.g. a document or collection). */\nexport interface TargetEntity {\n type: string;\n id: string;\n}\n\n/** Policy evaluation summary attached to an approval request. */\nexport interface ApprovalPolicyResult {\n /** \"full_autonomy\" | \"silent_approval\" | \"hard_block\" (null when not evaluated). */\n level: string | null;\n rulePackId: string | null;\n ruleId: string | null;\n severity: string | null;\n reason: string;\n}\n\n/** List-safe approval view — no payload or evidence (use `approvals.get` for the full record). */\nexport interface ApprovalSummary {\n approvalId: string;\n /** One of APPROVAL_STATUSES. */\n status: string;\n action: string;\n targetEntity: TargetEntity | null;\n actorType: string;\n agentId: string | null;\n subagentId: string | null;\n executionId: string | null;\n approvalLevel: string;\n policyResult: ApprovalPolicyResult;\n idempotencyKey: string;\n reviewUntil: string | Date | null;\n expiresAt: string | Date;\n decidedBy: string | null;\n decidedAt: string | Date | null;\n createdAt: string | Date;\n}\n\n/** Full approval record including the bound payload (credentials stripped server-side) and evidence. */\nexport interface ApprovalDetail extends ApprovalSummary {\n payload: Record<string, unknown>;\n payloadHash: string | null;\n decisionNote: string | null;\n approvalEvidence: Record<string, unknown> | null;\n executionResult: Record<string, unknown> | null;\n executedAt: string | Date | null;\n consumedAt: string | Date | null;\n ledgerSeqRequested: number | null;\n}\n\n/** Params for `approvals.list`. */\nexport interface ListApprovalsParams {\n /** Filter by one or more statuses (sent comma-joined). */\n status?: ApprovalStatus[];\n /** Page size (default 50, max 200). */\n limit?: number;\n /** Only approvals created before this ISO date. */\n beforeCreatedAt?: string | Date;\n}\n\n/** Result of `approvals.list`. */\nexport interface ApprovalsListResult {\n items: ApprovalSummary[];\n total: number;\n}\n\n/** Input for `approvals.decide`. Public API keys carry no user identity, so the deciding workspace member must be named. */\nexport interface DecideApprovalInput {\n decision: \"approve\" | \"reject\";\n /** User id of a current member of this workspace. */\n decidedBy: string;\n /** Optional note (truncated to 2000 chars server-side). */\n note?: string;\n /** Optional structured evidence attached to the decision. */\n evidence?: Record<string, unknown>;\n}\n\n/** Result of `approvals.decide`. */\nexport interface DecideApprovalResult {\n approvalId: string;\n status: string | null;\n}\n\n/** Result of `approvals.execute`. The approval is consumed exactly once on the success path. */\nexport interface ExecuteApprovalResult {\n /** False when the executor ran and failed — the outcome is recorded, NOT retried. */\n ok: boolean;\n approvalId: string;\n action: string | null;\n /** Always \"consumed\" on HTTP 200 (the approval was atomically consumed). */\n status: \"consumed\";\n result: Record<string, unknown> | null;\n error?: string;\n}\n\n// --- Policies ---------------------------------------------------------------\n\n/** Match conditions for a policy rule (all present fields must match the action descriptor). */\nexport interface PolicyRuleConditions {\n action?: string;\n httpMethod?: string[];\n collection?: string[];\n}\n\n/** A single policy rule as returned by `policies.get`. */\nexport interface PolicyRule {\n ruleId: string;\n rulePackId: string;\n version: number;\n description: string;\n conditions: PolicyRuleConditions;\n severity: \"info\" | \"low\" | \"medium\" | \"high\" | \"critical\";\n approvalLevel: \"full_autonomy\" | \"silent_approval\" | \"hard_block\";\n correctiveAction: string | null;\n}\n\n/** A policy rule pack (active packs are evaluated; roadmap packs are not). */\nexport interface PolicyPack {\n id: string;\n name: string;\n version: number;\n description: string;\n active: boolean;\n rules: PolicyRule[];\n}\n\n/** A client-specified rule pack documented as a roadmap requirement (definitions to be supplied by the client). */\nexport interface RoadmapPolicyPack {\n id: string;\n note: string;\n}\n\n/** Result of `policies.get`. */\nexport interface PoliciesResult {\n packs: PolicyPack[];\n activePackIds: string[];\n roadmapPacks: RoadmapPolicyPack[];\n stats: { total: number; active: number; roadmap: number; rulesTotal: number };\n}\n\n// --- Events (hash-chained audit ledger) --------------------------------------\n\n/** One event in the workspace's append-only, hash-chained audit ledger. */\nexport interface LedgerEvent {\n seq: number;\n type: string;\n actorType: string;\n actorId: string;\n agentId: string | null;\n subagentId: string | null;\n executionId: string | null;\n entityRefs: TargetEntity[];\n payload: Record<string, unknown>;\n prevHash: string;\n eventHash: string;\n timestampMs: number;\n createdAt: string | Date;\n}\n\n/** Params for `events.list` (newest first; `beforeSeq` pages backwards). */\nexport interface ListEventsParams {\n /** Page size (default 50, max 200). */\n limit?: number;\n /** Only events with seq < this value. */\n beforeSeq?: number;\n /** Only these event types (sent comma-joined). */\n types?: string[];\n}\n\n/** Result of `events.list`. */\nexport interface EventsPage {\n items: LedgerEvent[];\n hasMore: boolean;\n /** Pass as `beforeSeq` to fetch the next (older) page when `hasMore`. */\n nextBeforeSeq?: number;\n total?: number;\n}\n\n/** Params for `events.verify`. */\nexport interface VerifyChainParams {\n /** Verify only events with seq <= this value (windowed verification). */\n afterSeq?: number;\n}\n\n/** Result of `events.verify` — recomputes every hash and checks each prevHash link. */\nexport interface VerifyChainResult {\n valid: boolean;\n checkedCount: number;\n firstBadSeq?: number;\n reason?: string;\n}\n\n/** Result of `events.retention`. No automatic deletion runs (fail-closed audit posture). */\nexport interface RetentionReport {\n retentionDays: number;\n oldestEventAt?: string | Date;\n eventsInsideRetentionWindow: number;\n eventsOutsideRetentionWindow: number;\n autoDeletionEnabled: false;\n note: string;\n}\n\n// --- Subagents ---------------------------------------------------------------\n\n/** Agent tool names a subagent may be granted. */\nexport type AgentToolName =\n | \"fetch_collections\"\n | \"fetch_schema\"\n | \"query_collection\"\n | \"create_document\"\n | \"update_document\"\n | \"delete_document\"\n | \"http_request\"\n | \"dispatch_agent\";\n\n/** Capability scopes a subagent may hold (audited, enforced at the tool layer). */\nexport type SubagentPermission = \"db.read\" | \"db.write\" | \"http.outbound\";\n\n/** A declared input of a subagent dispatch. */\nexport interface SubagentInputSpec {\n name: string;\n type: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\";\n required: boolean;\n description: string;\n}\n\n/** Output contract of a subagent (minimal JSON-schema-style object). */\nexport interface SubagentOutputSchema {\n type: \"object\";\n properties: Record<string, { type: string; description?: string }>;\n required?: string[];\n}\n\n/** Bounded execution constraints for one dispatch. */\nexport interface SubagentExecutionConstraints {\n /** Max model tool rounds for one dispatch (bounded loop). */\n maxRounds: number;\n /** Per-round model call timeout. */\n roundTimeoutMs: number;\n /** Wall-clock budget for the whole dispatch (soft, best-effort race). */\n totalTimeoutMs: number;\n}\n\n/** A versioned specialist subagent definition owned by exactly one domain agent. */\nexport interface SubagentDefinition {\n /** Stable id: \"<ownerAgentId>.<kebab-name>\" — never rename. */\n id: string;\n name: string;\n description: string;\n /** Owning top-level agent id (one of the eight domain agents). */\n ownerAgentId: string;\n responsibilities: string[];\n inputs: SubagentInputSpec[];\n outputSchema: SubagentOutputSchema;\n /** Skill ids this specialist may use. */\n skills: string[];\n permittedTools: AgentToolName[];\n permissions: SubagentPermission[];\n constraints: string[];\n executionConstraints: SubagentExecutionConstraints;\n /** Dispatch depth at which this specialist may be activated (1 = direct child of its owner). */\n activationDepth: number;\n enabled: boolean;\n /** Present when the specialist applies only to certain verticals. */\n applicabilityNote?: string;\n version: number;\n}\n\n/** Honest registry stats over a set of subagent definitions. */\nexport interface SubagentStats {\n total: number;\n enabled: number;\n disabled: number;\n /** Ids of specialists granted the http_request tool. */\n withHttp: string[];\n byAgent: Record<string, { total: number; enabled: number }>;\n}\n\n/** Result of `subagents.list`. */\nexport interface SubagentsListResult {\n items: SubagentDefinition[];\n stats: SubagentStats;\n}\n\n// --- Skills ------------------------------------------------------------------\n\n/** \"read\" → gated as skill_read (read-only); \"write\" → skill_run (protected). */\nexport type SkillExecutionClass = \"read\" | \"write\";\n\n/** Permission scopes a calling agent/subagent must hold. */\nexport type SkillPermission = \"db.read\" | \"db.write\" | \"http.outbound\";\n\n/** A property in a skill input/output contract. */\nexport interface SkillProperty {\n type: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\";\n description?: string;\n /** When true, null is accepted for this property (strict otherwise). */\n nullable?: boolean;\n /** Numbers only. */\n minimum?: number;\n maximum?: number;\n}\n\n/** Minimal JSON-schema-style object contract (strict: unknown keys are rejected). */\nexport interface SkillIOContract {\n type: \"object\";\n properties: Record<string, SkillProperty>;\n required?: string[];\n}\n\n/** Public skill definition — the implementation function is never exposed. */\nexport interface SkillDefinition {\n /** Stable id: \"<domainAgentId>.<kebab-name>\" — never rename. */\n id: string;\n name: string;\n description: string;\n /** Bumped on any behavior change. */\n version: number;\n enabled: boolean;\n executionClass: SkillExecutionClass;\n /** Owning/permitted caller domains (agent template ids). User actors are always permitted. */\n domains: string[];\n /** Permissions the calling agent/subagent must hold (empty = none required). */\n requiredPermissions: SkillPermission[];\n inputSchema: SkillIOContract;\n outputSchema: SkillIOContract;\n /** Wall-clock execution limit (bounded by design). */\n timeoutMs: number;\n /** Max serialized input size in bytes. */\n maxInputBytes: number;\n /** True → the run fails closed if its required audit event cannot be recorded. */\n auditRequired: boolean;\n /** All skill failures surface as structured {ok:false, errorCode, error} results. */\n errorBehavior: \"structured\";\n}\n\n/** Honest registry stats over all skills. */\nexport interface SkillStats {\n total: number;\n readOnly: number;\n write: number;\n enabled: number;\n /** Count keyed by the domain prefix of the skill id (before the first dot). */\n byDomain: Record<string, number>;\n}\n\n/** Result of `skills.list`. */\nexport interface SkillsListResult {\n items: SkillDefinition[];\n stats: SkillStats;\n}\n\n/** Policy evaluation attached to a gated skill run. */\nexport interface SkillPolicyEvaluation {\n level: \"full_autonomy\" | \"silent_approval\" | \"hard_block\";\n rulePackId?: string | null;\n ruleId?: string | null;\n severity?: \"info\" | \"low\" | \"medium\" | \"high\" | \"critical\" | null;\n reason: string;\n correctiveAction?: string;\n /** True when the hard_block is a fail-closed default (no valid rule matched). */\n failClosed?: boolean;\n skippedMalformedRules?: number;\n}\n\n/** Input for `skills.run`. Public API keys carry no user identity, so the acting workspace member must be named. */\nexport interface SkillRunInput {\n skillId: string;\n input: Record<string, unknown>;\n /** User id of a current member of this workspace. */\n actorUserId: string;\n /** Approval dedupe key (prevents duplicate approval requests — NOT result caching). */\n idempotencyKey?: string;\n}\n\n/** Structured outcome of one skill run through the validation → authorization → policy → audit → execution pipeline. */\nexport interface SkillRunResult {\n ok: boolean;\n status: \"completed\" | \"blocked\" | \"approval_required\" | \"failed\";\n skillId: string;\n errorCode?: string;\n error?: string;\n output?: unknown;\n /** Present when the run is policy-gated as silent_approval — drive it via approvals.decide + approvals.execute. */\n approvalId?: string;\n evaluation?: SkillPolicyEvaluation;\n}\n\n// --- Executions ---------------------------------------------------------------\n\n/** Execution lifecycle states (GET /api/v1/executions `status` filter accepts these). */\nexport const EXECUTION_STATUSES = [\"running\", \"completed\", \"failed\", \"cancelled\", \"timeout\"] as const;\n\nexport type ExecutionStatus = (typeof EXECUTION_STATUSES)[number];\n\n/** One tool call recorded in an execution trace. */\nexport interface ExecutionToolCall {\n seq: number;\n toolName: string;\n ok: boolean;\n durationMs?: number;\n error?: string;\n /** Approval request id when the tool call was policy-gated. */\n approvalId?: string;\n /** Ledger seq of the related audit event, if any. */\n ledgerSeq?: number;\n}\n\n/** Token usage recorded for an execution (when reported by the model layer). */\nexport interface ExecutionTokenUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n model?: string;\n}\n\n/** List-safe execution view — no embedded tool-call log (use `executions.get` for the full trace). */\nexport interface ExecutionSummary {\n executionId: string;\n parentExecutionId: string | null;\n agentType: \"agent\" | \"subagent\";\n agentId: string;\n subagentId: string | null;\n status: ExecutionStatus;\n startedAt: string | Date;\n finishedAt: string | Date | null;\n durationMs: number | null;\n costUsd: number | null;\n createdAt: string | Date;\n}\n\n/** Params for `executions.list`. */\nexport interface ListExecutionsParams {\n /** Filter by owning domain agent slug. */\n agentId?: string;\n /** Filter by one or more statuses (sent comma-joined). */\n status?: ExecutionStatus[];\n /** Page size (default 50, max 200). */\n limit?: number;\n /** Only executions created before this ISO date. */\n beforeCreatedAt?: string | Date;\n}\n\n/** Result of `executions.list`. */\nexport interface ExecutionsListResult {\n items: ExecutionSummary[];\n total: number;\n}\n\n/** Full execution trace including tool calls, approvals, and ledger references. */\nexport interface ExecutionDetail {\n execution: {\n executionId: string;\n parentExecutionId: string | null;\n agentType: \"agent\" | \"subagent\";\n agentId: string;\n subagentId: string | null;\n userId: string | null;\n status: ExecutionStatus;\n inputMeta: Record<string, unknown> | null;\n outputMeta: Record<string, unknown> | null;\n toolCalls: ExecutionToolCall[];\n tokenUsage: ExecutionTokenUsage | null;\n costUsd: number | null;\n durationMs: number | null;\n error: string | null;\n /** ApprovalRequest ids involved in this execution. */\n approvalRefs: string[];\n /** Ledger seqs of audit events emitted for this execution. */\n ledgerEventIds: number[];\n startedAt: string | Date;\n finishedAt: string | Date | null;\n createdAt: string | Date;\n };\n /** Direct child executions (subagent dispatches from this execution). */\n children: ExecutionSummary[];\n}\n"],"mappings":"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","names":[]}
|