@kubuild/ai 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-27AY2KBI.js → chunk-3DRAVYU3.js} +173 -46
- package/dist/chunk-3DRAVYU3.js.map +1 -0
- package/dist/chunk-ILLNRABB.js +24 -0
- package/dist/chunk-ILLNRABB.js.map +1 -0
- package/dist/{chunk-JY4NHD3Q.js → chunk-K7CBTQCY.js} +91 -1
- package/dist/chunk-K7CBTQCY.js.map +1 -0
- package/dist/{chunk-UH24LHRY.js → chunk-YETTTWHI.js} +226 -1
- package/dist/chunk-YETTTWHI.js.map +1 -0
- package/dist/client/ai-client.d.ts +27 -1
- package/dist/client/ai-client.d.ts.map +1 -1
- package/dist/client/index.cjs +90 -0
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/core/document-outline.d.ts +60 -0
- package/dist/core/document-outline.d.ts.map +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/messages.d.ts +18 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/prompt-compiler.d.ts +29 -0
- package/dist/core/prompt-compiler.d.ts.map +1 -1
- package/dist/index.cjs +261 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +31 -3
- package/dist/react/index.cjs +233 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +143 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/use-ai-agent.d.ts +47 -0
- package/dist/react/use-ai-agent.d.ts.map +1 -0
- package/dist/react/use-ai-generator.d.ts +2 -1
- package/dist/react/use-ai-generator.d.ts.map +1 -1
- package/dist/server/adapters/anthropic.d.ts.map +1 -1
- package/dist/server/adapters/custom.d.ts.map +1 -1
- package/dist/server/adapters/gemini.d.ts.map +1 -1
- package/dist/server/adapters/index.cjs +180 -45
- package/dist/server/adapters/index.cjs.map +1 -1
- package/dist/server/adapters/index.js +2 -1
- package/dist/server/adapters/openai.d.ts +25 -0
- package/dist/server/adapters/openai.d.ts.map +1 -1
- package/dist/server/agent.d.ts +59 -0
- package/dist/server/agent.d.ts.map +1 -0
- package/dist/server/engine.d.ts +5 -1
- package/dist/server/engine.d.ts.map +1 -1
- package/dist/server/handler.d.ts +18 -2
- package/dist/server/handler.d.ts.map +1 -1
- package/dist/server/index.cjs +1843 -258
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1379 -133
- package/dist/server/index.js.map +1 -1
- package/dist/server/tools/helpers.d.ts +66 -0
- package/dist/server/tools/helpers.d.ts.map +1 -0
- package/dist/server/tools/index.d.ts +25 -0
- package/dist/server/tools/index.d.ts.map +1 -0
- package/dist/server/tools/read-tools.d.ts +3 -0
- package/dist/server/tools/read-tools.d.ts.map +1 -0
- package/dist/server/tools/types.d.ts +51 -0
- package/dist/server/tools/types.d.ts.map +1 -0
- package/dist/server/tools/write-tools.d.ts +3 -0
- package/dist/server/tools/write-tools.d.ts.map +1 -0
- package/dist/types.d.ts +224 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-27AY2KBI.js.map +0 -1
- package/dist/chunk-JY4NHD3Q.js.map +0 -1
- package/dist/chunk-UH24LHRY.js.map +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Node, PageDocument } from '@kubuild/schema';
|
|
2
|
+
import type { DocumentSecurityLimits } from '@kubuild/core';
|
|
3
|
+
import type { AgentOp, AiCompiledComponentSpec, AiToolDefinition } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Everything a tool needs to answer or mutate (STORA-530).
|
|
6
|
+
*
|
|
7
|
+
* `document` is the agent's private **snapshot** — never the user's live canvas document.
|
|
8
|
+
* Write tools return an updated snapshot plus an `AgentOp`; the real document is only
|
|
9
|
+
* touched later, on the client, when the user applies the run.
|
|
10
|
+
*/
|
|
11
|
+
export interface ToolExecutionContext {
|
|
12
|
+
document: PageDocument;
|
|
13
|
+
catalog: AiCompiledComponentSpec[];
|
|
14
|
+
securityLimits?: DocumentSecurityLimits;
|
|
15
|
+
/**
|
|
16
|
+
* Delegate used by `insert_section` to synthesize a section node — wired to
|
|
17
|
+
* `KubuildAiEngine.generateSection` so section generation keeps going through the
|
|
18
|
+
* existing plan/normalize/validate path rather than a second implementation.
|
|
19
|
+
*/
|
|
20
|
+
generateSection?: (params: {
|
|
21
|
+
prompt: string;
|
|
22
|
+
parentContext?: string;
|
|
23
|
+
}) => Promise<Node>;
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
}
|
|
26
|
+
export interface ToolExecutionResult {
|
|
27
|
+
ok: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Payload handed back to the model as a `tool_result` block. Always a JSON string, so
|
|
30
|
+
* the model sees a uniform shape whether the call succeeded or failed.
|
|
31
|
+
*/
|
|
32
|
+
content: unknown;
|
|
33
|
+
/** One-line description for the run timeline / op review UI. */
|
|
34
|
+
summary: string;
|
|
35
|
+
/** Present on a successful write — the patch the client will replay. */
|
|
36
|
+
op?: AgentOp;
|
|
37
|
+
/** Present on a successful write — the snapshot later steps reason about. */
|
|
38
|
+
document?: PageDocument;
|
|
39
|
+
}
|
|
40
|
+
export interface AgentTool {
|
|
41
|
+
definition: AiToolDefinition;
|
|
42
|
+
/** Read tools never produce ops; write tools always do (when they succeed). */
|
|
43
|
+
kind: 'read' | 'write';
|
|
44
|
+
/**
|
|
45
|
+
* True for tools that can destroy user content. The editor refuses to auto-apply these
|
|
46
|
+
* even when the user has auto-apply turned on.
|
|
47
|
+
*/
|
|
48
|
+
destructive?: boolean;
|
|
49
|
+
execute(input: Record<string, unknown>, context: ToolExecutionContext): Promise<ToolExecutionResult> | ToolExecutionResult;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/server/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtF;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CACL,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/write-tools.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAA6C,MAAM,SAAS,CAAC;AAslBpF,eAAO,MAAM,WAAW,EAAE,SAAS,EASlC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
import type { Node, PageDocument, DocumentMetadata } from '@kubuild/schema';
|
|
2
2
|
import type { DocumentSecurityLimits } from '@kubuild/core';
|
|
3
|
-
export type AiGenerationMode = 'full-page' | 'section' | 'refactor' | 'chat';
|
|
3
|
+
export type AiGenerationMode = 'full-page' | 'section' | 'refactor' | 'chat' | 'agent' | 'plan';
|
|
4
|
+
/** Plain text content block. */
|
|
5
|
+
export interface AiTextBlock {
|
|
6
|
+
type: 'text';
|
|
7
|
+
text: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A tool invocation requested by the model (STORA-530). Provider-agnostic shape: the
|
|
11
|
+
* OpenAI adapter maps this to `assistant.tool_calls`, Anthropic to a `tool_use` block.
|
|
12
|
+
*/
|
|
13
|
+
export interface AiToolUseBlock {
|
|
14
|
+
type: 'tool_use';
|
|
15
|
+
/** Provider-issued call id — echoed back on the matching `tool_result`. */
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
input: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** The host's answer to an `AiToolUseBlock`, fed back into the next model turn. */
|
|
21
|
+
export interface AiToolResultBlock {
|
|
22
|
+
type: 'tool_result';
|
|
23
|
+
/** Must match the `id` of the `tool_use` block being answered. */
|
|
24
|
+
toolUseId: string;
|
|
25
|
+
/** Serialized result payload (JSON string for structured results). */
|
|
26
|
+
content: string;
|
|
27
|
+
/** True when the tool failed — the model is expected to self-correct and retry. */
|
|
28
|
+
isError?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export type AiContentBlock = AiTextBlock | AiToolUseBlock | AiToolResultBlock;
|
|
4
31
|
export interface AiChatMessage {
|
|
5
32
|
role: 'user' | 'assistant' | 'system';
|
|
6
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Either a plain string (every pre-STORA-530 call site) or a list of content blocks
|
|
35
|
+
* carrying tool calls/results. Adapters that don't support tool calling only ever see
|
|
36
|
+
* the string form, since `tools` is never passed to them.
|
|
37
|
+
*/
|
|
38
|
+
content: string | AiContentBlock[];
|
|
7
39
|
timestamp?: number;
|
|
8
40
|
}
|
|
9
41
|
export interface AiChatRequest {
|
|
@@ -15,6 +47,28 @@ export interface AiChatRequest {
|
|
|
15
47
|
export interface AiChatResponse {
|
|
16
48
|
message: AiChatMessage;
|
|
17
49
|
}
|
|
50
|
+
export interface PlannedSection {
|
|
51
|
+
type: string;
|
|
52
|
+
title: string;
|
|
53
|
+
prompt: string;
|
|
54
|
+
}
|
|
55
|
+
export interface PagePlan {
|
|
56
|
+
title?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
pageStyles?: Node['styles'];
|
|
59
|
+
sections?: PlannedSection[];
|
|
60
|
+
}
|
|
61
|
+
export interface AiPlanPageRequest {
|
|
62
|
+
prompt: string;
|
|
63
|
+
stylePreference?: string;
|
|
64
|
+
tone?: string;
|
|
65
|
+
locale?: string;
|
|
66
|
+
sectionCount?: number | {
|
|
67
|
+
min?: number;
|
|
68
|
+
max?: number;
|
|
69
|
+
};
|
|
70
|
+
conversationHistory?: AiChatMessage[];
|
|
71
|
+
}
|
|
18
72
|
export interface AiGeneratePageRequest {
|
|
19
73
|
prompt: string;
|
|
20
74
|
stylePreference?: string;
|
|
@@ -22,6 +76,15 @@ export interface AiGeneratePageRequest {
|
|
|
22
76
|
locale?: string;
|
|
23
77
|
metadata?: Partial<DocumentMetadata>;
|
|
24
78
|
stream?: boolean;
|
|
79
|
+
/** Prior conversation history from chat mode so generator keeps full context. */
|
|
80
|
+
conversationHistory?: AiChatMessage[];
|
|
81
|
+
/** Desired number of sections or range. */
|
|
82
|
+
sectionCount?: number | {
|
|
83
|
+
min?: number;
|
|
84
|
+
max?: number;
|
|
85
|
+
};
|
|
86
|
+
/** Pre-confirmed plan to generate directly without re-planning. */
|
|
87
|
+
plan?: PagePlan;
|
|
25
88
|
}
|
|
26
89
|
export interface AiGenerateSectionRequest {
|
|
27
90
|
prompt: string;
|
|
@@ -65,6 +128,32 @@ export type AiStreamEvent = {
|
|
|
65
128
|
| {
|
|
66
129
|
type: 'chat-complete';
|
|
67
130
|
message: AiChatMessage;
|
|
131
|
+
}
|
|
132
|
+
/** Agent mode (STORA-530): a new reasoning step has begun. */
|
|
133
|
+
| {
|
|
134
|
+
type: 'agent-step';
|
|
135
|
+
step: number;
|
|
136
|
+
maxSteps: number;
|
|
137
|
+
}
|
|
138
|
+
/** Agent mode: the model asked to run a tool. */
|
|
139
|
+
| {
|
|
140
|
+
type: 'tool-call';
|
|
141
|
+
id: string;
|
|
142
|
+
name: string;
|
|
143
|
+
input: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
/** Agent mode: the tool finished (or failed — the model then self-corrects). */
|
|
146
|
+
| {
|
|
147
|
+
type: 'tool-result';
|
|
148
|
+
id: string;
|
|
149
|
+
name: string;
|
|
150
|
+
ok: boolean;
|
|
151
|
+
summary: string;
|
|
152
|
+
}
|
|
153
|
+
/** Agent mode terminal event: the patch the client replays through the store. */
|
|
154
|
+
| {
|
|
155
|
+
type: 'agent-complete';
|
|
156
|
+
result: AiAgentRunResult;
|
|
68
157
|
} | {
|
|
69
158
|
type: 'error';
|
|
70
159
|
error: {
|
|
@@ -81,6 +170,20 @@ export interface AiStreamCallbacks {
|
|
|
81
170
|
onChatChunk?: (delta: string, content: string) => void;
|
|
82
171
|
/** Fired once, when a streaming chat response has finished assembling. */
|
|
83
172
|
onChatComplete?: (message: AiChatMessage) => void;
|
|
173
|
+
/** Agent mode (STORA-530). */
|
|
174
|
+
onAgentStep?: (step: number, maxSteps: number) => void;
|
|
175
|
+
onToolCall?: (call: {
|
|
176
|
+
id: string;
|
|
177
|
+
name: string;
|
|
178
|
+
input: Record<string, unknown>;
|
|
179
|
+
}) => void;
|
|
180
|
+
onToolResult?: (result: {
|
|
181
|
+
id: string;
|
|
182
|
+
name: string;
|
|
183
|
+
ok: boolean;
|
|
184
|
+
summary: string;
|
|
185
|
+
}) => void;
|
|
186
|
+
onAgentComplete?: (result: AiAgentRunResult) => void;
|
|
84
187
|
onError?: (error: Error) => void;
|
|
85
188
|
}
|
|
86
189
|
export interface AiErrorDetail {
|
|
@@ -116,22 +219,59 @@ export interface AiCompiledComponentSpec {
|
|
|
116
219
|
defaultProps?: Record<string, unknown>;
|
|
117
220
|
props?: AiCompiledComponentProp[];
|
|
118
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* A tool the model may call (STORA-530). `inputSchema` is a JSON Schema object describing
|
|
224
|
+
* the tool's arguments — passed through verbatim to the provider (OpenAI
|
|
225
|
+
* `function.parameters`, Anthropic `input_schema`, Gemini `parameters`).
|
|
226
|
+
*/
|
|
227
|
+
export interface AiToolDefinition {
|
|
228
|
+
name: string;
|
|
229
|
+
description: string;
|
|
230
|
+
inputSchema: Record<string, unknown>;
|
|
231
|
+
}
|
|
232
|
+
export type AiToolChoice = 'auto' | 'none' | 'required' | {
|
|
233
|
+
name: string;
|
|
234
|
+
};
|
|
119
235
|
export interface AiProviderGenerateParams {
|
|
120
236
|
systemPrompt: string;
|
|
121
237
|
userPrompt: string;
|
|
122
238
|
messages?: AiChatMessage[];
|
|
123
239
|
jsonSchema?: Record<string, unknown>;
|
|
124
240
|
signal?: AbortSignal;
|
|
241
|
+
/**
|
|
242
|
+
* Tools the model may call this turn. Adapters that don't implement tool calling ignore
|
|
243
|
+
* this field entirely, so passing it can never break an older adapter — but the agent
|
|
244
|
+
* loop refuses to run against such an adapter (see `KubuildAiAgent`).
|
|
245
|
+
*/
|
|
246
|
+
tools?: AiToolDefinition[];
|
|
247
|
+
toolChoice?: AiToolChoice;
|
|
248
|
+
/** Overrides the adapter's configured sampling temperature for this call. */
|
|
249
|
+
temperature?: number;
|
|
125
250
|
}
|
|
251
|
+
/** Why the model stopped generating — drives the agent loop's continue/stop decision. */
|
|
252
|
+
export type AiStopReason = 'stop' | 'tool_calls' | 'length' | 'content_filter' | 'unknown';
|
|
126
253
|
export interface AiProviderGenerateResult {
|
|
127
254
|
text: string;
|
|
128
255
|
usage?: {
|
|
129
256
|
promptTokens?: number;
|
|
130
257
|
completionTokens?: number;
|
|
131
258
|
};
|
|
259
|
+
/**
|
|
260
|
+
* Tool invocations requested by the model. Non-empty only when `params.tools` was given
|
|
261
|
+
* and the adapter supports tool calling.
|
|
262
|
+
*/
|
|
263
|
+
toolCalls?: AiToolUseBlock[];
|
|
264
|
+
stopReason?: AiStopReason;
|
|
132
265
|
}
|
|
133
266
|
export interface AiProviderAdapter {
|
|
134
267
|
readonly name: string;
|
|
268
|
+
/**
|
|
269
|
+
* Whether this adapter forwards `params.tools` to its provider and parses tool calls
|
|
270
|
+
* back out (STORA-530). Adapters predating tool calling simply omit it, which reads as
|
|
271
|
+
* `false` — `KubuildAiAgent` refuses to start rather than silently running a tool-less
|
|
272
|
+
* loop that can never edit anything.
|
|
273
|
+
*/
|
|
274
|
+
readonly supportsTools?: boolean;
|
|
135
275
|
generate(params: AiProviderGenerateParams): Promise<AiProviderGenerateResult>;
|
|
136
276
|
/**
|
|
137
277
|
* Optional token-level streaming variant (STORA-515). Adapters whose provider API
|
|
@@ -178,7 +318,89 @@ export interface KubuildAiEngineOptions {
|
|
|
178
318
|
adapter: AiProviderAdapter;
|
|
179
319
|
securityLimits?: DocumentSecurityLimits;
|
|
180
320
|
systemPromptPrefix?: string;
|
|
321
|
+
/** Agent loop step ceiling (STORA-530). Default: 8. */
|
|
322
|
+
maxAgentSteps?: number;
|
|
181
323
|
debug?: boolean;
|
|
182
324
|
logger?: (level: 'info' | 'warn' | 'error' | 'debug', message: string, meta?: unknown) => void;
|
|
183
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* A single, surgical document mutation produced by an agent tool call. Deliberately
|
|
328
|
+
* mirrors the editor store's existing action surface (`updateNodeProps`,
|
|
329
|
+
* `updateNodeStyle`, `insertComponent`, `moveComponent`, `deleteComponent`,
|
|
330
|
+
* `duplicateComponent`, `replaceNodeSubtree`) so the client can replay a whole run
|
|
331
|
+
* through the exact same code path manual editing uses — and therefore inherit
|
|
332
|
+
* `DocumentHistoryManager` undo for free.
|
|
333
|
+
*
|
|
334
|
+
* The agent never returns a whole regenerated document; it returns a list of these.
|
|
335
|
+
*/
|
|
336
|
+
export type AgentOp = {
|
|
337
|
+
kind: 'update-props';
|
|
338
|
+
nodeId: string;
|
|
339
|
+
props: Record<string, unknown>;
|
|
340
|
+
merge: boolean;
|
|
341
|
+
} | {
|
|
342
|
+
kind: 'update-styles';
|
|
343
|
+
nodeId: string;
|
|
344
|
+
styles: Record<string, unknown>;
|
|
345
|
+
/** Set for a breakpoint layer write. Mutually exclusive with `state`. */
|
|
346
|
+
breakpoint?: 'base' | 'desktop' | 'tablet' | 'mobile';
|
|
347
|
+
/** Set for a pseudo-state layer write (e.g. ':hover'). Mutually exclusive with `breakpoint`. */
|
|
348
|
+
state?: string;
|
|
349
|
+
merge: boolean;
|
|
350
|
+
} | {
|
|
351
|
+
kind: 'insert-node';
|
|
352
|
+
parentId: string;
|
|
353
|
+
index?: number;
|
|
354
|
+
node: Node;
|
|
355
|
+
} | {
|
|
356
|
+
kind: 'move-node';
|
|
357
|
+
nodeId: string;
|
|
358
|
+
targetParentId: string;
|
|
359
|
+
index?: number;
|
|
360
|
+
} | {
|
|
361
|
+
kind: 'delete-node';
|
|
362
|
+
nodeId: string;
|
|
363
|
+
} | {
|
|
364
|
+
kind: 'duplicate-node';
|
|
365
|
+
nodeId: string;
|
|
366
|
+
targetParentId?: string;
|
|
367
|
+
index?: number;
|
|
368
|
+
} | {
|
|
369
|
+
kind: 'replace-node';
|
|
370
|
+
nodeId: string;
|
|
371
|
+
node: Node;
|
|
372
|
+
};
|
|
373
|
+
/** An `AgentOp` plus the metadata the review UI needs before the user hits Apply. */
|
|
374
|
+
export interface AgentOpRecord {
|
|
375
|
+
id: string;
|
|
376
|
+
op: AgentOp;
|
|
377
|
+
/** Human-readable one-liner, e.g. `Ubah props tombol "cta-btn"`. */
|
|
378
|
+
summary: string;
|
|
379
|
+
/**
|
|
380
|
+
* True for ops that can destroy user content (`delete-node`, `replace-node`). The
|
|
381
|
+
* editor never auto-applies these, even with auto-apply turned on.
|
|
382
|
+
*/
|
|
383
|
+
destructive: boolean;
|
|
384
|
+
}
|
|
385
|
+
export interface AiAgentRequest {
|
|
386
|
+
messages: AiChatMessage[];
|
|
387
|
+
/** The canvas document the agent reasons about and mutates a snapshot of. */
|
|
388
|
+
document: PageDocument;
|
|
389
|
+
selectedNodeId?: string;
|
|
390
|
+
systemPrompt?: string;
|
|
391
|
+
stylePreference?: string;
|
|
392
|
+
/** Overrides the engine's configured step ceiling for this run. */
|
|
393
|
+
maxSteps?: number;
|
|
394
|
+
}
|
|
395
|
+
export interface AiAgentRunResult {
|
|
396
|
+
ops: AgentOpRecord[];
|
|
397
|
+
/** The agent's closing natural-language message. */
|
|
398
|
+
summary: string;
|
|
399
|
+
stepsUsed: number;
|
|
400
|
+
stoppedBy: 'complete' | 'max-steps' | 'aborted' | 'error';
|
|
401
|
+
usage?: {
|
|
402
|
+
promptTokens?: number;
|
|
403
|
+
completionTokens?: number;
|
|
404
|
+
};
|
|
405
|
+
}
|
|
184
406
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubuild/ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Component-aware AI generation engine and adapters for KUBUILD",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -58,12 +58,12 @@
|
|
|
58
58
|
"author": "KUBUILD",
|
|
59
59
|
"license": "MIT",
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@kubuild/
|
|
62
|
-
"@kubuild/
|
|
61
|
+
"@kubuild/schema": "0.5.0",
|
|
62
|
+
"@kubuild/core": "0.5.0"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"react": "^18.0.0 || ^19.0.0",
|
|
66
|
-
"@kubuild/components": "0.
|
|
66
|
+
"@kubuild/components": "0.5.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependenciesMeta": {
|
|
69
69
|
"@kubuild/components": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"tsup": "^8.3.6",
|
|
83
83
|
"typescript": "^6.0.0",
|
|
84
84
|
"vitest": "^3.0.5",
|
|
85
|
-
"@kubuild/components": "0.
|
|
85
|
+
"@kubuild/components": "0.5.0"
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"build": "tsup && tsc --emitDeclarationOnly",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/adapters/stream-utils.ts","../src/server/adapters/gemini.ts","../src/server/adapters/openai.ts","../src/server/adapters/anthropic.ts","../src/server/adapters/custom.ts"],"sourcesContent":["/**\n * Shared SSE (server-sent events) frame reader for provider adapters that support\n * token-level streaming (STORA-515) — OpenAI, Anthropic and Gemini all expose their\n * streaming APIs as `data: <json>\\n\\n` frames, so every adapter reuses this single\n * low-level reader instead of re-implementing buffering/decoding three times.\n *\n * Yields the raw string payload of each `data:` line (already trimmed), in arrival\n * order. Callers are responsible for `JSON.parse`-ing (or ignoring sentinel values\n * like OpenAI's `[DONE]`) and for interpreting provider-specific event shapes.\n */\nexport async function* readSseDataLines(\n body: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): AsyncGenerator<string, void, void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n if (signal?.aborted) {\n throw new Error('Streaming aborted by client');\n }\n\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const frames = buffer.split('\\n\\n');\n buffer = frames.pop() || '';\n\n for (const frame of frames) {\n for (const line of frame.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('data:')) {\n yield trimmed.slice(5).trim();\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import type {\n AiProviderAdapter,\n AiProviderGenerateParams,\n AiProviderGenerateResult,\n} from '../../types';\nimport { readSseDataLines } from './stream-utils';\n\nexport interface GeminiAdapterOptions {\n apiKey: string;\n model?: string;\n temperature?: number;\n baseUrl?: string;\n}\n\nexport class GeminiAdapter implements AiProviderAdapter {\n readonly name = 'gemini';\n private apiKey: string;\n private model: string;\n private temperature: number;\n private baseUrl: string;\n\n constructor(options: GeminiAdapterOptions) {\n if (!options.apiKey) {\n throw new Error('GeminiAdapter requires an apiKey');\n }\n this.apiKey = options.apiKey;\n this.model = options.model || 'gemini-2.5-flash';\n this.temperature = options.temperature ?? 0.4;\n this.baseUrl =\n options.baseUrl || 'https://generativelanguage.googleapis.com/v1beta';\n }\n\n private buildContents(\n params: AiProviderGenerateParams,\n ): Array<{ role: string; parts: Array<{ text: string }> }> {\n const { userPrompt, messages: chatMessages } = params;\n return chatMessages && chatMessages.length > 0\n ? chatMessages.map((m) => ({\n role: m.role === 'assistant' ? 'model' : 'user',\n parts: [{ text: m.content }],\n }))\n : [\n {\n role: 'user',\n parts: [{ text: userPrompt }],\n },\n ];\n }\n\n async generate(params: AiProviderGenerateParams): Promise<AiProviderGenerateResult> {\n const { systemPrompt, messages: chatMessages, signal } = params;\n\n const url = `${this.baseUrl}/models/${encodeURIComponent(this.model)}:generateContent?key=${encodeURIComponent(this.apiKey)}`;\n const contents = this.buildContents(params);\n\n const generationConfig: Record<string, unknown> = {\n temperature: this.temperature,\n };\n\n if (params.jsonSchema || (!chatMessages && (systemPrompt.includes('JSON') || systemPrompt.includes('json')))) {\n generationConfig.responseMimeType = 'application/json';\n }\n\n const body: Record<string, unknown> = {\n system_instruction: {\n parts: [{ text: systemPrompt }],\n },\n contents,\n generationConfig,\n };\n\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `Gemini API error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n const data = (await res.json()) as {\n candidates?: Array<{\n content?: {\n parts?: Array<{ text?: string }>;\n };\n }>;\n usageMetadata?: {\n promptTokenCount?: number;\n candidatesTokenCount?: number;\n };\n };\n\n const candidateText = data.candidates?.[0]?.content?.parts?.[0]?.text;\n if (!candidateText) {\n throw new Error('Gemini returned an empty or invalid candidate response');\n }\n\n return {\n text: candidateText,\n usage: data.usageMetadata\n ? {\n promptTokens: data.usageMetadata.promptTokenCount,\n completionTokens: data.usageMetadata.candidatesTokenCount,\n }\n : undefined,\n };\n }\n\n /**\n * Token-level streaming via Gemini's `streamGenerateContent` SSE endpoint (STORA-515).\n */\n async *generateStream(\n params: AiProviderGenerateParams,\n ): AsyncGenerator<string, AiProviderGenerateResult, void> {\n const { systemPrompt, signal } = params;\n const url = `${this.baseUrl}/models/${encodeURIComponent(this.model)}:streamGenerateContent?alt=sse&key=${encodeURIComponent(this.apiKey)}`;\n const contents = this.buildContents(params);\n\n const generationConfig: Record<string, unknown> = {\n temperature: this.temperature,\n };\n\n const body: Record<string, unknown> = {\n system_instruction: {\n parts: [{ text: systemPrompt }],\n },\n contents,\n generationConfig,\n };\n\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `Gemini API error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n if (!res.body) {\n throw new Error('Gemini streaming response has no readable body');\n }\n\n let text = '';\n let usage: AiProviderGenerateResult['usage'];\n\n for await (const raw of readSseDataLines(res.body, signal)) {\n let parsed: {\n candidates?: Array<{ content?: { parts?: Array<{ text?: string }> } }>;\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n };\n try {\n parsed = JSON.parse(raw);\n } catch {\n continue;\n }\n\n const delta = parsed.candidates?.[0]?.content?.parts?.[0]?.text;\n if (typeof delta === 'string' && delta.length > 0) {\n text += delta;\n yield delta;\n }\n\n if (parsed.usageMetadata) {\n usage = {\n promptTokens: parsed.usageMetadata.promptTokenCount,\n completionTokens: parsed.usageMetadata.candidatesTokenCount,\n };\n }\n }\n\n return { text, usage };\n }\n}\n","import type {\n AiProviderAdapter,\n AiProviderGenerateParams,\n AiProviderGenerateResult,\n} from '../../types';\nimport { readSseDataLines } from './stream-utils';\n\nexport interface OpenAiAdapterOptions {\n apiKey: string;\n model?: string;\n temperature?: number;\n baseUrl?: string;\n headers?: Record<string, string>;\n}\n\nexport class OpenAiAdapter implements AiProviderAdapter {\n readonly name = 'openai';\n private apiKey: string;\n private model: string;\n private temperature: number;\n private baseUrl: string;\n private customHeaders?: Record<string, string>;\n\n constructor(options: OpenAiAdapterOptions) {\n if (!options.apiKey) {\n throw new Error('OpenAiAdapter requires an apiKey');\n }\n this.apiKey = options.apiKey;\n this.model = options.model || 'gpt-4o';\n this.temperature = options.temperature ?? 0.4;\n this.baseUrl = (options.baseUrl || 'https://api.openai.com/v1').replace(/\\/+$/, '');\n this.customHeaders = options.headers;\n }\n\n private buildMessages(params: AiProviderGenerateParams): Array<{ role: string; content: string }> {\n const { systemPrompt, userPrompt, messages: chatMessages } = params;\n return chatMessages && chatMessages.length > 0\n ? [\n { role: 'system', content: systemPrompt },\n ...chatMessages.map((m) => ({ role: m.role, content: m.content })),\n ]\n : [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ];\n }\n\n async generate(params: AiProviderGenerateParams): Promise<AiProviderGenerateResult> {\n const { systemPrompt, signal } = params;\n\n const url = `${this.baseUrl}/chat/completions`;\n const messages = this.buildMessages(params);\n const chatMessages = params.messages;\n\n const body: Record<string, unknown> = {\n model: this.model,\n temperature: this.temperature,\n messages,\n };\n\n // Only force json_object when JSON schema is provided or specifically requested,\n // allowing natural conversation text in chat mode.\n if (params.jsonSchema || (!chatMessages && (systemPrompt.includes('JSON') || systemPrompt.includes('json')))) {\n body.response_format = { type: 'json_object' };\n }\n\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n ...this.customHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `OpenAI API error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n const data = (await res.json()) as {\n choices?: Array<{\n message?: {\n content?: string;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n };\n\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n throw new Error('OpenAI returned an empty message content');\n }\n\n return {\n text: content,\n usage: data.usage\n ? {\n promptTokens: data.usage.prompt_tokens,\n completionTokens: data.usage.completion_tokens,\n }\n : undefined,\n };\n }\n\n /**\n * Token-level streaming via OpenAI's `stream: true` chat completions mode (STORA-515).\n * Yields each `delta.content` fragment as it arrives and returns the fully assembled\n * text + usage (when the final chunk includes it) once the stream ends.\n */\n async *generateStream(\n params: AiProviderGenerateParams,\n ): AsyncGenerator<string, AiProviderGenerateResult, void> {\n const { signal } = params;\n const url = `${this.baseUrl}/chat/completions`;\n const messages = this.buildMessages(params);\n\n const body: Record<string, unknown> = {\n model: this.model,\n temperature: this.temperature,\n messages,\n stream: true,\n };\n\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n ...this.customHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `OpenAI API error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n if (!res.body) {\n throw new Error('OpenAI streaming response has no readable body');\n }\n\n let text = '';\n let usage: AiProviderGenerateResult['usage'];\n\n for await (const raw of readSseDataLines(res.body, signal)) {\n if (raw === '[DONE]') break;\n\n let parsed: {\n choices?: Array<{ delta?: { content?: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n };\n try {\n parsed = JSON.parse(raw);\n } catch {\n continue;\n }\n\n const delta = parsed.choices?.[0]?.delta?.content;\n if (typeof delta === 'string' && delta.length > 0) {\n text += delta;\n yield delta;\n }\n\n if (parsed.usage) {\n usage = {\n promptTokens: parsed.usage.prompt_tokens,\n completionTokens: parsed.usage.completion_tokens,\n };\n }\n }\n\n return { text, usage };\n }\n}\n","import type {\n AiProviderAdapter,\n AiProviderGenerateParams,\n AiProviderGenerateResult,\n} from '../../types';\nimport { readSseDataLines } from './stream-utils';\n\nexport interface AnthropicAdapterOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n baseUrl?: string;\n anthropicVersion?: string;\n headers?: Record<string, string>;\n}\n\nexport class AnthropicAdapter implements AiProviderAdapter {\n readonly name = 'anthropic';\n private apiKey: string;\n private model: string;\n private maxTokens: number;\n private temperature: number;\n private baseUrl: string;\n private anthropicVersion: string;\n private customHeaders?: Record<string, string>;\n\n constructor(options: AnthropicAdapterOptions) {\n if (!options.apiKey) {\n throw new Error('AnthropicAdapter requires an apiKey');\n }\n this.apiKey = options.apiKey;\n this.model = options.model || 'claude-3-5-sonnet-20241022';\n this.maxTokens = options.maxTokens ?? 4096;\n this.temperature = options.temperature ?? 0.4;\n this.baseUrl = (options.baseUrl || 'https://api.anthropic.com/v1').replace(/\\/+$/, '');\n this.anthropicVersion = options.anthropicVersion || '2023-06-01';\n this.customHeaders = options.headers;\n }\n\n private buildMessages(\n params: AiProviderGenerateParams,\n ): Array<{ role: 'user' | 'assistant'; content: string }> {\n const { userPrompt, messages: chatMessages } = params;\n return chatMessages && chatMessages.length > 0\n ? chatMessages\n .filter((m) => m.role === 'user' || m.role === 'assistant')\n .map((m) => ({ role: m.role as 'user' | 'assistant', content: m.content }))\n : [\n {\n role: 'user' as const,\n content: userPrompt,\n },\n ];\n }\n\n async generate(params: AiProviderGenerateParams): Promise<AiProviderGenerateResult> {\n const { systemPrompt, signal } = params;\n\n const url = `${this.baseUrl}/messages`;\n const messages = this.buildMessages(params);\n\n const body: Record<string, unknown> = {\n model: this.model,\n max_tokens: this.maxTokens,\n temperature: this.temperature,\n system: systemPrompt,\n messages,\n };\n\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': this.anthropicVersion,\n ...this.customHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `Anthropic API error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n const data = (await res.json()) as {\n content?: Array<{\n type?: string;\n text?: string;\n }>;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n };\n\n const textPart = data.content?.find((c) => c.type === 'text')?.text;\n if (!textPart) {\n throw new Error('Anthropic returned an empty text content');\n }\n\n return {\n text: textPart,\n usage: data.usage\n ? {\n promptTokens: data.usage.input_tokens,\n completionTokens: data.usage.output_tokens,\n }\n : undefined,\n };\n }\n\n /**\n * Token-level streaming via Anthropic's `stream: true` Messages API (STORA-515).\n * Parses the `content_block_delta` (`text_delta`) events for incremental text and the\n * `message_start`/`message_delta` events for usage accounting.\n */\n async *generateStream(\n params: AiProviderGenerateParams,\n ): AsyncGenerator<string, AiProviderGenerateResult, void> {\n const { systemPrompt, signal } = params;\n const url = `${this.baseUrl}/messages`;\n const messages = this.buildMessages(params);\n\n const body: Record<string, unknown> = {\n model: this.model,\n max_tokens: this.maxTokens,\n temperature: this.temperature,\n system: systemPrompt,\n messages,\n stream: true,\n };\n\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': this.anthropicVersion,\n ...this.customHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `Anthropic API error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n if (!res.body) {\n throw new Error('Anthropic streaming response has no readable body');\n }\n\n let text = '';\n let promptTokens: number | undefined;\n let completionTokens: number | undefined;\n\n for await (const raw of readSseDataLines(res.body, signal)) {\n if (!raw) continue;\n\n let evt: {\n type?: string;\n delta?: { type?: string; text?: string };\n usage?: { output_tokens?: number };\n message?: { usage?: { input_tokens?: number } };\n };\n try {\n evt = JSON.parse(raw);\n } catch {\n continue;\n }\n\n if (evt.type === 'content_block_delta' && evt.delta?.type === 'text_delta') {\n const delta = evt.delta.text;\n if (typeof delta === 'string' && delta.length > 0) {\n text += delta;\n yield delta;\n }\n } else if (evt.type === 'message_start' && evt.message?.usage?.input_tokens !== undefined) {\n promptTokens = evt.message.usage.input_tokens;\n } else if (evt.type === 'message_delta' && evt.usage?.output_tokens !== undefined) {\n completionTokens = evt.usage.output_tokens;\n }\n }\n\n return {\n text,\n usage:\n promptTokens !== undefined || completionTokens !== undefined\n ? { promptTokens, completionTokens }\n : undefined,\n };\n }\n}\n","import type {\n AiProviderAdapter,\n AiProviderGenerateParams,\n AiProviderGenerateResult,\n} from '../../types';\n\nexport interface CustomHttpAdapterOptions {\n url: string;\n name?: string;\n headers?: Record<string, string>;\n formatRequestBody?: (params: AiProviderGenerateParams) => unknown;\n parseResponse?: (json: unknown) => string;\n}\n\nexport class CustomHttpAdapter implements AiProviderAdapter {\n readonly name: string;\n private url: string;\n private headers?: Record<string, string>;\n private formatRequestBody: (params: AiProviderGenerateParams) => unknown;\n private parseResponse: (json: unknown) => string;\n\n constructor(options: CustomHttpAdapterOptions) {\n if (!options.url) {\n throw new Error('CustomHttpAdapter requires a url');\n }\n this.url = options.url;\n this.name = options.name || 'custom-http';\n this.headers = options.headers;\n\n // Default body formatter (OpenAI compatible or Ollama chat compatible)\n this.formatRequestBody =\n options.formatRequestBody ||\n ((params) => ({\n messages:\n params.messages && params.messages.length > 0\n ? [\n { role: 'system', content: params.systemPrompt },\n ...params.messages.map((m) => ({ role: m.role, content: m.content })),\n ]\n : [\n { role: 'system', content: params.systemPrompt },\n { role: 'user', content: params.userPrompt },\n ],\n }));\n\n // Default response parser\n this.parseResponse =\n options.parseResponse ||\n ((json: unknown) => {\n if (!json || typeof json !== 'object') {\n throw new Error('Response is not a valid JSON object');\n }\n const obj = json as Record<string, unknown>;\n if (typeof obj.response === 'string') return obj.response; // Ollama generate\n if (typeof obj.text === 'string') return obj.text;\n const choices = obj.choices as Array<{ message?: { content?: string } }>;\n if (Array.isArray(choices) && choices[0]?.message?.content) {\n return choices[0].message.content; // OpenAI format\n }\n const message = obj.message as { content?: string };\n if (message && typeof message.content === 'string') {\n return message.content; // Ollama chat format\n }\n throw new Error('Unable to extract generated text from custom HTTP response');\n });\n }\n\n async generate(params: AiProviderGenerateParams): Promise<AiProviderGenerateResult> {\n const body = this.formatRequestBody(params);\n\n const res = await fetch(this.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n body: JSON.stringify(body),\n signal: params.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n throw new Error(\n `Custom HTTP adapter error [${res.status} ${res.statusText}]: ${errText || 'Unknown error'}`,\n );\n }\n\n const json = await res.json();\n const text = this.parseResponse(json);\n\n return { text };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/ai-client.ts"],"sourcesContent":["import type { PageDocument, Node } from '@kubuild/schema';\nimport type {\n AiGeneratePageRequest,\n AiGenerateSectionRequest,\n AiRefactorNodeRequest,\n AiChatRequest,\n AiChatResponse,\n AiChatMessage,\n AiGenerateResponse,\n AiStreamCallbacks,\n AiStreamEvent,\n} from '../types';\n\nexport interface AiClientOptions {\n endpoint: string;\n headers?:\n | Record<string, string>\n | (() => Promise<Record<string, string>> | Record<string, string>);\n fetch?: typeof fetch;\n}\n\nexport class KubuildAiClient {\n private endpoint: string;\n private headers?: AiClientOptions['headers'];\n private fetchFn: typeof fetch;\n\n constructor(options: AiClientOptions) {\n if (!options.endpoint) {\n throw new Error('KubuildAiClient requires an endpoint URL');\n }\n this.endpoint = options.endpoint;\n this.headers = options.headers;\n this.fetchFn = options.fetch || globalThis.fetch.bind(globalThis);\n }\n\n private async resolveHeaders(): Promise<Record<string, string>> {\n if (!this.headers) return {};\n if (typeof this.headers === 'function') {\n return await this.headers();\n }\n return this.headers;\n }\n\n private async sendRequest<T>(\n body: Record<string, unknown>,\n signal?: AbortSignal,\n ): Promise<T> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify(body),\n signal,\n });\n\n const json = (await res.json()) as AiGenerateResponse<T>;\n\n if (!res.ok || !json.success || !json.data) {\n const errMessage = json?.error?.message || `HTTP ${res.status}: ${res.statusText}`;\n const error = new Error(errMessage);\n (error as unknown as { code?: string; details?: unknown }).code = json?.error?.code;\n (error as unknown as { code?: string; details?: unknown }).details = json?.error?.details;\n throw error;\n }\n\n return json.data;\n }\n\n /**\n * Standard single-pass full page generator (non-streaming).\n */\n async generatePage(\n params: AiGeneratePageRequest,\n options?: { signal?: AbortSignal },\n ): Promise<PageDocument> {\n return this.sendRequest<PageDocument>(\n {\n mode: 'full-page',\n ...params,\n },\n options?.signal,\n );\n }\n\n /**\n * Low-level SSE frame consumer shared by every streaming method on this client\n * (`streamPage`, `chatStream`) — one transport implementation, reused rather than\n * duplicated per stream \"flavor\" (STORA-515).\n *\n * Reads `res.body`, decodes `data: <json>\\n\\n` frames into `AiStreamEvent`s, and\n * invokes `onEvent` for each one in arrival order. If `onEvent` throws (the\n * conventional way callers signal a fatal `error` event), the throw propagates out of\n * this method after the reader lock is released.\n */\n private async consumeSse(\n res: Response,\n onEvent: (event: AiStreamEvent) => void,\n ): Promise<void> {\n if (!res.body) {\n throw new Error('Response body is null, cannot stream');\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split('\\n\\n');\n buffer = parts.pop() || '';\n\n for (const part of parts) {\n const lines = part.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n let event: AiStreamEvent;\n try {\n event = JSON.parse(line.slice(6).trim()) as AiStreamEvent;\n } catch {\n // Ignore incomplete or non-JSON data frames\n continue;\n }\n onEvent(event);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Progressive section streamer (SSE).\n * Calls callbacks on each event (status, metadata, section, complete).\n */\n async streamPage(\n params: AiGeneratePageRequest,\n callbacks?: AiStreamCallbacks,\n options?: { signal?: AbortSignal },\n ): Promise<PageDocument> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify({\n mode: 'full-page',\n stream: true,\n ...params,\n }),\n signal: options?.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n const err = new Error(`Streaming failed [${res.status} ${res.statusText}]: ${errText}`);\n callbacks?.onError?.(err);\n throw err;\n }\n\n let finalDoc: PageDocument | null = null;\n\n await this.consumeSse(res, (event) => {\n if (event.type === 'status') {\n callbacks?.onStatus?.(event.message);\n } else if (event.type === 'metadata') {\n callbacks?.onMetadata?.(event.metadata, event.rootPageNode);\n } else if (event.type === 'section') {\n callbacks?.onSection?.(event.section, event.index, event.total);\n } else if (event.type === 'complete') {\n finalDoc = event.document;\n callbacks?.onComplete?.(event.document);\n } else if (event.type === 'error') {\n const err = new Error(event.error.message || 'Stream error');\n (err as unknown as { code?: string }).code = event.error.code;\n callbacks?.onError?.(err);\n throw err;\n }\n });\n\n if (!finalDoc) {\n throw new Error('Stream ended without receiving complete document');\n }\n\n return finalDoc;\n }\n\n /**\n * Token-level streaming chat (STORA-515). Calls `onChatChunk` for every partial chunk\n * as it arrives and resolves with the fully assembled assistant `AiChatMessage` once\n * the stream's terminal `chat-complete` event is received. Reuses the exact same SSE\n * transport as `streamPage` via `consumeSse` — no separate parsing path.\n */\n async chatStream(\n params: AiChatRequest,\n callbacks?: Pick<AiStreamCallbacks, 'onChatChunk' | 'onChatComplete' | 'onError'>,\n options?: { signal?: AbortSignal },\n ): Promise<AiChatMessage> {\n const dynamicHeaders = await this.resolveHeaders();\n\n const res = await this.fetchFn(this.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...dynamicHeaders,\n },\n body: JSON.stringify({\n mode: 'chat',\n stream: true,\n ...params,\n }),\n signal: options?.signal,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => '');\n const err = new Error(`Chat streaming failed [${res.status} ${res.statusText}]: ${errText}`);\n callbacks?.onError?.(err);\n throw err;\n }\n\n let finalMessage: AiChatMessage | null = null;\n\n await this.consumeSse(res, (event) => {\n if (event.type === 'chat-chunk') {\n callbacks?.onChatChunk?.(event.delta, event.content);\n } else if (event.type === 'chat-complete') {\n finalMessage = event.message;\n callbacks?.onChatComplete?.(event.message);\n } else if (event.type === 'error') {\n const err = new Error(event.error.message || 'Stream error');\n (err as unknown as { code?: string }).code = event.error.code;\n callbacks?.onError?.(err);\n throw err;\n }\n });\n\n if (!finalMessage) {\n throw new Error('Chat stream ended without receiving a complete message');\n }\n\n return finalMessage;\n }\n\n async generateSection(\n params: AiGenerateSectionRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Node> {\n return this.sendRequest<Node>(\n {\n mode: 'section',\n ...params,\n },\n options?.signal,\n );\n }\n\n async refactorNode(\n params: AiRefactorNodeRequest,\n options?: { signal?: AbortSignal },\n ): Promise<Node> {\n return this.sendRequest<Node>(\n {\n mode: 'refactor',\n ...params,\n },\n options?.signal,\n );\n }\n\n async chat(\n params: AiChatRequest,\n options?: { signal?: AbortSignal },\n ): Promise<AiChatResponse> {\n return this.sendRequest<AiChatResponse>(\n {\n mode: 'chat',\n ...params,\n },\n options?.signal,\n );\n }\n}\n\nexport function createAiClient(options: AiClientOptions): KubuildAiClient {\n return new KubuildAiClient(options);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/prompt-compiler.ts","../src/core/normalizer.ts"],"sourcesContent":["import type {\n AiCompiledComponentSpec,\n AiCompiledComponentProp,\n ComponentRegistryLike,\n ComponentDefinitionLike,\n AiGenerationMode,\n} from '../types';\n\nexport function compileComponentCatalog(\n registry?: ComponentRegistryLike,\n): AiCompiledComponentSpec[] {\n if (!registry) return [];\n\n const definitions = registry.list();\n return definitions.map((def: ComponentDefinitionLike) => {\n const props: AiCompiledComponentProp[] = [];\n\n if (def.propFields && Array.isArray(def.propFields)) {\n for (const field of def.propFields) {\n props.push({\n name: field.name,\n type: field.type || 'string',\n defaultValue: field.defaultValue,\n options: field.options?.map((o) => o.value),\n description: field.description,\n });\n }\n }\n\n return {\n type: def.type,\n label: def.label || def.type,\n category: def.category || 'custom',\n description: def.description,\n acceptsChildren: def.acceptsChildren ?? false,\n allowedChildren: def.allowedChildren,\n disallowedParents: def.disallowedParents,\n defaultProps: def.defaultProps,\n props: props.length > 0 ? props : undefined,\n };\n });\n}\n\nexport function buildSystemPrompt(options: {\n catalog: AiCompiledComponentSpec[];\n mode: AiGenerationMode;\n prefix?: string;\n stylePreference?: string;\n}): string {\n const { catalog, mode, prefix, stylePreference } = options;\n\n const catalogSummary = catalog\n .map((c) => {\n let desc = `- **${c.type}** (${c.category}): ${c.label}`;\n if (c.description) desc += ` - ${c.description}`;\n desc += ` | acceptsChildren: ${c.acceptsChildren}`;\n if (c.allowedChildren && c.allowedChildren.length > 0) {\n desc += ` | allowedChildren: [${c.allowedChildren.join(', ')}]`;\n }\n if (c.props && c.props.length > 0) {\n const propList = c.props\n .map((p) => {\n let pStr = `${p.name} (${p.type})`;\n if (p.options) pStr += `[${p.options.map(String).join('|')}]`;\n return pStr;\n })\n .join(', ');\n desc += ` | props: { ${propList} }`;\n }\n return desc;\n })\n .join('\\n');\n\n let modeInstructions = '';\n if (mode === 'full-page') {\n modeInstructions = `\nYou must generate a complete, valid KUBUILD PageDocument JSON with this exact structure:\n{\n \"schema\": \"stora.page\",\n \"version\": \"1.0.0\",\n \"metadata\": {\n \"title\": \"<Page Title>\",\n \"description\": \"<Page Description>\",\n \"tags\": [\"<tag1>\", \"<tag2>\"],\n \"category\": \"<category>\"\n },\n \"document\": {\n \"id\": \"root-page\",\n \"type\": \"page\",\n \"styles\": {\n \"base\": {\n \"backgroundColor\": \"#ffffff\",\n \"fontFamily\": \"Inter, system-ui, sans-serif\",\n \"color\": \"#111827\",\n \"minHeight\": \"100vh\"\n }\n },\n \"children\": [\n // Sections here...\n ]\n }\n}\n`;\n } else if (mode === 'section') {\n modeInstructions = `\nYou must generate a single valid KUBUILD section Node JSON with this structure:\n{\n \"id\": \"section_<unique_suffix>\",\n \"type\": \"section\",\n \"styles\": {\n \"base\": {\n \"paddingTop\": \"64px\",\n \"paddingBottom\": \"64px\",\n \"paddingLeft\": \"24px\",\n \"paddingRight\": \"24px\"\n }\n },\n \"children\": [\n // Container and child nodes...\n ]\n}\n`;\n } else if (mode === 'refactor') {\n modeInstructions = `\nYou must refactor the provided KUBUILD Node based on the user's instructions.\nReturn ONLY the updated Node JSON while maintaining structural integrity.\n`;\n }\n\n const styleGuide = stylePreference\n ? `\\nUser Style Preference: \"${stylePreference}\". Follow this visual aesthetic closely.`\n : '\\nStyle with modern, clean, high-conversion design patterns (accessible contrast, harmonious spacing, beautiful typography, subtle shadows/borders).';\n\n return `${prefix ? prefix + '\\n\\n' : ''}You are an expert web designer and KUBUILD architecture generator.\nKUBUILD is a component-driven visual website builder. Your job is to output pure, valid JSON (and NOTHING ELSE) matching the KUBUILD schema and the registered component definitions.\n\n### RULES & CONSTRAINTS:\n1. Output MUST be valid JSON only. No markdown fences, no explanatory text, no HTML tags outside html-embed.\n2. Only use component types listed in the Component Catalog below. Do NOT invent new component types.\n3. Obey \\`acceptsChildren\\` and \\`allowedChildren\\`:\n - Layout hierarchy: \\`page\\` -> \\`section\\` -> \\`container\\` or \\`columns\\` -> content components (\\`heading\\`, \\`paragraph\\`, \\`button\\`, \\`image\\`, \\`form\\`, etc.).\n - Leaf components (e.g. \\`button\\`, \\`input\\`, \\`heading\\`, \\`text\\`, \\`badge\\`) must have \\`acceptsChildren: false\\` and empty or omitted \\`children\\`.\n4. Every node MUST have a unique string \\`id\\` (e.g. \"hero-section\", \"hero-title\", \"cta-btn\").\n5. Responsive & Interactive State Styling:\n - Use the \\`styles\\` object with breakpoint keys: \\`base\\` (all viewports/desktop), and optionally \\`tablet\\` or \\`mobile\\`.\n - In \\`base\\`, \\`tablet\\`, and \\`mobile\\`, values MUST be CSS primitives (strings or numbers, e.g. \"backgroundColor\": \"#3b82f6\"). NEVER put nested objects or \":hover\" inside \"base\"!\n - For hover, active, or interactive pseudo-classes, use \\`styles.states\\` with pseudo-class keys (e.g. \\`\":hover\"\\`), like:\n \"styles\": {\n \"base\": { \"backgroundColor\": \"#3b82f6\", \"color\": \"#ffffff\" },\n \"states\": {\n \":hover\": { \"backgroundColor\": \"#2563eb\" }\n }\n }\n6. NEVER include dangerous scripts, \\`javascript:\\` URIs, or malicious payload attributes.\n${styleGuide}\n\n### OUTPUT SPECIFICATION:\n${modeInstructions}\n\n### REGISTERED COMPONENT CATALOG:\n${catalogSummary || '(Standard core components: page, section, container, columns, heading, paragraph, text, button, input, textarea, select, image, video, icon, badge, code-block)'}\n`;\n}\n\nexport function buildJsonSchemaForMode(mode: AiGenerationMode): Record<string, unknown> {\n const nodeSchema: Record<string, unknown> = {\n type: 'object',\n required: ['id', 'type'],\n properties: {\n id: { type: 'string' },\n type: { type: 'string' },\n props: { type: 'object' },\n styles: {\n type: 'object',\n properties: {\n base: { type: 'object' },\n tablet: { type: 'object' },\n mobile: { type: 'object' },\n states: { type: 'object' },\n },\n },\n children: {\n type: 'array',\n items: { $ref: '#' },\n },\n },\n };\n\n if (mode === 'full-page') {\n return {\n type: 'object',\n required: ['schema', 'version', 'document'],\n properties: {\n schema: { type: 'string', const: 'stora.page' },\n version: { type: 'string', const: '1.0.0' },\n metadata: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n description: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n category: { type: 'string' },\n },\n },\n document: nodeSchema,\n },\n };\n }\n\n return nodeSchema;\n}\n","import {\n PageDocument,\n PageDocumentSchema,\n DocumentMetadata,\n DocumentMetadataSchema,\n Node,\n NodeSchema,\n CURRENT_SCHEMA_VERSION,\n SCHEMA_NAME,\n} from '@kubuild/schema';\nimport {\n validateDocument,\n validateDocumentSecurity,\n DocumentSecurityLimits,\n} from '@kubuild/core';\n\nexport function extractJsonFromResponse(raw: string): unknown {\n let cleaned = raw.trim();\n // Strip Markdown code blocks if present (```json ... ``` or ``` ...)\n if (cleaned.startsWith('```')) {\n const firstNewline = cleaned.indexOf('\\n');\n if (firstNewline !== -1) {\n cleaned = cleaned.slice(firstNewline + 1);\n }\n if (cleaned.endsWith('```')) {\n cleaned = cleaned.slice(0, cleaned.length - 3).trim();\n }\n }\n\n // Find the outermost JSON object bounds if there is extraneous text\n const firstBrace = cleaned.indexOf('{');\n const lastBrace = cleaned.lastIndexOf('}');\n if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {\n cleaned = cleaned.slice(firstBrace, lastBrace + 1);\n }\n\n try {\n return JSON.parse(cleaned);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to parse AI response as JSON: ${msg}. Response was: ${raw.slice(0, 200)}...`);\n }\n}\n\nexport function normalizeStyles(rawStyles: unknown): Node['styles'] {\n if (!rawStyles || typeof rawStyles !== 'object' || Array.isArray(rawStyles)) {\n return undefined;\n }\n\n const raw = rawStyles as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n const states: Record<string, Record<string, unknown>> = {};\n\n // Existing states\n if (raw.states && typeof raw.states === 'object' && !Array.isArray(raw.states)) {\n for (const [stateKey, stateVal] of Object.entries(raw.states as Record<string, unknown>)) {\n if (stateVal && typeof stateVal === 'object' && !Array.isArray(stateVal)) {\n states[stateKey] = { ...(stateVal as Record<string, unknown>) };\n }\n }\n }\n\n const knownBreakpoints = ['base', 'desktop', 'tablet', 'mobile'];\n const hasBreakpoint = Object.keys(raw).some((k) => knownBreakpoints.includes(k));\n\n if (!hasBreakpoint) {\n // If AI output flat CSS properties without 'base' wrapper\n const baseStyles: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(raw)) {\n if (key === 'states') continue;\n if (key.startsWith(':') || key === 'hover' || key === 'focus' || key === 'active') {\n const stateKey = key.startsWith(':') ? key : `:${key}`;\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n states[stateKey] = { ...(states[stateKey] || {}), ...(value as Record<string, unknown>) };\n }\n } else if (typeof value !== 'object' || value === null) {\n baseStyles[key] = value;\n }\n }\n if (Object.keys(baseStyles).length > 0) {\n result.base = baseStyles;\n }\n } else {\n for (const bp of knownBreakpoints) {\n const bpVal = raw[bp];\n if (bpVal && typeof bpVal === 'object' && !Array.isArray(bpVal)) {\n const cleanBp: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(bpVal as Record<string, unknown>)) {\n if (key.startsWith(':') || key === 'hover' || key === 'focus' || key === 'active') {\n const stateKey = key.startsWith(':') ? key : `:${key}`;\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n states[stateKey] = { ...(states[stateKey] || {}), ...(value as Record<string, unknown>) };\n }\n } else if (typeof value !== 'object' || value === null) {\n cleanBp[key] = value;\n }\n }\n if (Object.keys(cleanBp).length > 0) {\n result[bp] = cleanBp;\n }\n }\n }\n\n // Also extract any pseudo-classes at top level\n for (const [key, value] of Object.entries(raw)) {\n if (knownBreakpoints.includes(key) || key === 'states') continue;\n if (key.startsWith(':') || key === 'hover' || key === 'focus' || key === 'active') {\n const stateKey = key.startsWith(':') ? key : `:${key}`;\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n states[stateKey] = { ...(states[stateKey] || {}), ...(value as Record<string, unknown>) };\n }\n }\n }\n }\n\n // Clean and sanitize states: each state can only have primitives\n const cleanStates: Record<string, Record<string, unknown>> = {};\n for (const [stateKey, stateDef] of Object.entries(states)) {\n const cleanDef: Record<string, unknown> = {};\n for (const [propKey, propVal] of Object.entries(stateDef)) {\n if (typeof propVal !== 'object' || propVal === null) {\n cleanDef[propKey] = propVal;\n }\n }\n if (Object.keys(cleanDef).length > 0) {\n cleanStates[stateKey] = cleanDef;\n }\n }\n\n if (Object.keys(cleanStates).length > 0) {\n result.states = cleanStates;\n }\n\n return Object.keys(result).length > 0 ? (result as Node['styles']) : undefined;\n}\n\nexport function normalizeNodeTree(\n node: unknown,\n usedIds: Set<string> = new Set(),\n depth = 0,\n): Node {\n if (!node || typeof node !== 'object') {\n throw new Error(`Invalid node at depth ${depth}: must be an object`);\n }\n\n const raw = node as Record<string, unknown>;\n const type = typeof raw.type === 'string' && raw.type.trim() ? raw.type.trim() : 'container';\n\n // Ensure deterministic, unique ID\n let id = typeof raw.id === 'string' && raw.id.trim() ? raw.id.trim() : '';\n if (!id || usedIds.has(id)) {\n let counter = 1;\n let candidate = `${type}-${counter}`;\n while (usedIds.has(candidate)) {\n counter++;\n candidate = `${type}-${counter}`;\n }\n id = candidate;\n }\n usedIds.add(id);\n\n // Normalize props\n const props =\n raw.props && typeof raw.props === 'object' && !Array.isArray(raw.props)\n ? { ...(raw.props as Record<string, unknown>) }\n : {};\n\n // Fix common LLM prop quirks:\n // e.g. heading level passed as string \"1\" instead of number 1\n if (type === 'heading' && typeof props.level === 'string') {\n const parsedLevel = parseInt(props.level, 10);\n if (!isNaN(parsedLevel) && parsedLevel >= 1 && parsedLevel <= 6) {\n props.level = parsedLevel;\n }\n }\n\n // Normalize styles\n const styles = normalizeStyles(raw.styles);\n\n // Normalize children recursively\n let children: Node[] | undefined = undefined;\n if (Array.isArray(raw.children)) {\n children = raw.children\n .filter((c) => c && typeof c === 'object')\n .map((c) => normalizeNodeTree(c, usedIds, depth + 1));\n }\n\n return {\n id,\n type,\n props: Object.keys(props).length > 0 ? props : undefined,\n styles,\n children,\n };\n}\n\nexport function normalizeAndValidatePageDocument(\n rawJson: unknown,\n securityLimits?: DocumentSecurityLimits,\n): PageDocument {\n if (!rawJson || typeof rawJson !== 'object') {\n throw new Error('AI output must be a JSON object');\n }\n\n const obj = rawJson as Record<string, unknown>;\n\n // Case 1: AI returned directly a page node instead of PageDocument\n let docObject: Record<string, unknown>;\n if (obj.type === 'page' && !obj.document) {\n docObject = {\n schema: SCHEMA_NAME,\n version: CURRENT_SCHEMA_VERSION,\n metadata: {\n title: (typeof obj.props === 'object' && obj.props !== null && (obj.props as Record<string, unknown>).title) || 'AI Generated Page',\n description: 'Generated by KUBUILD AI',\n },\n document: obj,\n };\n } else {\n docObject = {\n schema: SCHEMA_NAME,\n version: typeof obj.version === 'string' ? obj.version : CURRENT_SCHEMA_VERSION,\n metadata: typeof obj.metadata === 'object' && obj.metadata !== null\n ? obj.metadata\n : { title: 'AI Generated Page', description: 'Generated by KUBUILD AI' },\n document: obj.document || obj,\n };\n }\n\n // Normalize the node tree and ensure IDs\n const usedIds = new Set<string>();\n const normalizedRoot = normalizeNodeTree(docObject.document, usedIds);\n\n if (normalizedRoot.type !== 'page') {\n normalizedRoot.type = 'page';\n }\n\n const parsedMetadata = DocumentMetadataSchema.parse({\n title: 'AI Generated Page',\n description: 'Generated by KUBUILD AI',\n author: 'KUBUILD AI',\n tags: ['ai-generated'],\n category: 'general',\n version: '1.0.0',\n ...(typeof docObject.metadata === 'object' && docObject.metadata !== null\n ? (docObject.metadata as Record<string, unknown>)\n : {}),\n });\n\n const finalDocument: PageDocument = {\n schema: SCHEMA_NAME,\n version: CURRENT_SCHEMA_VERSION,\n metadata: parsedMetadata,\n document: normalizedRoot as PageDocument['document'],\n };\n\n // 1. Zod Schema parse\n const parsed = PageDocumentSchema.safeParse(finalDocument);\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n throw new Error(`Document schema validation failed: ${issues}`);\n }\n\n // 2. Core document and security validation\n const validationResult = validateDocument(finalDocument, { securityLimits });\n if (!validationResult.valid) {\n const errorMsgs = validationResult.errors.map((e) => `${e.code}: ${e.message} (${e.path})`).join('; ');\n throw new Error(`Document validation failed: ${errorMsgs}`);\n }\n\n return parsed.data;\n}\n\nexport function normalizeAndValidateSectionNode(\n rawJson: unknown,\n securityLimits?: DocumentSecurityLimits,\n): Node {\n if (!rawJson || typeof rawJson !== 'object') {\n throw new Error('AI output must be a JSON object');\n }\n\n const usedIds = new Set<string>();\n const normalized = normalizeNodeTree(rawJson, usedIds);\n\n if (normalized.type !== 'section') {\n // If AI wrapped it or returned another root, enforce section\n normalized.type = 'section';\n }\n\n const parsed = NodeSchema.safeParse(normalized);\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n throw new Error(`Section node schema validation failed: ${issues}`);\n }\n\n // Security check\n const secCheck = validateDocumentSecurity({ document: normalized }, securityLimits);\n if (!secCheck.safe) {\n const issues = secCheck.errors.map((e) => `${e.code}: ${e.message}`).join('; ');\n throw new Error(`Section security check failed: ${issues}`);\n }\n\n return parsed.data;\n}\n\nexport function normalizeAndValidateRefactoredNode(\n rawJson: unknown,\n originalNode: Node,\n securityLimits?: DocumentSecurityLimits,\n): Node {\n if (!rawJson || typeof rawJson !== 'object') {\n throw new Error('AI output must be a JSON object');\n }\n\n const usedIds = new Set<string>();\n const normalized = normalizeNodeTree(rawJson, usedIds);\n\n // Preserve original ID and type if AI changed them accidentally\n normalized.id = originalNode.id;\n normalized.type = originalNode.type;\n\n const parsed = NodeSchema.safeParse(normalized);\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n throw new Error(`Refactored node schema validation failed: ${issues}`);\n }\n\n const secCheck = validateDocumentSecurity({ document: normalized }, securityLimits);\n if (!secCheck.safe) {\n const issues = secCheck.errors.map((e) => `${e.code}: ${e.message}`).join('; ');\n throw new Error(`Refactored node security check failed: ${issues}`);\n }\n\n return parsed.data;\n}\n"],"mappings":"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","names":[]}
|