@braincrew-lab/langchain-canvas 0.3.0 → 0.4.9

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
@@ -1,296 +1,9 @@
1
+ import { A as Artifact, a as CanvasEvent, E as ElementSelection, S as StreamEvent, C as CanvasTransport, F as FileData, b as SlidesData, T as TableData, D as DocumentData, c as ChartData, H as HtmlData } from './types-BfGP9R2I.js';
2
+ export { d as ArtifactStatus, e as CanvasAppend, f as CanvasCommit, g as CanvasCreate, h as CanvasNodePatch, i as CanvasPatch, j as CanvasReplace, k as CanvasStatus, l as ChartArtifact, m as ChartOptions, n as ChartSeries, o as ChatEvent, p as DocumentArtifact, q as DoneEvent, r as ErrorEvent, s as FileArtifact, t as HtmlArtifact, K as KnownArtifact, M as MessageDelta, u as MessageEnd, v as Slide, w as SlideElement, x as SlidePage, y as SlidesArtifact, z as TableArtifact, B as TableColumn, G as ToolEnd, I as ToolStart, J as TransportRequest, L as isCanvasEvent, N as isChatEvent } from './types-BfGP9R2I.js';
1
3
  import * as react from 'react';
2
4
  import { ReactNode, ComponentType } from 'react';
3
5
  import { StoreApi } from 'zustand/vanilla';
4
6
 
