@xom11/whiteboard 0.24.1 → 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.
- package/README.md +85 -12
- package/dist/ai.d.mts +472 -0
- package/dist/ai.d.ts +472 -0
- package/dist/ai.js +2156 -0
- package/dist/ai.js.map +1 -0
- package/dist/ai.mjs +1495 -0
- package/dist/ai.mjs.map +1 -0
- package/dist/catalog.json +4 -4
- package/dist/chunk-73Q7ADVL.mjs +35 -0
- package/dist/chunk-73Q7ADVL.mjs.map +1 -0
- package/dist/{chunk-BKSXPNPQ.mjs → chunk-AYSFWUPK.mjs} +4 -3
- package/dist/chunk-AYSFWUPK.mjs.map +1 -0
- package/dist/chunk-B4NJJZFR.mjs +18 -0
- package/dist/chunk-B4NJJZFR.mjs.map +1 -0
- package/dist/{chunk-LVNCYP4J.mjs → chunk-CJBLJUWG.mjs} +5 -5
- package/dist/{chunk-LVNCYP4J.mjs.map → chunk-CJBLJUWG.mjs.map} +1 -1
- package/dist/{chunk-YIPI3WUL.mjs → chunk-ESVPQWHX.mjs} +5 -5
- package/dist/{chunk-YIPI3WUL.mjs.map → chunk-ESVPQWHX.mjs.map} +1 -1
- package/dist/{chunk-IBTRMWD6.mjs → chunk-I24QOHPU.mjs} +3 -3
- package/dist/{chunk-IBTRMWD6.mjs.map → chunk-I24QOHPU.mjs.map} +1 -1
- package/dist/{chunk-ZBJBQKJ2.mjs → chunk-IHUFOV7L.mjs} +4 -19
- package/dist/chunk-IHUFOV7L.mjs.map +1 -0
- package/dist/{chunk-AZIARTGX.mjs → chunk-M42TGYT6.mjs} +3 -3
- package/dist/{chunk-AZIARTGX.mjs.map → chunk-M42TGYT6.mjs.map} +1 -1
- package/dist/{chunk-WWMQ2VHZ.mjs → chunk-NDEZJKNY.mjs} +4 -4
- package/dist/{chunk-WWMQ2VHZ.mjs.map → chunk-NDEZJKNY.mjs.map} +1 -1
- package/dist/{chunk-CSCF3YFZ.mjs → chunk-ONBCUWVI.mjs} +6 -4
- package/dist/chunk-ONBCUWVI.mjs.map +1 -0
- package/dist/{chunk-6V4SH4JJ.mjs → chunk-REIJZDVZ.mjs} +6 -35
- package/dist/chunk-REIJZDVZ.mjs.map +1 -0
- package/dist/{chunk-4D5CSIJO.mjs → chunk-TB4CL25L.mjs} +10 -8
- package/dist/chunk-TB4CL25L.mjs.map +1 -0
- package/dist/chunk-VNCCIV6O.mjs +938 -0
- package/dist/chunk-VNCCIV6O.mjs.map +1 -0
- package/dist/{chunk-MFOGFFIL.mjs → chunk-VRHWDZ66.mjs} +6 -5
- package/dist/chunk-VRHWDZ66.mjs.map +1 -0
- package/dist/{chunk-CRAPWQKJ.mjs → chunk-YSJOVBCD.mjs} +4 -4
- package/dist/{chunk-CRAPWQKJ.mjs.map → chunk-YSJOVBCD.mjs.map} +1 -1
- package/dist/geometry-2d.d.mts +2 -1
- package/dist/geometry-2d.d.ts +2 -1
- package/dist/geometry-2d.js +1383 -23
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +7 -5
- package/dist/geometry-3d.d.mts +2 -1
- package/dist/geometry-3d.d.ts +2 -1
- package/dist/geometry-3d.js +2 -2
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +6 -4
- package/dist/graph-2d.d.mts +2 -1
- package/dist/graph-2d.d.ts +2 -1
- package/dist/graph-2d.js +2 -2
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +9 -7
- package/dist/{host-TLIXN4CF.mjs → host-A64ITWVX.mjs} +8 -6
- package/dist/host-A64ITWVX.mjs.map +1 -0
- package/dist/{host-DOAYVL35.mjs → host-L7FMFZUW.mjs} +228 -30
- package/dist/host-L7FMFZUW.mjs.map +1 -0
- package/dist/{host-GKNQBBUE.mjs → host-QK53UYMD.mjs} +12 -10
- package/dist/host-QK53UYMD.mjs.map +1 -0
- package/dist/index.d.mts +4 -616
- package/dist/index.d.ts +4 -616
- package/dist/index.js +8889 -8529
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -1012
- package/dist/index.mjs.map +1 -1
- package/dist/latex.d.mts +2 -1
- package/dist/latex.d.ts +2 -1
- package/dist/render-3WTY7NZB.mjs +9 -0
- package/dist/{render-SA4JTOW3.mjs.map → render-3WTY7NZB.mjs.map} +1 -1
- package/dist/serialize-SRJVKYUG.mjs +8 -0
- package/dist/{serialize-3NZS6A6Q.mjs.map → serialize-SRJVKYUG.mjs.map} +1 -1
- package/dist/{types-rA4slL08.d.ts → types-DWRyCa2m.d.mts} +139 -1
- package/dist/{types-rA4slL08.d.mts → types-DWRyCa2m.d.ts} +139 -1
- package/package.json +6 -1
- package/dist/chunk-4D5CSIJO.mjs.map +0 -1
- package/dist/chunk-6V4SH4JJ.mjs.map +0 -1
- package/dist/chunk-BKSXPNPQ.mjs.map +0 -1
- package/dist/chunk-CSCF3YFZ.mjs.map +0 -1
- package/dist/chunk-MFOGFFIL.mjs.map +0 -1
- package/dist/chunk-ZBJBQKJ2.mjs.map +0 -1
- package/dist/host-DOAYVL35.mjs.map +0 -1
- package/dist/host-GKNQBBUE.mjs.map +0 -1
- package/dist/host-TLIXN4CF.mjs.map +0 -1
- package/dist/render-SA4JTOW3.mjs +0 -8
- package/dist/serialize-3NZS6A6Q.mjs +0 -6
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
|
-
import { generateFigure } from '@xom11/whiteboard';
|
|
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)
|
package/dist/ai.d.mts
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { b as State, D as DslInputT, a as AiFigureUiResult } from './types-DWRyCa2m.mjs';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import 'react';
|
|
4
|
+
import '@excalidraw/excalidraw/element/types';
|
|
5
|
+
|
|
6
|
+
type TranspileErrorCode = 'SCHEMA' | 'DUPLICATE_NAME' | 'UNKNOWN_REF' | 'KIND_MISMATCH' | 'CYCLE';
|
|
7
|
+
interface TranspileError {
|
|
8
|
+
code: TranspileErrorCode;
|
|
9
|
+
message: string;
|
|
10
|
+
path?: string[];
|
|
11
|
+
hint?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
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 {
|
|
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. */
|
|
102
|
+
model?: string;
|
|
103
|
+
maxTokens?: number;
|
|
104
|
+
signal?: AbortSignal;
|
|
105
|
+
}
|
|
106
|
+
interface TokenUsage$1 {
|
|
107
|
+
inputTokens: number;
|
|
108
|
+
outputTokens: number;
|
|
109
|
+
cacheReadTokens: number;
|
|
110
|
+
cacheCreationTokens: number;
|
|
111
|
+
}
|
|
112
|
+
type GenerateResult = {
|
|
113
|
+
ok: true;
|
|
114
|
+
state: State;
|
|
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';
|
|
308
|
+
usage: TokenUsage;
|
|
309
|
+
provider: string;
|
|
310
|
+
} | {
|
|
311
|
+
ok: false;
|
|
312
|
+
reason: 'refused';
|
|
313
|
+
message: string;
|
|
314
|
+
usage?: TokenUsage;
|
|
315
|
+
provider?: string;
|
|
316
|
+
} | {
|
|
317
|
+
ok: false;
|
|
318
|
+
reason: 'parse_error';
|
|
319
|
+
message: string;
|
|
320
|
+
raw?: unknown;
|
|
321
|
+
usage?: TokenUsage;
|
|
322
|
+
provider?: string;
|
|
323
|
+
} | {
|
|
324
|
+
ok: false;
|
|
325
|
+
reason: 'transpile_error';
|
|
326
|
+
message: string;
|
|
327
|
+
errors: TranspileError[];
|
|
328
|
+
dsl: unknown;
|
|
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;
|
|
349
|
+
} | {
|
|
350
|
+
ok: false;
|
|
351
|
+
reason: 'api_error';
|
|
352
|
+
message: string;
|
|
353
|
+
status?: number;
|
|
354
|
+
provider?: string;
|
|
355
|
+
};
|
|
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>;
|
|
471
|
+
|
|
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 };
|