@usepanacea/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@usepanacea/sdk` will be documented in this file.
4
+
5
+ ## [0.1.0] - 2026-06-05
6
+
7
+ ### Features
8
+
9
+ - `PanaceaClient` with `query()`, `ingest()`, `health()` top-level methods
10
+ - `wiki.*` sub-client: `list()`, `get()`, `create()`, `update()`, `delete()`, `rollback()`
11
+ - `review.*` sub-client: `list()`, `approve()`, `reject()`, `modify()`
12
+ - `webhooks.*` sub-client: `list()`, `create()`, `delete()`
13
+ - Multi-turn session support via `sessionId` on `query()`
14
+ - SSE streaming support via `Accept: text/event-stream` (native fetch)
15
+ - `PanaceaApiError` with typed `code`, `status`, and `traceId`
16
+ - Browser + Node.js entry points (ESM + CJS)
17
+ - Zero runtime dependencies — `@panacea/shared` bundled at build time
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # @usepanacea/sdk
2
+
3
+ Official TypeScript SDK for the Panacea platform. Works in Node.js, edge runtimes (Vercel/Cloudflare), and the browser.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @usepanacea/sdk
9
+ # or
10
+ pnpm add @usepanacea/sdk
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```ts
16
+ import { PanaceaClient } from "@usepanacea/sdk";
17
+
18
+ const client = new PanaceaClient({
19
+ apiKey: process.env.PANACEA_API_KEY!,
20
+ baseURL: "https://your-panacea-instance.example.com",
21
+ });
22
+
23
+ // Ask a question
24
+ const result = await client.query("How do I reset my password?");
25
+ console.log(result.answer);
26
+ console.log(`Confidence: ${(result.confidence * 100).toFixed(0)}%`);
27
+ console.log(
28
+ "Sources:",
29
+ result.sources.map((s) => s.path),
30
+ );
31
+
32
+ // Multi-turn conversation
33
+ const followUp = await client.query("What about enterprise SSO?", {
34
+ sessionId: result.sessionId,
35
+ });
36
+ ```
37
+
38
+ ## Ingestion
39
+
40
+ ```ts
41
+ // Ingest a URL
42
+ const job = await client.ingest({
43
+ type: "url",
44
+ url: "https://docs.example.com/setup",
45
+ });
46
+ console.log(job.jobId); // track via GET /api/v1/ingest/:jobId
47
+
48
+ // Ingest raw Markdown text
49
+ await client.ingest({
50
+ type: "text",
51
+ content: "# FAQ\n\n## How do I reset my password?\n...",
52
+ filename: "faq.md",
53
+ category: "faq",
54
+ });
55
+ ```
56
+
57
+ ## Wiki
58
+
59
+ ```ts
60
+ // List entries
61
+ const { data } = await client.wiki.list({ tag: "billing", limit: 20 });
62
+
63
+ // Get a single entry
64
+ const entry = await client.wiki.get("faq/reset-password");
65
+
66
+ // Create or update an entry (trainer+ role required)
67
+ await client.wiki.create({ path: "faq/reset-password", content: "..." });
68
+ await client.wiki.update("faq/reset-password", { content: "Updated content" });
69
+
70
+ // Roll back to a previous version
71
+ await client.wiki.rollback("faq/reset-password", { version: 2 });
72
+
73
+ // Delete
74
+ await client.wiki.delete("faq/reset-password");
75
+ ```
76
+
77
+ ## Review Queue
78
+
79
+ ```ts
80
+ const { items } = await client.review.list({ status: "pending" });
81
+
82
+ await client.review.approve(items[0].id);
83
+ await client.review.reject(items[0].id, { reason: "Contradicts billing policy" });
84
+ await client.review.modify(items[0].id, { content: "Corrected content..." });
85
+ ```
86
+
87
+ ## Health
88
+
89
+ ```ts
90
+ const health = await client.health();
91
+ console.log(`Wiki size: ${health.wikiSize}`);
92
+ console.log(`Health score: ${health.healthScore}`);
93
+ console.log(`Needs review: ${health.needsReview}`);
94
+ ```
95
+
96
+ ## Error Handling
97
+
98
+ ```ts
99
+ import { PanaceaApiError } from "@usepanacea/sdk";
100
+
101
+ try {
102
+ await client.query("...");
103
+ } catch (err) {
104
+ if (err instanceof PanaceaApiError) {
105
+ console.error(err.code); // e.g. "rate_limit_exceeded"
106
+ console.error(err.status); // HTTP status code
107
+ console.error(err.traceId); // for support
108
+ if (err.code === "session_expired") {
109
+ // Start a new session
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## Client Options
116
+
117
+ ```ts
118
+ new PanaceaClient({
119
+ apiKey: "pk_live_...", // required
120
+ baseURL: "https://...", // required
121
+ tenantId: "tenant_abc", // optional — sent as X-Tenant-Id header
122
+ headers: { "X-Custom": "value" }, // optional extra headers
123
+ fetch: customFetch, // optional fetch override (testing)
124
+ });
125
+ ```
126
+
127
+ ## Build
128
+
129
+ ```bash
130
+ pnpm build # tsup → dist/ (ESM + CJS)
131
+ pnpm typecheck # tsc --noEmit
132
+ pnpm test # vitest run
133
+ ```
@@ -0,0 +1,249 @@
1
+ 'use strict';
2
+
3
+ // src/http.ts
4
+ var PanaceaApiError = class extends Error {
5
+ code;
6
+ status;
7
+ retriable;
8
+ traceId;
9
+ constructor(status, body) {
10
+ super(body.error.message);
11
+ this.name = "PanaceaApiError";
12
+ this.code = body.error.code;
13
+ this.status = status;
14
+ this.retriable = body.error.retriable;
15
+ this.traceId = body.error.traceId;
16
+ }
17
+ };
18
+ var HttpClient = class {
19
+ baseURL;
20
+ defaultHeaders;
21
+ _fetch;
22
+ constructor(opts) {
23
+ this.baseURL = opts.baseURL.replace(/\/$/, "");
24
+ this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
25
+ this.defaultHeaders = {
26
+ "Content-Type": "application/json",
27
+ Accept: "application/json",
28
+ Authorization: `Bearer ${opts.apiKey}`,
29
+ ...opts.tenantId ? { "X-Tenant-Id": opts.tenantId } : {},
30
+ ...opts.headers
31
+ };
32
+ }
33
+ async get(path, params) {
34
+ const url = new URL(this.baseURL + path);
35
+ if (params) {
36
+ for (const [k, v] of Object.entries(params)) {
37
+ if (v !== void 0) url.searchParams.set(k, String(v));
38
+ }
39
+ }
40
+ const res = await this._fetch(url.toString(), {
41
+ method: "GET",
42
+ headers: this.defaultHeaders
43
+ });
44
+ return this.parseResponse(res);
45
+ }
46
+ async post(path, body) {
47
+ const res = await this._fetch(this.baseURL + path, {
48
+ method: "POST",
49
+ headers: this.defaultHeaders,
50
+ body: body !== void 0 ? JSON.stringify(body) : void 0
51
+ });
52
+ return this.parseResponse(res);
53
+ }
54
+ async patch(path, body) {
55
+ const res = await this._fetch(this.baseURL + path, {
56
+ method: "PATCH",
57
+ headers: this.defaultHeaders,
58
+ body: body !== void 0 ? JSON.stringify(body) : void 0
59
+ });
60
+ return this.parseResponse(res);
61
+ }
62
+ async delete(path) {
63
+ const res = await this._fetch(this.baseURL + path, {
64
+ method: "DELETE",
65
+ headers: this.defaultHeaders
66
+ });
67
+ return this.parseResponse(res);
68
+ }
69
+ async parseResponse(res) {
70
+ const text = await res.text();
71
+ let json;
72
+ try {
73
+ json = JSON.parse(text);
74
+ } catch {
75
+ if (!res.ok) throw new Error(`HTTP ${res.status}: ${text}`);
76
+ return void 0;
77
+ }
78
+ if (!res.ok) {
79
+ throw new PanaceaApiError(res.status, json);
80
+ }
81
+ return json;
82
+ }
83
+ };
84
+
85
+ // src/wiki.ts
86
+ var WikiClient = class {
87
+ constructor(http) {
88
+ this.http = http;
89
+ }
90
+ http;
91
+ /**
92
+ * List wiki entries (paginated).
93
+ */
94
+ list(opts) {
95
+ return this.http.get("/api/v1/wiki", {
96
+ page: opts?.page,
97
+ limit: opts?.limit,
98
+ status: opts?.status
99
+ });
100
+ }
101
+ /**
102
+ * Get a single wiki entry by path slug.
103
+ */
104
+ get(path) {
105
+ return this.http.get(`/api/v1/wiki/${encodeURIComponent(path)}`);
106
+ }
107
+ /**
108
+ * Create a new wiki entry.
109
+ */
110
+ create(opts) {
111
+ return this.http.post("/api/v1/wiki", opts);
112
+ }
113
+ /**
114
+ * Update an existing wiki entry.
115
+ */
116
+ update(path, opts) {
117
+ return this.http.patch(`/api/v1/wiki/${encodeURIComponent(path)}`, opts);
118
+ }
119
+ /**
120
+ * Delete a wiki entry.
121
+ */
122
+ delete(path) {
123
+ return this.http.delete(`/api/v1/wiki/${encodeURIComponent(path)}`);
124
+ }
125
+ };
126
+
127
+ // src/review.ts
128
+ var ReviewClient = class {
129
+ constructor(http) {
130
+ this.http = http;
131
+ }
132
+ http;
133
+ /**
134
+ * List review queue items (paginated).
135
+ */
136
+ list(opts) {
137
+ return this.http.get("/api/v1/review", {
138
+ page: opts?.page,
139
+ limit: opts?.limit,
140
+ status: opts?.status
141
+ });
142
+ }
143
+ /**
144
+ * Get a single review item by ID.
145
+ */
146
+ get(id) {
147
+ return this.http.get(`/api/v1/review/${id}`);
148
+ }
149
+ /**
150
+ * Approve, reject, or modify a review item.
151
+ */
152
+ act(id, opts) {
153
+ return this.http.post(`/api/v1/review/${id}`, opts);
154
+ }
155
+ };
156
+
157
+ // src/webhooks-client.ts
158
+ var WebhooksClient = class {
159
+ constructor(http) {
160
+ this.http = http;
161
+ }
162
+ http;
163
+ /**
164
+ * List registered webhooks.
165
+ */
166
+ list() {
167
+ return this.http.get("/api/v1/webhooks");
168
+ }
169
+ /**
170
+ * Register a new webhook endpoint.
171
+ */
172
+ create(opts) {
173
+ return this.http.post("/api/v1/webhooks", opts);
174
+ }
175
+ /**
176
+ * Delete a webhook registration.
177
+ */
178
+ delete(id) {
179
+ return this.http.delete(`/api/v1/webhooks/${id}`);
180
+ }
181
+ /**
182
+ * Replay the last event delivery for a webhook.
183
+ */
184
+ replay(id) {
185
+ return this.http.post(`/api/v1/webhooks/${id}/replay`);
186
+ }
187
+ };
188
+
189
+ // src/client.ts
190
+ var PanaceaClient = class {
191
+ http;
192
+ /** Wiki knowledge base CRUD */
193
+ wiki;
194
+ /** Review queue operations */
195
+ review;
196
+ /** Webhook registration management */
197
+ webhooks;
198
+ constructor(opts) {
199
+ if (!opts.apiKey) throw new Error("PanaceaClient: apiKey is required");
200
+ if (!opts.baseURL) throw new Error("PanaceaClient: baseURL is required");
201
+ this.http = new HttpClient(opts);
202
+ this.wiki = new WikiClient(this.http);
203
+ this.review = new ReviewClient(this.http);
204
+ this.webhooks = new WebhooksClient(this.http);
205
+ }
206
+ query(questionOrOpts, rest) {
207
+ const body = typeof questionOrOpts === "string" ? { question: questionOrOpts, ...rest } : questionOrOpts;
208
+ return this.http.post("/api/v1/query", body);
209
+ }
210
+ // ---------------------------------------------------------------------------
211
+ // Ingest
212
+ // ---------------------------------------------------------------------------
213
+ /**
214
+ * Submit a URL or raw text content for ingestion.
215
+ *
216
+ * @example URL
217
+ * ```typescript
218
+ * await client.ingest({ type: "url", url: "https://docs.example.com" })
219
+ * ```
220
+ *
221
+ * @example Raw text
222
+ * ```typescript
223
+ * await client.ingest({ type: "text", content: "# FAQ\n...", filename: "faq.md" })
224
+ * ```
225
+ */
226
+ ingest(opts) {
227
+ const body = opts.type === "url" ? { url: opts.url, slug: opts.slug, category: opts.category } : {
228
+ content: opts.content,
229
+ filename: opts.filename,
230
+ slug: opts.slug,
231
+ category: opts.category
232
+ };
233
+ return this.http.post("/api/v1/ingest", body);
234
+ }
235
+ // ---------------------------------------------------------------------------
236
+ // Health
237
+ // ---------------------------------------------------------------------------
238
+ /**
239
+ * Get the current system health report.
240
+ */
241
+ health() {
242
+ return this.http.get("/api/v1/health");
243
+ }
244
+ };
245
+
246
+ exports.PanaceaApiError = PanaceaApiError;
247
+ exports.PanaceaClient = PanaceaClient;
248
+ //# sourceMappingURL=browser.cjs.map
249
+ //# sourceMappingURL=browser.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/http.ts","../src/wiki.ts","../src/review.ts","../src/webhooks-client.ts","../src/client.ts"],"names":[],"mappings":"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","file":"browser.cjs","sourcesContent":["/**\n * @module http\n * Internal fetch wrapper used by PanaceaClient.\n * Works in Node.js (18+), browser, and edge runtimes (native fetch).\n */\n\nimport type { ApiErrorBody } from \"./types.js\";\n\nexport class PanaceaApiError extends Error {\n readonly code: string;\n readonly status: number;\n readonly retriable: boolean;\n readonly traceId?: string;\n\n constructor(status: number, body: ApiErrorBody) {\n super(body.error.message);\n this.name = \"PanaceaApiError\";\n this.code = body.error.code;\n this.status = status;\n this.retriable = body.error.retriable;\n this.traceId = body.error.traceId;\n }\n}\n\nexport interface HttpClientOptions {\n baseURL: string;\n apiKey: string;\n /** Tenant ID header value (X-Tenant-Id). Required if your installation uses it. */\n tenantId?: string;\n /** Override the global fetch (e.g. for testing) */\n fetch?: typeof globalThis.fetch;\n /** Additional default headers */\n headers?: Record<string, string>;\n}\n\nexport class HttpClient {\n private readonly baseURL: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly _fetch: typeof globalThis.fetch;\n\n constructor(opts: HttpClientOptions) {\n this.baseURL = opts.baseURL.replace(/\\/$/, \"\");\n this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.defaultHeaders = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: `Bearer ${opts.apiKey}`,\n ...(opts.tenantId ? { \"X-Tenant-Id\": opts.tenantId } : {}),\n ...opts.headers,\n };\n }\n\n async get<T>(\n path: string,\n params?: Record<string, string | number | boolean | undefined>,\n ): Promise<T> {\n const url = new URL(this.baseURL + path);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined) url.searchParams.set(k, String(v));\n }\n }\n const res = await this._fetch(url.toString(), {\n method: \"GET\",\n headers: this.defaultHeaders,\n });\n return this.parseResponse<T>(res);\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n const res = await this._fetch(this.baseURL + path, {\n method: \"POST\",\n headers: this.defaultHeaders,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n return this.parseResponse<T>(res);\n }\n\n async patch<T>(path: string, body?: unknown): Promise<T> {\n const res = await this._fetch(this.baseURL + path, {\n method: \"PATCH\",\n headers: this.defaultHeaders,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n return this.parseResponse<T>(res);\n }\n\n async delete<T = void>(path: string): Promise<T> {\n const res = await this._fetch(this.baseURL + path, {\n method: \"DELETE\",\n headers: this.defaultHeaders,\n });\n return this.parseResponse<T>(res);\n }\n\n private async parseResponse<T>(res: Response): Promise<T> {\n const text = await res.text();\n let json: unknown;\n try {\n json = JSON.parse(text);\n } catch {\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${text}`);\n return undefined as T;\n }\n\n if (!res.ok) {\n throw new PanaceaApiError(res.status, json as ApiErrorBody);\n }\n\n return json as T;\n }\n}\n","/**\n * @module wiki\n * Wiki knowledge base sub-client.\n */\n\nimport { HttpClient } from \"./http.js\";\nimport type {\n WikiEntry,\n ListWikiOptions,\n CreateWikiEntryOptions,\n UpdateWikiEntryOptions,\n PaginatedResponse,\n} from \"./types.js\";\n\nexport class WikiClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List wiki entries (paginated).\n */\n list(opts?: ListWikiOptions): Promise<PaginatedResponse<WikiEntry>> {\n return this.http.get<PaginatedResponse<WikiEntry>>(\"/api/v1/wiki\", {\n page: opts?.page,\n limit: opts?.limit,\n status: opts?.status,\n });\n }\n\n /**\n * Get a single wiki entry by path slug.\n */\n get(path: string): Promise<WikiEntry> {\n return this.http.get<WikiEntry>(`/api/v1/wiki/${encodeURIComponent(path)}`);\n }\n\n /**\n * Create a new wiki entry.\n */\n create(opts: CreateWikiEntryOptions): Promise<WikiEntry> {\n return this.http.post<WikiEntry>(\"/api/v1/wiki\", opts);\n }\n\n /**\n * Update an existing wiki entry.\n */\n update(path: string, opts: UpdateWikiEntryOptions): Promise<WikiEntry> {\n return this.http.patch<WikiEntry>(`/api/v1/wiki/${encodeURIComponent(path)}`, opts);\n }\n\n /**\n * Delete a wiki entry.\n */\n delete(path: string): Promise<void> {\n return this.http.delete<void>(`/api/v1/wiki/${encodeURIComponent(path)}`);\n }\n}\n","/**\n * @module review\n * Review queue sub-client.\n */\n\nimport { HttpClient } from \"./http.js\";\nimport type {\n ReviewQueueItem,\n ListReviewOptions,\n ActOnReviewOptions,\n PaginatedResponse,\n} from \"./types.js\";\n\nexport class ReviewClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List review queue items (paginated).\n */\n list(opts?: ListReviewOptions): Promise<PaginatedResponse<ReviewQueueItem>> {\n return this.http.get<PaginatedResponse<ReviewQueueItem>>(\"/api/v1/review\", {\n page: opts?.page,\n limit: opts?.limit,\n status: opts?.status,\n });\n }\n\n /**\n * Get a single review item by ID.\n */\n get(id: string): Promise<ReviewQueueItem> {\n return this.http.get<ReviewQueueItem>(`/api/v1/review/${id}`);\n }\n\n /**\n * Approve, reject, or modify a review item.\n */\n act(id: string, opts: ActOnReviewOptions): Promise<ReviewQueueItem> {\n return this.http.post<ReviewQueueItem>(`/api/v1/review/${id}`, opts);\n }\n}\n","/**\n * @module webhooks-client\n * Webhook registration sub-client.\n */\n\nimport { HttpClient } from \"./http.js\";\nimport type { WebhookRegistration, CreateWebhookOptions } from \"./types.js\";\n\nexport class WebhooksClient {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List registered webhooks.\n */\n list(): Promise<WebhookRegistration[]> {\n return this.http.get<WebhookRegistration[]>(\"/api/v1/webhooks\");\n }\n\n /**\n * Register a new webhook endpoint.\n */\n create(opts: CreateWebhookOptions): Promise<WebhookRegistration> {\n return this.http.post<WebhookRegistration>(\"/api/v1/webhooks\", opts);\n }\n\n /**\n * Delete a webhook registration.\n */\n delete(id: string): Promise<void> {\n return this.http.delete<void>(`/api/v1/webhooks/${id}`);\n }\n\n /**\n * Replay the last event delivery for a webhook.\n */\n replay(id: string): Promise<void> {\n return this.http.post<void>(`/api/v1/webhooks/${id}/replay`);\n }\n}\n","/**\n * @module client\n * PanaceaClient — top-level entry point for the @usepanacea/sdk.\n *\n * @example Node.js / Edge\n * ```typescript\n * import { PanaceaClient } from \"@usepanacea/sdk\"\n *\n * const client = new PanaceaClient({\n * apiKey: process.env.PANACEA_API_KEY!,\n * baseURL: \"https://your-panacea-instance.example.com\",\n * })\n *\n * // Query\n * const result = await client.query(\"How do I reset my password?\")\n * console.log(result.answer)\n *\n * // Ingest\n * await client.ingest({ type: \"url\", url: \"https://docs.example.com/setup\" })\n *\n * // Wiki\n * const entry = await client.wiki.get(\"faq/reset-password\")\n * ```\n */\n\nimport { HttpClient, PanaceaApiError } from \"./http.js\";\nimport { WikiClient } from \"./wiki.js\";\nimport { ReviewClient } from \"./review.js\";\nimport { WebhooksClient } from \"./webhooks-client.js\";\nimport type {\n QueryOptions,\n QueryResult,\n IngestOptions,\n IngestResult,\n HealthReport,\n} from \"./types.js\";\n\nexport interface PanaceaClientOptions {\n /** Base URL of your Panacea instance, e.g. \"https://panacea.example.com\" */\n baseURL: string;\n /** Your API key (Bearer token) */\n apiKey: string;\n /** Optional tenant ID sent as X-Tenant-Id header */\n tenantId?: string;\n /** Additional default request headers */\n headers?: Record<string, string>;\n /** Override the global fetch implementation (e.g. for testing) */\n fetch?: typeof globalThis.fetch;\n}\n\nexport class PanaceaClient {\n private readonly http: HttpClient;\n\n /** Wiki knowledge base CRUD */\n readonly wiki: WikiClient;\n\n /** Review queue operations */\n readonly review: ReviewClient;\n\n /** Webhook registration management */\n readonly webhooks: WebhooksClient;\n\n constructor(opts: PanaceaClientOptions) {\n if (!opts.apiKey) throw new Error(\"PanaceaClient: apiKey is required\");\n if (!opts.baseURL) throw new Error(\"PanaceaClient: baseURL is required\");\n\n this.http = new HttpClient(opts);\n this.wiki = new WikiClient(this.http);\n this.review = new ReviewClient(this.http);\n this.webhooks = new WebhooksClient(this.http);\n }\n\n // ---------------------------------------------------------------------------\n // Query\n // ---------------------------------------------------------------------------\n\n /**\n * Submit a question to the Q&A agent.\n *\n * @param question - The user's question string\n * @param opts - Optional session ID and context override\n */\n query(question: string, opts?: Omit<QueryOptions, \"question\">): Promise<QueryResult>;\n query(opts: QueryOptions): Promise<QueryResult>;\n query(\n questionOrOpts: string | QueryOptions,\n rest?: Omit<QueryOptions, \"question\">,\n ): Promise<QueryResult> {\n const body: QueryOptions =\n typeof questionOrOpts === \"string\" ? { question: questionOrOpts, ...rest } : questionOrOpts;\n return this.http.post<QueryResult>(\"/api/v1/query\", body);\n }\n\n // ---------------------------------------------------------------------------\n // Ingest\n // ---------------------------------------------------------------------------\n\n /**\n * Submit a URL or raw text content for ingestion.\n *\n * @example URL\n * ```typescript\n * await client.ingest({ type: \"url\", url: \"https://docs.example.com\" })\n * ```\n *\n * @example Raw text\n * ```typescript\n * await client.ingest({ type: \"text\", content: \"# FAQ\\n...\", filename: \"faq.md\" })\n * ```\n */\n ingest(opts: IngestOptions): Promise<IngestResult> {\n const body =\n opts.type === \"url\"\n ? { url: opts.url, slug: opts.slug, category: opts.category }\n : {\n content: opts.content,\n filename: opts.filename,\n slug: opts.slug,\n category: opts.category,\n };\n return this.http.post<IngestResult>(\"/api/v1/ingest\", body);\n }\n\n // ---------------------------------------------------------------------------\n // Health\n // ---------------------------------------------------------------------------\n\n /**\n * Get the current system health report.\n */\n health(): Promise<HealthReport> {\n return this.http.get<HealthReport>(\"/api/v1/health\");\n }\n}\n\nexport { PanaceaApiError };\n"]}
@@ -0,0 +1,191 @@
1
+ import { ApiErrorBody, ListWikiOptions, PaginatedResponse, WikiEntry, CreateWikiEntryOptions, UpdateWikiEntryOptions, ListReviewOptions, ReviewQueueItem, ActOnReviewOptions, WebhookRegistration, CreateWebhookOptions, QueryOptions, QueryResult, IngestOptions, IngestResult, HealthReport } from './types.cjs';
2
+ export { AgentHealth, AgentStatus, IngestTextOptions, IngestUrlOptions, PaginationMeta, QuerySource, ReviewStatus, SystemStatus, WebhookEvent, WikiEntryStatus } from './types.cjs';
3
+
4
+ /**
5
+ * @module http
6
+ * Internal fetch wrapper used by PanaceaClient.
7
+ * Works in Node.js (18+), browser, and edge runtimes (native fetch).
8
+ */
9
+
10
+ declare class PanaceaApiError extends Error {
11
+ readonly code: string;
12
+ readonly status: number;
13
+ readonly retriable: boolean;
14
+ readonly traceId?: string;
15
+ constructor(status: number, body: ApiErrorBody);
16
+ }
17
+ interface HttpClientOptions {
18
+ baseURL: string;
19
+ apiKey: string;
20
+ /** Tenant ID header value (X-Tenant-Id). Required if your installation uses it. */
21
+ tenantId?: string;
22
+ /** Override the global fetch (e.g. for testing) */
23
+ fetch?: typeof globalThis.fetch;
24
+ /** Additional default headers */
25
+ headers?: Record<string, string>;
26
+ }
27
+ declare class HttpClient {
28
+ private readonly baseURL;
29
+ private readonly defaultHeaders;
30
+ private readonly _fetch;
31
+ constructor(opts: HttpClientOptions);
32
+ get<T>(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
33
+ post<T>(path: string, body?: unknown): Promise<T>;
34
+ patch<T>(path: string, body?: unknown): Promise<T>;
35
+ delete<T = void>(path: string): Promise<T>;
36
+ private parseResponse;
37
+ }
38
+
39
+ /**
40
+ * @module wiki
41
+ * Wiki knowledge base sub-client.
42
+ */
43
+
44
+ declare class WikiClient {
45
+ private readonly http;
46
+ constructor(http: HttpClient);
47
+ /**
48
+ * List wiki entries (paginated).
49
+ */
50
+ list(opts?: ListWikiOptions): Promise<PaginatedResponse<WikiEntry>>;
51
+ /**
52
+ * Get a single wiki entry by path slug.
53
+ */
54
+ get(path: string): Promise<WikiEntry>;
55
+ /**
56
+ * Create a new wiki entry.
57
+ */
58
+ create(opts: CreateWikiEntryOptions): Promise<WikiEntry>;
59
+ /**
60
+ * Update an existing wiki entry.
61
+ */
62
+ update(path: string, opts: UpdateWikiEntryOptions): Promise<WikiEntry>;
63
+ /**
64
+ * Delete a wiki entry.
65
+ */
66
+ delete(path: string): Promise<void>;
67
+ }
68
+
69
+ /**
70
+ * @module review
71
+ * Review queue sub-client.
72
+ */
73
+
74
+ declare class ReviewClient {
75
+ private readonly http;
76
+ constructor(http: HttpClient);
77
+ /**
78
+ * List review queue items (paginated).
79
+ */
80
+ list(opts?: ListReviewOptions): Promise<PaginatedResponse<ReviewQueueItem>>;
81
+ /**
82
+ * Get a single review item by ID.
83
+ */
84
+ get(id: string): Promise<ReviewQueueItem>;
85
+ /**
86
+ * Approve, reject, or modify a review item.
87
+ */
88
+ act(id: string, opts: ActOnReviewOptions): Promise<ReviewQueueItem>;
89
+ }
90
+
91
+ /**
92
+ * @module webhooks-client
93
+ * Webhook registration sub-client.
94
+ */
95
+
96
+ declare class WebhooksClient {
97
+ private readonly http;
98
+ constructor(http: HttpClient);
99
+ /**
100
+ * List registered webhooks.
101
+ */
102
+ list(): Promise<WebhookRegistration[]>;
103
+ /**
104
+ * Register a new webhook endpoint.
105
+ */
106
+ create(opts: CreateWebhookOptions): Promise<WebhookRegistration>;
107
+ /**
108
+ * Delete a webhook registration.
109
+ */
110
+ delete(id: string): Promise<void>;
111
+ /**
112
+ * Replay the last event delivery for a webhook.
113
+ */
114
+ replay(id: string): Promise<void>;
115
+ }
116
+
117
+ /**
118
+ * @module client
119
+ * PanaceaClient — top-level entry point for the @usepanacea/sdk.
120
+ *
121
+ * @example Node.js / Edge
122
+ * ```typescript
123
+ * import { PanaceaClient } from "@usepanacea/sdk"
124
+ *
125
+ * const client = new PanaceaClient({
126
+ * apiKey: process.env.PANACEA_API_KEY!,
127
+ * baseURL: "https://your-panacea-instance.example.com",
128
+ * })
129
+ *
130
+ * // Query
131
+ * const result = await client.query("How do I reset my password?")
132
+ * console.log(result.answer)
133
+ *
134
+ * // Ingest
135
+ * await client.ingest({ type: "url", url: "https://docs.example.com/setup" })
136
+ *
137
+ * // Wiki
138
+ * const entry = await client.wiki.get("faq/reset-password")
139
+ * ```
140
+ */
141
+
142
+ interface PanaceaClientOptions {
143
+ /** Base URL of your Panacea instance, e.g. "https://panacea.example.com" */
144
+ baseURL: string;
145
+ /** Your API key (Bearer token) */
146
+ apiKey: string;
147
+ /** Optional tenant ID sent as X-Tenant-Id header */
148
+ tenantId?: string;
149
+ /** Additional default request headers */
150
+ headers?: Record<string, string>;
151
+ /** Override the global fetch implementation (e.g. for testing) */
152
+ fetch?: typeof globalThis.fetch;
153
+ }
154
+ declare class PanaceaClient {
155
+ private readonly http;
156
+ /** Wiki knowledge base CRUD */
157
+ readonly wiki: WikiClient;
158
+ /** Review queue operations */
159
+ readonly review: ReviewClient;
160
+ /** Webhook registration management */
161
+ readonly webhooks: WebhooksClient;
162
+ constructor(opts: PanaceaClientOptions);
163
+ /**
164
+ * Submit a question to the Q&A agent.
165
+ *
166
+ * @param question - The user's question string
167
+ * @param opts - Optional session ID and context override
168
+ */
169
+ query(question: string, opts?: Omit<QueryOptions, "question">): Promise<QueryResult>;
170
+ query(opts: QueryOptions): Promise<QueryResult>;
171
+ /**
172
+ * Submit a URL or raw text content for ingestion.
173
+ *
174
+ * @example URL
175
+ * ```typescript
176
+ * await client.ingest({ type: "url", url: "https://docs.example.com" })
177
+ * ```
178
+ *
179
+ * @example Raw text
180
+ * ```typescript
181
+ * await client.ingest({ type: "text", content: "# FAQ\n...", filename: "faq.md" })
182
+ * ```
183
+ */
184
+ ingest(opts: IngestOptions): Promise<IngestResult>;
185
+ /**
186
+ * Get the current system health report.
187
+ */
188
+ health(): Promise<HealthReport>;
189
+ }
190
+
191
+ export { ActOnReviewOptions, ApiErrorBody, CreateWebhookOptions, CreateWikiEntryOptions, HealthReport, IngestOptions, IngestResult, ListReviewOptions, ListWikiOptions, PaginatedResponse, PanaceaApiError, PanaceaClient, type PanaceaClientOptions, QueryOptions, QueryResult, ReviewQueueItem, UpdateWikiEntryOptions, WebhookRegistration, WikiEntry };