@xom11/whiteboard 0.24.2 → 0.25.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.
Files changed (84) hide show
  1. package/README.md +84 -11
  2. package/dist/ai.d.mts +422 -566
  3. package/dist/ai.d.ts +422 -566
  4. package/dist/ai.js +1527 -407
  5. package/dist/ai.js.map +1 -1
  6. package/dist/ai.mjs +1008 -512
  7. package/dist/ai.mjs.map +1 -1
  8. package/dist/catalog.json +4 -4
  9. package/dist/{chunk-BKSXPNPQ.mjs → chunk-AYSFWUPK.mjs} +4 -3
  10. package/dist/chunk-AYSFWUPK.mjs.map +1 -0
  11. package/dist/chunk-B4NJJZFR.mjs +18 -0
  12. package/dist/chunk-B4NJJZFR.mjs.map +1 -0
  13. package/dist/{chunk-LVNCYP4J.mjs → chunk-CJBLJUWG.mjs} +5 -5
  14. package/dist/{chunk-LVNCYP4J.mjs.map → chunk-CJBLJUWG.mjs.map} +1 -1
  15. package/dist/{chunk-7WQXXEVR.mjs → chunk-ESVPQWHX.mjs} +5 -5
  16. package/dist/{chunk-7WQXXEVR.mjs.map → chunk-ESVPQWHX.mjs.map} +1 -1
  17. package/dist/{chunk-KRC2XOIG.mjs → chunk-I24QOHPU.mjs} +3 -3
  18. package/dist/{chunk-KRC2XOIG.mjs.map → chunk-I24QOHPU.mjs.map} +1 -1
  19. package/dist/{chunk-ZBJBQKJ2.mjs → chunk-IHUFOV7L.mjs} +4 -19
  20. package/dist/chunk-IHUFOV7L.mjs.map +1 -0
  21. package/dist/{chunk-AZIARTGX.mjs → chunk-M42TGYT6.mjs} +3 -3
  22. package/dist/{chunk-AZIARTGX.mjs.map → chunk-M42TGYT6.mjs.map} +1 -1
  23. package/dist/{chunk-45CGKJ7S.mjs → chunk-NDEZJKNY.mjs} +4 -4
  24. package/dist/{chunk-45CGKJ7S.mjs.map → chunk-NDEZJKNY.mjs.map} +1 -1
  25. package/dist/{chunk-BEZSQKPY.mjs → chunk-ONBCUWVI.mjs} +5 -4
  26. package/dist/chunk-ONBCUWVI.mjs.map +1 -0
  27. package/dist/{chunk-WM2VDYQA.mjs → chunk-REIJZDVZ.mjs} +4 -3
  28. package/dist/chunk-REIJZDVZ.mjs.map +1 -0
  29. package/dist/{chunk-2WF6KIGF.mjs → chunk-TB4CL25L.mjs} +9 -8
  30. package/dist/chunk-TB4CL25L.mjs.map +1 -0
  31. package/dist/chunk-VNCCIV6O.mjs +938 -0
  32. package/dist/chunk-VNCCIV6O.mjs.map +1 -0
  33. package/dist/{chunk-CGZZO4BX.mjs → chunk-VRHWDZ66.mjs} +5 -5
  34. package/dist/{chunk-CGZZO4BX.mjs.map → chunk-VRHWDZ66.mjs.map} +1 -1
  35. package/dist/{chunk-4DS3MKID.mjs → chunk-YSJOVBCD.mjs} +4 -4
  36. package/dist/{chunk-4DS3MKID.mjs.map → chunk-YSJOVBCD.mjs.map} +1 -1
  37. package/dist/geometry-2d.d.mts +2 -2
  38. package/dist/geometry-2d.d.ts +2 -2
  39. package/dist/geometry-2d.js +1383 -23
  40. package/dist/geometry-2d.js.map +1 -1
  41. package/dist/geometry-2d.mjs +6 -5
  42. package/dist/geometry-3d.d.mts +2 -2
  43. package/dist/geometry-3d.d.ts +2 -2
  44. package/dist/geometry-3d.js +2 -2
  45. package/dist/geometry-3d.js.map +1 -1
  46. package/dist/geometry-3d.mjs +5 -4
  47. package/dist/graph-2d.d.mts +2 -2
  48. package/dist/graph-2d.d.ts +2 -2
  49. package/dist/graph-2d.js +2 -2
  50. package/dist/graph-2d.js.map +1 -1
  51. package/dist/graph-2d.mjs +8 -7
  52. package/dist/{host-ZIQ77W33.mjs → host-A64ITWVX.mjs} +7 -6
  53. package/dist/host-A64ITWVX.mjs.map +1 -0
  54. package/dist/{host-EPZCNFLH.mjs → host-L7FMFZUW.mjs} +226 -29
  55. package/dist/host-L7FMFZUW.mjs.map +1 -0
  56. package/dist/{host-LKCMYEAV.mjs → host-QK53UYMD.mjs} +11 -10
  57. package/dist/host-QK53UYMD.mjs.map +1 -0
  58. package/dist/index.d.mts +3 -3
  59. package/dist/index.d.ts +3 -3
  60. package/dist/index.js +1414 -54
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +18 -17
  63. package/dist/index.mjs.map +1 -1
  64. package/dist/latex.d.mts +2 -2
  65. package/dist/latex.d.ts +2 -2
  66. package/dist/render-3WTY7NZB.mjs +9 -0
  67. package/dist/{render-SA4JTOW3.mjs.map → render-3WTY7NZB.mjs.map} +1 -1
  68. package/dist/serialize-SRJVKYUG.mjs +8 -0
  69. package/dist/{serialize-JAVOU22E.mjs.map → serialize-SRJVKYUG.mjs.map} +1 -1
  70. package/dist/{types-vtvyKGAA.d.mts → types-DWRyCa2m.d.mts} +187 -2
  71. package/dist/{types-Crbefnfe.d.ts → types-DWRyCa2m.d.ts} +187 -2
  72. package/package.json +1 -1
  73. package/dist/chunk-2WF6KIGF.mjs.map +0 -1
  74. package/dist/chunk-BEZSQKPY.mjs.map +0 -1
  75. package/dist/chunk-BKSXPNPQ.mjs.map +0 -1
  76. package/dist/chunk-WM2VDYQA.mjs.map +0 -1
  77. package/dist/chunk-ZBJBQKJ2.mjs.map +0 -1
  78. package/dist/host-EPZCNFLH.mjs.map +0 -1
  79. package/dist/host-LKCMYEAV.mjs.map +0 -1
  80. package/dist/host-ZIQ77W33.mjs.map +0 -1
  81. package/dist/render-SA4JTOW3.mjs +0 -8
  82. package/dist/serialize-JAVOU22E.mjs +0 -7
  83. package/dist/types-DxlMPh-6.d.mts +0 -49
  84. package/dist/types-DxlMPh-6.d.ts +0 -49
