@babav/knowledge-core-client 0.42.0 → 0.44.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/README.md +8 -8
- package/dist/index.d.ts +34 -29
- package/dist/index.js +34 -32
- package/package.json +1 -1
- package/src/index.ts +52 -50
package/README.md
CHANGED
|
@@ -39,15 +39,15 @@ const kc = new KnowledgeCoreClient({
|
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
// One-shot grounded query
|
|
42
|
-
const r = await kc.query(
|
|
42
|
+
const r = await kc.query(profileId, { corpus_ids: [corpusId], query: "..." });
|
|
43
43
|
console.log(r.answer, r.retrieval_contents, r.citations, r.groundedness);
|
|
44
44
|
|
|
45
45
|
// Conversational (persisted, history-aware)
|
|
46
46
|
const convo = await kc.conversations.create({ title: "Contract review", custom_metadata: { account_id } });
|
|
47
|
-
const turn = await kc.query(
|
|
47
|
+
const turn = await kc.query(profileId, { corpus_ids: [corpusId], query: "...", conversation_id: convo.id });
|
|
48
48
|
|
|
49
49
|
// Streaming (SSE)
|
|
50
|
-
await kc.queryStream(
|
|
50
|
+
await kc.queryStream(profileId, { corpus_ids: [corpusId], query: "..." }, {
|
|
51
51
|
onSources: (s) => render(s.retrieval_contents),
|
|
52
52
|
onToken: (t) => append(t),
|
|
53
53
|
onFinal: (f) => done(f),
|
|
@@ -57,7 +57,7 @@ await kc.queryStream(agentId, { corpus_ids: [corpusId], query: "..." }, {
|
|
|
57
57
|
// Attachment-backed review
|
|
58
58
|
const att = await kc.attachments.upload(convo.id, { filename: "c.pdf", content_type: "application/pdf", data: bytes });
|
|
59
59
|
await kc.attachments.waitReady(convo.id, att.id);
|
|
60
|
-
const review = await kc.query(
|
|
60
|
+
const review = await kc.query(profileId, { corpus_ids: [corpusId], conversation_id: convo.id, query: "Review the attached contract." });
|
|
61
61
|
|
|
62
62
|
// View/download a stored doc (signed URL)
|
|
63
63
|
const { content_url, content_type } = await kc.documents.contentUrl(documentId, "inline");
|
|
@@ -65,7 +65,7 @@ const { content_url, content_type } = await kc.documents.contentUrl(documentId,
|
|
|
65
65
|
|
|
66
66
|
### Error handling (structured guards)
|
|
67
67
|
```ts
|
|
68
|
-
try { await kc.query(
|
|
68
|
+
try { await kc.query(profileId, body); }
|
|
69
69
|
catch (e) {
|
|
70
70
|
if (e instanceof KnowledgeCoreError) {
|
|
71
71
|
if (e.code === "attachments_pending") { /* a document is still parsing */ }
|
|
@@ -75,7 +75,7 @@ catch (e) {
|
|
|
75
75
|
}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
## Admin client (tenant + key +
|
|
78
|
+
## Admin client (tenant + key + profile management — ADMIN key)
|
|
79
79
|
```ts
|
|
80
80
|
import { AdminClient } from "@babav/knowledge-core-client";
|
|
81
81
|
const admin = new AdminClient({ baseUrl, apiKey: ADMIN_KEY });
|
|
@@ -90,5 +90,5 @@ const created = await admin.tenants.createApiKey(tenantId, "label"); // created.
|
|
|
90
90
|
- `conversations` (CRUD, search, listMessages)
|
|
91
91
|
- `attachments` (upload, list, get, contentUrl, delete, waitReady)
|
|
92
92
|
- `messages` (get, createFeedback, listFeedback), `feedback` (get, delete)
|
|
93
|
-
- `parseJobs` (list, get), `
|
|
94
|
-
- `AdminClient`: `tenants` (CRUD + api-keys), `
|
|
93
|
+
- `parseJobs` (list, get), `profiles` (list, get)
|
|
94
|
+
- `AdminClient`: `tenants` (CRUD + api-keys), `profiles` (create/update/delete)
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Auth: every call carries an X-API-Key. Use KnowledgeCoreClient with a TENANT
|
|
12
12
|
* key for all data ops; use AdminClient with the ADMIN key for tenant / API-key /
|
|
13
|
-
*
|
|
13
|
+
* profile management. The key is server-side only — never ship it to a browser.
|
|
14
14
|
*
|
|
15
15
|
* Configuration — the CALLER supplies credentials at construction; the SDK never reads
|
|
16
16
|
* the environment or defaults/derives a key itself:
|
|
@@ -77,7 +77,7 @@ export interface VisualOverrides {
|
|
|
77
77
|
claims_check_model?: string;
|
|
78
78
|
vision_judge_model?: string;
|
|
79
79
|
}
|
|
80
|
-
/** Per-request visual control. Absent => mode resolves from the
|
|
80
|
+
/** Per-request visual control. Absent => mode resolves from the profile default. All visual
|
|
81
81
|
* PROCESSING is server-side; the client only displays the result. */
|
|
82
82
|
export interface VisualRequest {
|
|
83
83
|
mode?: "off" | "on";
|
|
@@ -215,7 +215,7 @@ export interface Corpus {
|
|
|
215
215
|
/** Build-time knob bundle that DEFINES an index. Defaults are today's blessed config, so a
|
|
216
216
|
* profile created with no params is the blessed profile. Change any knob => different vectors
|
|
217
217
|
* => a different physical collection. Embedding/indexing/chunking is SYSTEM-level, never a
|
|
218
|
-
* query knob — this is the build-side counterpart to
|
|
218
|
+
* query knob — this is the build-side counterpart to a query profile. */
|
|
219
219
|
export interface IngestionProfileParams {
|
|
220
220
|
chunker: string;
|
|
221
221
|
chunk_child_max_tokens: number;
|
|
@@ -477,7 +477,7 @@ export interface Conversation {
|
|
|
477
477
|
export interface Message {
|
|
478
478
|
id: UUID;
|
|
479
479
|
conversation_id: UUID;
|
|
480
|
-
|
|
480
|
+
query_profile_id: UUID | null;
|
|
481
481
|
corpus_ids: UUID[] | null;
|
|
482
482
|
query: string;
|
|
483
483
|
answer: string | null;
|
|
@@ -506,7 +506,7 @@ export interface Feedback {
|
|
|
506
506
|
rating: number | null;
|
|
507
507
|
comment: string | null;
|
|
508
508
|
}
|
|
509
|
-
export interface
|
|
509
|
+
export interface QueryProfile {
|
|
510
510
|
id: UUID;
|
|
511
511
|
tenant_id: UUID;
|
|
512
512
|
name: string;
|
|
@@ -539,13 +539,13 @@ export interface Agent {
|
|
|
539
539
|
visual_combine_generation_and_concept: boolean | null;
|
|
540
540
|
concept_model_mode: string | null;
|
|
541
541
|
}
|
|
542
|
-
/** Fields settable when creating/updating
|
|
542
|
+
/** Fields settable when creating/updating a query profile. All optional except `name` on create
|
|
543
543
|
* (null/omit => server default); model fields must be one of
|
|
544
|
-
* `
|
|
544
|
+
* `profiles.modelOptions().fields[field].supported`. The owning tenant is the caller's key —
|
|
545
545
|
* it is never part of the body. */
|
|
546
|
-
export type
|
|
547
|
-
/** Model catalog for the
|
|
548
|
-
* capabilities; `fields` gives each
|
|
546
|
+
export type QueryProfileWrite = Partial<Omit<QueryProfile, "id" | "tenant_id">>;
|
|
547
|
+
/** Model catalog for the query-profile-config UI (GET /v1/query-profiles/model-options). `models` maps id → its
|
|
548
|
+
* capabilities; `fields` gives each profile model-field its supported ids + default (+ usage metadata);
|
|
549
549
|
* `modes` says which model field governs each mode (reasoning is valid only if that model's
|
|
550
550
|
* supports_reasoning is true). KC provides the data; the UI decides presentation. */
|
|
551
551
|
export interface ModelOptions {
|
|
@@ -686,11 +686,11 @@ export interface DocumentEventHandlers {
|
|
|
686
686
|
export declare class KnowledgeCoreClient extends HttpBase {
|
|
687
687
|
/** @param opts.apiKey a TENANT key, supplied by the caller. */
|
|
688
688
|
constructor(opts: ClientOptions);
|
|
689
|
-
query(
|
|
689
|
+
query(profileId: UUID, body: QueryRequest): Promise<QueryResponse>;
|
|
690
690
|
/** Streaming query (SSE). Resolves when the stream ends (the Promise resolving is normal, not an
|
|
691
691
|
* error). Pass `signal` and abort() on unmount / when the user cancels or navigates away so the
|
|
692
692
|
* connection doesn't linger. Transient (ends on `done`) — no reopen logic needed. */
|
|
693
|
-
queryStream(
|
|
693
|
+
queryStream(profileId: UUID, body: QueryRequest, handlers: StreamHandlers, signal?: AbortSignal): Promise<void>;
|
|
694
694
|
/** Fetch a visual's PNG bytes BY ID. This is the ONLY way to get a visual image — the API never
|
|
695
695
|
* returns a URL. Authenticated + tenant-scoped like every call. Use `visual.id` from a query
|
|
696
696
|
* response / streamed `visual` event / persisted message. Returns a Blob (browser: `URL.
|
|
@@ -708,11 +708,11 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
708
708
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
709
709
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
710
710
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
|
711
|
-
* New chat: const chat = kc.chat(
|
|
712
|
-
* Resume: const chat = kc.chat(
|
|
711
|
+
* New chat: const chat = kc.chat(profileId, corpusIds);
|
|
712
|
+
* Resume: const chat = kc.chat(profileId, corpusIds, { conversationId });
|
|
713
713
|
* The conversation is created LAZILY on the first `send()` (opening a "new chat" and never
|
|
714
714
|
* sending leaves nothing behind). See ChatSession.send. */
|
|
715
|
-
chat(
|
|
715
|
+
chat(profileId: UUID, corpusIds: UUID[], opts?: {
|
|
716
716
|
conversationId?: UUID;
|
|
717
717
|
}): ChatSession;
|
|
718
718
|
/** Shared SSE reader for the document-status streams (documents.events / folders.events).
|
|
@@ -778,6 +778,7 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
778
778
|
visibility?: Visibility;
|
|
779
779
|
folder_id?: UUID;
|
|
780
780
|
custom_metadata?: Record<string, unknown>;
|
|
781
|
+
profile_id?: UUID;
|
|
781
782
|
}) => Promise<Document>;
|
|
782
783
|
/** Mint a signed PUT URL to upload a large file straight to GCS (bypasses the
|
|
783
784
|
* ~32 MB request limit). PUT the bytes to upload_url, then ingestFromUpload. */
|
|
@@ -794,6 +795,7 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
794
795
|
visibility?: Visibility;
|
|
795
796
|
folder_id?: UUID;
|
|
796
797
|
custom_metadata?: Record<string, unknown>;
|
|
798
|
+
profile_id?: UUID;
|
|
797
799
|
}) => Promise<Document>;
|
|
798
800
|
/** Convenience for LARGE files: uploadUrl → PUT the bytes to GCS → ingestFromUpload.
|
|
799
801
|
* Use this instead of ingestDocument when the file may exceed ~32 MB. */
|
|
@@ -804,6 +806,7 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
804
806
|
visibility?: Visibility;
|
|
805
807
|
folder_id?: UUID;
|
|
806
808
|
custom_metadata?: Record<string, unknown>;
|
|
809
|
+
profile_id?: UUID;
|
|
807
810
|
}) => Promise<Document>;
|
|
808
811
|
/** Ingest MANY files in ONE go — any size, no 429, no client backoff. Mints all signed URLs in
|
|
809
812
|
* one request, PUTs the bytes straight to GCS (bounded concurrency; never touches the KC), then
|
|
@@ -819,6 +822,7 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
819
822
|
visibility?: Visibility;
|
|
820
823
|
custom_metadata?: Record<string, unknown>;
|
|
821
824
|
concurrency?: number;
|
|
825
|
+
profile_id?: UUID;
|
|
822
826
|
}) => Promise<Document[]>;
|
|
823
827
|
/** (server-side) Mint one RESUMABLE GCS upload session per file. Return only the sessions to the
|
|
824
828
|
* browser; the browser PUTs bytes to each `upload_url` and needs NO KC/tenant credential (the
|
|
@@ -845,6 +849,7 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
845
849
|
folder_id?: UUID;
|
|
846
850
|
visibility?: Visibility;
|
|
847
851
|
custom_metadata?: Record<string, unknown>;
|
|
852
|
+
profile_id?: UUID;
|
|
848
853
|
}) => Promise<{
|
|
849
854
|
results: FinalizeResult[];
|
|
850
855
|
}>;
|
|
@@ -984,26 +989,26 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
984
989
|
get: (id: UUID) => Promise<Feedback>;
|
|
985
990
|
delete: (id: UUID) => Promise<void>;
|
|
986
991
|
};
|
|
987
|
-
|
|
988
|
-
/** List this tenant's
|
|
992
|
+
queryProfiles: {
|
|
993
|
+
/** List this tenant's query profiles. */
|
|
989
994
|
list: (q?: {
|
|
990
995
|
limit?: number;
|
|
991
996
|
cursor?: string;
|
|
992
|
-
}) => Promise<Page<
|
|
993
|
-
listAll: () => Promise<
|
|
994
|
-
get: (id: UUID) => Promise<
|
|
995
|
-
/** Create
|
|
996
|
-
create: (b:
|
|
997
|
+
}) => Promise<Page<QueryProfile>>;
|
|
998
|
+
listAll: () => Promise<QueryProfile[]>;
|
|
999
|
+
get: (id: UUID) => Promise<QueryProfile>;
|
|
1000
|
+
/** Create a query profile owned by this tenant (the owning tenant is the key's — no tenant_id in the body). */
|
|
1001
|
+
create: (b: QueryProfileWrite & {
|
|
997
1002
|
name: string;
|
|
998
|
-
}) => Promise<
|
|
999
|
-
update: (id: UUID, b:
|
|
1003
|
+
}) => Promise<QueryProfile>;
|
|
1004
|
+
update: (id: UUID, b: QueryProfileWrite) => Promise<QueryProfile>;
|
|
1000
1005
|
delete: (id: UUID) => Promise<void>;
|
|
1001
|
-
/** The model catalog for an
|
|
1006
|
+
/** The model catalog for an query-profile-config UI: supported models + default per field, per-model
|
|
1002
1007
|
* capabilities (`supports_reasoning`), and mode↔model dependencies. */
|
|
1003
1008
|
modelOptions: () => Promise<ModelOptions>;
|
|
1004
1009
|
};
|
|
1005
|
-
/** Ingestion profiles — the build-side config object (counterpart to
|
|
1006
|
-
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike
|
|
1010
|
+
/** Ingestion profiles — the build-side config object (counterpart to query profiles): a tenant-owned,
|
|
1011
|
+
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike a query profile
|
|
1007
1012
|
* (chosen per query), a profile binds at the TENANT/COLLECTION level — the tenant's one
|
|
1008
1013
|
* `is_default` profile governs how ALL its documents are ingested; swapping it re-indexes.
|
|
1009
1014
|
* A corpus's content is a RESULT of ingestion, so a corpus never selects a profile. */
|
|
@@ -1024,7 +1029,7 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
1024
1029
|
delete: (id: UUID) => Promise<void>;
|
|
1025
1030
|
/** The config catalog for a profile UI: supported embedding models (+ provider/dims),
|
|
1026
1031
|
* chunkers, distances, quantizations, per-field defaults/bounds, and the standard params.
|
|
1027
|
-
* Build-side mirror of `
|
|
1032
|
+
* Build-side mirror of `queryProfiles.modelOptions()`. */
|
|
1028
1033
|
modelOptions: () => Promise<IngestionProfileOptions>;
|
|
1029
1034
|
};
|
|
1030
1035
|
analytics: {
|
|
@@ -1123,7 +1128,7 @@ export declare class ChatSession {
|
|
|
1123
1128
|
#private;
|
|
1124
1129
|
/** The conversation id — null until the first `send()` (unless resumed). */
|
|
1125
1130
|
conversationId: UUID | null;
|
|
1126
|
-
constructor(kc: KnowledgeCoreClient,
|
|
1131
|
+
constructor(kc: KnowledgeCoreClient, profileId: UUID, corpusIds: UUID[], conversationId: UUID | null);
|
|
1127
1132
|
/** Send a chat message (streaming). Lazily creates the conversation on the first message and
|
|
1128
1133
|
* ALWAYS passes conversation_id, so the turn is persisted. `onConversationId` fires before the
|
|
1129
1134
|
* stream so you can show the conversation immediately. Pass `signal` to cancel on unmount. */
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Auth: every call carries an X-API-Key. Use KnowledgeCoreClient with a TENANT
|
|
12
12
|
* key for all data ops; use AdminClient with the ADMIN key for tenant / API-key /
|
|
13
|
-
*
|
|
13
|
+
* profile management. The key is server-side only — never ship it to a browser.
|
|
14
14
|
*
|
|
15
15
|
* Configuration — the CALLER supplies credentials at construction; the SDK never reads
|
|
16
16
|
* the environment or defaults/derives a key itself:
|
|
@@ -156,18 +156,18 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
156
156
|
constructor(opts) {
|
|
157
157
|
super(opts);
|
|
158
158
|
}
|
|
159
|
-
// --- query (
|
|
160
|
-
query(
|
|
161
|
-
return this.request("POST", `/v1/
|
|
159
|
+
// --- query (query-profile-anchored) ---
|
|
160
|
+
query(profileId, body) {
|
|
161
|
+
return this.request("POST", `/v1/query-profiles/${profileId}/query`, { json: body });
|
|
162
162
|
}
|
|
163
163
|
/** Streaming query (SSE). Resolves when the stream ends (the Promise resolving is normal, not an
|
|
164
164
|
* error). Pass `signal` and abort() on unmount / when the user cancels or navigates away so the
|
|
165
165
|
* connection doesn't linger. Transient (ends on `done`) — no reopen logic needed. */
|
|
166
|
-
async queryStream(
|
|
167
|
-
const res = await this.raw("POST", `/v1/
|
|
166
|
+
async queryStream(profileId, body, handlers, signal) {
|
|
167
|
+
const res = await this.raw("POST", `/v1/query-profiles/${profileId}/query/stream`, { json: body, signal });
|
|
168
168
|
if (!res.ok || !res.body) {
|
|
169
169
|
const t = await res.text();
|
|
170
|
-
throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/
|
|
170
|
+
throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/query-profiles/${profileId}/query/stream`);
|
|
171
171
|
}
|
|
172
172
|
const reader = res.body.getReader();
|
|
173
173
|
const decoder = new TextDecoder();
|
|
@@ -217,12 +217,12 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
217
217
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
218
218
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
219
219
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
|
220
|
-
* New chat: const chat = kc.chat(
|
|
221
|
-
* Resume: const chat = kc.chat(
|
|
220
|
+
* New chat: const chat = kc.chat(profileId, corpusIds);
|
|
221
|
+
* Resume: const chat = kc.chat(profileId, corpusIds, { conversationId });
|
|
222
222
|
* The conversation is created LAZILY on the first `send()` (opening a "new chat" and never
|
|
223
223
|
* sending leaves nothing behind). See ChatSession.send. */
|
|
224
|
-
chat(
|
|
225
|
-
return new ChatSession(this,
|
|
224
|
+
chat(profileId, corpusIds, opts) {
|
|
225
|
+
return new ChatSession(this, profileId, corpusIds, opts?.conversationId ?? null);
|
|
226
226
|
}
|
|
227
227
|
/** Shared SSE reader for the document-status streams (documents.events / folders.events).
|
|
228
228
|
* Resolves when the stream ends (server sends `complete` once nothing is in-flight, or the
|
|
@@ -303,6 +303,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
303
303
|
return this.corpora.ingestFromUpload(id, {
|
|
304
304
|
document_id: u.document_id, filename: a.filename, content_type: a.content_type,
|
|
305
305
|
visibility: a.visibility, folder_id: a.folder_id, custom_metadata: a.custom_metadata,
|
|
306
|
+
profile_id: a.profile_id,
|
|
306
307
|
});
|
|
307
308
|
},
|
|
308
309
|
/** Ingest MANY files in ONE go — any size, no 429, no client backoff. Mints all signed URLs in
|
|
@@ -328,6 +329,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
328
329
|
});
|
|
329
330
|
const res = await this.request("POST", `/v1/corpora/${id}/documents/batch`, { json: {
|
|
330
331
|
folder_id: opts?.folder_id, visibility: opts?.visibility, custom_metadata: opts?.custom_metadata,
|
|
332
|
+
profile_id: opts?.profile_id,
|
|
331
333
|
items: items.map((it) => ({ document_id: it.document_id, filename: it.filename })),
|
|
332
334
|
} });
|
|
333
335
|
return res.documents;
|
|
@@ -353,7 +355,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
353
355
|
* items. `document_id` is stable from createUploadSessions, so documents.events (SSE) tracks it. */
|
|
354
356
|
finalizeUploads: (id, items, opts) => this.request("POST", `/v1/corpora/${id}/documents/finalize`, { json: {
|
|
355
357
|
items, folder_id: opts?.folder_id, visibility: opts?.visibility,
|
|
356
|
-
custom_metadata: opts?.custom_metadata,
|
|
358
|
+
custom_metadata: opts?.custom_metadata, profile_id: opts?.profile_id,
|
|
357
359
|
} }),
|
|
358
360
|
/** (server-side) Cancel upload sessions the browser gave up on (idempotent cleanup). Pass the
|
|
359
361
|
* `upload_url` from createUploadSessions so the resumable session is dropped; any pending row is
|
|
@@ -453,22 +455,22 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
453
455
|
get: (id) => this.request("GET", `/v1/feedback/${id}`),
|
|
454
456
|
delete: (id) => this.request("DELETE", `/v1/feedback/${id}`),
|
|
455
457
|
};
|
|
456
|
-
// ---
|
|
457
|
-
|
|
458
|
-
/** List this tenant's
|
|
459
|
-
list: (q) => this.request("GET", "/v1/
|
|
460
|
-
listAll: () => this.pageAll("/v1/
|
|
461
|
-
get: (id) => this.request("GET", `/v1/
|
|
462
|
-
/** Create
|
|
463
|
-
create: (b) => this.request("POST", "/v1/
|
|
464
|
-
update: (id, b) => this.request("PATCH", `/v1/
|
|
465
|
-
delete: (id) => this.request("DELETE", `/v1/
|
|
466
|
-
/** The model catalog for an
|
|
458
|
+
// --- query profiles (tenant-owned query config; full CRUD with the tenant key) ---
|
|
459
|
+
queryProfiles = {
|
|
460
|
+
/** List this tenant's query profiles. */
|
|
461
|
+
list: (q) => this.request("GET", "/v1/query-profiles", { query: q }),
|
|
462
|
+
listAll: () => this.pageAll("/v1/query-profiles"),
|
|
463
|
+
get: (id) => this.request("GET", `/v1/query-profiles/${id}`),
|
|
464
|
+
/** Create a query profile owned by this tenant (the owning tenant is the key's — no tenant_id in the body). */
|
|
465
|
+
create: (b) => this.request("POST", "/v1/query-profiles", { json: b }),
|
|
466
|
+
update: (id, b) => this.request("PATCH", `/v1/query-profiles/${id}`, { json: b }),
|
|
467
|
+
delete: (id) => this.request("DELETE", `/v1/query-profiles/${id}`),
|
|
468
|
+
/** The model catalog for an query-profile-config UI: supported models + default per field, per-model
|
|
467
469
|
* capabilities (`supports_reasoning`), and mode↔model dependencies. */
|
|
468
|
-
modelOptions: () => this.request("GET", "/v1/
|
|
470
|
+
modelOptions: () => this.request("GET", "/v1/query-profiles/model-options"),
|
|
469
471
|
};
|
|
470
|
-
/** Ingestion profiles — the build-side config object (counterpart to
|
|
471
|
-
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike
|
|
472
|
+
/** Ingestion profiles — the build-side config object (counterpart to query profiles): a tenant-owned,
|
|
473
|
+
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike a query profile
|
|
472
474
|
* (chosen per query), a profile binds at the TENANT/COLLECTION level — the tenant's one
|
|
473
475
|
* `is_default` profile governs how ALL its documents are ingested; swapping it re-indexes.
|
|
474
476
|
* A corpus's content is a RESULT of ingestion, so a corpus never selects a profile. */
|
|
@@ -484,7 +486,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
484
486
|
delete: (id) => this.request("DELETE", `/v1/profiles/${id}`),
|
|
485
487
|
/** The config catalog for a profile UI: supported embedding models (+ provider/dims),
|
|
486
488
|
* chunkers, distances, quantizations, per-field defaults/bounds, and the standard params.
|
|
487
|
-
* Build-side mirror of `
|
|
489
|
+
* Build-side mirror of `queryProfiles.modelOptions()`. */
|
|
488
490
|
modelOptions: () => this.request("GET", "/v1/profiles/model-options"),
|
|
489
491
|
};
|
|
490
492
|
// --- retrieval analytics (read-only, tenant-scoped, aggregate-on-read) ---
|
|
@@ -519,7 +521,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
519
521
|
}
|
|
520
522
|
// ---------------------------------------------------------------------------
|
|
521
523
|
// Admin client (tenant + API-key provisioning) — use the ADMIN key.
|
|
522
|
-
//
|
|
524
|
+
// Query profiles are tenant data; manage them with the tenant client (KnowledgeCoreClient.queryProfiles).
|
|
523
525
|
// ---------------------------------------------------------------------------
|
|
524
526
|
export class AdminClient extends HttpBase {
|
|
525
527
|
/** @param opts.apiKey the ADMIN key, supplied by the caller. */
|
|
@@ -544,14 +546,14 @@ export class AdminClient extends HttpBase {
|
|
|
544
546
|
* a chat turn is never lost and a chat conversation is never left blank. */
|
|
545
547
|
export class ChatSession {
|
|
546
548
|
#kc;
|
|
547
|
-
#
|
|
549
|
+
#profileId;
|
|
548
550
|
#corpusIds;
|
|
549
551
|
#creating = null;
|
|
550
552
|
/** The conversation id — null until the first `send()` (unless resumed). */
|
|
551
553
|
conversationId;
|
|
552
|
-
constructor(kc,
|
|
554
|
+
constructor(kc, profileId, corpusIds, conversationId) {
|
|
553
555
|
this.#kc = kc;
|
|
554
|
-
this.#
|
|
556
|
+
this.#profileId = profileId;
|
|
555
557
|
this.#corpusIds = corpusIds;
|
|
556
558
|
this.conversationId = conversationId;
|
|
557
559
|
}
|
|
@@ -572,7 +574,7 @@ export class ChatSession {
|
|
|
572
574
|
async send(text, o = {}) {
|
|
573
575
|
const convId = await this.#ensure(o, text);
|
|
574
576
|
o.onConversationId?.(convId);
|
|
575
|
-
await this.#kc.queryStream(this.#
|
|
577
|
+
await this.#kc.queryStream(this.#profileId, { corpus_ids: this.#corpusIds, query: text, conversation_id: convId,
|
|
576
578
|
overrides: o.overrides, filter: o.filter, visual: o.visual }, o, o.signal);
|
|
577
579
|
}
|
|
578
580
|
/** The conversation history (messages), once it exists. Empty page before the first send. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@babav/knowledge-core-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "TypeScript client for the Babav Knowledge Core API (Deno + Node 18+, zero deps). Includes the babav.visual grammar TYPES at the ./visual subpath (types only; all visual rendering is server-side).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Auth: every call carries an X-API-Key. Use KnowledgeCoreClient with a TENANT
|
|
12
12
|
* key for all data ops; use AdminClient with the ADMIN key for tenant / API-key /
|
|
13
|
-
*
|
|
13
|
+
* profile management. The key is server-side only — never ship it to a browser.
|
|
14
14
|
*
|
|
15
15
|
* Configuration — the CALLER supplies credentials at construction; the SDK never reads
|
|
16
16
|
* the environment or defaults/derives a key itself:
|
|
@@ -100,7 +100,7 @@ export interface VisualOverrides {
|
|
|
100
100
|
vision_judge_model?: string;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
/** Per-request visual control. Absent => mode resolves from the
|
|
103
|
+
/** Per-request visual control. Absent => mode resolves from the profile default. All visual
|
|
104
104
|
* PROCESSING is server-side; the client only displays the result. */
|
|
105
105
|
export interface VisualRequest {
|
|
106
106
|
mode?: "off" | "on";
|
|
@@ -250,7 +250,7 @@ export interface Corpus {
|
|
|
250
250
|
/** Build-time knob bundle that DEFINES an index. Defaults are today's blessed config, so a
|
|
251
251
|
* profile created with no params is the blessed profile. Change any knob => different vectors
|
|
252
252
|
* => a different physical collection. Embedding/indexing/chunking is SYSTEM-level, never a
|
|
253
|
-
* query knob — this is the build-side counterpart to
|
|
253
|
+
* query knob — this is the build-side counterpart to a query profile. */
|
|
254
254
|
export interface IngestionProfileParams {
|
|
255
255
|
chunker: string; // "hybrid"
|
|
256
256
|
chunk_child_max_tokens: number;
|
|
@@ -446,7 +446,7 @@ export interface Conversation {
|
|
|
446
446
|
export interface Message {
|
|
447
447
|
id: UUID;
|
|
448
448
|
conversation_id: UUID;
|
|
449
|
-
|
|
449
|
+
query_profile_id: UUID | null;
|
|
450
450
|
corpus_ids: UUID[] | null;
|
|
451
451
|
query: string;
|
|
452
452
|
answer: string | null;
|
|
@@ -472,14 +472,14 @@ export interface Feedback {
|
|
|
472
472
|
rating: number | null;
|
|
473
473
|
comment: string | null;
|
|
474
474
|
}
|
|
475
|
-
export interface
|
|
475
|
+
export interface QueryProfile {
|
|
476
476
|
id: UUID;
|
|
477
|
-
tenant_id: UUID; // the owning tenant (every
|
|
477
|
+
tenant_id: UUID; // the owning tenant (every profile belongs to exactly one; no globals)
|
|
478
478
|
name: string;
|
|
479
479
|
identity_prompt: string | null; // answer-system: who/purpose (null => server default)
|
|
480
480
|
response_prompt: string | null; // answer-system: output guidelines (null => server default)
|
|
481
481
|
generation_model: string | null;
|
|
482
|
-
generation_model_mode: string | null; // "reasoning" (adaptive thinking) | "standard"; per-
|
|
482
|
+
generation_model_mode: string | null; // "reasoning" (adaptive thinking) | "standard"; per-profile
|
|
483
483
|
max_response_tokens: number | null;
|
|
484
484
|
top_k_retrieved_chunks: number | null;
|
|
485
485
|
top_k_reranked_chunks: number | null;
|
|
@@ -507,14 +507,14 @@ export interface Agent {
|
|
|
507
507
|
concept_model_mode: string | null; // "reasoning" | "standard"; overrules gen mode when combining
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
-
/** Fields settable when creating/updating
|
|
510
|
+
/** Fields settable when creating/updating a query profile. All optional except `name` on create
|
|
511
511
|
* (null/omit => server default); model fields must be one of
|
|
512
|
-
* `
|
|
512
|
+
* `profiles.modelOptions().fields[field].supported`. The owning tenant is the caller's key —
|
|
513
513
|
* it is never part of the body. */
|
|
514
|
-
export type
|
|
514
|
+
export type QueryProfileWrite = Partial<Omit<QueryProfile, "id" | "tenant_id">>;
|
|
515
515
|
|
|
516
|
-
/** Model catalog for the
|
|
517
|
-
* capabilities; `fields` gives each
|
|
516
|
+
/** Model catalog for the query-profile-config UI (GET /v1/query-profiles/model-options). `models` maps id → its
|
|
517
|
+
* capabilities; `fields` gives each profile model-field its supported ids + default (+ usage metadata);
|
|
518
518
|
* `modes` says which model field governs each mode (reasoning is valid only if that model's
|
|
519
519
|
* supports_reasoning is true). KC provides the data; the UI decides presentation. */
|
|
520
520
|
export interface ModelOptions {
|
|
@@ -758,19 +758,19 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
758
758
|
super(opts);
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
-
// --- query (
|
|
762
|
-
query(
|
|
763
|
-
return this.request("POST", `/v1/
|
|
761
|
+
// --- query (query-profile-anchored) ---
|
|
762
|
+
query(profileId: UUID, body: QueryRequest): Promise<QueryResponse> {
|
|
763
|
+
return this.request("POST", `/v1/query-profiles/${profileId}/query`, { json: body });
|
|
764
764
|
}
|
|
765
765
|
|
|
766
766
|
/** Streaming query (SSE). Resolves when the stream ends (the Promise resolving is normal, not an
|
|
767
767
|
* error). Pass `signal` and abort() on unmount / when the user cancels or navigates away so the
|
|
768
768
|
* connection doesn't linger. Transient (ends on `done`) — no reopen logic needed. */
|
|
769
|
-
async queryStream(
|
|
770
|
-
const res = await this.raw("POST", `/v1/
|
|
769
|
+
async queryStream(profileId: UUID, body: QueryRequest, handlers: StreamHandlers, signal?: AbortSignal): Promise<void> {
|
|
770
|
+
const res = await this.raw("POST", `/v1/query-profiles/${profileId}/query/stream`, { json: body, signal });
|
|
771
771
|
if (!res.ok || !res.body) {
|
|
772
772
|
const t = await res.text();
|
|
773
|
-
throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/
|
|
773
|
+
throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/query-profiles/${profileId}/query/stream`);
|
|
774
774
|
}
|
|
775
775
|
const reader = res.body.getReader();
|
|
776
776
|
const decoder = new TextDecoder();
|
|
@@ -825,12 +825,12 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
825
825
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
826
826
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
827
827
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
|
828
|
-
* New chat: const chat = kc.chat(
|
|
829
|
-
* Resume: const chat = kc.chat(
|
|
828
|
+
* New chat: const chat = kc.chat(profileId, corpusIds);
|
|
829
|
+
* Resume: const chat = kc.chat(profileId, corpusIds, { conversationId });
|
|
830
830
|
* The conversation is created LAZILY on the first `send()` (opening a "new chat" and never
|
|
831
831
|
* sending leaves nothing behind). See ChatSession.send. */
|
|
832
|
-
chat(
|
|
833
|
-
return new ChatSession(this,
|
|
832
|
+
chat(profileId: UUID, corpusIds: UUID[], opts?: { conversationId?: UUID }): ChatSession {
|
|
833
|
+
return new ChatSession(this, profileId, corpusIds, opts?.conversationId ?? null);
|
|
834
834
|
}
|
|
835
835
|
|
|
836
836
|
/** Shared SSE reader for the document-status streams (documents.events / folders.events).
|
|
@@ -893,7 +893,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
893
893
|
* `pending` (HTTP 202); track via documents.events()/get() or the tenant webhook.
|
|
894
894
|
* ALWAYS uploads the bytes straight to GCS via a signed URL (uploadUrl → PUT → ingestFromUpload),
|
|
895
895
|
* regardless of size — so there is NO request-size cap, ever. One method, any size. */
|
|
896
|
-
ingestDocument: (id: UUID, a: { file: FileData; filename: string; content_type?: string; visibility?: Visibility; folder_id?: UUID; custom_metadata?: Record<string, unknown
|
|
896
|
+
ingestDocument: (id: UUID, a: { file: FileData; filename: string; content_type?: string; visibility?: Visibility; folder_id?: UUID; custom_metadata?: Record<string, unknown>; profile_id?: UUID }) =>
|
|
897
897
|
this.corpora.uploadDocument(id, a),
|
|
898
898
|
/** Mint a signed PUT URL to upload a large file straight to GCS (bypasses the
|
|
899
899
|
* ~32 MB request limit). PUT the bytes to upload_url, then ingestFromUpload. */
|
|
@@ -901,11 +901,11 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
901
901
|
this.request<UploadUrl>("POST", `/v1/corpora/${id}/documents/upload-url`, { json: a }),
|
|
902
902
|
/** Ingest a file already PUT to GCS via uploadUrl. Resolves with the `pending`
|
|
903
903
|
* document (202); track via documents.get() / webhook. */
|
|
904
|
-
ingestFromUpload: (id: UUID, a: { document_id: UUID; filename: string; content_type?: string; visibility?: Visibility; folder_id?: UUID; custom_metadata?: Record<string, unknown
|
|
904
|
+
ingestFromUpload: (id: UUID, a: { document_id: UUID; filename: string; content_type?: string; visibility?: Visibility; folder_id?: UUID; custom_metadata?: Record<string, unknown>; profile_id?: UUID }) =>
|
|
905
905
|
this.request<Document>("POST", `/v1/corpora/${id}/documents/from-upload`, { json: a }),
|
|
906
906
|
/** Convenience for LARGE files: uploadUrl → PUT the bytes to GCS → ingestFromUpload.
|
|
907
907
|
* Use this instead of ingestDocument when the file may exceed ~32 MB. */
|
|
908
|
-
uploadDocument: async (id: UUID, a: { file: FileData; filename: string; content_type?: string; visibility?: Visibility; folder_id?: UUID; custom_metadata?: Record<string, unknown
|
|
908
|
+
uploadDocument: async (id: UUID, a: { file: FileData; filename: string; content_type?: string; visibility?: Visibility; folder_id?: UUID; custom_metadata?: Record<string, unknown>; profile_id?: UUID }): Promise<Document> => {
|
|
909
909
|
const u = await this.corpora.uploadUrl(id, { filename: a.filename, content_type: a.content_type });
|
|
910
910
|
const put = await this._fetch(u.upload_url, {
|
|
911
911
|
method: "PUT",
|
|
@@ -918,6 +918,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
918
918
|
return this.corpora.ingestFromUpload(id, {
|
|
919
919
|
document_id: u.document_id, filename: a.filename, content_type: a.content_type,
|
|
920
920
|
visibility: a.visibility, folder_id: a.folder_id, custom_metadata: a.custom_metadata,
|
|
921
|
+
profile_id: a.profile_id,
|
|
921
922
|
});
|
|
922
923
|
},
|
|
923
924
|
/** Ingest MANY files in ONE go — any size, no 429, no client backoff. Mints all signed URLs in
|
|
@@ -928,7 +929,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
928
929
|
uploadMany: async (
|
|
929
930
|
id: UUID,
|
|
930
931
|
files: Array<{ file: FileData; filename: string; content_type?: string }>,
|
|
931
|
-
opts?: { folder_id?: UUID; visibility?: Visibility; custom_metadata?: Record<string, unknown>; concurrency?: number },
|
|
932
|
+
opts?: { folder_id?: UUID; visibility?: Visibility; custom_metadata?: Record<string, unknown>; concurrency?: number; profile_id?: UUID },
|
|
932
933
|
): Promise<Document[]> => {
|
|
933
934
|
if (files.length === 0) return [];
|
|
934
935
|
const urls = await this.request<BatchUploadUrls>(
|
|
@@ -950,6 +951,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
950
951
|
"POST", `/v1/corpora/${id}/documents/batch`,
|
|
951
952
|
{ json: {
|
|
952
953
|
folder_id: opts?.folder_id, visibility: opts?.visibility, custom_metadata: opts?.custom_metadata,
|
|
954
|
+
profile_id: opts?.profile_id,
|
|
953
955
|
items: items.map((it) => ({ document_id: it.document_id, filename: it.filename })),
|
|
954
956
|
} },
|
|
955
957
|
);
|
|
@@ -988,13 +990,13 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
988
990
|
finalizeUploads: (
|
|
989
991
|
id: UUID,
|
|
990
992
|
items: Array<{ document_id: UUID; filename: string; content_type?: string }>,
|
|
991
|
-
opts?: { folder_id?: UUID; visibility?: Visibility; custom_metadata?: Record<string, unknown
|
|
993
|
+
opts?: { folder_id?: UUID; visibility?: Visibility; custom_metadata?: Record<string, unknown>; profile_id?: UUID },
|
|
992
994
|
): Promise<{ results: FinalizeResult[] }> =>
|
|
993
995
|
this.request<{ results: FinalizeResult[] }>(
|
|
994
996
|
"POST", `/v1/corpora/${id}/documents/finalize`,
|
|
995
997
|
{ json: {
|
|
996
998
|
items, folder_id: opts?.folder_id, visibility: opts?.visibility,
|
|
997
|
-
custom_metadata: opts?.custom_metadata,
|
|
999
|
+
custom_metadata: opts?.custom_metadata, profile_id: opts?.profile_id,
|
|
998
1000
|
} },
|
|
999
1001
|
),
|
|
1000
1002
|
|
|
@@ -1126,23 +1128,23 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
1126
1128
|
delete: (id: UUID) => this.request<void>("DELETE", `/v1/feedback/${id}`),
|
|
1127
1129
|
};
|
|
1128
1130
|
|
|
1129
|
-
// ---
|
|
1130
|
-
|
|
1131
|
-
/** List this tenant's
|
|
1132
|
-
list: (q?: { limit?: number; cursor?: string }) => this.request<Page<
|
|
1133
|
-
listAll: () => this.pageAll<
|
|
1134
|
-
get: (id: UUID) => this.request<
|
|
1135
|
-
/** Create
|
|
1136
|
-
create: (b:
|
|
1137
|
-
update: (id: UUID, b:
|
|
1138
|
-
delete: (id: UUID) => this.request<void>("DELETE", `/v1/
|
|
1139
|
-
/** The model catalog for an
|
|
1131
|
+
// --- query profiles (tenant-owned query config; full CRUD with the tenant key) ---
|
|
1132
|
+
queryProfiles = {
|
|
1133
|
+
/** List this tenant's query profiles. */
|
|
1134
|
+
list: (q?: { limit?: number; cursor?: string }) => this.request<Page<QueryProfile>>("GET", "/v1/query-profiles", { query: q }),
|
|
1135
|
+
listAll: () => this.pageAll<QueryProfile>("/v1/query-profiles"),
|
|
1136
|
+
get: (id: UUID) => this.request<QueryProfile>("GET", `/v1/query-profiles/${id}`),
|
|
1137
|
+
/** Create a query profile owned by this tenant (the owning tenant is the key's — no tenant_id in the body). */
|
|
1138
|
+
create: (b: QueryProfileWrite & { name: string }) => this.request<QueryProfile>("POST", "/v1/query-profiles", { json: b }),
|
|
1139
|
+
update: (id: UUID, b: QueryProfileWrite) => this.request<QueryProfile>("PATCH", `/v1/query-profiles/${id}`, { json: b }),
|
|
1140
|
+
delete: (id: UUID) => this.request<void>("DELETE", `/v1/query-profiles/${id}`),
|
|
1141
|
+
/** The model catalog for an query-profile-config UI: supported models + default per field, per-model
|
|
1140
1142
|
* capabilities (`supports_reasoning`), and mode↔model dependencies. */
|
|
1141
|
-
modelOptions: () => this.request<ModelOptions>("GET", "/v1/
|
|
1143
|
+
modelOptions: () => this.request<ModelOptions>("GET", "/v1/query-profiles/model-options"),
|
|
1142
1144
|
};
|
|
1143
1145
|
|
|
1144
|
-
/** Ingestion profiles — the build-side config object (counterpart to
|
|
1145
|
-
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike
|
|
1146
|
+
/** Ingestion profiles — the build-side config object (counterpart to query profiles): a tenant-owned,
|
|
1147
|
+
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike a query profile
|
|
1146
1148
|
* (chosen per query), a profile binds at the TENANT/COLLECTION level — the tenant's one
|
|
1147
1149
|
* `is_default` profile governs how ALL its documents are ingested; swapping it re-indexes.
|
|
1148
1150
|
* A corpus's content is a RESULT of ingestion, so a corpus never selects a profile. */
|
|
@@ -1161,7 +1163,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
1161
1163
|
delete: (id: UUID) => this.request<void>("DELETE", `/v1/profiles/${id}`),
|
|
1162
1164
|
/** The config catalog for a profile UI: supported embedding models (+ provider/dims),
|
|
1163
1165
|
* chunkers, distances, quantizations, per-field defaults/bounds, and the standard params.
|
|
1164
|
-
* Build-side mirror of `
|
|
1166
|
+
* Build-side mirror of `queryProfiles.modelOptions()`. */
|
|
1165
1167
|
modelOptions: () => this.request<IngestionProfileOptions>("GET", "/v1/profiles/model-options"),
|
|
1166
1168
|
};
|
|
1167
1169
|
|
|
@@ -1202,7 +1204,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
1202
1204
|
|
|
1203
1205
|
// ---------------------------------------------------------------------------
|
|
1204
1206
|
// Admin client (tenant + API-key provisioning) — use the ADMIN key.
|
|
1205
|
-
//
|
|
1207
|
+
// Query profiles are tenant data; manage them with the tenant client (KnowledgeCoreClient.queryProfiles).
|
|
1206
1208
|
// ---------------------------------------------------------------------------
|
|
1207
1209
|
export class AdminClient extends HttpBase {
|
|
1208
1210
|
/** @param opts.apiKey the ADMIN key, supplied by the caller. */
|
|
@@ -1221,8 +1223,8 @@ export class AdminClient extends HttpBase {
|
|
|
1221
1223
|
listApiKeys: (tenantId: UUID, q?: { limit?: number; cursor?: string }) => this.request<Page<ApiKey>>("GET", `/v1/tenants/${tenantId}/api-keys`, { query: q }),
|
|
1222
1224
|
revokeApiKey: (tenantId: UUID, keyId: UUID) => this.request<void>("DELETE", `/v1/tenants/${tenantId}/api-keys/${keyId}`),
|
|
1223
1225
|
};
|
|
1224
|
-
//
|
|
1225
|
-
// KnowledgeCoreClient.
|
|
1226
|
+
// Query profiles are TENANT data, not an admin surface — manage them with the tenant key via
|
|
1227
|
+
// KnowledgeCoreClient.queryProfiles (create/update/delete/list/get/modelOptions).
|
|
1226
1228
|
}
|
|
1227
1229
|
|
|
1228
1230
|
export interface ChatSendOptions extends StreamHandlers {
|
|
@@ -1247,15 +1249,15 @@ export interface ChatSendOptions extends StreamHandlers {
|
|
|
1247
1249
|
* a chat turn is never lost and a chat conversation is never left blank. */
|
|
1248
1250
|
export class ChatSession {
|
|
1249
1251
|
#kc: KnowledgeCoreClient;
|
|
1250
|
-
#
|
|
1252
|
+
#profileId: UUID;
|
|
1251
1253
|
#corpusIds: UUID[];
|
|
1252
1254
|
#creating: Promise<UUID> | null = null;
|
|
1253
1255
|
/** The conversation id — null until the first `send()` (unless resumed). */
|
|
1254
1256
|
conversationId: UUID | null;
|
|
1255
1257
|
|
|
1256
|
-
constructor(kc: KnowledgeCoreClient,
|
|
1258
|
+
constructor(kc: KnowledgeCoreClient, profileId: UUID, corpusIds: UUID[], conversationId: UUID | null) {
|
|
1257
1259
|
this.#kc = kc;
|
|
1258
|
-
this.#
|
|
1260
|
+
this.#profileId = profileId;
|
|
1259
1261
|
this.#corpusIds = corpusIds;
|
|
1260
1262
|
this.conversationId = conversationId;
|
|
1261
1263
|
}
|
|
@@ -1278,7 +1280,7 @@ export class ChatSession {
|
|
|
1278
1280
|
const convId = await this.#ensure(o, text);
|
|
1279
1281
|
o.onConversationId?.(convId);
|
|
1280
1282
|
await this.#kc.queryStream(
|
|
1281
|
-
this.#
|
|
1283
|
+
this.#profileId,
|
|
1282
1284
|
{ corpus_ids: this.#corpusIds, query: text, conversation_id: convId,
|
|
1283
1285
|
overrides: o.overrides, filter: o.filter, visual: o.visual },
|
|
1284
1286
|
o,
|