@babav/knowledge-core-client 0.41.0 → 0.43.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.d.ts +48 -23
- package/dist/index.js +33 -29
- package/package.json +1 -1
- package/src/index.ts +52 -36
package/dist/index.d.ts
CHANGED
|
@@ -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;
|
|
@@ -245,6 +245,27 @@ export interface IngestionProfileWrite {
|
|
|
245
245
|
params?: Partial<IngestionProfileParams>;
|
|
246
246
|
is_default?: boolean;
|
|
247
247
|
}
|
|
248
|
+
/** Config catalog for a profile UI (GET /v1/profiles/model-options) — build-side mirror of the
|
|
249
|
+
* query model-options. `embedding_models` maps id → { provider, dimensions, label }; `fields`
|
|
250
|
+
* gives each param its supported list / default / bounds; `standard_params` is the blessed default. */
|
|
251
|
+
export interface IngestionProfileOptions {
|
|
252
|
+
embedding_models: Record<string, {
|
|
253
|
+
provider: string;
|
|
254
|
+
dimensions: number;
|
|
255
|
+
label: string;
|
|
256
|
+
}>;
|
|
257
|
+
chunkers: Record<string, {
|
|
258
|
+
label: string;
|
|
259
|
+
}>;
|
|
260
|
+
distances: string[];
|
|
261
|
+
quantizations: string[];
|
|
262
|
+
fields: Record<string, {
|
|
263
|
+
supported?: string[];
|
|
264
|
+
default?: unknown;
|
|
265
|
+
min?: number;
|
|
266
|
+
}>;
|
|
267
|
+
standard_params: IngestionProfileParams;
|
|
268
|
+
}
|
|
248
269
|
export interface Folder {
|
|
249
270
|
id: UUID;
|
|
250
271
|
corpus_id: UUID;
|
|
@@ -456,7 +477,7 @@ export interface Conversation {
|
|
|
456
477
|
export interface Message {
|
|
457
478
|
id: UUID;
|
|
458
479
|
conversation_id: UUID;
|
|
459
|
-
|
|
480
|
+
query_profile_id: UUID | null;
|
|
460
481
|
corpus_ids: UUID[] | null;
|
|
461
482
|
query: string;
|
|
462
483
|
answer: string | null;
|
|
@@ -485,7 +506,7 @@ export interface Feedback {
|
|
|
485
506
|
rating: number | null;
|
|
486
507
|
comment: string | null;
|
|
487
508
|
}
|
|
488
|
-
export interface
|
|
509
|
+
export interface QueryProfile {
|
|
489
510
|
id: UUID;
|
|
490
511
|
tenant_id: UUID;
|
|
491
512
|
name: string;
|
|
@@ -522,8 +543,8 @@ export interface Agent {
|
|
|
522
543
|
* (null/omit => server default); model fields must be one of
|
|
523
544
|
* `agents.modelOptions().fields[field].supported`. The owning tenant is the caller's key —
|
|
524
545
|
* it is never part of the body. */
|
|
525
|
-
export type
|
|
526
|
-
/** Model catalog for the
|
|
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
|
|
527
548
|
* capabilities; `fields` gives each agent model-field its supported ids + default (+ usage metadata);
|
|
528
549
|
* `modes` says which model field governs each mode (reasoning is valid only if that model's
|
|
529
550
|
* supports_reasoning is true). KC provides the data; the UI decides presentation. */
|
|
@@ -665,11 +686,11 @@ export interface DocumentEventHandlers {
|
|
|
665
686
|
export declare class KnowledgeCoreClient extends HttpBase {
|
|
666
687
|
/** @param opts.apiKey a TENANT key, supplied by the caller. */
|
|
667
688
|
constructor(opts: ClientOptions);
|
|
668
|
-
query(
|
|
689
|
+
query(profileId: UUID, body: QueryRequest): Promise<QueryResponse>;
|
|
669
690
|
/** Streaming query (SSE). Resolves when the stream ends (the Promise resolving is normal, not an
|
|
670
691
|
* error). Pass `signal` and abort() on unmount / when the user cancels or navigates away so the
|
|
671
692
|
* connection doesn't linger. Transient (ends on `done`) — no reopen logic needed. */
|
|
672
|
-
queryStream(
|
|
693
|
+
queryStream(profileId: UUID, body: QueryRequest, handlers: StreamHandlers, signal?: AbortSignal): Promise<void>;
|
|
673
694
|
/** Fetch a visual's PNG bytes BY ID. This is the ONLY way to get a visual image — the API never
|
|
674
695
|
* returns a URL. Authenticated + tenant-scoped like every call. Use `visual.id` from a query
|
|
675
696
|
* response / streamed `visual` event / persisted message. Returns a Blob (browser: `URL.
|
|
@@ -687,11 +708,11 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
687
708
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
688
709
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
689
710
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
|
690
|
-
* New chat: const chat = kc.chat(
|
|
691
|
-
* Resume: const chat = kc.chat(
|
|
711
|
+
* New chat: const chat = kc.chat(profileId, corpusIds);
|
|
712
|
+
* Resume: const chat = kc.chat(profileId, corpusIds, { conversationId });
|
|
692
713
|
* The conversation is created LAZILY on the first `send()` (opening a "new chat" and never
|
|
693
714
|
* sending leaves nothing behind). See ChatSession.send. */
|
|
694
|
-
chat(
|
|
715
|
+
chat(profileId: UUID, corpusIds: UUID[], opts?: {
|
|
695
716
|
conversationId?: UUID;
|
|
696
717
|
}): ChatSession;
|
|
697
718
|
/** Shared SSE reader for the document-status streams (documents.events / folders.events).
|
|
@@ -963,25 +984,25 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
963
984
|
get: (id: UUID) => Promise<Feedback>;
|
|
964
985
|
delete: (id: UUID) => Promise<void>;
|
|
965
986
|
};
|
|
966
|
-
|
|
967
|
-
/** List this tenant's
|
|
987
|
+
queryProfiles: {
|
|
988
|
+
/** List this tenant's query profiles. */
|
|
968
989
|
list: (q?: {
|
|
969
990
|
limit?: number;
|
|
970
991
|
cursor?: string;
|
|
971
|
-
}) => Promise<Page<
|
|
972
|
-
listAll: () => Promise<
|
|
973
|
-
get: (id: UUID) => Promise<
|
|
974
|
-
/** Create
|
|
975
|
-
create: (b:
|
|
992
|
+
}) => Promise<Page<QueryProfile>>;
|
|
993
|
+
listAll: () => Promise<QueryProfile[]>;
|
|
994
|
+
get: (id: UUID) => Promise<QueryProfile>;
|
|
995
|
+
/** Create a query profile owned by this tenant (the owning tenant is the key's — no tenant_id in the body). */
|
|
996
|
+
create: (b: QueryProfileWrite & {
|
|
976
997
|
name: string;
|
|
977
|
-
}) => Promise<
|
|
978
|
-
update: (id: UUID, b:
|
|
998
|
+
}) => Promise<QueryProfile>;
|
|
999
|
+
update: (id: UUID, b: QueryProfileWrite) => Promise<QueryProfile>;
|
|
979
1000
|
delete: (id: UUID) => Promise<void>;
|
|
980
|
-
/** The model catalog for an
|
|
1001
|
+
/** The model catalog for an query-profile-config UI: supported models + default per field, per-model
|
|
981
1002
|
* capabilities (`supports_reasoning`), and mode↔model dependencies. */
|
|
982
1003
|
modelOptions: () => Promise<ModelOptions>;
|
|
983
1004
|
};
|
|
984
|
-
/** Ingestion profiles — the build-side config object (counterpart to
|
|
1005
|
+
/** Ingestion profiles — the build-side config object (counterpart to query profiles): a tenant-owned,
|
|
985
1006
|
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike an agent
|
|
986
1007
|
* (chosen per query), a profile binds at the TENANT/COLLECTION level — the tenant's one
|
|
987
1008
|
* `is_default` profile governs how ALL its documents are ingested; swapping it re-indexes.
|
|
@@ -999,8 +1020,12 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
999
1020
|
name: string;
|
|
1000
1021
|
}) => Promise<IngestionProfile>;
|
|
1001
1022
|
update: (id: UUID, b: IngestionProfileWrite) => Promise<IngestionProfile>;
|
|
1002
|
-
/** Delete a profile. 409
|
|
1023
|
+
/** Delete a profile. 409 when it's the tenant's active (default) profile. */
|
|
1003
1024
|
delete: (id: UUID) => Promise<void>;
|
|
1025
|
+
/** The config catalog for a profile UI: supported embedding models (+ provider/dims),
|
|
1026
|
+
* chunkers, distances, quantizations, per-field defaults/bounds, and the standard params.
|
|
1027
|
+
* Build-side mirror of `queryProfiles.modelOptions()`. */
|
|
1028
|
+
modelOptions: () => Promise<IngestionProfileOptions>;
|
|
1004
1029
|
};
|
|
1005
1030
|
analytics: {
|
|
1006
1031
|
/** Query-volume time series for a corpus (the denominator for everything). */
|
|
@@ -1098,7 +1123,7 @@ export declare class ChatSession {
|
|
|
1098
1123
|
#private;
|
|
1099
1124
|
/** The conversation id — null until the first `send()` (unless resumed). */
|
|
1100
1125
|
conversationId: UUID | null;
|
|
1101
|
-
constructor(kc: KnowledgeCoreClient,
|
|
1126
|
+
constructor(kc: KnowledgeCoreClient, profileId: UUID, corpusIds: UUID[], conversationId: UUID | null);
|
|
1102
1127
|
/** Send a chat message (streaming). Lazily creates the conversation on the first message and
|
|
1103
1128
|
* ALWAYS passes conversation_id, so the turn is persisted. `onConversationId` fires before the
|
|
1104
1129
|
* stream so you can show the conversation immediately. Pass `signal` to cancel on unmount. */
|
package/dist/index.js
CHANGED
|
@@ -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
|
|
@@ -453,21 +453,21 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
453
453
|
get: (id) => this.request("GET", `/v1/feedback/${id}`),
|
|
454
454
|
delete: (id) => this.request("DELETE", `/v1/feedback/${id}`),
|
|
455
455
|
};
|
|
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
|
|
456
|
+
// --- query profiles (tenant-owned query config; full CRUD with the tenant key) ---
|
|
457
|
+
queryProfiles = {
|
|
458
|
+
/** List this tenant's query profiles. */
|
|
459
|
+
list: (q) => this.request("GET", "/v1/query-profiles", { query: q }),
|
|
460
|
+
listAll: () => this.pageAll("/v1/query-profiles"),
|
|
461
|
+
get: (id) => this.request("GET", `/v1/query-profiles/${id}`),
|
|
462
|
+
/** Create a query profile owned by this tenant (the owning tenant is the key's — no tenant_id in the body). */
|
|
463
|
+
create: (b) => this.request("POST", "/v1/query-profiles", { json: b }),
|
|
464
|
+
update: (id, b) => this.request("PATCH", `/v1/query-profiles/${id}`, { json: b }),
|
|
465
|
+
delete: (id) => this.request("DELETE", `/v1/query-profiles/${id}`),
|
|
466
|
+
/** The model catalog for an query-profile-config UI: supported models + default per field, per-model
|
|
467
467
|
* capabilities (`supports_reasoning`), and mode↔model dependencies. */
|
|
468
|
-
modelOptions: () => this.request("GET", "/v1/
|
|
468
|
+
modelOptions: () => this.request("GET", "/v1/query-profiles/model-options"),
|
|
469
469
|
};
|
|
470
|
-
/** Ingestion profiles — the build-side config object (counterpart to
|
|
470
|
+
/** Ingestion profiles — the build-side config object (counterpart to query profiles): a tenant-owned,
|
|
471
471
|
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike an agent
|
|
472
472
|
* (chosen per query), a profile binds at the TENANT/COLLECTION level — the tenant's one
|
|
473
473
|
* `is_default` profile governs how ALL its documents are ingested; swapping it re-indexes.
|
|
@@ -480,8 +480,12 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
480
480
|
/** Create a profile owned by this tenant. Omit `params` for the blessed profile (all defaults). */
|
|
481
481
|
create: (b) => this.request("POST", "/v1/profiles", { json: b }),
|
|
482
482
|
update: (id, b) => this.request("PATCH", `/v1/profiles/${id}`, { json: b }),
|
|
483
|
-
/** Delete a profile. 409
|
|
483
|
+
/** Delete a profile. 409 when it's the tenant's active (default) profile. */
|
|
484
484
|
delete: (id) => this.request("DELETE", `/v1/profiles/${id}`),
|
|
485
|
+
/** The config catalog for a profile UI: supported embedding models (+ provider/dims),
|
|
486
|
+
* chunkers, distances, quantizations, per-field defaults/bounds, and the standard params.
|
|
487
|
+
* Build-side mirror of `queryProfiles.modelOptions()`. */
|
|
488
|
+
modelOptions: () => this.request("GET", "/v1/profiles/model-options"),
|
|
485
489
|
};
|
|
486
490
|
// --- retrieval analytics (read-only, tenant-scoped, aggregate-on-read) ---
|
|
487
491
|
analytics = {
|
|
@@ -515,7 +519,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
515
519
|
}
|
|
516
520
|
// ---------------------------------------------------------------------------
|
|
517
521
|
// Admin client (tenant + API-key provisioning) — use the ADMIN key.
|
|
518
|
-
//
|
|
522
|
+
// Query profiles are tenant data; manage them with the tenant client (KnowledgeCoreClient.queryProfiles).
|
|
519
523
|
// ---------------------------------------------------------------------------
|
|
520
524
|
export class AdminClient extends HttpBase {
|
|
521
525
|
/** @param opts.apiKey the ADMIN key, supplied by the caller. */
|
|
@@ -540,14 +544,14 @@ export class AdminClient extends HttpBase {
|
|
|
540
544
|
* a chat turn is never lost and a chat conversation is never left blank. */
|
|
541
545
|
export class ChatSession {
|
|
542
546
|
#kc;
|
|
543
|
-
#
|
|
547
|
+
#profileId;
|
|
544
548
|
#corpusIds;
|
|
545
549
|
#creating = null;
|
|
546
550
|
/** The conversation id — null until the first `send()` (unless resumed). */
|
|
547
551
|
conversationId;
|
|
548
|
-
constructor(kc,
|
|
552
|
+
constructor(kc, profileId, corpusIds, conversationId) {
|
|
549
553
|
this.#kc = kc;
|
|
550
|
-
this.#
|
|
554
|
+
this.#profileId = profileId;
|
|
551
555
|
this.#corpusIds = corpusIds;
|
|
552
556
|
this.conversationId = conversationId;
|
|
553
557
|
}
|
|
@@ -568,7 +572,7 @@ export class ChatSession {
|
|
|
568
572
|
async send(text, o = {}) {
|
|
569
573
|
const convId = await this.#ensure(o, text);
|
|
570
574
|
o.onConversationId?.(convId);
|
|
571
|
-
await this.#kc.queryStream(this.#
|
|
575
|
+
await this.#kc.queryStream(this.#profileId, { corpus_ids: this.#corpusIds, query: text, conversation_id: convId,
|
|
572
576
|
overrides: o.overrides, filter: o.filter, visual: o.visual }, o, o.signal);
|
|
573
577
|
}
|
|
574
578
|
/** 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.43.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
|
@@ -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;
|
|
@@ -282,6 +282,18 @@ export interface IngestionProfileWrite {
|
|
|
282
282
|
params?: Partial<IngestionProfileParams>;
|
|
283
283
|
is_default?: boolean;
|
|
284
284
|
}
|
|
285
|
+
|
|
286
|
+
/** Config catalog for a profile UI (GET /v1/profiles/model-options) — build-side mirror of the
|
|
287
|
+
* query model-options. `embedding_models` maps id → { provider, dimensions, label }; `fields`
|
|
288
|
+
* gives each param its supported list / default / bounds; `standard_params` is the blessed default. */
|
|
289
|
+
export interface IngestionProfileOptions {
|
|
290
|
+
embedding_models: Record<string, { provider: string; dimensions: number; label: string }>;
|
|
291
|
+
chunkers: Record<string, { label: string }>;
|
|
292
|
+
distances: string[];
|
|
293
|
+
quantizations: string[];
|
|
294
|
+
fields: Record<string, { supported?: string[]; default?: unknown; min?: number }>;
|
|
295
|
+
standard_params: IngestionProfileParams;
|
|
296
|
+
}
|
|
285
297
|
export interface Folder {
|
|
286
298
|
id: UUID;
|
|
287
299
|
corpus_id: UUID;
|
|
@@ -434,7 +446,7 @@ export interface Conversation {
|
|
|
434
446
|
export interface Message {
|
|
435
447
|
id: UUID;
|
|
436
448
|
conversation_id: UUID;
|
|
437
|
-
|
|
449
|
+
query_profile_id: UUID | null;
|
|
438
450
|
corpus_ids: UUID[] | null;
|
|
439
451
|
query: string;
|
|
440
452
|
answer: string | null;
|
|
@@ -460,7 +472,7 @@ export interface Feedback {
|
|
|
460
472
|
rating: number | null;
|
|
461
473
|
comment: string | null;
|
|
462
474
|
}
|
|
463
|
-
export interface
|
|
475
|
+
export interface QueryProfile {
|
|
464
476
|
id: UUID;
|
|
465
477
|
tenant_id: UUID; // the owning tenant (every agent belongs to exactly one; no globals)
|
|
466
478
|
name: string;
|
|
@@ -499,9 +511,9 @@ export interface Agent {
|
|
|
499
511
|
* (null/omit => server default); model fields must be one of
|
|
500
512
|
* `agents.modelOptions().fields[field].supported`. The owning tenant is the caller's key —
|
|
501
513
|
* it is never part of the body. */
|
|
502
|
-
export type
|
|
514
|
+
export type QueryProfileWrite = Partial<Omit<QueryProfile, "id" | "tenant_id">>;
|
|
503
515
|
|
|
504
|
-
/** Model catalog for the
|
|
516
|
+
/** Model catalog for the query-profile-config UI (GET /v1/query-profiles/model-options). `models` maps id → its
|
|
505
517
|
* capabilities; `fields` gives each agent model-field its supported ids + default (+ usage metadata);
|
|
506
518
|
* `modes` says which model field governs each mode (reasoning is valid only if that model's
|
|
507
519
|
* supports_reasoning is true). KC provides the data; the UI decides presentation. */
|
|
@@ -746,19 +758,19 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
746
758
|
super(opts);
|
|
747
759
|
}
|
|
748
760
|
|
|
749
|
-
// --- query (
|
|
750
|
-
query(
|
|
751
|
-
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 });
|
|
752
764
|
}
|
|
753
765
|
|
|
754
766
|
/** Streaming query (SSE). Resolves when the stream ends (the Promise resolving is normal, not an
|
|
755
767
|
* error). Pass `signal` and abort() on unmount / when the user cancels or navigates away so the
|
|
756
768
|
* connection doesn't linger. Transient (ends on `done`) — no reopen logic needed. */
|
|
757
|
-
async queryStream(
|
|
758
|
-
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 });
|
|
759
771
|
if (!res.ok || !res.body) {
|
|
760
772
|
const t = await res.text();
|
|
761
|
-
throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/
|
|
773
|
+
throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/query-profiles/${profileId}/query/stream`);
|
|
762
774
|
}
|
|
763
775
|
const reader = res.body.getReader();
|
|
764
776
|
const decoder = new TextDecoder();
|
|
@@ -813,12 +825,12 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
813
825
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
814
826
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
815
827
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
|
816
|
-
* New chat: const chat = kc.chat(
|
|
817
|
-
* Resume: const chat = kc.chat(
|
|
828
|
+
* New chat: const chat = kc.chat(profileId, corpusIds);
|
|
829
|
+
* Resume: const chat = kc.chat(profileId, corpusIds, { conversationId });
|
|
818
830
|
* The conversation is created LAZILY on the first `send()` (opening a "new chat" and never
|
|
819
831
|
* sending leaves nothing behind). See ChatSession.send. */
|
|
820
|
-
chat(
|
|
821
|
-
return new ChatSession(this,
|
|
832
|
+
chat(profileId: UUID, corpusIds: UUID[], opts?: { conversationId?: UUID }): ChatSession {
|
|
833
|
+
return new ChatSession(this, profileId, corpusIds, opts?.conversationId ?? null);
|
|
822
834
|
}
|
|
823
835
|
|
|
824
836
|
/** Shared SSE reader for the document-status streams (documents.events / folders.events).
|
|
@@ -1114,22 +1126,22 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
1114
1126
|
delete: (id: UUID) => this.request<void>("DELETE", `/v1/feedback/${id}`),
|
|
1115
1127
|
};
|
|
1116
1128
|
|
|
1117
|
-
// ---
|
|
1118
|
-
|
|
1119
|
-
/** List this tenant's
|
|
1120
|
-
list: (q?: { limit?: number; cursor?: string }) => this.request<Page<
|
|
1121
|
-
listAll: () => this.pageAll<
|
|
1122
|
-
get: (id: UUID) => this.request<
|
|
1123
|
-
/** Create
|
|
1124
|
-
create: (b:
|
|
1125
|
-
update: (id: UUID, b:
|
|
1126
|
-
delete: (id: UUID) => this.request<void>("DELETE", `/v1/
|
|
1127
|
-
/** The model catalog for an
|
|
1129
|
+
// --- query profiles (tenant-owned query config; full CRUD with the tenant key) ---
|
|
1130
|
+
queryProfiles = {
|
|
1131
|
+
/** List this tenant's query profiles. */
|
|
1132
|
+
list: (q?: { limit?: number; cursor?: string }) => this.request<Page<QueryProfile>>("GET", "/v1/query-profiles", { query: q }),
|
|
1133
|
+
listAll: () => this.pageAll<QueryProfile>("/v1/query-profiles"),
|
|
1134
|
+
get: (id: UUID) => this.request<QueryProfile>("GET", `/v1/query-profiles/${id}`),
|
|
1135
|
+
/** Create a query profile owned by this tenant (the owning tenant is the key's — no tenant_id in the body). */
|
|
1136
|
+
create: (b: QueryProfileWrite & { name: string }) => this.request<QueryProfile>("POST", "/v1/query-profiles", { json: b }),
|
|
1137
|
+
update: (id: UUID, b: QueryProfileWrite) => this.request<QueryProfile>("PATCH", `/v1/query-profiles/${id}`, { json: b }),
|
|
1138
|
+
delete: (id: UUID) => this.request<void>("DELETE", `/v1/query-profiles/${id}`),
|
|
1139
|
+
/** The model catalog for an query-profile-config UI: supported models + default per field, per-model
|
|
1128
1140
|
* capabilities (`supports_reasoning`), and mode↔model dependencies. */
|
|
1129
|
-
modelOptions: () => this.request<ModelOptions>("GET", "/v1/
|
|
1141
|
+
modelOptions: () => this.request<ModelOptions>("GET", "/v1/query-profiles/model-options"),
|
|
1130
1142
|
};
|
|
1131
1143
|
|
|
1132
|
-
/** Ingestion profiles — the build-side config object (counterpart to
|
|
1144
|
+
/** Ingestion profiles — the build-side config object (counterpart to query profiles): a tenant-owned,
|
|
1133
1145
|
* named bundle of pipeline config (chunking + embedding + sparse + quant). Unlike an agent
|
|
1134
1146
|
* (chosen per query), a profile binds at the TENANT/COLLECTION level — the tenant's one
|
|
1135
1147
|
* `is_default` profile governs how ALL its documents are ingested; swapping it re-indexes.
|
|
@@ -1145,8 +1157,12 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
1145
1157
|
this.request<IngestionProfile>("POST", "/v1/profiles", { json: b }),
|
|
1146
1158
|
update: (id: UUID, b: IngestionProfileWrite) =>
|
|
1147
1159
|
this.request<IngestionProfile>("PATCH", `/v1/profiles/${id}`, { json: b }),
|
|
1148
|
-
/** Delete a profile. 409
|
|
1160
|
+
/** Delete a profile. 409 when it's the tenant's active (default) profile. */
|
|
1149
1161
|
delete: (id: UUID) => this.request<void>("DELETE", `/v1/profiles/${id}`),
|
|
1162
|
+
/** The config catalog for a profile UI: supported embedding models (+ provider/dims),
|
|
1163
|
+
* chunkers, distances, quantizations, per-field defaults/bounds, and the standard params.
|
|
1164
|
+
* Build-side mirror of `queryProfiles.modelOptions()`. */
|
|
1165
|
+
modelOptions: () => this.request<IngestionProfileOptions>("GET", "/v1/profiles/model-options"),
|
|
1150
1166
|
};
|
|
1151
1167
|
|
|
1152
1168
|
// --- retrieval analytics (read-only, tenant-scoped, aggregate-on-read) ---
|
|
@@ -1186,7 +1202,7 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
1186
1202
|
|
|
1187
1203
|
// ---------------------------------------------------------------------------
|
|
1188
1204
|
// Admin client (tenant + API-key provisioning) — use the ADMIN key.
|
|
1189
|
-
//
|
|
1205
|
+
// Query profiles are tenant data; manage them with the tenant client (KnowledgeCoreClient.queryProfiles).
|
|
1190
1206
|
// ---------------------------------------------------------------------------
|
|
1191
1207
|
export class AdminClient extends HttpBase {
|
|
1192
1208
|
/** @param opts.apiKey the ADMIN key, supplied by the caller. */
|
|
@@ -1205,8 +1221,8 @@ export class AdminClient extends HttpBase {
|
|
|
1205
1221
|
listApiKeys: (tenantId: UUID, q?: { limit?: number; cursor?: string }) => this.request<Page<ApiKey>>("GET", `/v1/tenants/${tenantId}/api-keys`, { query: q }),
|
|
1206
1222
|
revokeApiKey: (tenantId: UUID, keyId: UUID) => this.request<void>("DELETE", `/v1/tenants/${tenantId}/api-keys/${keyId}`),
|
|
1207
1223
|
};
|
|
1208
|
-
//
|
|
1209
|
-
// KnowledgeCoreClient.
|
|
1224
|
+
// Query profiles are TENANT data, not an admin surface — manage them with the tenant key via
|
|
1225
|
+
// KnowledgeCoreClient.queryProfiles (create/update/delete/list/get/modelOptions).
|
|
1210
1226
|
}
|
|
1211
1227
|
|
|
1212
1228
|
export interface ChatSendOptions extends StreamHandlers {
|
|
@@ -1231,15 +1247,15 @@ export interface ChatSendOptions extends StreamHandlers {
|
|
|
1231
1247
|
* a chat turn is never lost and a chat conversation is never left blank. */
|
|
1232
1248
|
export class ChatSession {
|
|
1233
1249
|
#kc: KnowledgeCoreClient;
|
|
1234
|
-
#
|
|
1250
|
+
#profileId: UUID;
|
|
1235
1251
|
#corpusIds: UUID[];
|
|
1236
1252
|
#creating: Promise<UUID> | null = null;
|
|
1237
1253
|
/** The conversation id — null until the first `send()` (unless resumed). */
|
|
1238
1254
|
conversationId: UUID | null;
|
|
1239
1255
|
|
|
1240
|
-
constructor(kc: KnowledgeCoreClient,
|
|
1256
|
+
constructor(kc: KnowledgeCoreClient, profileId: UUID, corpusIds: UUID[], conversationId: UUID | null) {
|
|
1241
1257
|
this.#kc = kc;
|
|
1242
|
-
this.#
|
|
1258
|
+
this.#profileId = profileId;
|
|
1243
1259
|
this.#corpusIds = corpusIds;
|
|
1244
1260
|
this.conversationId = conversationId;
|
|
1245
1261
|
}
|
|
@@ -1262,7 +1278,7 @@ export class ChatSession {
|
|
|
1262
1278
|
const convId = await this.#ensure(o, text);
|
|
1263
1279
|
o.onConversationId?.(convId);
|
|
1264
1280
|
await this.#kc.queryStream(
|
|
1265
|
-
this.#
|
|
1281
|
+
this.#profileId,
|
|
1266
1282
|
{ corpus_ids: this.#corpusIds, query: text, conversation_id: convId,
|
|
1267
1283
|
overrides: o.overrides, filter: o.filter, visual: o.visual },
|
|
1268
1284
|
o,
|