package/dist/ai.d.mts CHANGED
@@ -1,565 +1,7 @@
1
- import { S as State } from './types-DxlMPh-6.mjs';
1
+ import { b as State, D as DslInputT, a as AiFigureUiResult } from './types-DWRyCa2m.mjs';
2
2
  import { z } from 'zod';
3
-
4
- declare const DslInput: z.ZodObject<{
5
- version: z.ZodLiteral<1>;
6
- points: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
7
- name: z.ZodString;
8
- kind: z.ZodLiteral<"free">;
9
- x: z.ZodNumber;
10
- y: z.ZodNumber;
11
- }, "strip", z.ZodTypeAny, {
12
- kind: "free";
13
- name: string;
14
- x: number;
15
- y: number;
16
- }, {
17
- kind: "free";
18
- name: string;
19
- x: number;
20
- y: number;
21
- }>, z.ZodObject<{
22
- name: z.ZodString;
23
- kind: z.ZodLiteral<"midpoint">;
24
- p1: z.ZodString;
25
- p2: z.ZodString;
26
- }, "strip", z.ZodTypeAny, {
27
- kind: "midpoint";
28
- name: string;
29
- p1: string;
30
- p2: string;
31
- }, {
32
- kind: "midpoint";
33
- name: string;
34
- p1: string;
35
- p2: string;
36
- }>, z.ZodObject<{
37
- name: z.ZodString;
38
- kind: z.ZodLiteral<"onSegment">;
39
- segmentId: z.ZodString;
40
- t: z.ZodNumber;
41
- }, "strip", z.ZodTypeAny, {
42
- kind: "onSegment";
43
- name: string;
44
- segmentId: string;
45
- t: number;
46
- }, {
47
- kind: "onSegment";
48
- name: string;
49
- segmentId: string;
50
- t: number;
51
- }>, z.ZodObject<{
52
- name: z.ZodString;
53
- kind: z.ZodLiteral<"onLine">;
54
- lineId: z.ZodString;
55
- t: z.ZodNumber;
56
- }, "strip", z.ZodTypeAny, {
57
- kind: "onLine";
58
- name: string;
59
- t: number;
60
- lineId: string;
61
- }, {
62
- kind: "onLine";
63
- name: string;
64
- t: number;
65
- lineId: string;
66
- }>, z.ZodObject<{
67
- name: z.ZodString;
68
- kind: z.ZodLiteral<"onCircle">;
69
- circleId: z.ZodString;
70
- theta: z.ZodNumber;
71
- }, "strip", z.ZodTypeAny, {
72
- kind: "onCircle";
73
- name: string;
74
- circleId: string;
75
- theta: number;
76
- }, {
77
- kind: "onCircle";
78
- name: string;
79
- circleId: string;
80
- theta: number;
81
- }>, z.ZodObject<{
82
- name: z.ZodString;
83
- kind: z.ZodLiteral<"perpFoot">;
84
- from: z.ZodString;
85
- onLine: z.ZodString;
86
- }, "strip", z.ZodTypeAny, {
87
- kind: "perpFoot";
88
- name: string;
89
- onLine: string;
90
- from: string;
91
- }, {
92
- kind: "perpFoot";
93
- name: string;
94
- onLine: string;
95
- from: string;
96
- }>, z.ZodObject<{
97
- name: z.ZodString;
98
- kind: z.ZodLiteral<"circumcenter">;
99
- vertices: z.ZodTuple<[z.ZodString, z.ZodString, z.ZodString], null>;
100
- }, "strip", z.ZodTypeAny, {
101
- kind: "circumcenter";
102
- name: string;
103
- vertices: [string, string, string];
104
- }, {
105
- kind: "circumcenter";
106
- name: string;
107
- vertices: [string, string, string];
108
- }>, z.ZodObject<{
109
- name: z.ZodString;
110
- kind: z.ZodLiteral<"incenter">;
111
- vertices: z.ZodTuple<[z.ZodString, z.ZodString, z.ZodString], null>;
112
- }, "strip", z.ZodTypeAny, {
113
- kind: "incenter";
114
- name: string;
115
- vertices: [string, string, string];
116
- }, {
117
- kind: "incenter";
118
- name: string;
119
- vertices: [string, string, string];
120
- }>, z.ZodObject<{
121
- name: z.ZodString;
122
- kind: z.ZodLiteral<"centroid">;
123
- vertices: z.ZodTuple<[z.ZodString, z.ZodString, z.ZodString], null>;
124
- }, "strip", z.ZodTypeAny, {
125
- kind: "centroid";
126
- name: string;
127
- vertices: [string, string, string];
128
- }, {
129
- kind: "centroid";
130
- name: string;
131
- vertices: [string, string, string];
132
- }>, z.ZodObject<{
133
- name: z.ZodString;
134
- kind: z.ZodLiteral<"orthocenter">;
135
- vertices: z.ZodTuple<[z.ZodString, z.ZodString, z.ZodString], null>;
136
- }, "strip", z.ZodTypeAny, {
137
- kind: "orthocenter";
138
- name: string;
139
- vertices: [string, string, string];
140
- }, {
141
- kind: "orthocenter";
142
- name: string;
143
- vertices: [string, string, string];
144
- }>, z.ZodObject<{
145
- name: z.ZodString;
146
- kind: z.ZodLiteral<"intersection">;
147
- ref1: z.ZodString;
148
- ref2: z.ZodString;
149
- branch: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<0>, z.ZodLiteral<1>]>>;
150
- }, "strip", z.ZodTypeAny, {
151
- kind: "intersection";
152
- name: string;
153
- ref1: string;
154
- ref2: string;
155
- branch?: 0 | 1 | undefined;
156
- }, {
157
- kind: "intersection";
158
- name: string;
159
- ref1: string;
160
- ref2: string;
161
- branch?: 0 | 1 | undefined;
162
- }>]>, "many">;
163
- shapes: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
164
- name: z.ZodString;
165
- kind: z.ZodLiteral<"segment">;
166
- p1: z.ZodString;
167
- p2: z.ZodString;
168
- }, "strip", z.ZodTypeAny, {
169
- kind: "segment";
170
- name: string;
171
- p1: string;
172
- p2: string;
173
- }, {
174
- kind: "segment";
175
- name: string;
176
- p1: string;
177
- p2: string;
178
- }>, z.ZodObject<{
179
- name: z.ZodString;
180
- kind: z.ZodLiteral<"line">;
181
- p1: z.ZodString;
182
- p2: z.ZodString;
183
- }, "strip", z.ZodTypeAny, {
184
- kind: "line";
185
- name: string;
186
- p1: string;
187
- p2: string;
188
- }, {
189
- kind: "line";
190
- name: string;
191
- p1: string;
192
- p2: string;
193
- }>, z.ZodObject<{
194
- name: z.ZodString;
195
- kind: z.ZodLiteral<"ray">;
196
- origin: z.ZodString;
197
- through: z.ZodString;
198
- }, "strip", z.ZodTypeAny, {
199
- kind: "ray";
200
- name: string;
201
- origin: string;
202
- through: string;
203
- }, {
204
- kind: "ray";
205
- name: string;
206
- origin: string;
207
- through: string;
208
- }>, z.ZodObject<{
209
- name: z.ZodString;
210
- kind: z.ZodLiteral<"polygon">;
211
- vertices: z.ZodArray<z.ZodString, "many">;
212
- }, "strip", z.ZodTypeAny, {
213
- kind: "polygon";
214
- name: string;
215
- vertices: string[];
216
- }, {
217
- kind: "polygon";
218
- name: string;
219
- vertices: string[];
220
- }>, z.ZodObject<{
221
- name: z.ZodString;
222
- kind: z.ZodLiteral<"perpendicular">;
223
- throughPoint: z.ZodString;
224
- toLine: z.ZodString;
225
- }, "strip", z.ZodTypeAny, {
226
- kind: "perpendicular";
227
- name: string;
228
- throughPoint: string;
229
- toLine: string;
230
- }, {
231
- kind: "perpendicular";
232
- name: string;
233
- throughPoint: string;
234
- toLine: string;
235
- }>, z.ZodObject<{
236
- name: z.ZodString;
237
- kind: z.ZodLiteral<"parallel">;
238
- throughPoint: z.ZodString;
239
- toLine: z.ZodString;
240
- }, "strip", z.ZodTypeAny, {
241
- kind: "parallel";
242
- name: string;
243
- throughPoint: string;
244
- toLine: string;
245
- }, {
246
- kind: "parallel";
247
- name: string;
248
- throughPoint: string;
249
- toLine: string;
250
- }>, z.ZodObject<{
251
- name: z.ZodString;
252
- kind: z.ZodLiteral<"perpBisector">;
253
- p1: z.ZodString;
254
- p2: z.ZodString;
255
- }, "strip", z.ZodTypeAny, {
256
- kind: "perpBisector";
257
- name: string;
258
- p1: string;
259
- p2: string;
260
- }, {
261
- kind: "perpBisector";
262
- name: string;
263
- p1: string;
264
- p2: string;
265
- }>, z.ZodObject<{
266
- name: z.ZodString;
267
- kind: z.ZodLiteral<"angleBisector">;
268
- p1: z.ZodString;
269
- vertex: z.ZodString;
270
- p2: z.ZodString;
271
- }, "strip", z.ZodTypeAny, {
272
- kind: "angleBisector";
273
- name: string;
274
- p1: string;
275
- p2: string;
276
- vertex: string;
277
- }, {
278
- kind: "angleBisector";
279
- name: string;
280
- p1: string;
281
- p2: string;
282
- vertex: string;
283
- }>, z.ZodObject<{
284
- name: z.ZodString;
285
- kind: z.ZodLiteral<"tangent">;
286
- throughPoint: z.ZodString;
287
- toCircle: z.ZodString;
288
- branch: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<"on">]>>;
289
- }, "strip", z.ZodTypeAny, {
290
- kind: "tangent";
291
- name: string;
292
- throughPoint: string;
293
- toCircle: string;
294
- branch?: 0 | 1 | "on" | undefined;
295
- }, {
296
- kind: "tangent";
297
- name: string;
298
- throughPoint: string;
299
- toCircle: string;
300
- branch?: 0 | 1 | "on" | undefined;
301
- }>, z.ZodObject<{
302
- name: z.ZodString;
303
- kind: z.ZodLiteral<"circleCP">;
304
- center: z.ZodString;
305
- surfacePoint: z.ZodString;
306
- }, "strip", z.ZodTypeAny, {
307
- kind: "circleCP";
308
- name: string;
309
- center: string;
310
- surfacePoint: string;
311
- }, {
312
- kind: "circleCP";
313
- name: string;
314
- center: string;
315
- surfacePoint: string;
316
- }>, z.ZodObject<{
317
- name: z.ZodString;
318
- kind: z.ZodLiteral<"circle3">;
319
- p1: z.ZodString;
320
- p2: z.ZodString;
321
- p3: z.ZodString;
322
- }, "strip", z.ZodTypeAny, {
323
- kind: "circle3";
324
- name: string;
325
- p1: string;
326
- p2: string;
327
- p3: string;
328
- }, {
329
- kind: "circle3";
330
- name: string;
331
- p1: string;
332
- p2: string;
333
- p3: string;
334
- }>]>, "many">>;
335
- }, "strip", z.ZodTypeAny, {
336
- version: 1;
337
- points: ({
338
- kind: "free";
339
- name: string;
340
- x: number;
341
- y: number;
342
- } | {
343
- kind: "midpoint";
344
- name: string;
345
- p1: string;
346
- p2: string;
347
- } | {
348
- kind: "onSegment";
349
- name: string;
350
- segmentId: string;
351
- t: number;
352
- } | {
353
- kind: "onLine";
354
- name: string;
355
- t: number;
356
- lineId: string;
357
- } | {
358
- kind: "onCircle";
359
- name: string;
360
- circleId: string;
361
- theta: number;
362
- } | {
363
- kind: "perpFoot";
364
- name: string;
365
- onLine: string;
366
- from: string;
367
- } | {
368
- kind: "circumcenter";
369
- name: string;
370
- vertices: [string, string, string];
371
- } | {
372
- kind: "incenter";
373
- name: string;
374
- vertices: [string, string, string];
375
- } | {
376
- kind: "centroid";
377
- name: string;
378
- vertices: [string, string, string];
379
- } | {
380
- kind: "orthocenter";
381
- name: string;
382
- vertices: [string, string, string];
383
- } | {
384
- kind: "intersection";
385
- name: string;
386
- ref1: string;
387
- ref2: string;
388
- branch?: 0 | 1 | undefined;
389
- })[];
390
- shapes: ({
391
- kind: "segment";
392
- name: string;
393
- p1: string;
394
- p2: string;
395
- } | {
396
- kind: "line";
397
- name: string;
398
- p1: string;
399
- p2: string;
400
- } | {
401
- kind: "ray";
402
- name: string;
403
- origin: string;
404
- through: string;
405
- } | {
406
- kind: "polygon";
407
- name: string;
408
- vertices: string[];
409
- } | {
410
- kind: "perpendicular";
411
- name: string;
412
- throughPoint: string;
413
- toLine: string;
414
- } | {
415
- kind: "parallel";
416
- name: string;
417
- throughPoint: string;
418
- toLine: string;
419
- } | {
420
- kind: "perpBisector";
421
- name: string;
422
- p1: string;
423
- p2: string;
424
- } | {
425
- kind: "angleBisector";
426
- name: string;
427
- p1: string;
428
- p2: string;
429
- vertex: string;
430
- } | {
431
- kind: "tangent";
432
- name: string;
433
- throughPoint: string;
434
- toCircle: string;
435
- branch?: 0 | 1 | "on" | undefined;
436
- } | {
437
- kind: "circleCP";
438
- name: string;
439
- center: string;
440
- surfacePoint: string;
441
- } | {
442
- kind: "circle3";
443
- name: string;
444
- p1: string;
445
- p2: string;
446
- p3: string;
447
- })[];
448
- }, {
449
- version: 1;
450
- points: ({
451
- kind: "free";
452
- name: string;
453
- x: number;
454
- y: number;
455
- } | {
456
- kind: "midpoint";
457
- name: string;
458
- p1: string;
459
- p2: string;
460
- } | {
461
- kind: "onSegment";
462
- name: string;
463
- segmentId: string;
464
- t: number;
465
- } | {
466
- kind: "onLine";
467
- name: string;
468
- t: number;
469
- lineId: string;
470
- } | {
471
- kind: "onCircle";
472
- name: string;
473
- circleId: string;
474
- theta: number;
475
- } | {
476
- kind: "perpFoot";
477
- name: string;
478
- onLine: string;
479
- from: string;
480
- } | {
481
- kind: "circumcenter";
482
- name: string;
483
- vertices: [string, string, string];
484
- } | {
485
- kind: "incenter";
486
- name: string;
487
- vertices: [string, string, string];
488
- } | {
489
- kind: "centroid";
490
- name: string;
491
- vertices: [string, string, string];
492
- } | {
493
- kind: "orthocenter";
494
- name: string;
495
- vertices: [string, string, string];
496
- } | {
497
- kind: "intersection";
498
- name: string;
499
- ref1: string;
500
- ref2: string;
501
- branch?: 0 | 1 | undefined;
502
- })[];
503
- shapes?: ({
504
- kind: "segment";
505
- name: string;
506
- p1: string;
507
- p2: string;
508
- } | {
509
- kind: "line";
510
- name: string;
511
- p1: string;
512
- p2: string;
513
- } | {
514
- kind: "ray";
515
- name: string;
516
- origin: string;
517
- through: string;
518
- } | {
519
- kind: "polygon";
520
- name: string;
521
- vertices: string[];
522
- } | {
523
- kind: "perpendicular";
524
- name: string;
525
- throughPoint: string;
526
- toLine: string;
527
- } | {
528
- kind: "parallel";
529
- name: string;
530
- throughPoint: string;
531
- toLine: string;
532
- } | {
533
- kind: "perpBisector";
534
- name: string;
535
- p1: string;
536
- p2: string;
537
- } | {
538
- kind: "angleBisector";
539
- name: string;
540
- p1: string;
541
- p2: string;
542
- vertex: string;
543
- } | {
544
- kind: "tangent";
545
- name: string;
546
- throughPoint: string;
547
- toCircle: string;
548
- branch?: 0 | 1 | "on" | undefined;
549
- } | {
550
- kind: "circleCP";
551
- name: string;
552
- center: string;
553
- surfacePoint: string;
554
- } | {
555
- kind: "circle3";
556
- name: string;
557
- p1: string;
558
- p2: string;
559
- p3: string;
560
- })[] | undefined;
561
- }>;
562
- type DslInputT = z.infer<typeof DslInput>;
3
+ import 'react';
4
+ import '@excalidraw/excalidraw/element/types';
563
5
 
