@xom11/whiteboard 0.24.2 → 0.27.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/README.md +84 -11
- package/dist/{ExcalidrawWithMenus-WENZRYYE.mjs → ExcalidrawWithMenus-2QPPTXJM.mjs} +3 -2
- package/dist/ExcalidrawWithMenus-2QPPTXJM.mjs.map +1 -0
- package/dist/ai.d.mts +3217 -434
- package/dist/ai.d.ts +3217 -434
- package/dist/ai.js +7679 -598
- package/dist/ai.js.map +1 -1
- package/dist/ai.mjs +5707 -679
- package/dist/ai.mjs.map +1 -1
- package/dist/catalog.json +5 -5
- package/dist/{chunk-7WQXXEVR.mjs → chunk-4ETJ4CDY.mjs} +5 -5
- package/dist/{chunk-7WQXXEVR.mjs.map → chunk-4ETJ4CDY.mjs.map} +1 -1
- package/dist/chunk-AJAHD35N.mjs +1708 -0
- package/dist/chunk-AJAHD35N.mjs.map +1 -0
- package/dist/chunk-AYJPOHCI.mjs +265 -0
- package/dist/chunk-AYJPOHCI.mjs.map +1 -0
- package/dist/chunk-B4NJJZFR.mjs +18 -0
- package/dist/chunk-B4NJJZFR.mjs.map +1 -0
- package/dist/{chunk-AZIARTGX.mjs → chunk-BNBOIDO5.mjs} +3 -3
- package/dist/{chunk-AZIARTGX.mjs.map → chunk-BNBOIDO5.mjs.map} +1 -1
- package/dist/{chunk-LVNCYP4J.mjs → chunk-CXHNVYMD.mjs} +5 -5
- package/dist/{chunk-LVNCYP4J.mjs.map → chunk-CXHNVYMD.mjs.map} +1 -1
- package/dist/{chunk-45CGKJ7S.mjs → chunk-D5JLJ3PT.mjs} +4 -4
- package/dist/{chunk-45CGKJ7S.mjs.map → chunk-D5JLJ3PT.mjs.map} +1 -1
- package/dist/{chunk-WM2VDYQA.mjs → chunk-D5LWSN2Y.mjs} +944 -196
- package/dist/chunk-D5LWSN2Y.mjs.map +1 -0
- package/dist/{chunk-KRC2XOIG.mjs → chunk-HLAOGXEK.mjs} +3 -3
- package/dist/{chunk-KRC2XOIG.mjs.map → chunk-HLAOGXEK.mjs.map} +1 -1
- package/dist/{chunk-2WF6KIGF.mjs → chunk-I3L56GVH.mjs} +212 -71
- package/dist/chunk-I3L56GVH.mjs.map +1 -0
- package/dist/{chunk-ZBJBQKJ2.mjs → chunk-IHUFOV7L.mjs} +4 -19
- package/dist/chunk-IHUFOV7L.mjs.map +1 -0
- package/dist/chunk-J5LGTIGS.mjs +10 -0
- package/dist/chunk-J5LGTIGS.mjs.map +1 -0
- package/dist/{chunk-BEZSQKPY.mjs → chunk-KYMBUTPO.mjs} +5 -4
- package/dist/chunk-KYMBUTPO.mjs.map +1 -0
- package/dist/{chunk-4DS3MKID.mjs → chunk-KZGPSTZI.mjs} +4 -4
- package/dist/{chunk-4DS3MKID.mjs.map → chunk-KZGPSTZI.mjs.map} +1 -1
- package/dist/{chunk-SGFJLHHG.mjs → chunk-PPKHCRRE.mjs} +3 -3
- package/dist/{chunk-SGFJLHHG.mjs.map → chunk-PPKHCRRE.mjs.map} +1 -1
- package/dist/{chunk-BKSXPNPQ.mjs → chunk-SZDAS7LK.mjs} +81 -3
- package/dist/chunk-SZDAS7LK.mjs.map +1 -0
- package/dist/chunk-T3SOHYB2.mjs +851 -0
- package/dist/chunk-T3SOHYB2.mjs.map +1 -0
- package/dist/geometry-2d.d.mts +2 -2
- package/dist/geometry-2d.d.ts +2 -2
- package/dist/geometry-2d.js +6288 -901
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +7 -5
- package/dist/geometry-3d.d.mts +2 -2
- package/dist/geometry-3d.d.ts +2 -2
- package/dist/geometry-3d.js +1335 -253
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +6 -4
- package/dist/graph-2d.d.mts +2 -2
- package/dist/graph-2d.d.ts +2 -2
- package/dist/graph-2d.js +1501 -342
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +9 -7
- package/dist/handleExtractProblem-C-U5KluK.d.mts +158 -0
- package/dist/handleExtractProblem-C-U5KluK.d.ts +158 -0
- package/dist/{host-EPZCNFLH.mjs → host-HAYCJJ2T.mjs} +1390 -376
- package/dist/host-HAYCJJ2T.mjs.map +1 -0
- package/dist/{host-LKCMYEAV.mjs → host-LTJHAY5A.mjs} +12 -10
- package/dist/host-LTJHAY5A.mjs.map +1 -0
- package/dist/{host-ZIQ77W33.mjs → host-M26FS244.mjs} +8 -6
- package/dist/host-M26FS244.mjs.map +1 -0
- package/dist/{host-QS2EOTRJ.mjs → host-ZQCDAT6O.mjs} +3 -2
- package/dist/host-ZQCDAT6O.mjs.map +1 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +6493 -1102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -21
- package/dist/index.mjs.map +1 -1
- package/dist/latex.d.mts +2 -2
- package/dist/latex.d.ts +2 -2
- package/dist/latex.mjs +2 -1
- package/dist/render-ZX2O2IK7.mjs +10 -0
- package/dist/{render-SA4JTOW3.mjs.map → render-ZX2O2IK7.mjs.map} +1 -1
- package/dist/serialize-C3LSUMSA.mjs +9 -0
- package/dist/{serialize-JAVOU22E.mjs.map → serialize-C3LSUMSA.mjs.map} +1 -1
- package/dist/types-zc_Pa0mp.d.mts +418 -0
- package/dist/types-zc_Pa0mp.d.ts +418 -0
- package/package.json +10 -1
- package/dist/ExcalidrawWithMenus-WENZRYYE.mjs.map +0 -1
- package/dist/chunk-2WF6KIGF.mjs.map +0 -1
- package/dist/chunk-BEZSQKPY.mjs.map +0 -1
- package/dist/chunk-BKSXPNPQ.mjs.map +0 -1
- package/dist/chunk-CGZZO4BX.mjs +0 -96
- package/dist/chunk-CGZZO4BX.mjs.map +0 -1
- package/dist/chunk-WM2VDYQA.mjs.map +0 -1
- package/dist/chunk-ZBJBQKJ2.mjs.map +0 -1
- package/dist/host-EPZCNFLH.mjs.map +0 -1
- package/dist/host-LKCMYEAV.mjs.map +0 -1
- package/dist/host-QS2EOTRJ.mjs.map +0 -1
- package/dist/host-ZIQ77W33.mjs.map +0 -1
- package/dist/render-SA4JTOW3.mjs +0 -8
- package/dist/serialize-JAVOU22E.mjs +0 -7
- package/dist/types-Crbefnfe.d.ts +0 -128
- package/dist/types-DxlMPh-6.d.mts +0 -49
- package/dist/types-DxlMPh-6.d.ts +0 -49
- package/dist/types-vtvyKGAA.d.mts +0 -128
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ export function ClassroomBoard() {
|
|
|
63
63
|
|
|
64
64
|
### AI dựng hình học 2D (opt-in)
|
|
65
65
|
|
|
66
|
-
Textarea AI chỉ xuất hiện khi truyền `generateGeometryFigure`. Callback
|
|
66
|
+
Textarea AI chỉ xuất hiện khi truyền `generateGeometryFigure`. Callback chạy từ client nên phải gọi server boundary của ứng dụng; không bao giờ đặt API key vào component / biến môi trường public.
|
|
67
67
|
|
|
68
68
|
```tsx
|
|
69
69
|
'use client';
|
|
@@ -85,29 +85,102 @@ export function ClassroomBoard() {
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
#### Provider backend (chọn 1)
|
|
89
|
+
|
|
90
|
+
Từ phiên bản hỗ trợ multi-provider, có 2 lựa chọn:
|
|
91
|
+
|
|
92
|
+
**A. Local Gemma 3 qua Ollama (mặc định, miễn phí, không cần API key)**
|
|
93
|
+
|
|
94
|
+
Setup máy chạy server:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# macOS
|
|
98
|
+
brew install ollama
|
|
99
|
+
ollama serve # chạy nền cổng 11434
|
|
100
|
+
|
|
101
|
+
# Chọn 1 trong 2 model:
|
|
102
|
+
ollama pull gemma3:4b # ~3.3GB Q4 — nhanh ~20s/đề, accuracy 75%
|
|
103
|
+
ollama pull gemma3:12b # ~8GB Q4 — chậm ~60s/đề, accuracy 92% (recommended cho production)
|
|
104
|
+
|
|
105
|
+
# Linux
|
|
106
|
+
curl -fsSL https://ollama.com/install.sh | sh
|
|
107
|
+
ollama serve &
|
|
108
|
+
ollama pull gemma3:12b
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Eval 12 đề THCS/lớp 10** (transpile success rate + dùng đúng primitive):
|
|
112
|
+
|
|
113
|
+
| Model | Transpile OK | Kind đúng | Refuse đúng | Avg latency |
|
|
114
|
+
|-----------|--------------|-----------|-------------|-------------|
|
|
115
|
+
| gemma3:4b | 75% | 63% | 0/1 | 20s |
|
|
116
|
+
| gemma3:12b | 92% | 88% | 1/1 | 62s |
|
|
117
|
+
| Claude Opus 4.7 | ~100% | ~100% | 1/1 | ~5s (cost ~$0.01/đề) |
|
|
118
|
+
|
|
119
|
+
Đề nghị: 12b cho production, 4b cho prototype/máy yếu, Anthropic cho accuracy tuyệt đối.
|
|
120
|
+
|
|
121
|
+
Server-side route Next.js:
|
|
89
122
|
|
|
90
123
|
```ts
|
|
91
124
|
import { generateFigure } from '@xom11/whiteboard/ai';
|
|
92
125
|
|
|
93
126
|
export async function POST(request: Request) {
|
|
94
127
|
const { problem } = await request.json();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
128
|
+
// Default: provider=ollama, model=gemma3:4b, baseUrl=http://localhost:11434
|
|
129
|
+
const result = await generateFigure(problem);
|
|
98
130
|
return Response.json(
|
|
99
|
-
result.ok
|
|
100
|
-
? { ok: true, state: result.state }
|
|
101
|
-
: { ok: false, message: result.message },
|
|
131
|
+
result.ok ? { ok: true, state: result.state } : { ok: false, message: result.message },
|
|
102
132
|
);
|
|
103
133
|
}
|
|
104
134
|
```
|
|
105
135
|
|
|
106
|
-
|
|
136
|
+
Env override (optional):
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
WHITEBOARD_AI_PROVIDER=ollama # default
|
|
140
|
+
OLLAMA_BASE_URL=http://localhost:11434 # default
|
|
141
|
+
OLLAMA_DEFAULT_MODEL=gemma3:12b # default gemma3:4b; recommend gemma3:12b cho production
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**B. Anthropic Claude (chính xác cao, tốn API cost)**
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { generateFigure } from '@xom11/whiteboard/ai';
|
|
148
|
+
|
|
149
|
+
const result = await generateFigure(problem, {
|
|
150
|
+
apiKey: process.env.ANTHROPIC_API_KEY ?? '',
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Hoặc qua env:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
WHITEBOARD_AI_PROVIDER=anthropic
|
|
158
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**C. Provider tuỳ biến** (vd OpenAI, OpenRouter, vLLM): implement interface `AIProvider`:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import { generateFigure, type AIProvider } from '@xom11/whiteboard/ai';
|
|
165
|
+
|
|
166
|
+
const customProvider: AIProvider = {
|
|
167
|
+
name: 'my-llm',
|
|
168
|
+
defaultModel: 'my-model',
|
|
169
|
+
async call(req) {
|
|
170
|
+
// req.systemPrompt, req.userPrompt, req.schema (JSON Schema cho envelope)
|
|
171
|
+
// ...
|
|
172
|
+
return { kind: 'json', data: envelopeObject };
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const result = await generateFigure(problem, { provider: customProvider });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### Smoke test local Ollama
|
|
107
180
|
|
|
108
181
|
```bash
|
|
109
|
-
|
|
110
|
-
|
|
182
|
+
brew install ollama && ollama serve & ollama pull gemma3:4b
|
|
183
|
+
OLLAMA_SMOKE=1 npx jest ollama.smoke
|
|
111
184
|
```
|
|
112
185
|
|
|
113
186
|
## Migration to v0.8.0 (geometry-3d redesign)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import './chunk-J5LGTIGS.mjs';
|
|
2
3
|
import { Excalidraw, MainMenu, Footer, WelcomeScreen } from '@excalidraw/excalidraw';
|
|
3
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
5
|
|
|
@@ -18,5 +19,5 @@ function ExcalidrawWithMenus(props) {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export { ExcalidrawWithMenus };
|
|
21
|
-
//# sourceMappingURL=ExcalidrawWithMenus-
|
|
22
|
-
//# sourceMappingURL=ExcalidrawWithMenus-
|
|
22
|
+
//# sourceMappingURL=ExcalidrawWithMenus-2QPPTXJM.mjs.map
|
|
23
|
+
//# sourceMappingURL=ExcalidrawWithMenus-2QPPTXJM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ExcalidrawWithMenus.tsx"],"names":[],"mappings":";;;;AAiBO,SAAS,oBAAoB,KAAA,EAAwB;AAC1D,EAAA,MAAM,EAAE,QAAA,EAAU,GAAG,IAAA,EAAK,GAAI,KAAA;AAC9B,EAAA,uBACE,IAAA,CAAC,UAAA,EAAA,EAAY,GAAG,IAAA,EAEd,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,SAAA,EAAtB,EAAgC,CAAA;AAAA,sBACjC,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,WAAA,EAAtB,EAAkC,CAAA;AAAA,sBACnC,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,WAAA,EAAtB,EAAkC,CAAA;AAAA,sBACnC,GAAA,CAAC,QAAA,CAAS,YAAA,CAAa,WAAA,EAAtB,EAAkC;AAAA,KAAA,EACrC,CAAA;AAAA,oBAEA,GAAA,CAAC,MAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EACR,CAAA;AAAA,oBAGA,GAAA,CAAC,aAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EACR,CAAA;AAAA,IACC;AAAA,GAAA,EACH,CAAA;AAEJ","file":"ExcalidrawWithMenus-2QPPTXJM.mjs","sourcesContent":["'use client';\n\n// Client-only wrapper around Excalidraw that lets us reach for static helpers\n// like `MainMenu.DefaultItems.*`. Whiteboard dynamic-imports this\n// file so SSR never evaluates @excalidraw/excalidraw, while inside this file we\n// can use plain static imports (the entire module loads on the client).\n\nimport React from 'react';\nimport {\n Excalidraw,\n MainMenu,\n Footer,\n WelcomeScreen,\n} from '@excalidraw/excalidraw';\n \ntype ExcalidrawProps = any;\n\nexport function ExcalidrawWithMenus(props: ExcalidrawProps) {\n const { children, ...rest } = props;\n return (\n <Excalidraw {...rest}>\n {/* Replace default menu with curated items — no socials/help/branding */}\n <MainMenu>\n <MainMenu.DefaultItems.LoadScene />\n <MainMenu.DefaultItems.SaveAsImage />\n <MainMenu.DefaultItems.ClearCanvas />\n <MainMenu.DefaultItems.ToggleTheme />\n </MainMenu>\n {/* Footer slot with no content suppresses default \"Made with Excalidraw\" link */}\n <Footer>\n <span />\n </Footer>\n {/* WelcomeScreen slot (empty) prevents the default Excalidraw welcome panel\n * (which includes the Excalidraw logo and social links) from appearing. */}\n <WelcomeScreen>\n <span />\n </WelcomeScreen>\n {children}\n </Excalidraw>\n );\n}\n"]}
|