@babav/knowledge-core-client 0.32.0 → 0.33.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 +42 -10
- package/dist/index.js +15 -0
- package/package.json +1 -1
- package/src/index.ts +55 -11
package/dist/index.d.ts
CHANGED
|
@@ -94,30 +94,37 @@ export interface QueryRequest {
|
|
|
94
94
|
* "free" = renderer's judgment / not a declared arrangement (also the value for non-conceptual
|
|
95
95
|
* registers). */
|
|
96
96
|
export type VisualLayout = "linear-flow" | "ring-cycle" | "nesting" | "radial-hub" | "side-by-side" | "stacked-layers" | "two-state" | "free";
|
|
97
|
-
/** A visual attached to a response
|
|
98
|
-
* system as citations).
|
|
97
|
+
/** A visual attached to a response.
|
|
99
98
|
*
|
|
100
99
|
* IDs-ONLY: the API never returns a URL. Every visual (chart / structural / conceptual / scenic) is
|
|
101
|
-
* a PNG served by KC and identified by its `id`. To display it, fetch the bytes by id
|
|
102
|
-
* `getVisualImage(visual.id)`
|
|
103
|
-
*
|
|
104
|
-
* other KC call; there is no URL, no signed GCS link
|
|
100
|
+
* a PNG served by KC and identified by its `id`. To display it, fetch the bytes by id —
|
|
101
|
+
* `getVisualImage(visual.id)` for one, or `getVisualImages([...ids])` to fetch a whole answer's
|
|
102
|
+
* visuals in a SINGLE call (no per-visual fan-out). The image is authenticated + tenant-scoped
|
|
103
|
+
* exactly like every other KC call; there is no URL, no signed GCS link. */
|
|
105
104
|
export interface Visual {
|
|
106
105
|
id: string;
|
|
107
|
-
|
|
106
|
+
/** Char offsets into `answer` (SAME coordinate system as citations). OPTIONAL: a visual may be
|
|
107
|
+
* anchorless (belongs in the trailing strip) — when absent, place it after the answer. */
|
|
108
|
+
anchor?: {
|
|
108
109
|
start: number;
|
|
109
110
|
end: number;
|
|
110
111
|
};
|
|
111
112
|
register: "chart" | "structural" | "conceptual" | "scenic";
|
|
112
|
-
|
|
113
|
+
/** Client display ordering (higher first). OPTIONAL — default to 0 / arrival order if absent. */
|
|
114
|
+
priority?: number;
|
|
113
115
|
payload: Record<string, unknown>;
|
|
114
116
|
/** Declared spatial arrangement (meaningful for `conceptual`; "free" otherwise). */
|
|
115
117
|
layout: VisualLayout;
|
|
116
|
-
/** Pixel dimensions of the PNG
|
|
117
|
-
|
|
118
|
+
/** Pixel dimensions of the PNG — ALWAYS present on a shipped visual, so the UI can reserve space
|
|
119
|
+
* before the bytes arrive (no layout shift). Fetch the bytes with getVisualImage(id). */
|
|
120
|
+
image: {
|
|
118
121
|
width: number;
|
|
119
122
|
height: number;
|
|
120
123
|
};
|
|
124
|
+
/** Short KC-authored figure caption (the idea the visual carries). Present when authored. */
|
|
125
|
+
caption?: string;
|
|
126
|
+
/** Plain-text description for screen readers / accessible PDF·DOCX·LaTeX export. Present when authored. */
|
|
127
|
+
alt?: string;
|
|
121
128
|
}
|
|
122
129
|
/** Visual stage (streaming): generation has started. MAY be emitted twice — first with
|
|
123
130
|
* `pending: null` (started, count unknown), then again with the ACCURATE post-vet count before
|
|
@@ -126,8 +133,24 @@ export interface VisualsPending {
|
|
|
126
133
|
pending: number | null;
|
|
127
134
|
}
|
|
128
135
|
export interface VisualsMeta {
|
|
136
|
+
/** Visuals that shipped (authoritative — always matches the number of `visual` events). */
|
|
129
137
|
count: number;
|
|
138
|
+
/** Concepts accepted by the vet but not shipped (render_failed + timeout). */
|
|
130
139
|
dropped: number;
|
|
140
|
+
/** Counts-by-cause for every PROPOSED concept that did not become a visible visual, so a missing
|
|
141
|
+
* visual is explainable rather than silent. Keys (zero causes omitted):
|
|
142
|
+
* - `declined` the vet declined/trimmed the concept (never promised; reduces the pending count)
|
|
143
|
+
* - `render_failed` accepted but authoring/rendering/vision-review dropped it
|
|
144
|
+
* - `timeout` accepted but the post-answer render budget cut it off
|
|
145
|
+
* `dropped` = render_failed + timeout; `declined` is extra context beyond `dropped`. */
|
|
146
|
+
dropped_reasons?: Record<string, number>;
|
|
147
|
+
}
|
|
148
|
+
/** One image returned by getVisualImages(). `blob` is the PNG (browser: `URL.createObjectURL(blob)`). */
|
|
149
|
+
export interface VisualImage {
|
|
150
|
+
id: string;
|
|
151
|
+
blob: Blob;
|
|
152
|
+
width: number;
|
|
153
|
+
height: number;
|
|
131
154
|
}
|
|
132
155
|
export interface QueryResponse {
|
|
133
156
|
conversation_id: UUID | null;
|
|
@@ -540,6 +563,15 @@ export declare class KnowledgeCoreClient extends HttpBase {
|
|
|
540
563
|
* response / streamed `visual` event / persisted message. Returns a Blob (browser: `URL.
|
|
541
564
|
* createObjectURL(blob)` for an <img>; Node: `Buffer.from(await blob.arrayBuffer())`). */
|
|
542
565
|
getVisualImage(visualId: UUID | string, signal?: AbortSignal): Promise<Blob>;
|
|
566
|
+
/** Fetch MANY visual PNGs in ONE call — the way to load all of an answer's (or a conversation's)
|
|
567
|
+
* visuals without a per-visual round trip. Pass up to 32 ids; over that, split into chunks (the
|
|
568
|
+
* API returns 400 `too_many_ids`). Returns the found images (as Blobs, ready for
|
|
569
|
+
* `URL.createObjectURL`) plus `missing` — ids with no stored image (reaped/expired), which the UI
|
|
570
|
+
* can show as "visual no longer available". Order of `images` is not guaranteed; key by `id`. */
|
|
571
|
+
getVisualImages(visualIds: Array<UUID | string>, signal?: AbortSignal): Promise<{
|
|
572
|
+
images: VisualImage[];
|
|
573
|
+
missing: string[];
|
|
574
|
+
}>;
|
|
543
575
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
544
576
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
545
577
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
package/dist/index.js
CHANGED
|
@@ -190,6 +190,21 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
190
190
|
}
|
|
191
191
|
return await res.blob();
|
|
192
192
|
}
|
|
193
|
+
/** Fetch MANY visual PNGs in ONE call — the way to load all of an answer's (or a conversation's)
|
|
194
|
+
* visuals without a per-visual round trip. Pass up to 32 ids; over that, split into chunks (the
|
|
195
|
+
* API returns 400 `too_many_ids`). Returns the found images (as Blobs, ready for
|
|
196
|
+
* `URL.createObjectURL`) plus `missing` — ids with no stored image (reaped/expired), which the UI
|
|
197
|
+
* can show as "visual no longer available". Order of `images` is not guaranteed; key by `id`. */
|
|
198
|
+
async getVisualImages(visualIds, signal) {
|
|
199
|
+
if (visualIds.length === 0)
|
|
200
|
+
return { images: [], missing: [] };
|
|
201
|
+
const r = await this.request("POST", "/v1/visuals/images", { json: { ids: visualIds }, signal });
|
|
202
|
+
const images = r.images.map((im) => {
|
|
203
|
+
const bytes = Uint8Array.from(atob(im.png_base64), (c) => c.charCodeAt(0));
|
|
204
|
+
return { id: im.id, blob: new Blob([bytes], { type: "image/png" }), width: im.width, height: im.height };
|
|
205
|
+
});
|
|
206
|
+
return { images, missing: r.missing ?? [] };
|
|
207
|
+
}
|
|
193
208
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
194
209
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
195
210
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@babav/knowledge-core-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.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
|
@@ -128,24 +128,31 @@ export type VisualLayout =
|
|
|
128
128
|
| "two-state"
|
|
129
129
|
| "free";
|
|
130
130
|
|
|
131
|
-
/** A visual attached to a response
|
|
132
|
-
* system as citations).
|
|
131
|
+
/** A visual attached to a response.
|
|
133
132
|
*
|
|
134
133
|
* IDs-ONLY: the API never returns a URL. Every visual (chart / structural / conceptual / scenic) is
|
|
135
|
-
* a PNG served by KC and identified by its `id`. To display it, fetch the bytes by id
|
|
136
|
-
* `getVisualImage(visual.id)`
|
|
137
|
-
*
|
|
138
|
-
* other KC call; there is no URL, no signed GCS link
|
|
134
|
+
* a PNG served by KC and identified by its `id`. To display it, fetch the bytes by id —
|
|
135
|
+
* `getVisualImage(visual.id)` for one, or `getVisualImages([...ids])` to fetch a whole answer's
|
|
136
|
+
* visuals in a SINGLE call (no per-visual fan-out). The image is authenticated + tenant-scoped
|
|
137
|
+
* exactly like every other KC call; there is no URL, no signed GCS link. */
|
|
139
138
|
export interface Visual {
|
|
140
139
|
id: string;
|
|
141
|
-
|
|
140
|
+
/** Char offsets into `answer` (SAME coordinate system as citations). OPTIONAL: a visual may be
|
|
141
|
+
* anchorless (belongs in the trailing strip) — when absent, place it after the answer. */
|
|
142
|
+
anchor?: { start: number; end: number };
|
|
142
143
|
register: "chart" | "structural" | "conceptual" | "scenic";
|
|
143
|
-
|
|
144
|
+
/** Client display ordering (higher first). OPTIONAL — default to 0 / arrival order if absent. */
|
|
145
|
+
priority?: number;
|
|
144
146
|
payload: Record<string, unknown>; // {kind: "grammar"|"vega_lite"|"image", ...}
|
|
145
147
|
/** Declared spatial arrangement (meaningful for `conceptual`; "free" otherwise). */
|
|
146
148
|
layout: VisualLayout;
|
|
147
|
-
/** Pixel dimensions of the PNG
|
|
148
|
-
|
|
149
|
+
/** Pixel dimensions of the PNG — ALWAYS present on a shipped visual, so the UI can reserve space
|
|
150
|
+
* before the bytes arrive (no layout shift). Fetch the bytes with getVisualImage(id). */
|
|
151
|
+
image: { width: number; height: number };
|
|
152
|
+
/** Short KC-authored figure caption (the idea the visual carries). Present when authored. */
|
|
153
|
+
caption?: string;
|
|
154
|
+
/** Plain-text description for screen readers / accessible PDF·DOCX·LaTeX export. Present when authored. */
|
|
155
|
+
alt?: string;
|
|
149
156
|
}
|
|
150
157
|
|
|
151
158
|
/** Visual stage (streaming): generation has started. MAY be emitted twice — first with
|
|
@@ -156,8 +163,25 @@ export interface VisualsPending {
|
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
export interface VisualsMeta {
|
|
166
|
+
/** Visuals that shipped (authoritative — always matches the number of `visual` events). */
|
|
159
167
|
count: number;
|
|
168
|
+
/** Concepts accepted by the vet but not shipped (render_failed + timeout). */
|
|
160
169
|
dropped: number;
|
|
170
|
+
/** Counts-by-cause for every PROPOSED concept that did not become a visible visual, so a missing
|
|
171
|
+
* visual is explainable rather than silent. Keys (zero causes omitted):
|
|
172
|
+
* - `declined` the vet declined/trimmed the concept (never promised; reduces the pending count)
|
|
173
|
+
* - `render_failed` accepted but authoring/rendering/vision-review dropped it
|
|
174
|
+
* - `timeout` accepted but the post-answer render budget cut it off
|
|
175
|
+
* `dropped` = render_failed + timeout; `declined` is extra context beyond `dropped`. */
|
|
176
|
+
dropped_reasons?: Record<string, number>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** One image returned by getVisualImages(). `blob` is the PNG (browser: `URL.createObjectURL(blob)`). */
|
|
180
|
+
export interface VisualImage {
|
|
181
|
+
id: string;
|
|
182
|
+
blob: Blob;
|
|
183
|
+
width: number;
|
|
184
|
+
height: number;
|
|
161
185
|
}
|
|
162
186
|
|
|
163
187
|
export interface QueryResponse {
|
|
@@ -355,7 +379,7 @@ export interface Message {
|
|
|
355
379
|
groundedness: Record<string, unknown> | null;
|
|
356
380
|
retrieval_contents: unknown[] | null;
|
|
357
381
|
usage: Record<string, unknown> | null;
|
|
358
|
-
visuals?: { items: Visual[]; meta: VisualsMeta } | null; //
|
|
382
|
+
visuals?: { items: Visual[]; meta: VisualsMeta } | null; // persisted visuals; fetch bytes by id (getVisualImages)
|
|
359
383
|
}
|
|
360
384
|
export interface Attachment {
|
|
361
385
|
id: UUID;
|
|
@@ -664,6 +688,26 @@ export class KnowledgeCoreClient extends HttpBase {
|
|
|
664
688
|
return await res.blob();
|
|
665
689
|
}
|
|
666
690
|
|
|
691
|
+
/** Fetch MANY visual PNGs in ONE call — the way to load all of an answer's (or a conversation's)
|
|
692
|
+
* visuals without a per-visual round trip. Pass up to 32 ids; over that, split into chunks (the
|
|
693
|
+
* API returns 400 `too_many_ids`). Returns the found images (as Blobs, ready for
|
|
694
|
+
* `URL.createObjectURL`) plus `missing` — ids with no stored image (reaped/expired), which the UI
|
|
695
|
+
* can show as "visual no longer available". Order of `images` is not guaranteed; key by `id`. */
|
|
696
|
+
async getVisualImages(
|
|
697
|
+
visualIds: Array<UUID | string>,
|
|
698
|
+
signal?: AbortSignal,
|
|
699
|
+
): Promise<{ images: VisualImage[]; missing: string[] }> {
|
|
700
|
+
if (visualIds.length === 0) return { images: [], missing: [] };
|
|
701
|
+
const r = await this.request<{ images: Array<{ id: string; png_base64: string; width: number; height: number }>; missing: string[] }>(
|
|
702
|
+
"POST", "/v1/visuals/images", { json: { ids: visualIds }, signal },
|
|
703
|
+
);
|
|
704
|
+
const images = r.images.map((im) => {
|
|
705
|
+
const bytes = Uint8Array.from(atob(im.png_base64), (c) => c.charCodeAt(0));
|
|
706
|
+
return { id: im.id, blob: new Blob([bytes], { type: "image/png" }), width: im.width, height: im.height };
|
|
707
|
+
});
|
|
708
|
+
return { images, missing: r.missing ?? [] };
|
|
709
|
+
}
|
|
710
|
+
|
|
667
711
|
/** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
|
|
668
712
|
* to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
|
|
669
713
|
* `query`/`queryStream` ONLY for programmatic one-shots (tools).
|