@babav/knowledge-core-client 0.30.0 → 0.32.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 CHANGED
@@ -95,7 +95,13 @@ export interface QueryRequest {
95
95
  * registers). */
96
96
  export type VisualLayout = "linear-flow" | "ring-cycle" | "nesting" | "radial-hub" | "side-by-side" | "stacked-layers" | "two-state" | "free";
97
97
  /** A visual attached to a response, anchored by char offsets into `answer` (SAME coordinate
98
- * system as citations). For delivery="svg", `rendered_svg` is set; scenic sets `image`. */
98
+ * system as citations).
99
+ *
100
+ * 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)` (or GET /v1/visuals/{id}/image with your API key). `image` carries only
103
+ * the pixel DIMENSIONS, for layout. The image is authenticated + tenant-scoped exactly like every
104
+ * other KC call; there is no URL, no signed GCS link, and nothing to expire. */
99
105
  export interface Visual {
100
106
  id: string;
101
107
  anchor: {
@@ -107,10 +113,8 @@ export interface Visual {
107
113
  payload: Record<string, unknown>;
108
114
  /** Declared spatial arrangement (meaningful for `conceptual`; "free" otherwise). */
109
115
  layout: VisualLayout;
110
- rendered_svg?: string;
116
+ /** Pixel dimensions of the PNG (for layout). Fetch the bytes with getVisualImage(id). */
111
117
  image?: {
112
- url: string;
113
- expires_at: number;
114
118
  width: number;
115
119
  height: number;
116
120
  };
@@ -531,6 +535,11 @@ export declare class KnowledgeCoreClient extends HttpBase {
531
535
  * error). Pass `signal` and abort() on unmount / when the user cancels or navigates away so the
532
536
  * connection doesn't linger. Transient (ends on `done`) — no reopen logic needed. */
533
537
  queryStream(agentId: UUID, body: QueryRequest, handlers: StreamHandlers, signal?: AbortSignal): Promise<void>;
538
+ /** Fetch a visual's PNG bytes BY ID. This is the ONLY way to get a visual image — the API never
539
+ * returns a URL. Authenticated + tenant-scoped like every call. Use `visual.id` from a query
540
+ * response / streamed `visual` event / persisted message. Returns a Blob (browser: `URL.
541
+ * createObjectURL(blob)` for an <img>; Node: `Buffer.from(await blob.arrayBuffer())`). */
542
+ getVisualImage(visualId: UUID | string, signal?: AbortSignal): Promise<Blob>;
534
543
  /** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
535
544
  * to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
536
545
  * `query`/`queryStream` ONLY for programmatic one-shots (tools).
package/dist/index.js CHANGED
@@ -178,6 +178,18 @@ export class KnowledgeCoreClient extends HttpBase {
178
178
  if (buf.trim())
179
179
  dispatchSse(buf, handlers);
180
180
  }
181
+ /** Fetch a visual's PNG bytes BY ID. This is the ONLY way to get a visual image — the API never
182
+ * returns a URL. Authenticated + tenant-scoped like every call. Use `visual.id` from a query
183
+ * response / streamed `visual` event / persisted message. Returns a Blob (browser: `URL.
184
+ * createObjectURL(blob)` for an <img>; Node: `Buffer.from(await blob.arrayBuffer())`). */
185
+ async getVisualImage(visualId, signal) {
186
+ const res = await this.raw("GET", `/v1/visuals/${visualId}/image`, { signal });
187
+ if (!res.ok) {
188
+ const t = await res.text();
189
+ throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/visuals/${visualId}/image`);
190
+ }
191
+ return await res.blob();
192
+ }
181
193
  /** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
182
194
  * to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
183
195
  * `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.30.0",
3
+ "version": "0.32.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
@@ -129,17 +129,23 @@ export type VisualLayout =
129
129
  | "free";
130
130
 
131
131
  /** A visual attached to a response, anchored by char offsets into `answer` (SAME coordinate
132
- * system as citations). For delivery="svg", `rendered_svg` is set; scenic sets `image`. */
132
+ * system as citations).
133
+ *
134
+ * 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)` (or GET /v1/visuals/{id}/image with your API key). `image` carries only
137
+ * the pixel DIMENSIONS, for layout. The image is authenticated + tenant-scoped exactly like every
138
+ * other KC call; there is no URL, no signed GCS link, and nothing to expire. */
133
139
  export interface Visual {
134
140
  id: string;
135
141
  anchor: { start: number; end: number };
136
142
  register: "chart" | "structural" | "conceptual" | "scenic";
137
143
  priority: number;
138
- payload: Record<string, unknown>; // {kind: "grammar"|"vega_lite"|"svg"|"image", ...}
144
+ payload: Record<string, unknown>; // {kind: "grammar"|"vega_lite"|"image", ...}
139
145
  /** Declared spatial arrangement (meaningful for `conceptual`; "free" otherwise). */
140
146
  layout: VisualLayout;
141
- rendered_svg?: string;
142
- image?: { url: string; expires_at: number; width: number; height: number };
147
+ /** Pixel dimensions of the PNG (for layout). Fetch the bytes with getVisualImage(id). */
148
+ image?: { width: number; height: number };
143
149
  }
144
150
 
145
151
  /** Visual stage (streaming): generation has started. MAY be emitted twice — first with
@@ -645,6 +651,19 @@ export class KnowledgeCoreClient extends HttpBase {
645
651
  if (buf.trim()) dispatchSse(buf, handlers);
646
652
  }
647
653
 
654
+ /** Fetch a visual's PNG bytes BY ID. This is the ONLY way to get a visual image — the API never
655
+ * returns a URL. Authenticated + tenant-scoped like every call. Use `visual.id` from a query
656
+ * response / streamed `visual` event / persisted message. Returns a Blob (browser: `URL.
657
+ * createObjectURL(blob)` for an <img>; Node: `Buffer.from(await blob.arrayBuffer())`). */
658
+ async getVisualImage(visualId: UUID | string, signal?: AbortSignal): Promise<Blob> {
659
+ const res = await this.raw("GET", `/v1/visuals/${visualId}/image`, { signal });
660
+ if (!res.ok) {
661
+ const t = await res.text();
662
+ throw new KnowledgeCoreError(res.status, safeJson(t), `/v1/visuals/${visualId}/image`);
663
+ }
664
+ return await res.blob();
665
+ }
666
+
648
667
  /** DUMMY-PROOF CHAT. Every message goes through a conversation — it is structurally impossible
649
668
  * to send a chat turn as a non-persisted one-shot. Use this for ANY chat UI. Use the low-level
650
669
  * `query`/`queryStream` ONLY for programmatic one-shots (tools).