5
- /**
6
- * Artifact data shapes — mirror of `langchain_canvas/protocol/artifacts.py`.
7
- *
8
- * An `Artifact` is transport-agnostic: `{ id, type, title, version, status,
9
- * data }`. `type` is a registry key resolved to a React component; `data` is the
10
- * type-specific payload that component reads. Keep this file in lockstep with
11
- * the Python module — a field here must exist there, and vice versa.
12
- */
13
- type ArtifactStatus = "streaming" | "complete" | "error";
14
- interface Artifact<TData = unknown> {
15
- /** Stable identity — the reconciliation key. */
16
- id: string;
17
- /** Registry key: "document" | "chart" | ... */
18
- type: string;
19
- /** Shown in the canvas header / tab. */
20
- title: string;
21
- /** 1-based; bumped on every `canvas.replace`. */
22
- version: number;
23
- status: ArtifactStatus;
24
- data: TData;
25
- meta?: Record<string, unknown>;
26
- }
27
- /**
28
- * The base substrate: raw HTML, rendered in a sandboxed iframe. Everything a
29
- * canvas can show is ultimately HTML; `document` / `chart` / `table` are
30
- * structured conveniences the SDK renders for you, while `html` lets an agent
31
- * emit an arbitrary self-contained page (the Claude-Artifacts / Genspark model).
32
- */
33
- interface HtmlData {
34
- html: string;
35
- }
36
- interface DocumentData {
37
- format: "markdown";
38
- content: string;
39
- }
40
- interface ChartSeries {
41
- /** Column in `ChartData.rows` to plot. */
42
- key: string;
43
- label?: string;
44
- color?: string;
45
- }
46
- interface ChartOptions {
47
- stacked?: boolean;
48
- yLabel?: string;
49
- /** Chart title shown above the plot. */
50
- title?: string;
51
- /** Per-slice colors for pie charts, index-aligned to `rows`. */
52
- colors?: string[];
53
- }
54
- interface ChartData {
55
- chart: "line" | "bar" | "area" | "pie" | "scatter" | "donut";
56
- /** Tidy/long-form rows, consumed directly by the charting library. */
57
- rows: Array<Record<string, string | number>>;
58
- /** Category / x-axis field. */
59
- xKey: string;
60
- series: ChartSeries[];
61
- options?: ChartOptions;
62
- /**
63
- * Optional raw ECharts `option`. When present it's rendered verbatim — an
64
- * escape hatch for agents/apps that already produce a full ECharts config
65
- * (the tidy `rows`/`series` model is ignored, and inline editing is disabled).
66
- */
67
- echartsOption?: Record<string, unknown>;
68
- }
69
- interface TableColumn {
70
- key: string;
71
- label?: string;
72
- align?: "left" | "right" | "center";
73
- }
74
- interface TableData {
75
- columns: TableColumn[];
76
- rows: Array<Record<string, string | number>>;
77
- /**
78
- * Opaque spreadsheet state (Fortune-sheet sheets) once the user has edited the
79
- * grid — carries merges, per-cell fonts/formats, and formulas that the simple
80
- * columns/rows shape can't hold. Present after the first interactive edit;
81
- * exporters prefer it over columns/rows.
82
- */
83
- sheet?: Array<Record<string, unknown>>;
84
- }
85
- /**
86
- * A PDF shown in the browser's native viewer. `src` is a `data:application/pdf`
87
- * URL (self-contained, the common case for agent/file-sourced PDFs), a `blob:`
88
- * URL, or an `https:` URL the host is allowed to frame.
89
- */
90
- interface PdfData {
91
- src: string;
92
- /** Optional original filename, used for the download attribute. */
93
- filename?: string;
94
- }
95
- /** A freely-positioned element on a "blank" slide (percent geometry, 0–100). */
96
- interface SlideElement {
97
- id: string;
98
- type: "text" | "image" | "shape";
99
- x: number;
100
- y: number;
101
- w: number;
102
- h: number;
103
- text?: string;
104
- src?: string;
105
- fontSize?: number;
106
- bold?: boolean;
107
- color?: string;
108
- align?: "left" | "center" | "right";
109
- /** Shape kind for `type: "shape"`. */
110
- shape?: "rect" | "ellipse" | "line";
111
- /** Fill (rect/ellipse) or stroke (line) color for a shape. */
112
- fill?: string;
113
- /** Rotation in degrees, clockwise, about the element's center. Purely visual:
114
- * `x`/`y`/`w`/`h` always describe the unrotated box. */
115
- rotate?: number;
116
- /** How an image fills its box — "contain" (default, letterboxed) or "cover"
117
- * (fill and crop). */
118
- fit?: "contain" | "cover";
119
- /** Corner radius in px (0–32) for images and rect shapes. */
120
- radius?: number;
121
- /** Editor-only grouping: elements sharing a `group` id select and move as
122
- * one. Purely additive — exporters and the presenter ignore it. */
123
- group?: string;
124
- }
125
- interface Slide {
126
- /** title · content (bullets) · section · image · two-column · blank (free canvas). */
127
- layout?: "title" | "content" | "section" | "image" | "two-column" | "blank";
128
- /** Freely-positioned elements for the "blank" layout. */
129
- elements?: SlideElement[];
130
- title?: string;
131
- subtitle?: string;
132
- bullets?: string[];
133
- /** Right-hand bullets for the "two-column" layout. */
134
- bullets2?: string[];
135
- /** Image (data: URL or https URL) for the "image" layout. */
136
- image?: string;
137
- /** Slide background color (hex). */
138
- background?: string;
139
- /** Slide text color (hex). */
140
- textColor?: string;
141
- /** Theme accent color (hex) — used by quick layouts and new shapes for rules,
142
- * section numbers, and stats. Set by the theme presets. */
143
- accent?: string;
144
- /** Font stack for the slide's text (system fonts only, no external loads).
145
- * Set by the theme presets; cascades to every element. */
146
- fontFamily?: string;
147
- /** Speaker notes (not shown on the slide; exported to the .pptx notes pane). */
148
- notes?: string;
149
- /** Content padding as a percent of the slide width (a safe margin around the
150
- * free canvas). Applied in the editor, present view, thumbnails, and export. */
151
- padding?: number;
152
- }
153
- interface SlidesData {
154
- slides: Slide[];
155
- }
156
- type HtmlArtifact = Artifact<HtmlData> & {
157
- type: "html";
158
- };
159
- type DocumentArtifact = Artifact<DocumentData> & {
160
- type: "document";
161
- };
162
- type ChartArtifact = Artifact<ChartData> & {
163
- type: "chart";
164
- };
165
- type TableArtifact = Artifact<TableData> & {
166
- type: "table";
167
- };
168
- type SlidesArtifact = Artifact<SlidesData> & {
169
- type: "slides";
170
- };
171
- type PdfArtifact = Artifact<PdfData> & {
172
- type: "pdf";
173
- };
174
- type KnownArtifact = HtmlArtifact | DocumentArtifact | ChartArtifact | TableArtifact | SlidesArtifact | PdfArtifact;
175
-
176
- /**
177
- * Canvas Wire Protocol v1 — event envelopes. Mirror of
178
- * `langchain_canvas/protocol/events.py`. Every SSE frame is one `StreamEvent`,
179
- * discriminated by `type`. See `docs/02-protocol.md` for the specification.
180
- */
181
-
182
- interface MessageDelta {
183
- type: "message.delta";
184
- messageId: string;
185
- text: string;
186
- }
187
- interface MessageEnd {
188
- type: "message.end";
189
- messageId: string;
190
- }
191
- interface ToolStart {
192
- type: "tool.start";
193
- toolCallId: string;
194
- name: string;
195
- }
196
- interface ToolEnd {
197
- type: "tool.end";
198
- toolCallId: string;
199
- ok: boolean;
200
- }
201
- interface CanvasCreate {
202
- type: "canvas.create";
203
- artifact: Artifact;
204
- }
205
- /** Append `text` to the string at `data.<path>` (e.g. a document body). */
206
- interface CanvasAppend {
207
- type: "canvas.append";
208
- id: string;
209
- path: string;
210
- text: string;
211
- }
212
- /** JSON-merge-patch (RFC 7386) `patch` into the artifact's `data`. */
213
- interface CanvasPatch {
214
- type: "canvas.patch";
215
- id: string;
216
- patch: Record<string, unknown>;
217
- }
218
- /**
219
- * Replace a single element (by its `data-cid` tree path) inside an `html`
220
- * artifact with new outer HTML — an O(1) surgical edit that avoids resending the
221
- * whole page. The reconciler resolves the `cid` path against the source HTML.
222
- */
223
- interface CanvasNodePatch {
224
- type: "canvas.node_patch";
225
- id: string;
226
- cid: string;
227
- html: string;
228
- }
229
- /** Replace wholesale — the reconciler snapshots a new version. */
230
- interface CanvasReplace {
231
- type: "canvas.replace";
232
- id: string;
233
- artifact: Artifact;
234
- }
235
- interface CanvasStatus {
236
- type: "canvas.status";
237
- id: string;
238
- status: ArtifactStatus;
239
- }
240
- /**
241
- * Promote the artifact's current state to a described version snapshot.
242
- * `revision` is the opaque store revision when a CanvasStore backs the canvas.
243
- */
244
- interface CanvasCommit {
245
- type: "canvas.commit";
246
- id: string;
247
- description: string;
248
- revision?: string;
249
- }
250
- interface CanvasClose {
251
- type: "canvas.close";
252
- id: string;
253
- }
254
- interface ErrorEvent {
255
- type: "error";
256
- message: string;
257
- }
258
- interface DoneEvent {
259
- type: "done";
260
- }
261
- type ChatEvent = MessageDelta | MessageEnd | ToolStart | ToolEnd;
262
- type CanvasEvent = CanvasCreate | CanvasAppend | CanvasPatch | CanvasNodePatch | CanvasReplace | CanvasStatus | CanvasCommit | CanvasClose;
263
- type StreamEvent = ChatEvent | CanvasEvent | ErrorEvent | DoneEvent;
264
- /** Narrow a `StreamEvent` to the canvas family. */
265
- declare function isCanvasEvent(event: StreamEvent): event is CanvasEvent;
266
- /** Narrow a `StreamEvent` to the chat family. */
267
- declare function isChatEvent(event: StreamEvent): event is ChatEvent;
268
-
269
- /**
270
- * Element selection — a client→server concern (it rides the chat request, not
271
- * the SSE wire). When the user clicks an element inside an `html` artifact, the
272
- * inspector reports which element was chosen; an edit instruction then carries
273
- * this context so the agent can make a targeted change.
274
- */
275
- interface ElementSelection {
276
- /** The `html` artifact the element belongs to. */
277
- artifactId: string;
278
- /** Deterministic path id assigned by the inspector (e.g. "e-0-2"). */
279
- cid: string;
280
- /** Human/agent-readable selector, e.g. "button.cta". */
281
- selector: string;
282
- /** Lowercased tag name. */
283
- tag: string;
284
- /** Short text preview of the element. */
285
- text?: string;
286
- /** The element's current outer HTML (truncated) — edit context for the agent. */
287
- outerHtml?: string;
288
- /** Snapshot of the element's key computed styles (for the style panel). */
289
- styles?: Record<string, string>;
290
- /** True when the element is a group wrapper (offers "Ungroup"). */
291
- isGroup?: boolean;
292
- }
293
-
294
7
  /**
295
8
  * The reconciler — the single place artifact state is mutated.
296
9
  *
@@ -367,8 +80,13 @@ declare const INSPECTOR_MARK = "langchain-canvas";
367
80
  /** Inject the inspector into an HTML string, before `</body>` when present. The
368
81
  * injected nodes are tagged `data-lcx` so a full-document save can strip them.
369
82
  * Also ensures a responsive viewport meta so device-width media queries behave
370
- * the same in the preview, in export, and on a real device. */
371
- declare function withInspector(html: string): string;
83
+ * the same in the preview, in export, and on a real device.
84
+ *
85
+ * With `assetBaseUrl`, the inspector also resolves canvas-asset references
86
+ * (`src="assets/…"` / `src="sources/…"`) for display: the original relative
87
+ * src is kept in `data-lcx-src` and restored on every serialization, so the
88
+ * stored document never sees a resolved URL. */
89
+ declare function withInspector(html: string, assetBaseUrl?: string): string;
372
90
  /** Computed-style properties surfaced to the style panel (camelCase). */