564
6
  type TranspileErrorCode = 'SCHEMA' | 'DUPLICATE_NAME' | 'UNKNOWN_REF' | 'KIND_MISMATCH' | 'CYCLE';
565
7
  interface TranspileError {
@@ -569,14 +11,99 @@ interface TranspileError {
569
11
  hint?: string;
570
12
  }
571
13
 
572
- interface GenerateOptions {
14
+ interface ProviderTokenUsage {
15
+ inputTokens: number;
16
+ outputTokens: number;
17
+ /** Anthropic prompt caching — local provider để 0. */
18
+ cacheReadTokens?: number;
19
+ /** Anthropic prompt caching — local provider để 0. */
20
+ cacheCreationTokens?: number;
21
+ }
22
+ interface ProviderRequest {
23
+ systemPrompt: string;
24
+ userPrompt: string;
25
+ /**
26
+ * JSON Schema mà provider phải honor để constrain output. Anthropic → wrap
27
+ * thành tool input_schema. Ollama → pass thẳng vào `format` (v0.5+).
28
+ */
29
+ schema: Record<string, unknown>;
30
+ /** Provider-specific model id (vd "gemma3:4b", "claude-opus-4-7"). */
31
+ model: string;
32
+ /** Token cap cho response. */
33
+ maxTokens: number;
34
+ signal?: AbortSignal;
35
+ }
36
+ type ProviderOutput = {
37
+ kind: 'json';
38
+ data: unknown;
39
+ usage?: ProviderTokenUsage;
40
+ } | {
41
+ kind: 'error';
42
+ message: string;
43
+ status?: number;
44
+ };
45
+ interface AIProvider {
46
+ /** Tên định danh ("anthropic", "ollama", ...). */
47
+ readonly name: string;
48
+ /** Default model id khi caller không truyền. */
49
+ readonly defaultModel: string;
50
+ call(req: ProviderRequest): Promise<ProviderOutput>;
51
+ }
52
+
53
+ interface AnthropicProviderOptions {
573
54
  apiKey: string;
55
+ /** Cache system prompt qua Anthropic prompt-caching (mặc định bật). */
56
+ enableCaching?: boolean;
57
+ }
58
+ declare class AnthropicProvider implements AIProvider {
59
+ private readonly opts;
60
+ readonly name = "anthropic";
61
+ readonly defaultModel = "claude-opus-4-7";
62
+ constructor(opts: AnthropicProviderOptions);
63
+ call(req: ProviderRequest): Promise<ProviderOutput>;
64
+ }
65
+
66
+ interface OllamaProviderOptions {
67
+ /** Endpoint base URL, default http://localhost:11434. */
68
+ baseUrl?: string;
69
+ /** Default model id nếu request không truyền. */
70
+ defaultModel?: string;
71
+ /** Custom fetch impl (dùng cho test mock). */
72
+ fetchImpl?: typeof fetch;
73
+ }
74
+ declare class OllamaProvider implements AIProvider {
75
+ readonly name = "ollama";
76
+ readonly defaultModel: string;
77
+ private readonly baseUrl;
78
+ private readonly fetchImpl;
79
+ constructor(opts?: OllamaProviderOptions);
80
+ private resolveFetch;
81
+ call(req: ProviderRequest): Promise<ProviderOutput>;
82
+ }
83
+
84
+ interface SelectProviderOptions {
85
+ /** Provider instance dùng trực tiếp (override mọi env). */
86
+ provider?: AIProvider;
87
+ /** Anthropic API key. Khi truyền → auto chọn AnthropicProvider. */
88
+ apiKey?: string;
89
+ /** Anthropic prompt-caching, default true (chỉ áp dụng provider Anthropic). */
90
+ enableCaching?: boolean;
91
+ /** Ollama endpoint override. */
92
+ ollamaBaseUrl?: string;
93
+ /** Ollama model override (vd "gemma3:1b"). */
94
+ ollamaDefaultModel?: string;
95
+ /** Test env: env vars getter (default process.env). */
96
+ env?: Record<string, string | undefined>;
97
+ }
98
+ declare function selectProvider(opts?: SelectProviderOptions): AIProvider;
99
+
100
+ interface GenerateOptions extends SelectProviderOptions {
101
+ /** Model id override (provider-specific). Mặc định: provider.defaultModel. */
574
102
  model?: string;
575
103
  maxTokens?: number;
576
- enableCaching?: boolean;
577
104
  signal?: AbortSignal;
578
105
  }
579
- interface TokenUsage {
106
+ interface TokenUsage$1 {
580
107
  inputTokens: number;
581
108
  outputTokens: number;
582
109
  cacheReadTokens: number;
@@ -586,18 +113,213 @@ type GenerateResult = {
586
113
  ok: true;
587
114
  state: State;
588
115
  dsl: DslInputT;
116
+ usage: TokenUsage$1;
117
+ provider: string;
118
+ } | {
119
+ ok: false;
120
+ reason: 'refused';
121
+ message: string;
122
+ usage?: TokenUsage$1;
123
+ provider?: string;
124
+ } | {
125
+ ok: false;
126
+ reason: 'parse_error';
127
+ message: string;
128
+ raw?: unknown;
129
+ usage?: TokenUsage$1;
130
+ provider?: string;
131
+ } | {
132
+ ok: false;
133
+ reason: 'transpile_error';
134
+ message: string;
135
+ errors: TranspileError[];
136
+ dsl: unknown;
137
+ usage?: TokenUsage$1;
138
+ provider?: string;
139
+ } | {
140
+ ok: false;
141
+ reason: 'api_error';
142
+ message: string;
143
+ status?: number;
144
+ provider?: string;
145
+ };
146
+ declare function generateFigure(problem: string, opts?: GenerateOptions): Promise<GenerateResult>;
147
+
148
+ interface HandleGenerateFigureInput {
149
+ /** Đề bài tiếng Việt từ teacher. */
150
+ problem: string;
151
+ }
152
+ interface HandleGenerateFigureOptions extends GenerateOptions {
153
+ /**
154
+ * Optional telemetry hook. Gọi cho MỖI attempt với envelope nội bộ trước
155
+ * khi map sang AiFigureUiResult — consumer dùng để log usage/cost/error.
156
+ * Không throw từ logger — sẽ swallow để không vỡ response.
157
+ *
158
+ * @param result GenerateResult của attempt
159
+ * @param attempt 1-indexed (1 = lần đầu, 2 = retry, ...)
160
+ */
161
+ onResult?: (result: GenerateResult, attempt: number) => void;
162
+ /**
163
+ * Số attempt tối đa khi nhận `transpile_error`. Default 2 (1 retry).
164
+ * AI stochastic → lần 2 thường khá hơn. Min 1, max 5.
165
+ */
166
+ maxAttempts?: number;
167
+ }
168
+ /**
169
+ * Gọi AI orchestrator và trả về kết quả ở dạng `AiFigureUiResult` mà
170
+ * `<Whiteboard generateGeometryFigure>` chấp nhận trực tiếp.
171
+ *
172
+ * Auto-retry: chỉ retry khi `transpile_error` (DSL không hợp lệ — model
173
+ * stochastic có cơ hội emit khá hơn lần 2). KHÔNG retry `refused` (AI cố ý
174
+ * từ chối), `parse_error` (envelope sai schema — chắc chắn sai mọi lần),
175
+ * hay `api_error` (network / config — không liên quan model).
176
+ *
177
+ * Mapping:
178
+ * - ok=true → { ok: true, state }
179
+ * - refused → { ok: false, message: <message AI gửi> }
180
+ * - parse_error → { ok: false, message: 'AI trả JSON không hợp lệ…' }
181
+ * - transpile_error → { ok: false, message: 'AI tạo hình không hợp lệ…' }
182
+ * - api_error → { ok: false, message: <message gốc> }
183
+ *
184
+ * Server-side caller giữ `GenerateResult` đầy đủ qua `onResult` callback cho
185
+ * mục đích telemetry/logging.
186
+ */
187
+ declare function handleGenerateFigure(input: HandleGenerateFigureInput, opts?: HandleGenerateFigureOptions): Promise<AiFigureUiResult>;
188
+
189
+ declare const FigureEnvelopeZ: z.ZodEffects<z.ZodObject<{
190
+ decision: z.ZodEnum<["build", "refuse"]>;
191
+ figure: z.ZodOptional<z.ZodObject<{
192
+ version: z.ZodLiteral<1>;
193
+ points: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
194
+ [x: string]: any;
195
+ }, {
196
+ [x: string]: any;
197
+ }>, z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
198
+ [x: string]: any;
199
+ }, {
200
+ [x: string]: any;
201
+ }>, ...z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
202
+ [x: string]: any;
203
+ }, {
204
+ [x: string]: any;
205
+ }>[]]>, "many">;
206
+ shapes: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
207
+ [x: string]: any;
208
+ }, {
209
+ [x: string]: any;
210
+ }>, z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
211
+ [x: string]: any;
212
+ }, {
213
+ [x: string]: any;
214
+ }>, ...z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
215
+ [x: string]: any;
216
+ }, {
217
+ [x: string]: any;
218
+ }>[]]>, "many">>;
219
+ }, "strip", z.ZodTypeAny, {
220
+ points: {
221
+ [x: string]: any;
222
+ }[];
223
+ version: 1;
224
+ shapes: {
225
+ [x: string]: any;
226
+ }[];
227
+ }, {
228
+ points: {
229
+ [x: string]: any;
230
+ }[];
231
+ version: 1;
232
+ shapes?: {
233
+ [x: string]: any;
234
+ }[] | undefined;
235
+ }>>;
236
+ reason: z.ZodOptional<z.ZodString>;
237
+ }, "strip", z.ZodTypeAny, {
238
+ decision: "build" | "refuse";
239
+ reason?: string | undefined;
240
+ figure?: {
241
+ points: {
242
+ [x: string]: any;
243
+ }[];
244
+ version: 1;
245
+ shapes: {
246
+ [x: string]: any;
247
+ }[];
248
+ } | undefined;
249
+ }, {
250
+ decision: "build" | "refuse";
251
+ reason?: string | undefined;
252
+ figure?: {
253
+ points: {
254
+ [x: string]: any;
255
+ }[];
256
+ version: 1;
257
+ shapes?: {
258
+ [x: string]: any;
259
+ }[] | undefined;
260
+ } | undefined;
261
+ }>, {
262
+ decision: "build" | "refuse";
263
+ reason?: string | undefined;
264
+ figure?: {
265
+ points: {
266
+ [x: string]: any;
267
+ }[];
268
+ version: 1;
269
+ shapes: {
270
+ [x: string]: any;
271
+ }[];
272
+ } | undefined;
273
+ }, {
274
+ decision: "build" | "refuse";
275
+ reason?: string | undefined;
276
+ figure?: {
277
+ points: {
278
+ [x: string]: any;
279
+ }[];
280
+ version: 1;
281
+ shapes?: {
282
+ [x: string]: any;
283
+ }[] | undefined;
284
+ } | undefined;
285
+ }>;
286
+ type FigureEnvelopeT = z.infer<typeof FigureEnvelopeZ>;
287
+ declare function envelopeJsonSchema(): Record<string, unknown>;
288
+ /** Helper: ép envelope build hợp lệ về DslInputT (sau khi đã validate). */
289
+ declare function envelopeBuildDsl(env: FigureEnvelopeT): DslInputT;
290
+
291
+ interface GenerateDeltaOptions extends SelectProviderOptions {
292
+ model?: string;
293
+ maxTokens?: number;
294
+ signal?: AbortSignal;
295
+ maxAttempts?: number;
296
+ }
297
+ interface TokenUsage {
298
+ inputTokens: number;
299
+ outputTokens: number;
300
+ cacheReadTokens: number;
301
+ cacheCreationTokens: number;
302
+ }
303
+ type GenerateDeltaResult = {
304
+ ok: true;
305
+ state: State;
306
+ mergedDsl: DslInputT;
307
+ mode: 'add' | 'replace';
589
308
  usage: TokenUsage;
309
+ provider: string;
590
310
  } | {
591
311
  ok: false;
592
312
  reason: 'refused';
593
313
  message: string;
594
314
  usage?: TokenUsage;
315
+ provider?: string;
595
316
  } | {
596
317
  ok: false;
597
318
  reason: 'parse_error';
598
319
  message: string;
599
320
  raw?: unknown;
600
321
  usage?: TokenUsage;
322
+ provider?: string;
601
323
  } | {
602
324
  ok: false;
603
325
  reason: 'transpile_error';
@@ -605,12 +327,146 @@ type GenerateResult = {
605
327
  errors: TranspileError[];
606
328
  dsl: unknown;
607
329
  usage?: TokenUsage;
330
+ provider?: string;
331
+ } | {
332
+ ok: false;
333
+ reason: 'name_collision';
334
+ message: string;
335
+ collisions: string[];
336
+ errors: TranspileError[];
337
+ dsl: unknown;
338
+ usage?: TokenUsage;
339
+ provider?: string;
340
+ } | {
341
+ ok: false;
342
+ reason: 'unresolved_ref';
343
+ message: string;
344
+ refs: string[];
345
+ errors: TranspileError[];
346
+ dsl: unknown;
347
+ usage?: TokenUsage;
348
+ provider?: string;
608
349
  } | {
609
350
  ok: false;
610
351
  reason: 'api_error';
611
352
  message: string;
612
353
  status?: number;
354
+ provider?: string;
613
355
  };
614
- declare function generateFigure(problem: string, opts: GenerateOptions): Promise<GenerateResult>;
356
+ interface GenerateFigureDeltaInput {
357
+ problem: string;
358
+ currentDsl: DslInputT;
359
+ }
360
+ declare function generateFigureDelta(input: GenerateFigureDeltaInput, opts?: GenerateDeltaOptions): Promise<GenerateDeltaResult>;
361
+
362
+ interface HandleGenerateFigureDeltaInput {
363
+ problem: string;
364
+ currentDsl: DslInputT;
365
+ }
366
+ interface HandleGenerateFigureDeltaOptions extends GenerateDeltaOptions {
367
+ onResult?: (result: GenerateDeltaResult, attempt: number) => void;
368
+ maxAttempts?: number;
369
+ }
370
+ declare function handleGenerateFigureDelta(input: HandleGenerateFigureDeltaInput, opts?: HandleGenerateFigureDeltaOptions): Promise<AiFigureUiResult>;
371
+
372
+ declare const FigureRefineEnvelopeZ: z.ZodEffects<z.ZodObject<{
373
+ decision: z.ZodEnum<["add", "replace", "refuse"]>;
374
+ figure: z.ZodOptional<z.ZodObject<{
375
+ version: z.ZodLiteral<1>;
376
+ points: z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
377
+ [x: string]: any;
378
+ }, {
379
+ [x: string]: any;
380
+ }>, z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
381
+ [x: string]: any;
382
+ }, {
383
+ [x: string]: any;
384
+ }>, ...z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
385
+ [x: string]: any;
386
+ }, {
387
+ [x: string]: any;
388
+ }>[]]>, "many">;
389
+ shapes: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
390
+ [x: string]: any;
391
+ }, {
392
+ [x: string]: any;
393
+ }>, z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
394
+ [x: string]: any;
395
+ }, {
396
+ [x: string]: any;
397
+ }>, ...z.ZodObject<any, z.UnknownKeysParam, z.ZodTypeAny, {
398
+ [x: string]: any;
399
+ }, {
400
+ [x: string]: any;
401
+ }>[]]>, "many">>;
402
+ }, "strip", z.ZodTypeAny, {
403
+ points: {
404
+ [x: string]: any;
405
+ }[];
406
+ version: 1;
407
+ shapes: {
408
+ [x: string]: any;
409
+ }[];
410
+ }, {
411
+ points: {
412
+ [x: string]: any;
413
+ }[];
414
+ version: 1;
415
+ shapes?: {
416
+ [x: string]: any;
417
+ }[] | undefined;
418
+ }>>;
419
+ reason: z.ZodOptional<z.ZodString>;
420
+ }, "strip", z.ZodTypeAny, {
421
+ decision: "refuse" | "add" | "replace";
422
+ reason?: string | undefined;
423
+ figure?: {
424
+ points: {
425
+ [x: string]: any;
426
+ }[];
427
+ version: 1;
428
+ shapes: {
429
+ [x: string]: any;
430
+ }[];
431
+ } | undefined;
432
+ }, {
433
+ decision: "refuse" | "add" | "replace";
434
+ reason?: string | undefined;
435
+ figure?: {
436
+ points: {
437
+ [x: string]: any;
438
+ }[];
439
+ version: 1;
440
+ shapes?: {
441
+ [x: string]: any;
442
+ }[] | undefined;
443
+ } | undefined;
444
+ }>, {
445
+ decision: "refuse" | "add" | "replace";
446
+ reason?: string | undefined;
447
+ figure?: {
448
+ points: {
449
+ [x: string]: any;
450
+ }[];
451
+ version: 1;
452
+ shapes: {
453
+ [x: string]: any;
454
+ }[];
455
+ } | undefined;
456
+ }, {
457
+ decision: "refuse" | "add" | "replace";
458
+ reason?: string | undefined;
459
+ figure?: {
460
+ points: {
461
+ [x: string]: any;
462
+ }[];
463
+ version: 1;
464
+ shapes?: {
465
+ [x: string]: any;
466
+ }[] | undefined;
467
+ } | undefined;
468
+ }>;
469
+ type FigureRefineEnvelopeT = z.infer<typeof FigureRefineEnvelopeZ>;
470
+ declare function refineEnvelopeJsonSchema(): Record<string, unknown>;
615
471
 
616
- export { type GenerateOptions, type GenerateResult, type TokenUsage, generateFigure };
472
+ export { type AIProvider, AnthropicProvider, type FigureEnvelopeT, FigureEnvelopeZ, type FigureRefineEnvelopeT, FigureRefineEnvelopeZ, type GenerateDeltaOptions, type GenerateDeltaResult, type GenerateFigureDeltaInput, type GenerateOptions, type GenerateResult, type HandleGenerateFigureDeltaInput, type HandleGenerateFigureDeltaOptions, type HandleGenerateFigureInput, type HandleGenerateFigureOptions, OllamaProvider, type ProviderOutput, type ProviderRequest, type ProviderTokenUsage, type SelectProviderOptions, type TokenUsage$1 as TokenUsage, envelopeBuildDsl, envelopeJsonSchema, generateFigure, generateFigureDelta, handleGenerateFigure, handleGenerateFigureDelta, refineEnvelopeJsonSchema, selectProvider };