@ragable/sdk 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/request-client.ts","../src/shift.ts","../src/sse.ts","../src/agents.ts","../src/browser.ts","../src/rag.ts"],"sourcesContent":["export type {\n DefaultRagableDatabase,\n Json,\n RagableDatabase,\n RagableTableDefinition,\n Tables,\n TablesInsert,\n TablesUpdate,\n} from \"./database-schema\";\n\nexport type { RagableClientOptions, RequestOptions } from \"./request-client\";\nexport {\n extractErrorMessage,\n RagableError,\n RagableRequestClient,\n} from \"./request-client\";\n\nexport type {\n ShiftAddDocumentParams,\n ShiftCreateIndexParams,\n ShiftEntry,\n ShiftIndex,\n ShiftIngestResponse,\n ShiftListEntriesParams,\n ShiftListEntriesResponse,\n ShiftSearchParams,\n ShiftSearchResult,\n ShiftUpdateIndexParams,\n ShiftUploadableFile,\n ShiftUploadFileParams,\n} from \"./shift\";\nexport { ShiftClient } from \"./shift\";\n\nexport type {\n AgentChatMessage,\n AgentChatParams,\n AgentChatResult,\n AgentStreamEvent,\n AgentSummary,\n} from \"./agents\";\nexport { AgentsClient } from \"./agents\";\n\nexport type {\n AgentPublicChatParams,\n BrowserAuthSession,\n BrowserAuthTokens,\n BrowserSqlQueryParams,\n BrowserSqlQueryResult,\n RagableBrowserClientOptions,\n} from \"./browser\";\nexport {\n createBrowserClient,\n normalizeBrowserApiBase,\n RagableBrowser,\n RagableBrowserAgentsClient,\n RagableBrowserAuthClient,\n RagableBrowserDatabaseClient,\n} from \"./browser\";\n\nexport type { SseJsonEvent } from \"./sse\";\nexport { parseSseDataLine, readSseStream } from \"./sse\";\n\nexport type {\n FormatContextOptions,\n RagClientForPipeline,\n RagPipeline,\n RagPipelineOptions,\n RetrieveParams,\n} from \"./rag\";\nexport { createRagPipeline, formatRetrievalContext } from \"./rag\";\n\nimport { AgentsClient } from \"./agents\";\nimport {\n RagableRequestClient,\n type RagableClientOptions,\n} from \"./request-client\";\nimport { ShiftClient } from \"./shift\";\n\nexport class Ragable {\n readonly shift: ShiftClient;\n readonly agents: AgentsClient;\n readonly infrastructure: {\n shift: ShiftClient;\n };\n\n constructor(options: RagableClientOptions) {\n const client = new RagableRequestClient(options);\n this.shift = new ShiftClient(client);\n this.agents = new AgentsClient(client);\n this.infrastructure = {\n shift: this.shift,\n };\n }\n}\n\n/**\n * Server-side client with your **secret** `ragable_*` API key.\n * Use from Node, Edge, or your Engine — never in browser bundles.\n * For public agent streaming from the browser without a key, use {@link createBrowserClient}.\n */\nexport function createClient(options: RagableClientOptions) {\n return new Ragable(options);\n}\n","export interface RagableClientOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\nexport type RequestOptions = Omit<RequestInit, \"body\"> & {\n body?: unknown;\n};\n\nexport class RagableError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"RagableError\";\n this.status = status;\n this.body = body;\n }\n}\n\nexport function extractErrorMessage(payload: unknown, fallback: string) {\n if (payload && typeof payload === \"object\") {\n if (\"error\" in payload && typeof payload.error === \"string\") {\n return payload.error;\n }\n if (\"message\" in payload && typeof payload.message === \"string\") {\n return payload.message;\n }\n }\n\n if (typeof payload === \"string\" && payload.length > 0) {\n return payload;\n }\n\n return fallback || \"Request failed\";\n}\n\nexport class RagableRequestClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: HeadersInit | undefined;\n\n constructor(options: RagableClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl ?? \"http://localhost:8080/api\";\n this.fetchImpl = options.fetch ?? fetch;\n this.defaultHeaders = options.headers;\n }\n\n toUrl(path: string) {\n const normalizedBase = this.baseUrl.replace(/\\/+$/, \"\");\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${normalizedBase}${normalizedPath}`;\n }\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const response = await this.rawFetch(path, options);\n const payload = await this.parseResponseBody(response);\n if (!response.ok) {\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n\n return payload as T;\n }\n\n /**\n * Low-level fetch with API key and JSON body encoding. Caller handles status and body.\n */\n async rawFetch(path: string, options: RequestOptions = {}): Promise<Response> {\n const headers = new Headers(this.defaultHeaders);\n headers.set(\"Authorization\", `Bearer ${this.apiKey}`);\n\n let body = options.body;\n if (body !== undefined && !isBodyInit(body)) {\n headers.set(\"Content-Type\", \"application/json\");\n body = JSON.stringify(body);\n }\n\n return this.fetchImpl(this.toUrl(path), {\n ...options,\n headers,\n body: body as BodyInit | undefined,\n });\n }\n\n private async parseResponseBody(response: Response): Promise<unknown> {\n if (response.status === 204) {\n return null;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n }\n}\n\nexport function isBodyInit(value: unknown): value is BodyInit {\n return (\n typeof value === \"string\" ||\n value instanceof Blob ||\n value instanceof FormData ||\n value instanceof URLSearchParams ||\n value instanceof ArrayBuffer ||\n ArrayBuffer.isView(value)\n );\n}\n","import { RagableRequestClient } from \"./request-client\";\n\nexport interface ShiftIndex {\n id: string;\n name: string;\n description: string | null;\n dimensions: number;\n embeddingModel: string;\n status: string;\n entryCount?: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ShiftEntry {\n id: string;\n content: string;\n metadata: unknown;\n chunkIndex: number;\n createdAt: string;\n}\n\nexport interface ShiftSearchResult {\n content: string;\n score: number;\n metadata: unknown;\n}\n\nexport interface ShiftCreateIndexParams {\n name: string;\n description?: string;\n dimensions?: number;\n embeddingModel?: string;\n}\n\nexport interface ShiftUpdateIndexParams {\n name?: string;\n description?: string;\n}\n\nexport interface ShiftAddDocumentParams {\n content: string;\n metadata?: Record<string, unknown>;\n chunkSize?: number;\n chunkOverlap?: number;\n}\n\nexport type ShiftUploadableFile = Blob | ArrayBuffer | Uint8Array;\n\nexport interface ShiftUploadFileParams {\n file: ShiftUploadableFile;\n fileName?: string;\n contentType?: string;\n metadata?: Record<string, unknown>;\n chunkSize?: number;\n chunkOverlap?: number;\n}\n\nexport interface ShiftListEntriesParams {\n take?: number;\n skip?: number;\n}\n\nexport interface ShiftSearchParams {\n query: string;\n topK?: number;\n}\n\nexport interface ShiftIngestResponse {\n chunksCreated: number;\n entries: string[];\n extractedText?: string;\n message?: string;\n}\n\nexport interface ShiftListEntriesResponse {\n entries: ShiftEntry[];\n total: number;\n}\n\nexport class ShiftClient {\n readonly indexes: {\n list: () => Promise<{ indexes: ShiftIndex[] }>;\n create: (params: ShiftCreateIndexParams) => Promise<ShiftIndex>;\n get: (indexId: string) => Promise<ShiftIndex>;\n update: (indexId: string, params: ShiftUpdateIndexParams) => Promise<ShiftIndex>;\n delete: (indexId: string) => Promise<{ success: true }>;\n };\n\n readonly documents: {\n create: (\n indexId: string,\n params: ShiftAddDocumentParams,\n ) => Promise<ShiftIngestResponse>;\n upload: (\n indexId: string,\n params: ShiftUploadFileParams,\n ) => Promise<ShiftIngestResponse>;\n };\n\n readonly entries: {\n list: (\n indexId: string,\n params?: ShiftListEntriesParams,\n ) => Promise<ShiftListEntriesResponse>;\n delete: (indexId: string, entryId: string) => Promise<{ success: true }>;\n };\n\n constructor(private readonly client: RagableRequestClient) {\n this.indexes = {\n list: async () => {\n return this.client.request<{ indexes: ShiftIndex[] }>(\"/v1/shift/indexes\");\n },\n create: async (params) => {\n return this.client.request<ShiftIndex>(\"/v1/shift/indexes\", {\n method: \"POST\",\n body: params,\n });\n },\n get: async (indexId) => {\n return this.client.request<ShiftIndex>(`/v1/shift/indexes/${indexId}`);\n },\n update: async (indexId, params) => {\n return this.client.request<ShiftIndex>(`/v1/shift/indexes/${indexId}`, {\n method: \"PUT\",\n body: params,\n });\n },\n delete: async (indexId) => {\n return this.client.request<{ success: true }>(\n `/v1/shift/indexes/${indexId}`,\n {\n method: \"DELETE\",\n },\n );\n },\n };\n\n this.documents = {\n create: async (indexId, params) => {\n return this.client.request<ShiftIngestResponse>(\n `/v1/shift/indexes/${indexId}/documents`,\n {\n method: \"POST\",\n body: params,\n },\n );\n },\n upload: async (indexId, params) => {\n const formData = new FormData();\n const fileName = resolveUploadFileName(params);\n const contentType = resolveUploadContentType(params);\n const file = normalizeUploadFile(params.file, contentType);\n\n formData.set(\"file\", file, fileName);\n\n if (params.metadata) {\n formData.set(\"metadata\", JSON.stringify(params.metadata));\n }\n if (typeof params.chunkSize === \"number\") {\n formData.set(\"chunkSize\", String(params.chunkSize));\n }\n if (typeof params.chunkOverlap === \"number\") {\n formData.set(\"chunkOverlap\", String(params.chunkOverlap));\n }\n\n return this.client.request<ShiftIngestResponse>(\n `/v1/shift/indexes/${indexId}/files`,\n {\n method: \"POST\",\n body: formData,\n },\n );\n },\n };\n\n this.entries = {\n list: async (indexId, params = {}) => {\n const search = new URLSearchParams();\n if (typeof params.take === \"number\") {\n search.set(\"take\", String(params.take));\n }\n if (typeof params.skip === \"number\") {\n search.set(\"skip\", String(params.skip));\n }\n\n const suffix = search.size > 0 ? `?${search.toString()}` : \"\";\n return this.client.request<ShiftListEntriesResponse>(\n `/v1/shift/indexes/${indexId}/entries${suffix}`,\n );\n },\n delete: async (indexId, entryId) => {\n return this.client.request<{ success: true }>(\n `/v1/shift/indexes/${indexId}/entries/${entryId}`,\n {\n method: \"DELETE\",\n },\n );\n },\n };\n }\n\n async search(indexId: string, params: ShiftSearchParams) {\n return this.client.request<{ results: ShiftSearchResult[] }>(\n `/v1/shift/indexes/${indexId}/search`,\n {\n method: \"POST\",\n body: params,\n },\n );\n }\n}\n\nfunction resolveUploadFileName(params: ShiftUploadFileParams) {\n if (params.fileName) {\n return params.fileName;\n }\n\n if (isNamedBlob(params.file)) {\n return params.file.name;\n }\n\n return \"upload.bin\";\n}\n\nfunction resolveUploadContentType(params: ShiftUploadFileParams) {\n if (params.contentType) {\n return params.contentType;\n }\n\n if (params.file instanceof Blob && params.file.type) {\n return params.file.type;\n }\n\n return \"application/octet-stream\";\n}\n\nfunction normalizeUploadFile(file: ShiftUploadableFile, contentType: string) {\n if (file instanceof Blob) {\n return file;\n }\n\n if (file instanceof Uint8Array) {\n return new Blob([toArrayBuffer(file)], { type: contentType });\n }\n\n return new Blob([file], { type: contentType });\n}\n\nfunction isNamedBlob(value: ShiftUploadableFile): value is Blob & { name: string } {\n return value instanceof Blob && \"name\" in value && typeof value.name === \"string\";\n}\n\nfunction toArrayBuffer(value: Uint8Array) {\n const copy = new Uint8Array(value.byteLength);\n copy.set(value);\n return copy.buffer;\n}\n","/**\n * Shared SSE parsing for `data: {json}` lines (Ragable agent streams).\n */\nexport type SseJsonEvent = Record<string, unknown> & { type: string };\n\nexport async function parseMaybeJsonBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n return await response.json();\n } catch {\n return null;\n }\n }\n try {\n return await response.text();\n } catch {\n return null;\n }\n}\n\nexport function parseSseDataLine(line: string): SseJsonEvent | null {\n const dataPrefix = \"data: \";\n if (!line.startsWith(dataPrefix)) {\n return null;\n }\n const json = line.slice(dataPrefix.length).trim();\n if (json.length === 0 || json === \"[DONE]\") {\n return null;\n }\n try {\n return JSON.parse(json) as SseJsonEvent;\n } catch {\n return null;\n }\n}\n\n/**\n * Read an SSE body and yield parsed `data:` JSON objects (double-newline framed).\n */\nexport async function* readSseStream(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<SseJsonEvent, void, undefined> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n\n let boundary = buffer.indexOf(\"\\n\\n\");\n while (boundary !== -1) {\n const block = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n for (const line of block.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n boundary = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n if (buffer.trim().length > 0) {\n for (const line of buffer.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import {\n extractErrorMessage,\n RagableError,\n RagableRequestClient,\n} from \"./request-client\";\nimport { parseMaybeJsonBody, readSseStream } from \"./sse\";\n\nexport interface AgentSummary {\n id: string;\n name: string;\n description: string | null;\n active: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AgentChatMessage {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface AgentChatParams {\n message: string;\n history?: AgentChatMessage[];\n}\n\n/** Mirrors backend ExecutionResult JSON shape (traces are opaque in the SDK). */\nexport interface AgentChatResult {\n response: string;\n traces: unknown[];\n totalDurationMs: number;\n httpResponse?: unknown;\n}\n\n/**\n * Loose SSE event from POST /v1/agents/:id/chat/stream — narrows with `type` at runtime.\n */\nexport type AgentStreamEvent = Record<string, unknown> & { type: string };\n\nexport class AgentsClient {\n constructor(private readonly client: RagableRequestClient) {}\n\n async list(): Promise<{ agents: AgentSummary[] }> {\n return this.client.request(\"/v1/agents\");\n }\n\n async get(agentId: string): Promise<AgentSummary> {\n return this.client.request(`/v1/agents/${agentId}`);\n }\n\n async chat(\n agentId: string,\n params: AgentChatParams,\n ): Promise<AgentChatResult> {\n return this.client.request<AgentChatResult>(`/v1/agents/${agentId}/chat`, {\n method: \"POST\",\n body: {\n message: params.message,\n ...(params.history !== undefined ? { history: params.history } : {}),\n },\n });\n }\n\n /**\n * Stream agent execution as SSE (`data: {json}` lines). Yields parsed JSON objects.\n */\n async *chatStream(\n agentId: string,\n params: AgentChatParams,\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\n const response = await this.client.rawFetch(\n `/v1/agents/${agentId}/chat/stream`,\n {\n method: \"POST\",\n body: {\n message: params.message,\n ...(params.history !== undefined ? { history: params.history } : {}),\n },\n },\n );\n\n if (!response.ok) {\n const payload = await parseMaybeJsonBody(response);\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n\n const body = response.body;\n if (!body) {\n return;\n }\n\n yield* readSseStream(body);\n }\n}\n","import { extractErrorMessage, RagableError } from \"./request-client\";\nimport type { AgentChatParams, AgentStreamEvent } from \"./agents\";\nimport type { DefaultRagableDatabase, RagableDatabase } from \"./database-schema\";\nimport { parseMaybeJsonBody, readSseStream } from \"./sse\";\n\nexport function normalizeBrowserApiBase(baseUrl?: string): string {\n return (baseUrl ?? \"http://localhost:8080/api\").replace(/\\/+$/, \"\");\n}\n\nexport interface RagableBrowserClientOptions {\n /** Organization id (UUID) — public agent chat URLs. */\n organizationId: string;\n /**\n * Authentication group id when using {@link RagableBrowserAuthClient} or\n * {@link RagableBrowserDatabaseClient}.\n */\n authGroupId?: string;\n /**\n * Returns the end-user access JWT (from login/register/refresh).\n * Required for `auth.getMe`, `auth.updateMe`, and `database.query`.\n */\n getAccessToken?: () => string | null | Promise<string | null>;\n /**\n * API base URL including `/api`, e.g. `https://api.example.com/api`.\n * @default \"http://localhost:8080/api\"\n */\n baseUrl?: string;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\nfunction requireAuthGroupId(options: RagableBrowserClientOptions): string {\n const id = options.authGroupId?.trim();\n if (!id) {\n throw new Error(\n \"authGroupId is required for auth and database methods on the browser client\",\n );\n }\n return id;\n}\n\nasync function requireAccessToken(\n options: RagableBrowserClientOptions,\n): Promise<string> {\n const getter = options.getAccessToken;\n if (!getter) {\n throw new Error(\n \"getAccessToken is required for this call (return the end-user access JWT)\",\n );\n }\n const token = await getter();\n if (!token?.trim()) {\n throw new Error(\"getAccessToken returned no token\");\n }\n return token.trim();\n}\n\nasync function parseJsonOrThrow<T>(response: Response): Promise<T> {\n const payload = await parseMaybeJsonBody(response);\n if (!response.ok) {\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n return payload as T;\n}\n\n/** Successful register/login response (typed `user` via `AuthUser` generic). */\nexport interface BrowserAuthSession<\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n user: AuthUser;\n accessToken: string;\n refreshToken: string;\n expiresIn: string;\n}\n\nexport interface BrowserAuthTokens {\n accessToken: string;\n refreshToken: string;\n expiresIn: string;\n}\n\n/** End-user auth (email/password) for a linked authentication group — no org API key. */\nexport class RagableBrowserAuthClient<\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n constructor(private readonly options: RagableBrowserClientOptions) {}\n\n private get fetchImpl(): typeof fetch {\n return this.options.fetch ?? fetch;\n }\n\n private toUrl(path: string): string {\n return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n }\n\n private baseHeaders(json: boolean): Headers {\n const h = new Headers(this.options.headers);\n if (json) {\n h.set(\"Content-Type\", \"application/json\");\n }\n return h;\n }\n\n private authPrefix(): string {\n const gid = requireAuthGroupId(this.options);\n return `/auth-groups/${gid}/auth`;\n }\n\n async register(body: {\n email: string;\n password: string;\n name?: string;\n }): Promise<BrowserAuthSession<AuthUser>> {\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/register`, {\n method: \"POST\",\n headers: this.baseHeaders(true),\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n\n async login(body: {\n email: string;\n password: string;\n }): Promise<BrowserAuthSession<AuthUser>> {\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/login`, {\n method: \"POST\",\n headers: this.baseHeaders(true),\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n\n async refresh(body: { refreshToken: string }): Promise<BrowserAuthTokens> {\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/refresh`, {\n method: \"POST\",\n headers: this.baseHeaders(true),\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n\n async getMe(): Promise<{ user: AuthUser }> {\n const token = await requireAccessToken(this.options);\n const headers = this.baseHeaders(false);\n headers.set(\"Authorization\", `Bearer ${token}`);\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {\n method: \"GET\",\n headers,\n });\n return parseJsonOrThrow(response);\n }\n\n async updateMe(body: {\n name?: string | null;\n password?: string;\n }): Promise<{ user: AuthUser }> {\n const token = await requireAccessToken(this.options);\n const headers = this.baseHeaders(true);\n headers.set(\"Authorization\", `Bearer ${token}`);\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {\n method: \"PATCH\",\n headers,\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n}\n\nexport interface BrowserSqlQueryParams {\n databaseInstanceId: string;\n sql: string;\n params?: unknown[];\n /** Ignored — the API only allows safe read-only SQL for end users. */\n readOnly?: true;\n timeoutMs?: number;\n rowLimit?: number;\n}\n\nexport interface BrowserSqlQueryResult<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> {\n command: string;\n rowCount: number;\n truncated: boolean;\n rows: Row[];\n}\n\n/**\n * Run SQL against a Postgres instance linked to a website that uses the same `authGroupId`,\n * authenticated as the signed-in end-user (access token).\n *\n * Pass `createBrowserClient<YourDatabase>()` and use `query<Tables<YourDatabase, 't'>>()`\n * for Supabase-style row typing.\n */\nexport class RagableBrowserDatabaseClient<\n _Schema extends RagableDatabase = DefaultRagableDatabase,\n> {\n constructor(private readonly options: RagableBrowserClientOptions) {}\n\n private get fetchImpl(): typeof fetch {\n return this.options.fetch ?? fetch;\n }\n\n private toUrl(path: string): string {\n return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n }\n\n async query<Row extends Record<string, unknown> = Record<string, unknown>>(\n params: BrowserSqlQueryParams,\n ): Promise<BrowserSqlQueryResult<Row>> {\n const gid = requireAuthGroupId(this.options);\n const token = await requireAccessToken(this.options);\n const headers = this.baseHeaders();\n headers.set(\"Authorization\", `Bearer ${token}`);\n headers.set(\"Content-Type\", \"application/json\");\n const response = await this.fetchImpl(\n this.toUrl(`/auth-groups/${gid}/data/query`),\n {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n databaseInstanceId: params.databaseInstanceId,\n sql: params.sql,\n ...(params.params !== undefined ? { params: params.params } : {}),\n ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs } : {}),\n ...(params.rowLimit !== undefined ? { rowLimit: params.rowLimit } : {}),\n }),\n },\n );\n return parseJsonOrThrow(response);\n }\n\n private baseHeaders(): Headers {\n return new Headers(this.options.headers);\n }\n}\n\n/**\n * Browser-safe client: **no org API key**. Uses public routes and end-user JWTs\n * from {@link RagableBrowserAuthClient}.\n */\nexport class RagableBrowserAgentsClient {\n constructor(private readonly options: RagableBrowserClientOptions) {}\n\n private get fetchImpl(): typeof fetch {\n return this.options.fetch ?? fetch;\n }\n\n private toUrl(path: string): string {\n return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n }\n\n /**\n * Stream agent execution as SSE (`POST /public/organizations/:orgId/agents/:agentId/chat/stream`).\n */\n async *chatStream(\n agentId: string,\n params: AgentPublicChatParams,\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\n const orgId = this.options.organizationId;\n const body: Record<string, unknown> = {\n message: params.message,\n ...(params.history !== undefined ? { history: params.history } : {}),\n ...(params.triggerSubtype !== undefined\n ? { triggerSubtype: params.triggerSubtype }\n : {}),\n ...(params.triggerNodeId !== undefined\n ? { triggerNodeId: params.triggerNodeId }\n : {}),\n };\n\n const headers = new Headers(this.options.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n const response = await this.fetchImpl(\n this.toUrl(`/public/organizations/${orgId}/agents/${agentId}/chat/stream`),\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const payload = await parseMaybeJsonBody(response);\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n\n const streamBody = response.body;\n if (!streamBody) {\n return;\n }\n\n yield* readSseStream(streamBody);\n }\n}\n\n/** Public chat params — same shape as {@link AgentChatParams} plus optional trigger fields. */\nexport interface AgentPublicChatParams extends AgentChatParams {\n triggerSubtype?: string;\n triggerNodeId?: string;\n}\n\n/**\n * Browser client root. Use `createBrowserClient<Database, AuthUser>()` for Supabase-style\n * typing on {@link RagableBrowserDatabaseClient.query} and auth `user` payloads.\n */\nexport class RagableBrowser<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly agents: RagableBrowserAgentsClient;\n readonly auth: RagableBrowserAuthClient<AuthUser>;\n readonly database: RagableBrowserDatabaseClient<Database>;\n\n constructor(options: RagableBrowserClientOptions) {\n this.agents = new RagableBrowserAgentsClient(options);\n this.auth = new RagableBrowserAuthClient<AuthUser>(options);\n this.database = new RagableBrowserDatabaseClient<Database>(options);\n }\n}\n\n/**\n * Browser client: **no org `ragable_*` API key**.\n * - {@link RagableBrowser.agents} — public agent SSE.\n * - {@link RagableBrowser.auth} / {@link RagableBrowser.database} — need `authGroupId` (+ `getAccessToken` for protected calls).\n *\n * Pass schema and user types like Supabase: `createBrowserClient<Database, AuthUser>({ ... })`.\n * For Shift and `/v1/*`, use {@link createClient} on a server.\n */\nexport function createBrowserClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n>(options: RagableBrowserClientOptions): RagableBrowser<Database, AuthUser> {\n return new RagableBrowser<Database, AuthUser>(options);\n}\n","import type {\n ShiftAddDocumentParams,\n ShiftIngestResponse,\n ShiftSearchParams,\n ShiftSearchResult,\n ShiftUploadFileParams,\n} from \"./shift\";\n\n/** Minimal client surface for {@link createRagPipeline} (implemented by {@link Ragable}). */\nexport interface RagClientForPipeline {\n shift: {\n documents: {\n create: (\n indexId: string,\n params: ShiftAddDocumentParams,\n ) => Promise<ShiftIngestResponse>;\n upload: (\n indexId: string,\n params: ShiftUploadFileParams,\n ) => Promise<ShiftIngestResponse>;\n };\n search: (\n indexId: string,\n params: ShiftSearchParams,\n ) => Promise<{ results: ShiftSearchResult[] }>;\n };\n}\n\nexport interface FormatContextOptions {\n /** Prepended before numbered passages (default: \"Relevant passages:\\\\n\") */\n header?: string;\n /** Joiner between passages (default: \"\\\\n\\\\n\") */\n separator?: string;\n /** Omit results with similarity score below this (default: no filter) */\n minScore?: number;\n /** Truncate total context string to this UTF-16 length (default: no limit) */\n maxChars?: number;\n /** Include similarity score in each block (default: false) */\n includeScores?: boolean;\n}\n\nexport interface RagPipelineOptions {\n indexId: string;\n}\n\nexport type RetrieveParams = ShiftSearchParams & {\n format?: FormatContextOptions;\n};\n\nexport interface RagPipeline {\n readonly indexId: string;\n ingestText(params: ShiftAddDocumentParams): Promise<ShiftIngestResponse>;\n ingestFile(params: ShiftUploadFileParams): Promise<ShiftIngestResponse>;\n search(params: ShiftSearchParams): Promise<{ results: ShiftSearchResult[] }>;\n retrieve(params: RetrieveParams): Promise<{\n results: ShiftSearchResult[];\n context: string;\n }>;\n}\n\n/**\n * Turn vector search hits into a single block of text for system prompts or RAG user messages.\n */\nexport function formatRetrievalContext(\n results: ShiftSearchResult[],\n options: FormatContextOptions = {},\n): string {\n const header = options.header ?? \"Relevant passages:\\n\";\n const separator = options.separator ?? \"\\n\\n\";\n const minScore = options.minScore;\n\n let filtered = results;\n if (typeof minScore === \"number\") {\n filtered = results.filter((r) => r.score >= minScore);\n }\n\n const blocks = filtered.map((r, i) => {\n const scoreSuffix =\n options.includeScores === true ? ` (score: ${r.score.toFixed(4)})` : \"\";\n return `[${i + 1}]${scoreSuffix}\\n${r.content.trim()}`;\n });\n\n let text = (blocks.length > 0 ? header : \"\") + blocks.join(separator);\n\n if (typeof options.maxChars === \"number\" && text.length > options.maxChars) {\n text = text.slice(0, options.maxChars).trimEnd() + \"\\n…\";\n }\n\n return text;\n}\n\n/**\n * High-level RAG helpers bound to one Shift index: ingest, search, retrieve with prompt-ready context.\n */\nexport function createRagPipeline(\n client: RagClientForPipeline,\n options: RagPipelineOptions,\n): RagPipeline {\n const { indexId } = options;\n\n return {\n indexId,\n\n ingestText(params) {\n return client.shift.documents.create(indexId, params);\n },\n\n ingestFile(params) {\n return client.shift.documents.upload(indexId, params);\n },\n\n search(params) {\n return client.shift.search(indexId, params);\n },\n\n async retrieve(params) {\n const { format: formatOpts, ...searchParams } = params;\n const { results } = await client.shift.search(indexId, searchParams);\n const context = formatRetrievalContext(results, formatOpts ?? {});\n return { results, context };\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/request-client.ts","../src/shift.ts","../src/sse.ts","../src/agents.ts","../src/browser-postgrest.ts","../src/browser.ts","../src/rag.ts"],"sourcesContent":["export type {\n DefaultRagableDatabase,\n Json,\n RagableDatabase,\n RagableTableDefinition,\n Tables,\n TablesInsert,\n TablesUpdate,\n} from \"./database-schema\";\n\nexport type { RagableClientOptions, RequestOptions } from \"./request-client\";\nexport {\n extractErrorMessage,\n RagableError,\n RagableRequestClient,\n} from \"./request-client\";\n\nexport type {\n ShiftAddDocumentParams,\n ShiftCreateIndexParams,\n ShiftEntry,\n ShiftIndex,\n ShiftIngestResponse,\n ShiftListEntriesParams,\n ShiftListEntriesResponse,\n ShiftSearchParams,\n ShiftSearchResult,\n ShiftUpdateIndexParams,\n ShiftUploadableFile,\n ShiftUploadFileParams,\n} from \"./shift\";\nexport { ShiftClient } from \"./shift\";\n\nexport type {\n AgentChatMessage,\n AgentChatParams,\n AgentChatResult,\n AgentStreamEvent,\n AgentSummary,\n} from \"./agents\";\nexport { AgentsClient } from \"./agents\";\n\nexport type {\n AgentPublicChatParams,\n BrowserAuthSession,\n BrowserAuthTokens,\n BrowserSqlQueryParams,\n BrowserSqlQueryResult,\n PostgrestResult,\n RagableBrowserClientOptions,\n SupabaseCompatSession,\n} from \"./browser\";\nexport {\n createBrowserClient,\n createRagableBrowserClient,\n normalizeBrowserApiBase,\n RagableBrowser,\n RagableBrowserAgentsClient,\n RagableBrowserAuthClient,\n RagableBrowserDatabaseClient,\n} from \"./browser\";\n\nexport type {\n BrowserSqlExecParams,\n BrowserSqlExecResult,\n RunQuery,\n} from \"./browser-postgrest\";\nexport {\n asPostgrestResponse,\n PostgrestDeleteBuilder,\n PostgrestInsertBuilder,\n PostgrestSelectBuilder,\n PostgrestTableApi,\n PostgrestUpdateBuilder,\n} from \"./browser-postgrest\";\n\nexport type { SseJsonEvent } from \"./sse\";\nexport { parseSseDataLine, readSseStream } from \"./sse\";\n\nexport type {\n FormatContextOptions,\n RagClientForPipeline,\n RagPipeline,\n RagPipelineOptions,\n RetrieveParams,\n} from \"./rag\";\nexport { createRagPipeline, formatRetrievalContext } from \"./rag\";\n\nimport { AgentsClient } from \"./agents\";\nimport {\n createBrowserClient,\n normalizeBrowserApiBase,\n RagableBrowser,\n type RagableBrowserClientOptions,\n} from \"./browser\";\nimport type { DefaultRagableDatabase, RagableDatabase } from \"./database-schema\";\nimport {\n RagableRequestClient,\n type RagableClientOptions,\n} from \"./request-client\";\nimport { ShiftClient } from \"./shift\";\n\nexport class Ragable {\n readonly shift: ShiftClient;\n readonly agents: AgentsClient;\n readonly infrastructure: {\n shift: ShiftClient;\n };\n\n constructor(options: RagableClientOptions) {\n const client = new RagableRequestClient(options);\n this.shift = new ShiftClient(client);\n this.agents = new AgentsClient(client);\n this.infrastructure = {\n shift: this.shift,\n };\n }\n}\n\nfunction isServerClientOptions(o: unknown): o is RagableClientOptions {\n return (\n typeof o === \"object\" &&\n o !== null &&\n \"apiKey\" in o &&\n typeof (o as RagableClientOptions).apiKey === \"string\" &&\n (o as RagableClientOptions).apiKey.length > 0\n );\n}\n\n/**\n * **Supabase-style overloads**\n * - `createClient(RAGABLE_URL, { organizationId, authGroupId, … })` — browser (no API key)\n * - `createClient({ apiKey, baseUrl })` — server / Engine (secret key)\n *\n * Prefer {@link createRagableServerClient} in backend code if the dual overload is confusing.\n */\nexport function createClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n>(\n url: string,\n options: Omit<RagableBrowserClientOptions, \"baseUrl\">,\n): RagableBrowser<Database, AuthUser>;\nexport function createClient(options: RagableClientOptions): Ragable;\nexport function createClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n>(options: RagableBrowserClientOptions): RagableBrowser<Database, AuthUser>;\nexport function createClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n>(\n urlOrOptions: string | RagableClientOptions | RagableBrowserClientOptions,\n browserOptions?: Omit<RagableBrowserClientOptions, \"baseUrl\">,\n): Ragable | RagableBrowser<Database, AuthUser> {\n if (typeof urlOrOptions === \"string\") {\n if (!browserOptions) {\n throw new Error(\n \"createClient(url, options) requires options with at least organizationId\",\n );\n }\n const raw = urlOrOptions.trim().replace(/\\/+$/, \"\");\n const baseUrl = raw.endsWith(\"/api\") ? raw : `${raw}/api`;\n return createBrowserClient<Database, AuthUser>({\n ...browserOptions,\n baseUrl: normalizeBrowserApiBase(baseUrl),\n });\n }\n if (isServerClientOptions(urlOrOptions)) {\n return new Ragable(urlOrOptions);\n }\n if (\n typeof urlOrOptions === \"object\" &&\n urlOrOptions !== null &&\n \"organizationId\" in urlOrOptions &&\n typeof (urlOrOptions as RagableBrowserClientOptions).organizationId ===\n \"string\"\n ) {\n return createBrowserClient<Database, AuthUser>(\n urlOrOptions as RagableBrowserClientOptions,\n );\n }\n throw new Error(\n \"createClient(options) requires apiKey (server) or organizationId (browser)\",\n );\n}\n\n/**\n * Explicit **server** factory — same as `createClient({ apiKey, baseUrl })`.\n * Use in the Engine; never import alongside browser `createClient(url, …)` if you want tree-shaking clarity.\n */\nexport function createRagableServerClient(options: RagableClientOptions) {\n return new Ragable(options);\n}\n","export interface RagableClientOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\nexport type RequestOptions = Omit<RequestInit, \"body\"> & {\n body?: unknown;\n};\n\nexport class RagableError extends Error {\n readonly status: number;\n readonly body: unknown;\n\n constructor(message: string, status: number, body: unknown) {\n super(message);\n this.name = \"RagableError\";\n this.status = status;\n this.body = body;\n }\n}\n\nexport function extractErrorMessage(payload: unknown, fallback: string) {\n if (payload && typeof payload === \"object\") {\n if (\"error\" in payload && typeof payload.error === \"string\") {\n return payload.error;\n }\n if (\"message\" in payload && typeof payload.message === \"string\") {\n return payload.message;\n }\n }\n\n if (typeof payload === \"string\" && payload.length > 0) {\n return payload;\n }\n\n return fallback || \"Request failed\";\n}\n\nexport class RagableRequestClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly defaultHeaders: HeadersInit | undefined;\n\n constructor(options: RagableClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl ?? \"http://localhost:8080/api\";\n this.fetchImpl = options.fetch ?? fetch;\n this.defaultHeaders = options.headers;\n }\n\n toUrl(path: string) {\n const normalizedBase = this.baseUrl.replace(/\\/+$/, \"\");\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${normalizedBase}${normalizedPath}`;\n }\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const response = await this.rawFetch(path, options);\n const payload = await this.parseResponseBody(response);\n if (!response.ok) {\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n\n return payload as T;\n }\n\n /**\n * Low-level fetch with API key and JSON body encoding. Caller handles status and body.\n */\n async rawFetch(path: string, options: RequestOptions = {}): Promise<Response> {\n const headers = new Headers(this.defaultHeaders);\n headers.set(\"Authorization\", `Bearer ${this.apiKey}`);\n\n let body = options.body;\n if (body !== undefined && !isBodyInit(body)) {\n headers.set(\"Content-Type\", \"application/json\");\n body = JSON.stringify(body);\n }\n\n return this.fetchImpl(this.toUrl(path), {\n ...options,\n headers,\n body: body as BodyInit | undefined,\n });\n }\n\n private async parseResponseBody(response: Response): Promise<unknown> {\n if (response.status === 204) {\n return null;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n\n return response.text();\n }\n}\n\nexport function isBodyInit(value: unknown): value is BodyInit {\n return (\n typeof value === \"string\" ||\n value instanceof Blob ||\n value instanceof FormData ||\n value instanceof URLSearchParams ||\n value instanceof ArrayBuffer ||\n ArrayBuffer.isView(value)\n );\n}\n","import { RagableRequestClient } from \"./request-client\";\n\nexport interface ShiftIndex {\n id: string;\n name: string;\n description: string | null;\n dimensions: number;\n embeddingModel: string;\n status: string;\n entryCount?: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ShiftEntry {\n id: string;\n content: string;\n metadata: unknown;\n chunkIndex: number;\n createdAt: string;\n}\n\nexport interface ShiftSearchResult {\n content: string;\n score: number;\n metadata: unknown;\n}\n\nexport interface ShiftCreateIndexParams {\n name: string;\n description?: string;\n dimensions?: number;\n embeddingModel?: string;\n}\n\nexport interface ShiftUpdateIndexParams {\n name?: string;\n description?: string;\n}\n\nexport interface ShiftAddDocumentParams {\n content: string;\n metadata?: Record<string, unknown>;\n chunkSize?: number;\n chunkOverlap?: number;\n}\n\nexport type ShiftUploadableFile = Blob | ArrayBuffer | Uint8Array;\n\nexport interface ShiftUploadFileParams {\n file: ShiftUploadableFile;\n fileName?: string;\n contentType?: string;\n metadata?: Record<string, unknown>;\n chunkSize?: number;\n chunkOverlap?: number;\n}\n\nexport interface ShiftListEntriesParams {\n take?: number;\n skip?: number;\n}\n\nexport interface ShiftSearchParams {\n query: string;\n topK?: number;\n}\n\nexport interface ShiftIngestResponse {\n chunksCreated: number;\n entries: string[];\n extractedText?: string;\n message?: string;\n}\n\nexport interface ShiftListEntriesResponse {\n entries: ShiftEntry[];\n total: number;\n}\n\nexport class ShiftClient {\n readonly indexes: {\n list: () => Promise<{ indexes: ShiftIndex[] }>;\n create: (params: ShiftCreateIndexParams) => Promise<ShiftIndex>;\n get: (indexId: string) => Promise<ShiftIndex>;\n update: (indexId: string, params: ShiftUpdateIndexParams) => Promise<ShiftIndex>;\n delete: (indexId: string) => Promise<{ success: true }>;\n };\n\n readonly documents: {\n create: (\n indexId: string,\n params: ShiftAddDocumentParams,\n ) => Promise<ShiftIngestResponse>;\n upload: (\n indexId: string,\n params: ShiftUploadFileParams,\n ) => Promise<ShiftIngestResponse>;\n };\n\n readonly entries: {\n list: (\n indexId: string,\n params?: ShiftListEntriesParams,\n ) => Promise<ShiftListEntriesResponse>;\n delete: (indexId: string, entryId: string) => Promise<{ success: true }>;\n };\n\n constructor(private readonly client: RagableRequestClient) {\n this.indexes = {\n list: async () => {\n return this.client.request<{ indexes: ShiftIndex[] }>(\"/v1/shift/indexes\");\n },\n create: async (params) => {\n return this.client.request<ShiftIndex>(\"/v1/shift/indexes\", {\n method: \"POST\",\n body: params,\n });\n },\n get: async (indexId) => {\n return this.client.request<ShiftIndex>(`/v1/shift/indexes/${indexId}`);\n },\n update: async (indexId, params) => {\n return this.client.request<ShiftIndex>(`/v1/shift/indexes/${indexId}`, {\n method: \"PUT\",\n body: params,\n });\n },\n delete: async (indexId) => {\n return this.client.request<{ success: true }>(\n `/v1/shift/indexes/${indexId}`,\n {\n method: \"DELETE\",\n },\n );\n },\n };\n\n this.documents = {\n create: async (indexId, params) => {\n return this.client.request<ShiftIngestResponse>(\n `/v1/shift/indexes/${indexId}/documents`,\n {\n method: \"POST\",\n body: params,\n },\n );\n },\n upload: async (indexId, params) => {\n const formData = new FormData();\n const fileName = resolveUploadFileName(params);\n const contentType = resolveUploadContentType(params);\n const file = normalizeUploadFile(params.file, contentType);\n\n formData.set(\"file\", file, fileName);\n\n if (params.metadata) {\n formData.set(\"metadata\", JSON.stringify(params.metadata));\n }\n if (typeof params.chunkSize === \"number\") {\n formData.set(\"chunkSize\", String(params.chunkSize));\n }\n if (typeof params.chunkOverlap === \"number\") {\n formData.set(\"chunkOverlap\", String(params.chunkOverlap));\n }\n\n return this.client.request<ShiftIngestResponse>(\n `/v1/shift/indexes/${indexId}/files`,\n {\n method: \"POST\",\n body: formData,\n },\n );\n },\n };\n\n this.entries = {\n list: async (indexId, params = {}) => {\n const search = new URLSearchParams();\n if (typeof params.take === \"number\") {\n search.set(\"take\", String(params.take));\n }\n if (typeof params.skip === \"number\") {\n search.set(\"skip\", String(params.skip));\n }\n\n const suffix = search.size > 0 ? `?${search.toString()}` : \"\";\n return this.client.request<ShiftListEntriesResponse>(\n `/v1/shift/indexes/${indexId}/entries${suffix}`,\n );\n },\n delete: async (indexId, entryId) => {\n return this.client.request<{ success: true }>(\n `/v1/shift/indexes/${indexId}/entries/${entryId}`,\n {\n method: \"DELETE\",\n },\n );\n },\n };\n }\n\n async search(indexId: string, params: ShiftSearchParams) {\n return this.client.request<{ results: ShiftSearchResult[] }>(\n `/v1/shift/indexes/${indexId}/search`,\n {\n method: \"POST\",\n body: params,\n },\n );\n }\n}\n\nfunction resolveUploadFileName(params: ShiftUploadFileParams) {\n if (params.fileName) {\n return params.fileName;\n }\n\n if (isNamedBlob(params.file)) {\n return params.file.name;\n }\n\n return \"upload.bin\";\n}\n\nfunction resolveUploadContentType(params: ShiftUploadFileParams) {\n if (params.contentType) {\n return params.contentType;\n }\n\n if (params.file instanceof Blob && params.file.type) {\n return params.file.type;\n }\n\n return \"application/octet-stream\";\n}\n\nfunction normalizeUploadFile(file: ShiftUploadableFile, contentType: string) {\n if (file instanceof Blob) {\n return file;\n }\n\n if (file instanceof Uint8Array) {\n return new Blob([toArrayBuffer(file)], { type: contentType });\n }\n\n return new Blob([file], { type: contentType });\n}\n\nfunction isNamedBlob(value: ShiftUploadableFile): value is Blob & { name: string } {\n return value instanceof Blob && \"name\" in value && typeof value.name === \"string\";\n}\n\nfunction toArrayBuffer(value: Uint8Array) {\n const copy = new Uint8Array(value.byteLength);\n copy.set(value);\n return copy.buffer;\n}\n","/**\n * Shared SSE parsing for `data: {json}` lines (Ragable agent streams).\n */\nexport type SseJsonEvent = Record<string, unknown> & { type: string };\n\nexport async function parseMaybeJsonBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n return await response.json();\n } catch {\n return null;\n }\n }\n try {\n return await response.text();\n } catch {\n return null;\n }\n}\n\nexport function parseSseDataLine(line: string): SseJsonEvent | null {\n const dataPrefix = \"data: \";\n if (!line.startsWith(dataPrefix)) {\n return null;\n }\n const json = line.slice(dataPrefix.length).trim();\n if (json.length === 0 || json === \"[DONE]\") {\n return null;\n }\n try {\n return JSON.parse(json) as SseJsonEvent;\n } catch {\n return null;\n }\n}\n\n/**\n * Read an SSE body and yield parsed `data:` JSON objects (double-newline framed).\n */\nexport async function* readSseStream(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<SseJsonEvent, void, undefined> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n buffer += decoder.decode(value, { stream: true });\n\n let boundary = buffer.indexOf(\"\\n\\n\");\n while (boundary !== -1) {\n const block = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n for (const line of block.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n boundary = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n if (buffer.trim().length > 0) {\n for (const line of buffer.split(\"\\n\")) {\n const evt = parseSseDataLine(line);\n if (evt) {\n yield evt;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import {\n extractErrorMessage,\n RagableError,\n RagableRequestClient,\n} from \"./request-client\";\nimport { parseMaybeJsonBody, readSseStream } from \"./sse\";\n\nexport interface AgentSummary {\n id: string;\n name: string;\n description: string | null;\n active: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AgentChatMessage {\n role: \"user\" | \"assistant\";\n content: string;\n}\n\nexport interface AgentChatParams {\n message: string;\n history?: AgentChatMessage[];\n}\n\n/** Mirrors backend ExecutionResult JSON shape (traces are opaque in the SDK). */\nexport interface AgentChatResult {\n response: string;\n traces: unknown[];\n totalDurationMs: number;\n httpResponse?: unknown;\n}\n\n/**\n * Loose SSE event from POST /v1/agents/:id/chat/stream — narrows with `type` at runtime.\n */\nexport type AgentStreamEvent = Record<string, unknown> & { type: string };\n\nexport class AgentsClient {\n constructor(private readonly client: RagableRequestClient) {}\n\n async list(): Promise<{ agents: AgentSummary[] }> {\n return this.client.request(\"/v1/agents\");\n }\n\n async get(agentId: string): Promise<AgentSummary> {\n return this.client.request(`/v1/agents/${agentId}`);\n }\n\n async chat(\n agentId: string,\n params: AgentChatParams,\n ): Promise<AgentChatResult> {\n return this.client.request<AgentChatResult>(`/v1/agents/${agentId}/chat`, {\n method: \"POST\",\n body: {\n message: params.message,\n ...(params.history !== undefined ? { history: params.history } : {}),\n },\n });\n }\n\n /**\n * Stream agent execution as SSE (`data: {json}` lines). Yields parsed JSON objects.\n */\n async *chatStream(\n agentId: string,\n params: AgentChatParams,\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\n const response = await this.client.rawFetch(\n `/v1/agents/${agentId}/chat/stream`,\n {\n method: \"POST\",\n body: {\n message: params.message,\n ...(params.history !== undefined ? { history: params.history } : {}),\n },\n },\n );\n\n if (!response.ok) {\n const payload = await parseMaybeJsonBody(response);\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n\n const body = response.body;\n if (!body) {\n return;\n }\n\n yield* readSseStream(body);\n }\n}\n","import { RagableError } from \"./request-client\";\n\n/** Shared with {@link RagableBrowserDatabaseClient.query} — duplicated to avoid circular imports. */\nexport interface BrowserSqlExecParams {\n databaseInstanceId: string;\n sql: string;\n params?: unknown[];\n readOnly?: boolean;\n timeoutMs?: number;\n rowLimit?: number;\n}\n\nexport interface BrowserSqlExecResult<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> {\n command: string;\n rowCount: number;\n truncated: boolean;\n rows: Row[];\n}\n\ntype FilterOp = \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"like\" | \"ilike\";\n\ninterface Filter {\n op: FilterOp;\n column: string;\n value: unknown;\n}\n\nfunction assertIdent(name: string, ctx: string): void {\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {\n throw new RagableError(\n `Invalid ${ctx} identifier \"${name}\" (use letters, numbers, underscore)`,\n 400,\n null,\n );\n }\n}\n\nfunction quoteIdent(name: string): string {\n assertIdent(name, \"column\");\n return `\"${name}\"`;\n}\n\nconst OP_SQL: Record<FilterOp, string> = {\n eq: \"=\",\n neq: \"<>\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n like: \"LIKE\",\n ilike: \"ILIKE\",\n};\n\nexport type PostgrestResult<T> = {\n data: T;\n error: null;\n} | {\n data: null;\n error: RagableError;\n};\n\n/** Map async throws to `{ data, error }` like Supabase JS client. */\nexport async function asPostgrestResponse<T>(\n fn: () => Promise<T>,\n): Promise<PostgrestResult<T>> {\n try {\n const data = await fn();\n return { data, error: null };\n } catch (e) {\n const err =\n e instanceof RagableError\n ? e\n : new RagableError((e as Error).message, 500, null);\n return { data: null, error: err };\n }\n}\n\nexport type RunQuery = <R extends Record<string, unknown> = Record<string, unknown>>(\n p: BrowserSqlExecParams,\n) => Promise<BrowserSqlExecResult<R>>;\n\nfunction buildWhere(\n filters: Filter[],\n params: unknown[],\n): { clause: string; nextIdx: number } {\n if (filters.length === 0) return { clause: \"\", nextIdx: 1 };\n const parts: string[] = [];\n let i = params.length;\n for (const f of filters) {\n assertIdent(f.column, \"filter\");\n i += 1;\n parts.push(`${quoteIdent(f.column)} ${OP_SQL[f.op]} $${i}`);\n params.push(f.value);\n }\n return { clause: ` WHERE ${parts.join(\" AND \")}`, nextIdx: i };\n}\n\n/** Supabase/PostgREST-style read builder: `.from('t').select().eq().single()` */\nexport class PostgrestSelectBuilder<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> implements PromiseLike<PostgrestResult<Row[]>>\n{\n private filters: Filter[] = [];\n private _limit?: number;\n private _order?: { column: string; ascending: boolean };\n\n constructor(\n private readonly run: RunQuery,\n private readonly databaseInstanceId: string,\n private readonly table: string,\n private readonly columns: string,\n ) {\n assertIdent(table, \"table\");\n }\n\n eq(column: string, value: unknown): this {\n this.filters.push({ op: \"eq\", column, value });\n return this;\n }\n\n neq(column: string, value: unknown): this {\n this.filters.push({ op: \"neq\", column, value });\n return this;\n }\n\n gt(column: string, value: unknown): this {\n this.filters.push({ op: \"gt\", column, value });\n return this;\n }\n\n gte(column: string, value: unknown): this {\n this.filters.push({ op: \"gte\", column, value });\n return this;\n }\n\n lt(column: string, value: unknown): this {\n this.filters.push({ op: \"lt\", column, value });\n return this;\n }\n\n lte(column: string, value: unknown): this {\n this.filters.push({ op: \"lte\", column, value });\n return this;\n }\n\n like(column: string, value: unknown): this {\n this.filters.push({ op: \"like\", column, value });\n return this;\n }\n\n ilike(column: string, value: unknown): this {\n this.filters.push({ op: \"ilike\", column, value });\n return this;\n }\n\n limit(n: number): this {\n this._limit = n;\n return this;\n }\n\n order(column: string, options?: { ascending?: boolean }): this {\n this._order = { column, ascending: options?.ascending !== false };\n return this;\n }\n\n /** @param includeUserLimit when false, omit `.limit()` (for `.single()` / `.maybeSingle()`). */\n private buildSelectCore(params: unknown[], includeUserLimit: boolean): string {\n const tbl = quoteIdent(this.table);\n const { clause } = buildWhere(this.filters, params);\n let sql = `SELECT ${this.columns} FROM ${tbl}${clause}`;\n if (this._order) {\n sql += ` ORDER BY ${quoteIdent(this._order.column)} ${this._order.ascending ? \"ASC\" : \"DESC\"}`;\n }\n if (includeUserLimit && this._limit != null) {\n sql += ` LIMIT ${Math.max(0, Math.floor(this._limit))}`;\n }\n return sql;\n }\n\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\n onfulfilled?:\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null,\n ): Promise<TResult1 | TResult2> {\n return this.executeMany().then(onfulfilled, onrejected);\n }\n\n private async executeMany(): Promise<PostgrestResult<Row[]>> {\n return asPostgrestResponse(async () => {\n const params: unknown[] = [];\n const sql = this.buildSelectCore(params, true);\n const res = await this.run<Row>({\n databaseInstanceId: this.databaseInstanceId,\n sql,\n params,\n readOnly: true,\n });\n return res.rows;\n });\n }\n\n async single(): Promise<PostgrestResult<Row>> {\n return asPostgrestResponse(async () => {\n const params: unknown[] = [];\n const base = this.buildSelectCore(params, false);\n const sql = `${base} LIMIT 2`;\n const res = await this.run<Row>({\n databaseInstanceId: this.databaseInstanceId,\n sql,\n params,\n readOnly: true,\n });\n if (res.rows.length === 0) {\n throw new RagableError(\"JSON object requested, multiple (or no) rows returned\", 406, {\n code: \"PGRST116\",\n });\n }\n if (res.rows.length > 1) {\n throw new RagableError(\"JSON object requested, multiple (or no) rows returned\", 406, {\n code: \"PGRST116\",\n });\n }\n return res.rows[0]!;\n });\n }\n\n async maybeSingle(): Promise<PostgrestResult<Row | null>> {\n return asPostgrestResponse(async () => {\n const params: unknown[] = [];\n const base = this.buildSelectCore(params, false);\n const sql = `${base} LIMIT 2`;\n const res = await this.run<Row>({\n databaseInstanceId: this.databaseInstanceId,\n sql,\n params,\n readOnly: true,\n });\n if (res.rows.length > 1) {\n throw new RagableError(\"JSON object requested, multiple (or no) rows returned\", 406, {\n code: \"PGRST116\",\n });\n }\n return res.rows[0] ?? null;\n });\n }\n}\n\nexport class PostgrestInsertBuilder<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> implements PromiseLike<PostgrestResult<Row[]>>\n{\n private returning = \"*\";\n\n constructor(\n private readonly run: RunQuery,\n private readonly databaseInstanceId: string,\n private readonly table: string,\n private readonly rows: Record<string, unknown>[],\n ) {\n assertIdent(table, \"table\");\n }\n\n select(columns = \"*\"): this {\n this.returning = columns;\n return this;\n }\n\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\n onfulfilled?:\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null,\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n\n private async execute(): Promise<PostgrestResult<Row[]>> {\n return asPostgrestResponse(async () => {\n if (this.rows.length === 0) return [];\n const keys = Object.keys(this.rows[0]!);\n for (const k of keys) assertIdent(k, \"column\");\n const tbl = quoteIdent(this.table);\n const params: unknown[] = [];\n const valueGroups: string[] = [];\n for (const row of this.rows) {\n const placeholders: string[] = [];\n for (const k of keys) {\n params.push(row[k]);\n placeholders.push(`$${params.length}`);\n }\n valueGroups.push(`(${placeholders.join(\", \")})`);\n }\n const cols = keys.map(quoteIdent).join(\", \");\n const sql = `INSERT INTO ${tbl} (${cols}) VALUES ${valueGroups.join(\", \")} RETURNING ${this.returning}`;\n const res = await this.run<Row>({\n databaseInstanceId: this.databaseInstanceId,\n sql,\n params,\n readOnly: false,\n });\n return res.rows;\n });\n }\n}\n\nexport class PostgrestUpdateBuilder<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> implements PromiseLike<PostgrestResult<Row[]>>\n{\n private filters: Filter[] = [];\n private returning = \"*\";\n\n constructor(\n private readonly run: RunQuery,\n private readonly databaseInstanceId: string,\n private readonly table: string,\n private readonly patch: Record<string, unknown>,\n ) {\n assertIdent(table, \"table\");\n }\n\n eq(column: string, value: unknown): this {\n this.filters.push({ op: \"eq\", column, value });\n return this;\n }\n\n select(columns = \"*\"): this {\n this.returning = columns;\n return this;\n }\n\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\n onfulfilled?:\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null,\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n\n private async execute(): Promise<PostgrestResult<Row[]>> {\n return asPostgrestResponse(async () => {\n const keys = Object.keys(this.patch);\n if (keys.length === 0) {\n throw new RagableError(\"Empty update payload\", 400, null);\n }\n for (const k of keys) assertIdent(k, \"column\");\n if (this.filters.length === 0) {\n throw new RagableError(\n \"UPDATE requires a filter (e.g. .eq('id', value)) — refusing unscoped update\",\n 400,\n null,\n );\n }\n const params: unknown[] = [];\n const sets: string[] = [];\n for (const k of keys) {\n params.push(this.patch[k]);\n sets.push(`${quoteIdent(k)} = $${params.length}`);\n }\n const { clause } = buildWhere(this.filters, params);\n const tbl = quoteIdent(this.table);\n const sql = `UPDATE ${tbl} SET ${sets.join(\", \")}${clause} RETURNING ${this.returning}`;\n const res = await this.run<Row>({\n databaseInstanceId: this.databaseInstanceId,\n sql,\n params,\n readOnly: false,\n });\n return res.rows;\n });\n }\n}\n\nexport class PostgrestDeleteBuilder<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> implements PromiseLike<PostgrestResult<Row[]>>\n{\n private filters: Filter[] = [];\n private returning = \"*\";\n\n constructor(\n private readonly run: RunQuery,\n private readonly databaseInstanceId: string,\n private readonly table: string,\n ) {\n assertIdent(table, \"table\");\n }\n\n eq(column: string, value: unknown): this {\n this.filters.push({ op: \"eq\", column, value });\n return this;\n }\n\n select(columns = \"*\"): this {\n this.returning = columns;\n return this;\n }\n\n then<TResult1 = PostgrestResult<Row[]>, TResult2 = never>(\n onfulfilled?:\n | ((value: PostgrestResult<Row[]>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null,\n ): Promise<TResult1 | TResult2> {\n return this.execute().then(onfulfilled, onrejected);\n }\n\n private async execute(): Promise<PostgrestResult<Row[]>> {\n return asPostgrestResponse(async () => {\n if (this.filters.length === 0) {\n throw new RagableError(\n \"DELETE requires a filter (e.g. .eq('id', value)) — refusing unscoped delete\",\n 400,\n null,\n );\n }\n const params: unknown[] = [];\n const { clause } = buildWhere(this.filters, params);\n const tbl = quoteIdent(this.table);\n const sql = `DELETE FROM ${tbl}${clause} RETURNING ${this.returning}`;\n const res = await this.run<Row>({\n databaseInstanceId: this.databaseInstanceId,\n sql,\n params,\n readOnly: false,\n });\n return res.rows;\n });\n }\n}\n\nexport class PostgrestTableApi<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> {\n constructor(\n private readonly run: RunQuery,\n private readonly databaseInstanceId: string,\n private readonly table: string,\n ) {}\n\n select(columns = \"*\"): PostgrestSelectBuilder<Row> {\n return new PostgrestSelectBuilder(\n this.run,\n this.databaseInstanceId,\n this.table,\n columns,\n );\n }\n\n insert(\n values: Record<string, unknown> | Record<string, unknown>[],\n ): PostgrestInsertBuilder<Row> {\n const rows = Array.isArray(values) ? values : [values];\n return new PostgrestInsertBuilder(\n this.run,\n this.databaseInstanceId,\n this.table,\n rows,\n );\n }\n\n update(patch: Record<string, unknown>): PostgrestUpdateBuilder<Row> {\n return new PostgrestUpdateBuilder(\n this.run,\n this.databaseInstanceId,\n this.table,\n patch,\n );\n }\n\n delete(): PostgrestDeleteBuilder<Row> {\n return new PostgrestDeleteBuilder(\n this.run,\n this.databaseInstanceId,\n this.table,\n );\n }\n}\n","import { extractErrorMessage, RagableError } from \"./request-client\";\nimport type { AgentChatParams, AgentStreamEvent } from \"./agents\";\nimport type { DefaultRagableDatabase, RagableDatabase } from \"./database-schema\";\nimport { parseMaybeJsonBody, readSseStream } from \"./sse\";\nimport {\n asPostgrestResponse,\n PostgrestTableApi,\n type BrowserSqlExecParams,\n type PostgrestResult,\n type RunQuery,\n} from \"./browser-postgrest\";\n\nexport function normalizeBrowserApiBase(baseUrl?: string): string {\n return (baseUrl ?? \"http://localhost:8080/api\").replace(/\\/+$/, \"\");\n}\n\nexport interface RagableBrowserClientOptions {\n /** Organization id (UUID) — public agent chat URLs. */\n organizationId: string;\n /**\n * Authentication group id when using {@link RagableBrowserAuthClient} or\n * {@link RagableBrowserDatabaseClient}.\n */\n authGroupId?: string;\n /**\n * Default Backspace SQL instance id for {@link RagableBrowser.from} (Supabase-style table API).\n */\n databaseInstanceId?: string;\n /**\n * Returns the end-user access JWT (from login/register/refresh).\n * Required for `auth.getMe`, `auth.updateMe`, and `database.query`.\n */\n getAccessToken?: () => string | null | Promise<string | null>;\n /**\n * API base URL including `/api`, e.g. `https://api.example.com/api`.\n * @default \"http://localhost:8080/api\"\n */\n baseUrl?: string;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n}\n\nfunction requireAuthGroupId(options: RagableBrowserClientOptions): string {\n const id = options.authGroupId?.trim();\n if (!id) {\n throw new Error(\n \"authGroupId is required for auth and database methods on the browser client\",\n );\n }\n return id;\n}\n\nasync function requireAccessToken(\n options: RagableBrowserClientOptions,\n): Promise<string> {\n const getter = options.getAccessToken;\n if (!getter) {\n throw new Error(\n \"getAccessToken is required for this call (return the end-user access JWT)\",\n );\n }\n const token = await getter();\n if (!token?.trim()) {\n throw new Error(\"getAccessToken returned no token\");\n }\n return token.trim();\n}\n\nasync function parseJsonOrThrow<T>(response: Response): Promise<T> {\n const payload = await parseMaybeJsonBody(response);\n if (!response.ok) {\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n return payload as T;\n}\n\n/** Successful register/login response (typed `user` via `AuthUser` generic). */\nexport interface BrowserAuthSession<\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n user: AuthUser;\n accessToken: string;\n refreshToken: string;\n expiresIn: string;\n}\n\nexport interface BrowserAuthTokens {\n accessToken: string;\n refreshToken: string;\n expiresIn: string;\n}\n\n/** Supabase-compatible session shape (snake_case tokens). */\nexport interface SupabaseCompatSession<\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n access_token: string;\n refresh_token: string;\n /** Best-effort seconds from Ragable `expiresIn` (e.g. `7d`, `3600`). */\n expires_in: number;\n token_type: \"bearer\";\n user: AuthUser;\n}\n\nfunction parseExpiresInSeconds(expiresIn: string): number {\n const s = expiresIn.trim().toLowerCase();\n const m = /^(\\d+)([smhd])?$/.exec(s);\n if (m) {\n const n = Number(m[1]);\n const u = m[2] ?? \"s\";\n const mult =\n u === \"s\" ? 1 : u === \"m\" ? 60 : u === \"h\" ? 3600 : u === \"d\" ? 86400 : 1;\n return n * mult;\n }\n const asNum = Number(s);\n return Number.isFinite(asNum) ? asNum : 0;\n}\n\nfunction toSupabaseSession<\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n>(s: BrowserAuthSession<AuthUser>): SupabaseCompatSession<AuthUser> {\n return {\n access_token: s.accessToken,\n refresh_token: s.refreshToken,\n expires_in: parseExpiresInSeconds(s.expiresIn),\n token_type: \"bearer\",\n user: s.user,\n };\n}\n\nexport type { PostgrestResult };\n\n/** End-user auth — Ragable names + Supabase/Firebase-style aliases returning `{ data, error }`. */\nexport class RagableBrowserAuthClient<\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n constructor(private readonly options: RagableBrowserClientOptions) {}\n\n private get fetchImpl(): typeof fetch {\n return this.options.fetch ?? fetch;\n }\n\n private toUrl(path: string): string {\n return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n }\n\n private baseHeaders(json: boolean): Headers {\n const h = new Headers(this.options.headers);\n if (json) {\n h.set(\"Content-Type\", \"application/json\");\n }\n return h;\n }\n\n private authPrefix(): string {\n const gid = requireAuthGroupId(this.options);\n return `/auth-groups/${gid}/auth`;\n }\n\n /** Supabase: `signUp` → `{ data: { user, session }, error }` */\n async signUp(credentials: {\n email: string;\n password: string;\n options?: { data?: Record<string, unknown> };\n }): Promise<\n PostgrestResult<{\n user: AuthUser;\n session: SupabaseCompatSession<AuthUser>;\n }>\n > {\n return asPostgrestResponse(async () => {\n const name =\n typeof credentials.options?.data?.name === \"string\"\n ? credentials.options.data.name\n : undefined;\n const session = await this.register({\n email: credentials.email,\n password: credentials.password,\n name,\n });\n return { user: session.user, session: toSupabaseSession(session) };\n });\n }\n\n /** Supabase: `signInWithPassword` */\n async signInWithPassword(credentials: {\n email: string;\n password: string;\n }): Promise<\n PostgrestResult<{\n user: AuthUser;\n session: SupabaseCompatSession<AuthUser>;\n }>\n > {\n return asPostgrestResponse(async () => {\n const session = await this.login(credentials);\n return { user: session.user, session: toSupabaseSession(session) };\n });\n }\n\n /** Supabase: `refreshSession` */\n async refreshSession(refreshToken: string): Promise<\n PostgrestResult<{ session: SupabaseCompatSession<AuthUser>; user: AuthUser }>\n > {\n return asPostgrestResponse(async () => {\n const tokens = await this.refresh({ refreshToken });\n const me = await this.getUserFromToken(tokens.accessToken);\n const session: SupabaseCompatSession<AuthUser> = {\n access_token: tokens.accessToken,\n refresh_token: tokens.refreshToken,\n expires_in: parseExpiresInSeconds(tokens.expiresIn),\n token_type: \"bearer\",\n user: me.user,\n };\n return { session, user: me.user };\n });\n }\n\n /** Supabase: `getUser()` — needs `getAccessToken` on the client */\n async getUser(): Promise<PostgrestResult<{ user: AuthUser }>> {\n return asPostgrestResponse(() => this.getMe());\n }\n\n /** Supabase: `updateUser` */\n async updateUser(attributes: {\n email?: string;\n password?: string;\n data?: { name?: string | null };\n }): Promise<PostgrestResult<{ user: AuthUser }>> {\n return asPostgrestResponse(() =>\n this.updateMe({\n password: attributes.password,\n name: attributes.data?.name,\n }),\n );\n }\n\n /**\n * Supabase/Firebase: no server call — clear tokens in your app.\n * Returns `{ error: null }` for API compatibility.\n */\n async signOut(_options?: { scope?: \"global\" | \"local\" }): Promise<{\n error: null;\n }> {\n return { error: null };\n }\n\n private async getUserFromToken(accessToken: string): Promise<{ user: AuthUser }> {\n const headers = this.baseHeaders(false);\n headers.set(\"Authorization\", `Bearer ${accessToken}`);\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {\n method: \"GET\",\n headers,\n });\n return parseJsonOrThrow(response);\n }\n\n async register(body: {\n email: string;\n password: string;\n name?: string;\n }): Promise<BrowserAuthSession<AuthUser>> {\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/register`, {\n method: \"POST\",\n headers: this.baseHeaders(true),\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n\n async login(body: {\n email: string;\n password: string;\n }): Promise<BrowserAuthSession<AuthUser>> {\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/login`, {\n method: \"POST\",\n headers: this.baseHeaders(true),\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n\n async refresh(body: { refreshToken: string }): Promise<BrowserAuthTokens> {\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/refresh`, {\n method: \"POST\",\n headers: this.baseHeaders(true),\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n\n async getMe(): Promise<{ user: AuthUser }> {\n const token = await requireAccessToken(this.options);\n const headers = this.baseHeaders(false);\n headers.set(\"Authorization\", `Bearer ${token}`);\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {\n method: \"GET\",\n headers,\n });\n return parseJsonOrThrow(response);\n }\n\n async updateMe(body: {\n name?: string | null;\n password?: string;\n }): Promise<{ user: AuthUser }> {\n const token = await requireAccessToken(this.options);\n const headers = this.baseHeaders(true);\n headers.set(\"Authorization\", `Bearer ${token}`);\n const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {\n method: \"PATCH\",\n headers,\n body: JSON.stringify(body),\n });\n return parseJsonOrThrow(response);\n }\n}\n\nexport interface BrowserSqlQueryParams {\n databaseInstanceId: string;\n sql: string;\n params?: unknown[];\n /**\n * Default `true`. When `false`, the API allows INSERT/UPDATE/DELETE (and existing safe reads);\n * DDL (`CREATE`/`DROP`/`ALTER`/…) and privilege changes remain blocked.\n */\n readOnly?: boolean;\n timeoutMs?: number;\n rowLimit?: number;\n}\n\nexport interface BrowserSqlQueryResult<\n Row extends Record<string, unknown> = Record<string, unknown>,\n> {\n command: string;\n rowCount: number;\n truncated: boolean;\n rows: Row[];\n}\n\n/**\n * Raw SQL against linked Postgres (escape hatch). Prefer {@link RagableBrowser.from} for\n * Supabase-style `.select()` / `.insert()` / `.update()` / `.delete()`.\n */\nexport class RagableBrowserDatabaseClient<\n _Schema extends RagableDatabase = DefaultRagableDatabase,\n> {\n constructor(private readonly options: RagableBrowserClientOptions) {}\n\n private get fetchImpl(): typeof fetch {\n return this.options.fetch ?? fetch;\n }\n\n private toUrl(path: string): string {\n return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n }\n\n async query<Row extends Record<string, unknown> = Record<string, unknown>>(\n params: BrowserSqlQueryParams,\n ): Promise<BrowserSqlQueryResult<Row>> {\n const gid = requireAuthGroupId(this.options);\n const token = await requireAccessToken(this.options);\n const headers = this.baseHeaders();\n headers.set(\"Authorization\", `Bearer ${token}`);\n headers.set(\"Content-Type\", \"application/json\");\n const response = await this.fetchImpl(\n this.toUrl(`/auth-groups/${gid}/data/query`),\n {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n databaseInstanceId: params.databaseInstanceId,\n sql: params.sql,\n ...(params.params !== undefined ? { params: params.params } : {}),\n ...(params.readOnly === false ? { readOnly: false } : {}),\n ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs } : {}),\n ...(params.rowLimit !== undefined ? { rowLimit: params.rowLimit } : {}),\n }),\n },\n );\n return parseJsonOrThrow(response);\n }\n\n private baseHeaders(): Headers {\n return new Headers(this.options.headers);\n }\n}\n\n/**\n * Browser-safe client: **no org API key**. Uses public routes and end-user JWTs\n * from {@link RagableBrowserAuthClient}.\n */\nexport class RagableBrowserAgentsClient {\n constructor(private readonly options: RagableBrowserClientOptions) {}\n\n private get fetchImpl(): typeof fetch {\n return this.options.fetch ?? fetch;\n }\n\n private toUrl(path: string): string {\n return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith(\"/\") ? path : `/${path}`}`;\n }\n\n /**\n * Stream agent execution as SSE (`POST /public/organizations/:orgId/agents/:agentId/chat/stream`).\n */\n async *chatStream(\n agentId: string,\n params: AgentPublicChatParams,\n ): AsyncGenerator<AgentStreamEvent, void, undefined> {\n const orgId = this.options.organizationId;\n const body: Record<string, unknown> = {\n message: params.message,\n ...(params.history !== undefined ? { history: params.history } : {}),\n ...(params.triggerSubtype !== undefined\n ? { triggerSubtype: params.triggerSubtype }\n : {}),\n ...(params.triggerNodeId !== undefined\n ? { triggerNodeId: params.triggerNodeId }\n : {}),\n };\n\n const headers = new Headers(this.options.headers);\n headers.set(\"Content-Type\", \"application/json\");\n\n const response = await this.fetchImpl(\n this.toUrl(`/public/organizations/${orgId}/agents/${agentId}/chat/stream`),\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n const payload = await parseMaybeJsonBody(response);\n const message = extractErrorMessage(payload, response.statusText);\n throw new RagableError(message, response.status, payload);\n }\n\n const streamBody = response.body;\n if (!streamBody) {\n return;\n }\n\n yield* readSseStream(streamBody);\n }\n}\n\n/** Public chat params — same shape as {@link AgentChatParams} plus optional trigger fields. */\nexport interface AgentPublicChatParams extends AgentChatParams {\n triggerSubtype?: string;\n triggerNodeId?: string;\n}\n\n/**\n * Browser client: mirrors **Supabase JS** (`createClient`, `.from()`, `.auth.signInWithPassword`, `{ data, error }`)\n * plus Ragable **`agents.chatStream`**. Server secrets: {@link createRagableServerClient} / {@link createClient} with `apiKey`.\n */\nexport class RagableBrowser<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n> {\n readonly agents: RagableBrowserAgentsClient;\n readonly auth: RagableBrowserAuthClient<AuthUser>;\n readonly database: RagableBrowserDatabaseClient<Database>;\n private readonly options: RagableBrowserClientOptions;\n\n constructor(options: RagableBrowserClientOptions) {\n this.options = options;\n this.agents = new RagableBrowserAgentsClient(options);\n this.auth = new RagableBrowserAuthClient<AuthUser>(options);\n this.database = new RagableBrowserDatabaseClient<Database>(options);\n }\n\n /**\n * Supabase-style table API: `.from('items').select().eq('id', 1).single()`.\n * Pass `databaseInstanceId` here or set `databaseInstanceId` on the client options.\n */\n from<Row extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n databaseInstanceId?: string,\n ): PostgrestTableApi<Row> {\n const id =\n databaseInstanceId?.trim() || this.options.databaseInstanceId?.trim();\n if (!id) {\n throw new Error(\n \"RagableBrowser.from() requires databaseInstanceId in client options or as the second argument\",\n );\n }\n const run: RunQuery = <R extends Record<string, unknown>>(\n p: BrowserSqlExecParams,\n ) => this.database.query<R>(p);\n return new PostgrestTableApi<Row>(run, id, table);\n }\n}\n\n/**\n * **Supabase-equivalent** browser client factory (no org API key).\n * Same as {@link createRagableBrowserClient}.\n */\nexport function createBrowserClient<\n Database extends RagableDatabase = DefaultRagableDatabase,\n AuthUser extends Record<string, unknown> = Record<string, unknown>,\n>(options: RagableBrowserClientOptions): RagableBrowser<Database, AuthUser> {\n return new RagableBrowser<Database, AuthUser>(options);\n}\n\n/** Alias for {@link createBrowserClient} — matches Supabase `createClient` naming. */\nexport const createRagableBrowserClient = createBrowserClient;\n","import type {\n ShiftAddDocumentParams,\n ShiftIngestResponse,\n ShiftSearchParams,\n ShiftSearchResult,\n ShiftUploadFileParams,\n} from \"./shift\";\n\n/** Minimal client surface for {@link createRagPipeline} (implemented by {@link Ragable}). */\nexport interface RagClientForPipeline {\n shift: {\n documents: {\n create: (\n indexId: string,\n params: ShiftAddDocumentParams,\n ) => Promise<ShiftIngestResponse>;\n upload: (\n indexId: string,\n params: ShiftUploadFileParams,\n ) => Promise<ShiftIngestResponse>;\n };\n search: (\n indexId: string,\n params: ShiftSearchParams,\n ) => Promise<{ results: ShiftSearchResult[] }>;\n };\n}\n\nexport interface FormatContextOptions {\n /** Prepended before numbered passages (default: \"Relevant passages:\\\\n\") */\n header?: string;\n /** Joiner between passages (default: \"\\\\n\\\\n\") */\n separator?: string;\n /** Omit results with similarity score below this (default: no filter) */\n minScore?: number;\n /** Truncate total context string to this UTF-16 length (default: no limit) */\n maxChars?: number;\n /** Include similarity score in each block (default: false) */\n includeScores?: boolean;\n}\n\nexport interface RagPipelineOptions {\n indexId: string;\n}\n\nexport type RetrieveParams = ShiftSearchParams & {\n format?: FormatContextOptions;\n};\n\nexport interface RagPipeline {\n readonly indexId: string;\n ingestText(params: ShiftAddDocumentParams): Promise<ShiftIngestResponse>;\n ingestFile(params: ShiftUploadFileParams): Promise<ShiftIngestResponse>;\n search(params: ShiftSearchParams): Promise<{ results: ShiftSearchResult[] }>;\n retrieve(params: RetrieveParams): Promise<{\n results: ShiftSearchResult[];\n context: string;\n }>;\n}\n\n/**\n * Turn vector search hits into a single block of text for system prompts or RAG user messages.\n */\nexport function formatRetrievalContext(\n results: ShiftSearchResult[],\n options: FormatContextOptions = {},\n): string {\n const header = options.header ?? \"Relevant passages:\\n\";\n const separator = options.separator ?? \"\\n\\n\";\n const minScore = options.minScore;\n\n let filtered = results;\n if (typeof minScore === \"number\") {\n filtered = results.filter((r) => r.score >= minScore);\n }\n\n const blocks = filtered.map((r, i) => {\n const scoreSuffix =\n options.includeScores === true ? ` (score: ${r.score.toFixed(4)})` : \"\";\n return `[${i + 1}]${scoreSuffix}\\n${r.content.trim()}`;\n });\n\n let text = (blocks.length > 0 ? header : \"\") + blocks.join(separator);\n\n if (typeof options.maxChars === \"number\" && text.length > options.maxChars) {\n text = text.slice(0, options.maxChars).trimEnd() + \"\\n…\";\n }\n\n return text;\n}\n\n/**\n * High-level RAG helpers bound to one Shift index: ingest, search, retrieve with prompt-ready context.\n */\nexport function createRagPipeline(\n client: RagClientForPipeline,\n options: RagPipelineOptions,\n): RagPipeline {\n const { indexId } = options;\n\n return {\n indexId,\n\n ingestText(params) {\n return client.shift.documents.create(indexId, params);\n },\n\n ingestFile(params) {\n return client.shift.documents.upload(indexId, params);\n },\n\n search(params) {\n return client.shift.search(indexId, params);\n },\n\n async retrieve(params) {\n const { format: formatOpts, ...searchParams } = params;\n const { results } = await client.shift.search(indexId, searchParams);\n const context = formatRetrievalContext(results, formatOpts ?? {});\n return { results, context };\n },\n };\n}\n"],"mappings":"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","names":[]}