373
91
  declare const STYLE_PROPS: readonly ["color", "backgroundColor", "fontSize", "fontWeight", "textAlign", "lineHeight", "letterSpacing", "padding", "borderRadius", "width"];
374
92
 
@@ -391,6 +109,35 @@ interface MockStreamOptions {
391
109
  /** Yield a fixed list of events over time — a drop-in for `streamChat`. */
392
110
  declare function mockStream(events: StreamEvent[], options?: MockStreamOptions): AsyncGenerator<StreamEvent>;
393
111
 
112
+ /**
113
+ * `sseTransport` — the default socket: the Canvas Wire Protocol over SSE.
114
+ *
115
+ * Speaks to a reference-style server (`POST endpoint` with
116
+ * `{thread_id, message, selections}`, answered by an SSE stream of
117
+ * `StreamEvent` frames). This is exactly what `useCanvasStream` always did;
118
+ * it is now one `CanvasTransport` implementation among several.
119
+ */
120
+
121
+ interface SseTransportOptions {
122
+ /** Chat SSE endpoint. Defaults to `/api/chat`. */
123
+ endpoint?: string;
124
+ /** Extra request headers (e.g. auth). */
125
+ headers?: Record<string, string>;
126
+ }
127
+ declare function sseTransport(options?: SseTransportOptions): CanvasTransport;
128
+
129
+ /**
130
+ * `mockTransport` — scripted offline playback as a socket implementation.
131
+ *
132
+ * Wraps the `mockStream` player in the `CanvasTransport` contract: the script
133
+ * maps a user message to the `StreamEvent[]` to play. Returning `null` falls
134
+ * through to the wrapped transport (a live backend), which is how the demo
135
+ * mixes canned examples with real chat.
136
+ */
137
+
138
+ type MockScript = (message: string) => StreamEvent[] | null;
139
+ declare function mockTransport(script: MockScript, fallback?: CanvasTransport, options?: Pick<MockStreamOptions, "delayMs">): CanvasTransport;
140
+
394
141
  /**
395
142
  * The canvas store — chat transcript + reconciled canvas state in one place.
396
143
  *
@@ -451,6 +198,11 @@ interface CanvasStore {
451
198
  redoStack: CanvasState[];
452
199
  /** Host callback fired after a user edit reconciles — the write-back hook. */
453
200
  onUserEdit: UserEditHandler | null;
201
+ /** URL prefix that resolves a canvas-relative asset path (see `resolveAssetUrl`).
202
+ * Renderers use it to display `assets/` / `sources/` references live; the
203
+ * export menu uses it to inline them. Null = no file endpoint (references
204
+ * stay unresolved, everything else behaves as before). */
205
+ assetBaseUrl: string | null;
454
206
  applyEvent: (event: StreamEvent) => void;
455
207
  /** Apply a batch of events in a single store write (one re-render per frame). */
456
208
  applyEvents: (events: StreamEvent[]) => void;
@@ -465,6 +217,7 @@ interface CanvasStore {
465
217
  sendIframeCommand: (command: Omit<IframeCommand, "seq">) => void;
466
218
  /** Register (or clear) the user-edit write-back handler. */
467
219
  setOnUserEdit: (handler: UserEditHandler | null) => void;
220
+ setAssetBaseUrl: (url: string | null) => void;
468
221
  reset: () => void;
469
222
  }
470
223
  /** Create an isolated canvas store. */
@@ -482,14 +235,21 @@ declare function useCanvasStoreApi(): StoreApi<CanvasStore>;
482
235
  declare function useCanvasStore<T>(selector: (state: CanvasStore) => T): T;
483
236
 
484
237
  interface UseCanvasStreamOptions {
485
- /** Chat SSE endpoint. Defaults to `/api/chat`. */
238
+ /**
239
+ * How to reach the agent backend. Defaults to the reference Canvas Wire
240
+ * Protocol over SSE (`sseTransport`); pass `langgraphTransport(...)` (from
241
+ * the `/langgraph` entry) or your own `CanvasTransport` to speak to a
242
+ * different backend.
243
+ */
244
+ transport?: CanvasTransport;
245
+ /** Chat SSE endpoint for the default transport. Defaults to `/api/chat`. */
486
246
  endpoint?: string;
487
247
  /** Conversation thread id (for server-side memory). Defaults to a fresh uuid. */
488
248
  threadId?: string;
489
249
  /**
490
250
  * Offline mock: given the user's message, return a scripted `StreamEvent[]`
491
251
  * to play instead of hitting the network — an OpenAPI-style "try it" with no
492
- * real LLM call. Return `null` to fall through to the live endpoint.
252
+ * real LLM call. Return `null` to fall through to the live transport.
493
253
  */
494
254
  mock?: (message: string) => StreamEvent[] | null;
495
255
  }
@@ -571,699 +331,6 @@ interface Scenario {
571
331
  }
572
332
  declare const scenarios: Scenario[];
573
333
 
574
- type CanvasLocale = "en" | "ko";
575
- declare const MESSAGES: {
576
- undo: {
577
- en: string;
578
- ko: string;
579
- };
580
- redo: {
581
- en: string;
582
- ko: string;
583
- };
584
- export: {
585
- en: string;
586
- ko: string;
587
- };
588
- openInTab: {
589
- en: string;
590
- ko: string;
591
- };
592
- copyHtml: {
593
- en: string;
594
- ko: string;
595
- };
596
- copied: {
597
- en: string;
598
- ko: string;
599
- };
600
- versionHistory: {
601
- en: string;
602
- ko: string;
603
- };
604
- prevVersion: {
605
- en: string;
606
- ko: string;
607
- };
608
- nextVersion: {
609
- en: string;
610
- ko: string;
611
- };
612
- backToLatest: {
613
- en: string;
614
- ko: string;
615
- };
616
- historyNote: {
617
- en: string;
618
- ko: string;
619
- };
620
- loading: {
621
- en: string;
622
- ko: string;
623
- };
624
- noRenderer: {
625
- en: string;
626
- ko: string;
627
- };
628
- writing: {
629
- en: string;
630
- ko: string;
631
- };
632
- open: {
633
- en: string;
634
- ko: string;
635
- };
636
- kindWeb: {
637
- en: string;
638
- ko: string;
639
- };
640
- kindDocument: {
641
- en: string;
642
- ko: string;
643
- };
644
- kindChart: {
645
- en: string;
646
- ko: string;
647
- };
648
- kindTable: {
649
- en: string;
650
- ko: string;
651
- };
652
- kindSlides: {
653
- en: string;
654
- ko: string;
655
- };
656
- kindPdf: {
657
- en: string;
658
- ko: string;
659
- };
660
- design: {
661
- en: string;
662
- ko: string;
663
- };
664
- code: {
665
- en: string;
666
- ko: string;
667
- };
668
- add: {
669
- en: string;
670
- ko: string;
671
- };
672
- heading: {
673
- en: string;
674
- ko: string;
675
- };
676
- text: {
677
- en: string;
678
- ko: string;
679
- };
680
- button: {
681
- en: string;
682
- ko: string;
683
- };
684
- image: {
685
- en: string;
686
- ko: string;
687
- };
688
- divider: {
689
- en: string;
690
- ko: string;
691
- };
692
- pageMenu: {
693
- en: string;
694
- ko: string;
695
- };
696
- sectionMenu: {
697
- en: string;
698
- ko: string;
699
- };
700
- outlineMenu: {
701
- en: string;
702
- ko: string;
703
- };
704
- layoutMenu: {
705
- en: string;
706
- ko: string;
707
- };
708
- themeMenu: {
709
- en: string;
710
- ko: string;
711
- };
712
- fontMenu: {
713
- en: string;
714
- ko: string;
715
- };
716
- shapeMenu: {
717
- en: string;
718
- ko: string;
719
- };
720
- a11yCheck: {
721
- en: string;
722
- ko: string;
723
- };
724
- a11yTitle: {
725
- en: string;
726
- ko: string;
727
- };
728
- a11yClean: {
729
- en: string;
730
- ko: string;
731
- };
732
- bgImage: {
733
- en: string;
734
- ko: string;
735
- };
736
- present: {
737
- en: string;
738
- ko: string;
739
- };
740
- bold: {
741
- en: string;
742
- ko: string;
743
- };
744
- italic: {
745
- en: string;
746
- ko: string;
747
- };
748
- inlineCode: {
749
- en: string;
750
- ko: string;
751
- };
752
- bulletList: {
753
- en: string;
754
- ko: string;
755
- };
756
- numberedList: {
757
- en: string;
758
- ko: string;
759
- };
760
- quote: {
761
- en: string;
762
- ko: string;
763
- };
764
- link: {
765
- en: string;
766
- ko: string;
767
- };
768
- words: {
769
- en: string;
770
- ko: string;
771
- };
772
- minRead: {
773
- en: string;
774
- ko: string;
775
- };
776
- addColumn: {
777
- en: string;
778
- ko: string;
779
- };
780
- addRow: {
781
- en: string;
782
- ko: string;
783
- };
784
- sortBy: {
785
- en: string;
786
- ko: string;
787
- };
788
- filterRows: {
789
- en: string;
790
- ko: string;
791
- };
792
- cleanStyling: {
793
- en: string;
794
- ko: string;
795
- };
796
- freezeHeader: {
797
- en: string;
798
- ko: string;
799
- };
800
- fillColor: {
801
- en: string;
802
- ko: string;
803
- };
804
- textColor: {
805
- en: string;
806
- ko: string;
807
- };
808
- alignLeft: {
809
- en: string;
810
- ko: string;
811
- };
812
- alignCenter: {
813
- en: string;
814
- ko: string;
815
- };
816
- alignRight: {
817
- en: string;
818
- ko: string;
819
- };
820
- numberFormat: {
821
- en: string;
822
- ko: string;
823
- };
824
- mergeCells: {
825
- en: string;
826
- ko: string;
827
- };
828
- unmergeCells: {
829
- en: string;
830
- ko: string;
831
- };
832
- sheetHint: {
833
- en: string;
834
- ko: string;
835
- };
836
- quickFunction: {
837
- en: string;
838
- ko: string;
839
- };
840
- quickFunctionTip: {
841
- en: string;
842
- ko: string;
843
- };
844
- mergeTip: {
845
- en: string;
846
- ko: string;
847
- };
848
- unmergeTip: {
849
- en: string;
850
- ko: string;
851
- };
852
- cleanStylingTip: {
853
- en: string;
854
- ko: string;
855
- };
856
- freezeOnTip: {
857
- en: string;
858
- ko: string;
859
- };
860
- freezeOffTip: {
861
- en: string;
862
- ko: string;
863
- };
864
- numberFormatTip: {
865
- en: string;
866
- ko: string;
867
- };
868
- sortByColumn: {
869
- en: string;
870
- ko: string;
871
- };
872
- ascending: {
873
- en: string;
874
- ko: string;
875
- };
876
- descending: {
877
- en: string;
878
- ko: string;
879
- };
880
- filterTip: {
881
- en: string;
882
- ko: string;
883
- };
884
- fxPlaceholder: {
885
- en: string;
886
- ko: string;
887
- };
888
- groupInsert: {
889
- en: string;
890
- ko: string;
891
- };
892
- groupFont: {
893
- en: string;
894
- ko: string;
895
- };
896
- groupAlign: {
897
- en: string;
898
- ko: string;
899
- };
900
- groupNumber: {
901
- en: string;
902
- ko: string;
903
- };
904
- groupEdit: {
905
- en: string;
906
- ko: string;
907
- };
908
- groupView: {
909
- en: string;
910
- ko: string;
911
- };
912
- boldGlyph: {
913
- en: string;
914
- ko: string;
915
- };
916
- textGlyph: {
917
- en: string;
918
- ko: string;
919
- };
920
- autoSum: {
921
- en: string;
922
- ko: string;
923
- };
924
- fmtGeneral: {
925
- en: string;
926
- ko: string;
927
- };
928
- fmtCurrency: {
929
- en: string;
930
- ko: string;
931
- };
932
- fmtPercent: {
933
- en: string;
934
- ko: string;
935
- };
936
- fmtThousands: {
937
- en: string;
938
- ko: string;
939
- };
940
- fmtDecimal: {
941
- en: string;
942
- ko: string;
943
- };
944
- fmtDate: {
945
- en: string;
946
- ko: string;
947
- };
948
- chartTitle: {
949
- en: string;
950
- ko: string;
951
- };
952
- editData: {
953
- en: string;
954
- ko: string;
955
- };
956
- doneEditing: {
957
- en: string;
958
- ko: string;
959
- };
960
- addRowBtn: {
961
- en: string;
962
- ko: string;
963
- };
964
- downloadPng: {
965
- en: string;
966
- ko: string;
967
- };
968
- stacked: {
969
- en: string;
970
- ko: string;
971
- };
972
- seriesColor: {
973
- en: string;
974
- ko: string;
975
- };
976
- seriesName: {
977
- en: string;
978
- ko: string;
979
- };
980
- removeRow: {
981
- en: string;
982
- ko: string;
983
- };
984
- addText: {
985
- en: string;
986
- ko: string;
987
- };
988
- addImage: {
989
- en: string;
990
- ko: string;
991
- };
992
- addShape: {
993
- en: string;
994
- ko: string;
995
- };
996
- arrangeMenu: {
997
- en: string;
998
- ko: string;
999
- };
1000
- padding: {
1001
- en: string;
1002
- ko: string;
1003
- };
1004
- duplicate: {
1005
- en: string;
1006
- ko: string;
1007
- };
1008
- delete: {
1009
- en: string;
1010
- ko: string;
1011
- };
1012
- group: {
1013
- en: string;
1014
- ko: string;
1015
- };
1016
- ungroup: {
1017
- en: string;
1018
- ko: string;
1019
- };
1020
- bringToFront: {
1021
- en: string;
1022
- ko: string;
1023
- };
1024
- sendToBack: {
1025
- en: string;
1026
- ko: string;
1027
- };
1028
- fontSize: {
1029
- en: string;
1030
- ko: string;
1031
- };
1032
- resizeTip: {
1033
- en: string;
1034
- ko: string;
1035
- };
1036
- fitToggle: {
1037
- en: string;
1038
- ko: string;
1039
- };
1040
- cornerRadius: {
1041
- en: string;
1042
- ko: string;
1043
- };
1044
- rotateStep: {
1045
- en: string;
1046
- ko: string;
1047
- };
1048
- rotationDeg: {
1049
- en: string;
1050
- ko: string;
1051
- };
1052
- duplicateShort: {
1053
- en: string;
1054
- ko: string;
1055
- };
1056
- bringForward: {
1057
- en: string;
1058
- ko: string;
1059
- };
1060
- sendBackward: {
1061
- en: string;
1062
- ko: string;
1063
- };
1064
- groupShort: {
1065
- en: string;
1066
- ko: string;
1067
- };
1068
- ungroupShort: {
1069
- en: string;
1070
- ko: string;
1071
- };
1072
- alignLeftEdges: {
1073
- en: string;
1074
- ko: string;
1075
- };
1076
- alignHCenters: {
1077
- en: string;
1078
- ko: string;
1079
- };
1080
- alignRightEdges: {
1081
- en: string;
1082
- ko: string;
1083
- };
1084
- alignTopEdges: {
1085
- en: string;
1086
- ko: string;
1087
- };
1088
- alignVCenters: {
1089
- en: string;
1090
- ko: string;
1091
- };
1092
- alignBottomEdges: {
1093
- en: string;
1094
- ko: string;
1095
- };
1096
- deleteSelection: {
1097
- en: string;
1098
- ko: string;
1099
- };
1100
- presentHint: {
1101
- en: string;
1102
- ko: string;
1103
- };
1104
- speakerNotes: {
1105
- en: string;
1106
- ko: string;
1107
- };
1108
- download: {
1109
- en: string;
1110
- ko: string;
1111
- };
1112
- openBtn: {
1113
- en: string;
1114
- ko: string;
1115
- };
1116
- fitWidth: {
1117
- en: string;
1118
- ko: string;
1119
- };
1120
- zoomIn: {
1121
- en: string;
1122
- ko: string;
1123
- };
1124
- zoomOut: {
1125
- en: string;
1126
- ko: string;
1127
- };
1128
- waitingPdf: {
1129
- en: string;
1130
- ko: string;
1131
- };
1132
- addTextBox: {
1133
- en: string;
1134
- ko: string;
1135
- };
1136
- addImageTip: {
1137
- en: string;
1138
- ko: string;
1139
- };
1140
- addShapeTip: {
1141
- en: string;
1142
- ko: string;
1143
- };
1144
- applyLayout: {
1145
- en: string;
1146
- ko: string;
1147
- };
1148
- autoLayoutTip: {
1149
- en: string;
1150
- ko: string;
1151
- };
1152
- bgColor: {
1153
- en: string;
1154
- ko: string;
1155
- };
1156
- bgImageTip: {
1157
- en: string;
1158
- ko: string;
1159
- };
1160
- padTip: {
1161
- en: string;
1162
- ko: string;
1163
- };
1164
- presentTip: {
1165
- en: string;
1166
- ko: string;
1167
- };
1168
- duplicateSlide: {
1169
- en: string;
1170
- ko: string;
1171
- };
1172
- deleteSlide: {
1173
- en: string;
1174
- ko: string;
1175
- };
1176
- theme: {
1177
- en: string;
1178
- ko: string;
1179
- };
1180
- desktop: {
1181
- en: string;
1182
- ko: string;
1183
- };
1184
- tablet: {
1185
- en: string;
1186
- ko: string;
1187
- };
1188
- mobile: {
1189
- en: string;
1190
- ko: string;
1191
- };
1192
- a11yIssues: {
1193
- en: string;
1194
- ko: string;
1195
- };
1196
- a11yNone: {
1197
- en: string;
1198
- ko: string;
1199
- };
1200
- pageTemplateTitle: {
1201
- en: string;
1202
- ko: string;
1203
- };
1204
- sectionTemplateTitle: {
1205
- en: string;
1206
- ko: string;
1207
- };
1208
- jumpToHeading: {
1209
- en: string;
1210
- ko: string;
1211
- };
1212
- insertSlideLayout: {
1213
- en: string;
1214
- ko: string;
1215
- };
1216
- applySlideTheme: {
1217
- en: string;
1218
- ko: string;
1219
- };
1220
- insertShape: {
1221
- en: string;
1222
- ko: string;
1223
- };
1224
- slideFont: {
1225
- en: string;
1226
- ko: string;
1227
- };
1228
- slideBgImage: {
1229
- en: string;
1230
- ko: string;
1231
- };
1232
- moveUp: {
1233
- en: string;
1234
- ko: string;
1235
- };
1236
- moveDown: {
1237
- en: string;
1238
- ko: string;
1239
- };
1240
- waitingData: {
1241
- en: string;
1242
- ko: string;
1243
- };
1244
- calculating: {
1245
- en: string;
1246
- ko: string;
1247
- };
1248
- loadingSheet: {
1249
- en: string;
1250
- ko: string;
1251
- };
1252
- dropToOpen: {
1253
- en: string;
1254
- ko: string;
1255
- };
1256
- };
1257
- type MessageKey = keyof typeof MESSAGES;
1258
- interface CanvasLocaleProviderProps {
1259
- locale?: CanvasLocale;
1260
- children: ReactNode;
1261
- }
1262
- declare function CanvasLocaleProvider({ locale, children }: CanvasLocaleProviderProps): react.JSX.Element;
1263
- declare function useLocale(): CanvasLocale;
1264
- /** `const t = useT(); t("sortBy")` → the label in the canvas's locale. */
1265
- declare function useT(): (key: MessageKey) => string;
1266
-
1267
334
  interface RendererProps<TData = unknown> {
1268
335
  artifact: Artifact<TData>;
1269
336
  }
@@ -1279,11 +346,31 @@ declare function useRenderer(type: string): ArtifactRenderer | undefined;
1279
346
  /** Merge registries — later entries win. Handy for extending the built-ins. */
1280
347
  declare function mergeRegistries(...registries: ArtifactRegistry[]): ArtifactRegistry;
1281
348
 
349
+ /**
350
+ * `useCanvasImport` — open local files onto the canvas.
351
+ *
352
+ * Turns a `File` (from a file picker or a drag-and-drop) into canvas events and
353
+ * applies them through the store, so the imported document/sheet/page becomes a
354
+ * first-class artifact you can edit and re-export. Returns the id of the last
355
+ * artifact created so callers can focus it.
356
+ */
357
+
358
+ interface CanvasImportOptions {
359
+ /**
360
+ * Fired once per successfully imported file with the artifact that now
361
+ * renders on the canvas — the hook for a host to persist an imported
362
+ * table/document to its store right away.
363
+ */
364
+ onImported?: (artifact: Artifact, file: File) => void;
365
+ }
366
+ declare function useCanvasImport({ onImported }?: CanvasImportOptions): {
367
+ importFiles: (files: Iterable<File>) => Promise<string | null>;
368
+ canImport: (file: File) => boolean;
369
+ };
370
+
1282
371
  interface CanvasProps {
1283
372
  /** Renderer map. Defaults to the built-in html/document/chart/table renderers. */
1284
373
  registry?: ArtifactRegistry;
1285
- /** UI language for the canvas chrome (toolbars, menus, states). Default "en". */
1286
- locale?: CanvasLocale;
1287
374
  /** Rendered when no artifact has been opened yet. */
1288
375
  emptyState?: ReactNode;
1289
376
  /**
@@ -1307,8 +394,26 @@ interface CanvasProps {
1307
394
  * stay in-memory exactly as before.
1308
395
  */
1309
396
  onSave?: CanvasSaveHandler;
397
+ /**
398
+ * Fired with the raw files whenever the user opens files (picker or drop),
399
+ * before any import parsing — the hook for a host to upload originals to
400
+ * its store so the agent can read them. When provided, the file picker
401
+ * accepts every file type (the canvas still previews only what it can
402
+ * import; the host decides what to do with the rest).
403
+ */
404
+ onFilesOpened?: (files: File[]) => void;
405
+ /** Fired per successfully imported file with its canvas artifact (see `useCanvasImport`). */
406
+ onImported?: CanvasImportOptions["onImported"];
407
+ /**
408
+ * URL prefix that resolves a canvas-relative asset path (`assets/…`,
409
+ * `sources/…`) to fetchable bytes — the whole encoded path is appended, e.g.
410
+ * `http://host/api/canvas/<id>/file?path=`. With it, asset references in
411
+ * artifacts display live and export inlined as `data:` URIs. Omit it and
412
+ * references stay unresolved — everything else behaves exactly as before.
413
+ */
414
+ assetBaseUrl?: string;
1310
415
  }
1311
- declare function Canvas({ registry, locale, emptyState, onEditElement, onUserEdit, onSave }: CanvasProps): react.JSX.Element;
416
+ declare function Canvas({ registry, emptyState, onEditElement, onUserEdit, onSave, onFilesOpened, onImported, assetBaseUrl, }: CanvasProps): react.JSX.Element;
1312
417
 
1313
418
  interface ExportMenuProps {
1314
419
  artifact: Artifact;
@@ -1339,7 +444,7 @@ declare function ArtifactCard({ artifactId }: {
1339
444
  artifactId: string;
1340
445
  }): react.JSX.Element | null;
1341
446
 
1342
- declare function PdfRenderer$1({ artifact }: RendererProps<PdfData>): react.JSX.Element;
447
+ declare function FileRenderer$1({ artifact }: RendererProps<FileData>): react.JSX.Element;
1343
448
 
1344
449
  declare function SlidesRenderer$1({ artifact }: RendererProps<SlidesData>): react.JSX.Element;
1345
450
 
@@ -1355,7 +460,7 @@ declare const ChartRenderer: react.LazyExoticComponent<typeof ChartRenderer$1>;
1355
460
  declare const DocumentRenderer: react.LazyExoticComponent<typeof DocumentRenderer$1>;
1356
461
  declare const TableRenderer: react.LazyExoticComponent<typeof TableRenderer$1>;
1357
462
  declare const SlidesRenderer: react.LazyExoticComponent<typeof SlidesRenderer$1>;
1358
- declare const PdfRenderer: react.LazyExoticComponent<typeof PdfRenderer$1>;
463
+ declare const FileRenderer: react.LazyExoticComponent<typeof FileRenderer$1>;
1359
464
 
1360
465
  /**
1361
466
  * The batteries-included renderers. `html` is the base substrate (sandboxed
@@ -1443,7 +548,7 @@ declare function printToPdf(html: string): void;
1443
548
  */
1444
549
 
1445
550
  /** Extensions we can turn into an artifact, for `accept="…"` and drop filtering. */
1446
- declare const IMPORTABLE_EXTENSIONS: readonly [".csv", ".md", ".markdown", ".txt", ".html", ".htm", ".json", ".xlsx", ".pdf", ".hwpx", ".hwp", ".docx", ".pptx"];
551
+ declare const IMPORTABLE_EXTENSIONS: readonly [".csv", ".md", ".markdown", ".txt", ".html", ".htm", ".json", ".xlsx"];
1447
552
  /** True when the file has an extension we know how to import. */
1448
553
  declare const canImport: (file: File) => boolean;
1449
554
  /**
@@ -1456,16 +561,75 @@ declare function importFile(file: File): Promise<StreamEvent[]>;
1456
561
  declare function parseCsv(text: string): TableData;
1457
562
 
1458
563
  /**
1459
- * `useCanvasImport`open local files onto the canvas.
564
+ * Canvas asset references relative paths that point at files on the canvas.
1460
565
  *
1461
- * Turns a `File` (from a file picker or a drag-and-drop) into canvas events and
1462
- * applies them through the store, so the imported document/sheet/page becomes a
1463
- * first-class artifact you can edit and re-export. Returns the id of the last
1464
- * artifact created so callers can focus it.
566
+ * The reference contract: inside canvas content, a relative path starting with
567
+ * `assets/` (files brought in by the agent) or `sources/` (the user's uploads)
568
+ * points at a file on the *same* canvas `<img src="assets/logo.png">` in an
569
+ * html page, `![logo](assets/logo.png)` in a document, `src: "assets/logo.png"`
570
+ * on a slide image element.
571
+ *
572
+ * Display resolves a reference against the host's file endpoint
573
+ * (`resolveAssetUrl`), keeping the stored content relative. Export restores
574
+ * self-containment at the door (`inlineArtifactAssets` / `inlineHtmlAssets`):
575
+ * every reference becomes a `data:` URI so the exported file carries its
576
+ * images. The unit of self-containment is the canvas folder while
577
+ * collaborating, and the single file once exported.
578
+ *
579
+ * The Python twin lives in `langchain_canvas/assets.py`; the prefix list below
580
+ * is compared against it by the protocol parity tests.
1465
581
  */
1466
- declare function useCanvasImport(): {
1467
- importFiles: (files: Iterable<File>) => Promise<string | null>;
1468
- canImport: (file: File) => boolean;
1469
- };
1470
582
 
1471
- export { type Artifact, ArtifactCard, type ArtifactRegistry, type ArtifactRenderer, type ArtifactStatus, Canvas, type CanvasAppend, type CanvasClose, type CanvasCommit, type CanvasCreate, type CanvasEvent, type CanvasLocale, CanvasLocaleProvider, type CanvasNodePatch, type CanvasPatch, type CanvasProps, CanvasProvider, type CanvasProviderProps, CanvasRegistryProvider, type CanvasReplace, type CanvasSaveHandler, type CanvasSavePayload, type CanvasState, type CanvasStatus, type CanvasStore, type ChartArtifact, type ChartData, type ChartOptions, ChartRenderer, type ChartSeries, type ChatEvent, type ChatMessage, type ChatRequest, type DocumentArtifact, type DocumentData, DocumentRenderer, type DoneEvent, type ElementSelection, type ErrorEvent, ExportMenu, type FileExport, type HtmlArtifact, type HtmlData, HtmlRenderer, IMPORTABLE_EXTENSIONS, INSPECTOR_MARK, type IframeCommand, type KnownArtifact, type MessageDelta, type MessageEnd, type MessageKey, type MockStreamOptions, type PdfArtifact, type PdfData, PdfRenderer, type RendererProps, STYLE_PROPS, type Scenario, SelectionBar, type Slide, type SlideElement, type SlidesArtifact, type SlidesData, SlidesRenderer, type StreamEvent, type StreamOptions, StylePanel, type TableArtifact, type TableColumn, type TableData, TableRenderer, type ToolEnd, type ToolStart, type UseCanvasStreamOptions, type UserEditHandler, builtinRenderers, canImport, createCanvasStore, dataExporters, downloadBlob, emptyCanvasState, importFile, isCanvasEvent, isChatEvent, mergePatch, mergeRegistries, mockStream, parseCsv, parseSSE, printToPdf, reduceCanvas, scenarios, slidesToPrintHtml, slugify, streamChat, toStandaloneHtml, useArtifactPatch, useCanvasImport, useCanvasReplay, useCanvasSave, useCanvasStore, useCanvasStoreApi, useCanvasStream, useLocale, useRenderer, useT, withInspector };
583
+ declare const ASSET_REFERENCE_PREFIXES: readonly ["assets/", "sources/"];
584
+ /**
585
+ * The canvas-root-relative path `src` refers to, or `null`.
586
+ *
587
+ * References are root-relative by contract, but a model writing a page that
588
+ * lives in a folder often produces the document-relative form
589
+ * (`../sources/photo.png`). Store paths can never contain `..` (the store
590
+ * contract rejects them), and `assets/` / `sources/` exist only at the root —
591
+ * so folding leading `./` / `../` segments onto the root reading is lossless
592
+ * tolerance, not guesswork. Stored content is never rewritten; only consumers
593
+ * (display, export inlining) interpret leniently.
594
+ */
595
+ declare function normalizeAssetReference(src: string | undefined | null): string | null;
596
+ declare function isAssetReference(src: string | undefined | null): src is string;
597
+ /**
598
+ * Absolute URL for a canvas-relative asset path. `assetBaseUrl` is a prefix the
599
+ * whole (URI-encoded) path is appended to — e.g. the reference server's
600
+ * `http://host/api/canvas/<id>/file?path=`.
601
+ */
602
+ declare function resolveAssetUrl(src: string, assetBaseUrl: string): string;
603
+ /** Fetch one canvas asset and encode it as a `data:` URI (null on any failure). */
604
+ declare function fetchAssetDataUri(path: string, assetBaseUrl: string): Promise<string | null>;
605
+ /**
606
+ * Replace canvas-asset references in an HTML string with `data:` URIs.
607
+ *
608
+ * Handles both the stored form (`src="assets/logo.png"`) and the display form a
609
+ * rendered DOM serializes (`src="<assetBaseUrl><encoded path>"`). A reference
610
+ * that cannot be fetched is left untouched — honest: the export shows exactly
611
+ * what could be resolved. Only `src` attributes are rewritten; CSS `url(...)`
612
+ * references are out of contract.
613
+ */
614
+ declare function inlineHtmlAssets(html: string, assetBaseUrl: string): Promise<string>;
615
+ /**
616
+ * An artifact with every canvas-asset reference inlined as a `data:` URI —
617
+ * the export chokepoint. `html` inlines its page source; `slides` inlines
618
+ * image elements and the image-layout `image`; other types (and a missing
619
+ * `assetBaseUrl`) pass through unchanged, so hosts without a file endpoint
620
+ * keep today's behavior exactly.
621
+ */
622
+ declare function inlineArtifactAssets<T extends Artifact>(artifact: T, assetBaseUrl: string | null | undefined): Promise<T>;
623
+
624
+ /**
625
+ * Display-time resolver for canvas-asset references.
626
+ *
627
+ * Returns a function that maps a `src` to a displayable URL: a canvas-relative
628
+ * reference (`assets/…`, `sources/…`) resolves against the host's asset
629
+ * endpoint; anything else — and every reference when no endpoint is configured
630
+ * — passes through untouched. Resolution is display-only: stored artifact data
631
+ * always keeps the relative reference.
632
+ */
633
+ declare function useAssetUrl(): (src: string | undefined) => string | undefined;
634
+
635
+ export { ASSET_REFERENCE_PREFIXES, Artifact, ArtifactCard, type ArtifactRegistry, type ArtifactRenderer, Canvas, CanvasEvent, type CanvasProps, CanvasProvider, type CanvasProviderProps, CanvasRegistryProvider, type CanvasSaveHandler, type CanvasSavePayload, type CanvasState, type CanvasStore, CanvasTransport, ChartData, ChartRenderer, type ChatMessage, type ChatRequest, DocumentData, DocumentRenderer, ElementSelection, ExportMenu, FileData, type FileExport, FileRenderer, HtmlData, HtmlRenderer, IMPORTABLE_EXTENSIONS, INSPECTOR_MARK, type IframeCommand, type MockScript, type MockStreamOptions, type RendererProps, STYLE_PROPS, type Scenario, SelectionBar, SlidesData, SlidesRenderer, type SseTransportOptions, StreamEvent, type StreamOptions, StylePanel, TableData, TableRenderer, type UseCanvasStreamOptions, type UserEditHandler, builtinRenderers, canImport, createCanvasStore, dataExporters, downloadBlob, emptyCanvasState, fetchAssetDataUri, importFile, inlineArtifactAssets, inlineHtmlAssets, isAssetReference, mergePatch, mergeRegistries, mockStream, mockTransport, normalizeAssetReference, parseCsv, parseSSE, printToPdf, reduceCanvas, resolveAssetUrl, scenarios, slidesToPrintHtml, slugify, sseTransport, streamChat, toStandaloneHtml, useArtifactPatch, useAssetUrl, useCanvasImport, useCanvasReplay, useCanvasSave, useCanvasStore, useCanvasStoreApi, useCanvasStream, useRenderer, withInspector };