@ggui-ai/ui-gen 0.28.0 → 0.29.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/{adapter-h4_V69LI.d.ts → adapter-DLQ-5COm.d.ts} +1 -1
- package/dist/adapters/base.js +2 -27
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/generation-dispatch.d.ts +14 -6
- package/dist/adapters/generation-dispatch.js +40 -19260
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +25 -3561
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/types.js +2 -9
- package/dist/adapters/types.js.map +1 -1
- package/dist/advanced/index.d.ts +13 -12
- package/dist/advanced/index.js +63 -21954
- package/dist/advanced/index.js.map +1 -1
- package/dist/{bank-Ctdp3FUA.d.ts → bank-LWaiAtaA.d.ts} +1 -1
- package/dist/blueprint-validator.js +6 -2301
- package/dist/blueprint-validator.js.map +1 -1
- package/dist/boilerplate.d.ts +3 -2
- package/dist/boilerplate.js +6 -1867
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +3 -2
- package/dist/check/index.js +6 -1923
- package/dist/check/index.js.map +1 -1
- package/dist/chunk-33B3BAWS.js +24 -0
- package/dist/chunk-33B3BAWS.js.map +1 -0
- package/dist/chunk-3HSGA6NI.js +591 -0
- package/dist/chunk-3HSGA6NI.js.map +1 -0
- package/dist/chunk-3NNNGNTO.js +1707 -0
- package/dist/chunk-3NNNGNTO.js.map +1 -0
- package/dist/chunk-3T2HMTON.js +79 -0
- package/dist/chunk-3T2HMTON.js.map +1 -0
- package/dist/chunk-3ZSSDV3L.js +123 -0
- package/dist/chunk-3ZSSDV3L.js.map +1 -0
- package/dist/chunk-4MBR5GA3.js +99 -0
- package/dist/chunk-4MBR5GA3.js.map +1 -0
- package/dist/chunk-56NJFD55.js +337 -0
- package/dist/chunk-56NJFD55.js.map +1 -0
- package/dist/chunk-5AGTY555.js +26 -0
- package/dist/chunk-5AGTY555.js.map +1 -0
- package/dist/chunk-5EJM7EGY.js +115 -0
- package/dist/chunk-5EJM7EGY.js.map +1 -0
- package/dist/chunk-5KXCQLLR.js +529 -0
- package/dist/chunk-5KXCQLLR.js.map +1 -0
- package/dist/chunk-5VBXHVEH.js +171 -0
- package/dist/chunk-5VBXHVEH.js.map +1 -0
- package/dist/chunk-6KDDEING.js +515 -0
- package/dist/chunk-6KDDEING.js.map +1 -0
- package/dist/chunk-6VDRWAP6.js +123 -0
- package/dist/chunk-6VDRWAP6.js.map +1 -0
- package/dist/chunk-732IBFEJ.js +2400 -0
- package/dist/chunk-732IBFEJ.js.map +1 -0
- package/dist/chunk-73AURS3I.js +46 -0
- package/dist/chunk-73AURS3I.js.map +1 -0
- package/dist/chunk-77H5SKLX.js +8 -0
- package/dist/chunk-77H5SKLX.js.map +1 -0
- package/dist/chunk-7QE3AHLE.js +35 -0
- package/dist/chunk-7QE3AHLE.js.map +1 -0
- package/dist/chunk-A375NNWN.js +11 -0
- package/dist/chunk-A375NNWN.js.map +1 -0
- package/dist/chunk-AOU33EFS.js +140 -0
- package/dist/chunk-AOU33EFS.js.map +1 -0
- package/dist/chunk-BA4QYA6E.js +461 -0
- package/dist/chunk-BA4QYA6E.js.map +1 -0
- package/dist/chunk-DBP764GL.js +3 -0
- package/dist/chunk-DBP764GL.js.map +1 -0
- package/dist/chunk-DUU3ZJDQ.js +41 -0
- package/dist/chunk-DUU3ZJDQ.js.map +1 -0
- package/dist/chunk-DXKRBXNU.js +30 -0
- package/dist/chunk-DXKRBXNU.js.map +1 -0
- package/dist/chunk-FB7OEEAH.js +1467 -0
- package/dist/chunk-FB7OEEAH.js.map +1 -0
- package/dist/chunk-FLRNMZV2.js +18 -0
- package/dist/chunk-FLRNMZV2.js.map +1 -0
- package/dist/chunk-FWJIMKFZ.js +2032 -0
- package/dist/chunk-FWJIMKFZ.js.map +1 -0
- package/dist/chunk-FXRHWYIQ.js +163 -0
- package/dist/chunk-FXRHWYIQ.js.map +1 -0
- package/dist/chunk-G3PMV62Z.js +33 -0
- package/dist/chunk-G3PMV62Z.js.map +1 -0
- package/dist/chunk-GAJI7Y3P.js +13 -0
- package/dist/chunk-GAJI7Y3P.js.map +1 -0
- package/dist/chunk-GYINWMPR.js +2052 -0
- package/dist/chunk-GYINWMPR.js.map +1 -0
- package/dist/chunk-HD6ABIK7.js +484 -0
- package/dist/chunk-HD6ABIK7.js.map +1 -0
- package/dist/chunk-HDQVHYO6.js +100 -0
- package/dist/chunk-HDQVHYO6.js.map +1 -0
- package/dist/chunk-IHUT3SIW.js +7 -0
- package/dist/chunk-IHUT3SIW.js.map +1 -0
- package/dist/chunk-JDH5EGNZ.js +126 -0
- package/dist/chunk-JDH5EGNZ.js.map +1 -0
- package/dist/chunk-JMD4RGSV.js +37 -0
- package/dist/chunk-JMD4RGSV.js.map +1 -0
- package/dist/chunk-KJWGZL5B.js +33 -0
- package/dist/chunk-KJWGZL5B.js.map +1 -0
- package/dist/chunk-MKMDQFZ7.js +86 -0
- package/dist/chunk-MKMDQFZ7.js.map +1 -0
- package/dist/chunk-NF6JUZWF.js +85 -0
- package/dist/chunk-NF6JUZWF.js.map +1 -0
- package/dist/chunk-O2YC6XDC.js +1933 -0
- package/dist/chunk-O2YC6XDC.js.map +1 -0
- package/dist/chunk-OVLH5ICV.js +29 -0
- package/dist/chunk-OVLH5ICV.js.map +1 -0
- package/dist/chunk-PBOYHGSD.js +106 -0
- package/dist/chunk-PBOYHGSD.js.map +1 -0
- package/dist/chunk-PJFH7QWA.js +81 -0
- package/dist/chunk-PJFH7QWA.js.map +1 -0
- package/dist/chunk-PUH4CXGZ.js +284 -0
- package/dist/chunk-PUH4CXGZ.js.map +1 -0
- package/dist/chunk-QLXXPGTV.js +18 -0
- package/dist/chunk-QLXXPGTV.js.map +1 -0
- package/dist/chunk-R5GIGPW2.js +2845 -0
- package/dist/chunk-R5GIGPW2.js.map +1 -0
- package/dist/chunk-RH4IUSTO.js +83 -0
- package/dist/chunk-RH4IUSTO.js.map +1 -0
- package/dist/chunk-S2GVXKKY.js +153 -0
- package/dist/chunk-S2GVXKKY.js.map +1 -0
- package/dist/chunk-TVHGKFJS.js +58 -0
- package/dist/chunk-TVHGKFJS.js.map +1 -0
- package/dist/chunk-U7GALWLG.js +66 -0
- package/dist/chunk-U7GALWLG.js.map +1 -0
- package/dist/chunk-VTC263LT.js +256 -0
- package/dist/chunk-VTC263LT.js.map +1 -0
- package/dist/chunk-WEOXFEVE.js +739 -0
- package/dist/chunk-WEOXFEVE.js.map +1 -0
- package/dist/chunk-WYHP46LT.js +28 -0
- package/dist/chunk-WYHP46LT.js.map +1 -0
- package/dist/chunk-XGLO5LGG.js +274 -0
- package/dist/chunk-XGLO5LGG.js.map +1 -0
- package/dist/chunk-XRBCRKA2.js +29 -0
- package/dist/chunk-XRBCRKA2.js.map +1 -0
- package/dist/chunk-XW7ADFFV.js +340 -0
- package/dist/chunk-XW7ADFFV.js.map +1 -0
- package/dist/chunk-YIQ42IUX.js +34 -0
- package/dist/chunk-YIQ42IUX.js.map +1 -0
- package/dist/chunk-YJZTUY7B.js +101 -0
- package/dist/chunk-YJZTUY7B.js.map +1 -0
- package/dist/chunk-Z3CXME3K.js +107 -0
- package/dist/chunk-Z3CXME3K.js.map +1 -0
- package/dist/classifier/index.js +2 -527
- package/dist/classifier/index.js.map +1 -1
- package/dist/client-JBPCXU7W.js +4 -0
- package/dist/client-JBPCXU7W.js.map +1 -0
- package/dist/compose.js +3 -367
- package/dist/compose.js.map +1 -1
- package/dist/cost-tracker-HHGQ4FTW.js +67 -0
- package/dist/cost-tracker-HHGQ4FTW.js.map +1 -0
- package/dist/{create-ui-generator-BrZHF0cf.d.ts → create-ui-generator-BY-WeaPi.d.ts} +3 -3
- package/dist/{design-mode-DGWN_Gkm.d.ts → design-mode-XyOQmzE0.d.ts} +4 -3
- package/dist/{dispatch-B07TI30d.d.ts → dispatch-8LzTddKw.d.ts} +3 -2
- package/dist/dist-UALN6ZVB.js +543 -0
- package/dist/dist-UALN6ZVB.js.map +1 -0
- package/dist/dupe-break-X6K7QFIS.js +4 -0
- package/dist/dupe-break-X6K7QFIS.js.map +1 -0
- package/dist/evaluation/axis-checks/index.d.ts +5 -4
- package/dist/evaluation/axis-checks/index.js +6 -1914
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.d.ts +3 -2
- package/dist/evaluation/axis-checks/registry.js +3 -1844
- package/dist/evaluation/axis-checks/registry.js.map +1 -1
- package/dist/evaluation/index.d.ts +49 -132
- package/dist/evaluation/index.js +302 -6466
- package/dist/evaluation/index.js.map +1 -1
- package/dist/evaluation/types.d.ts +3 -2
- package/dist/evaluation/types.js +2 -5
- package/dist/evaluation/types.js.map +1 -1
- package/dist/fragments/index.js +2 -338
- package/dist/fragments/index.js.map +1 -1
- package/dist/{generate-tSO_shQ0.d.ts → generate-DQ4ci90s.d.ts} +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +35 -15
- package/dist/harness/check/runtime-render/index.js +6 -2390
- package/dist/harness/check/runtime-render/index.js.map +1 -1
- package/dist/harness/check/runtime-render/render-check-worker.js +4 -1739
- package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
- package/dist/harness/index.d.ts +3 -2
- package/dist/harness/index.js +23 -5126
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/llm-trace-sink.js +2 -24
- package/dist/harness/llm-trace-sink.js.map +1 -1
- package/dist/harness/prompts.d.ts +2 -2
- package/dist/harness/prompts.js +8 -324
- package/dist/harness/prompts.js.map +1 -1
- package/dist/harness/result-types.d.ts +6 -5
- package/dist/harness/result-types.js +2 -0
- package/dist/harness/result-types.js.map +1 -1
- package/dist/harness/runtime.d.ts +22 -5
- package/dist/harness/runtime.js +10 -2313
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +3 -2
- package/dist/harness/types-public.js +16 -2954
- package/dist/harness/types-public.js.map +1 -1
- package/dist/harness/validator-trace-sink.d.ts +3 -2
- package/dist/harness/validator-trace-sink.js +2 -26
- package/dist/harness/validator-trace-sink.js.map +1 -1
- package/dist/hash.js +2 -39
- package/dist/hash.js.map +1 -1
- package/dist/hashline-5OKREIRM.js +4 -0
- package/dist/hashline-5OKREIRM.js.map +1 -0
- package/dist/index.d.ts +50 -11
- package/dist/index.js +57 -22015
- package/dist/index.js.map +1 -1
- package/dist/llm-evaluator-PN3WFCS4.js +653 -0
- package/dist/llm-evaluator-PN3WFCS4.js.map +1 -0
- package/dist/magic-string.es-2NZTC4GZ.js +1307 -0
- package/dist/magic-string.es-2NZTC4GZ.js.map +1 -0
- package/dist/patch.d.ts +3 -2
- package/dist/patch.js +2 -56
- package/dist/patch.js.map +1 -1
- package/dist/policy-VCYKGSAC.js +5 -0
- package/dist/policy-VCYKGSAC.js.map +1 -0
- package/dist/policy.js +2 -35
- package/dist/policy.js.map +1 -1
- package/dist/primitive-index-2OF6F4TZ.js +131 -0
- package/dist/primitive-index-2OF6F4TZ.js.map +1 -0
- package/dist/primitive-slice-WTMBLYFJ.js +235 -0
- package/dist/primitive-slice-WTMBLYFJ.js.map +1 -0
- package/dist/{prompts-BhNUuRoZ.d.ts → prompts-CLZGywMP.d.ts} +1 -1
- package/dist/provider-adapter-contract.js +10407 -14204
- package/dist/provider-adapter-contract.js.map +1 -1
- package/dist/provider-adapter.js +2 -44
- package/dist/provider-adapter.js.map +1 -1
- package/dist/providers/index.d.ts +89 -1
- package/dist/providers/index.js +115 -44
- package/dist/providers/index.js.map +1 -1
- package/dist/raw-C6KBH5I3.js +141 -0
- package/dist/raw-C6KBH5I3.js.map +1 -0
- package/dist/raw-FXSBXQTZ.js +7 -0
- package/dist/raw-FXSBXQTZ.js.map +1 -0
- package/dist/raw-MURDUPGK.js +8 -0
- package/dist/raw-MURDUPGK.js.map +1 -0
- package/dist/raw-T3GW3UVX.js +8 -0
- package/dist/raw-T3GW3UVX.js.map +1 -0
- package/dist/render-check-host-ZNIS6BJ5.js +5 -0
- package/dist/render-check-host-ZNIS6BJ5.js.map +1 -0
- package/dist/sdk-4JNSDNSR.js +6 -0
- package/dist/sdk-4JNSDNSR.js.map +1 -0
- package/dist/sdk-DIVJMHCX.js +7 -0
- package/dist/sdk-DIVJMHCX.js.map +1 -0
- package/dist/sdk-QRJOCRTS.js +7 -0
- package/dist/sdk-QRJOCRTS.js.map +1 -0
- package/dist/tag-balance-CTHCTRJ7.js +123 -0
- package/dist/tag-balance-CTHCTRJ7.js.map +1 -0
- package/dist/tools/get-primitives-ts.d.ts +1 -1
- package/dist/tools/get-primitives-ts.js +3 -1
- package/dist/tools/get-primitives-ts.js.map +1 -1
- package/dist/tools/render-check-worker.js +3 -40
- package/dist/tools/render-check-worker.js.map +1 -1
- package/dist/{types-public-h8IMnYuh.d.ts → types-public-hYlrerZh.d.ts} +35 -2
- package/dist/validation/index.d.ts +2 -2
- package/dist/validation/index.js +3 -498
- package/dist/validation/index.js.map +1 -1
- package/dist/{visual-evaluator-C2strxqD.d.ts → visual-evaluator-KskajxD5.d.ts} +14 -4
- package/dist/visual-evaluator-TGEXYQTP.js +12 -0
- package/dist/visual-evaluator-TGEXYQTP.js.map +1 -0
- package/dist/workflows.d.ts +3 -2
- package/dist/workflows.js +2 -151
- package/dist/workflows.js.map +1 -1
- package/package.json +20 -16
- package/src/adapters/claude/sdk.ts +4 -2
- package/src/adapters/claude/tool-bridge.ts +2 -1
- package/src/adapters/generation-dispatch.ts +9 -0
- package/src/adapters/openai/raw.ts +4 -0
- package/src/adapters/openai/sdk.ts +6 -1
- package/src/adapters/openai/tokens.ts +21 -7
- package/src/adapters/tool-bridge.ts +1 -1
- package/src/adapters/tools.ts +1 -1
- package/src/advanced/feedback.ts +1 -2
- package/src/advanced/generator.ts +4 -3
- package/src/boilerplate/free-design-prompt.ts +7 -0
- package/src/boilerplate/generate.ts +18 -5
- package/src/boilerplate/hard-sections.ts +8 -3
- package/src/boilerplate/react-hooks.ts +56 -0
- package/src/boilerplate/system-prompt.ts +12 -3
- package/src/check/run-tier0.ts +233 -8
- package/src/check/type-checker.ts +128 -16
- package/src/coding-agent/tools.ts +26 -3
- package/src/design-mode.ts +4 -9
- package/src/evaluation/axis-checks/checks/state-merge.ts +2 -4
- package/src/evaluation/axis-checks/checks/state-payload.ts +1 -28
- package/src/evaluation/axis-checks/checks/tint.ts +197 -0
- package/src/evaluation/axis-checks/helpers.ts +121 -0
- package/src/evaluation/axis-checks/registry.ts +2 -0
- package/src/evaluation/criteria/__fixtures__/edge-v2-draw2.json +4629 -0
- package/src/evaluation/criteria/bank.ts +1 -1
- package/src/evaluation/criteria/edge-instruments.ts +14 -0
- package/src/evaluation/criteria/edge-probe-v2.ts +352 -0
- package/src/evaluation/criteria/edge-v2.ts +242 -0
- package/src/evaluation/criteria/resolve.ts +24 -5
- package/src/evaluation/index.ts +3 -5
- package/src/evaluation/mcp-server.ts +0 -50
- package/src/evaluation/types-public.ts +6 -1
- package/src/evaluation/visual-evaluator.ts +161 -30
- package/src/harness/check/runtime-render/index.ts +28 -4
- package/src/harness/check/runtime-render/render-check.ts +20 -21
- package/src/harness/claude-agent-sdk-loader.ts +93 -0
- package/src/harness/claude-code-login-query.ts +1 -1
- package/src/harness/coding/generate-task-runner.ts +1 -0
- package/src/harness/coding/run-coding-turn.ts +3 -0
- package/src/harness/coding/run-eval-round.ts +9 -0
- package/src/harness/llm-router.ts +50 -2
- package/src/harness/runtime.ts +17 -0
- package/src/index.ts +9 -0
- package/src/providers/anthropic-tool-call.ts +263 -0
- package/src/providers/index.ts +13 -0
- package/src/tools/get-primitives-ts.ts +1 -1
- package/src/tools/render-check.ts +4 -4
- package/src/validation/primitives.ts +2 -1
- package/src/evaluation/loop.ts +0 -218
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { dispatchGeneration } from './chunk-R5GIGPW2.js';
|
|
2
|
+
import { createGeneratorTools } from './chunk-3HSGA6NI.js';
|
|
3
|
+
import { injectRenderingContext, canvasForRenderingContext, injectVariance, injectContracts } from './chunk-VTC263LT.js';
|
|
4
|
+
import { buildSystemPrompt } from './chunk-5EJM7EGY.js';
|
|
5
|
+
import { resolveRoute, applyRouteToEnv } from './chunk-O2YC6XDC.js';
|
|
6
|
+
import { createRuntimeRenderCheck } from './chunk-BA4QYA6E.js';
|
|
7
|
+
import { generateBoilerplate } from './chunk-FB7OEEAH.js';
|
|
8
|
+
import { hasProfile } from './chunk-NF6JUZWF.js';
|
|
9
|
+
import { DEFAULT_DESIGN_MODE } from './chunk-3T2HMTON.js';
|
|
10
|
+
import { createHash } from 'crypto';
|
|
11
|
+
import { existsSync, readFileSync } from 'fs';
|
|
12
|
+
import { join, dirname } from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import { modelRefOfRoute, isGeneratorId, DEFAULT_MODEL as DEFAULT_MODEL$1 } from '@ggui-ai/protocol';
|
|
15
|
+
import { parseGeneratorSlug, formatGeneratorSlug, isValidGeneratorSlug } from '@ggui-ai/mcp-server-core';
|
|
16
|
+
|
|
17
|
+
// src/pin-fixtures.ts
|
|
18
|
+
var PIN_FIXTURES = [
|
|
19
|
+
{
|
|
20
|
+
userRequest: "A todo list where each item can be toggled done",
|
|
21
|
+
shellType: "chat",
|
|
22
|
+
screen: "mobile",
|
|
23
|
+
contract: {
|
|
24
|
+
propsSpec: {
|
|
25
|
+
properties: {
|
|
26
|
+
todos: {
|
|
27
|
+
required: true,
|
|
28
|
+
description: "The todos to show",
|
|
29
|
+
schema: {
|
|
30
|
+
type: "array",
|
|
31
|
+
items: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
id: { type: "string" },
|
|
35
|
+
title: { type: "string" },
|
|
36
|
+
done: { type: "boolean" }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
actionSpec: {
|
|
44
|
+
toggleTodo: {
|
|
45
|
+
label: "Toggle",
|
|
46
|
+
description: "Flip the done state of one todo",
|
|
47
|
+
schema: {
|
|
48
|
+
type: "object",
|
|
49
|
+
properties: { id: { type: "string" } },
|
|
50
|
+
required: ["id"]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
userRequest: "A kanban board with live task updates and a selected card",
|
|
58
|
+
shellType: "fullscreen",
|
|
59
|
+
screen: "desktop",
|
|
60
|
+
contract: {
|
|
61
|
+
propsSpec: {
|
|
62
|
+
properties: {
|
|
63
|
+
columns: {
|
|
64
|
+
required: true,
|
|
65
|
+
schema: { type: "array", items: { type: "string" } }
|
|
66
|
+
},
|
|
67
|
+
tasks: {
|
|
68
|
+
required: false,
|
|
69
|
+
schema: {
|
|
70
|
+
type: "array",
|
|
71
|
+
items: {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: {
|
|
74
|
+
id: { type: "string" },
|
|
75
|
+
column: { type: "string" },
|
|
76
|
+
title: { type: "string" }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
streamSpec: {
|
|
84
|
+
taskUpdates: {
|
|
85
|
+
description: "Task CRUD feed",
|
|
86
|
+
schema: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
action: { type: "string", enum: ["create", "move", "edit", "delete"] },
|
|
90
|
+
id: { type: "string" }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
contextSpec: {
|
|
96
|
+
selectedId: { schema: { type: "string", nullable: true } }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
// src/generator-build.ts
|
|
103
|
+
var TEMPLATE_FIXTURE_BOUNDARY = "\n<<<pin-fixture-boundary>>>\n";
|
|
104
|
+
function templateSha256(text) {
|
|
105
|
+
return createHash("sha256").update(text, "utf8").digest("hex");
|
|
106
|
+
}
|
|
107
|
+
function renderPromptTemplates(designMode) {
|
|
108
|
+
return PIN_FIXTURES.map((f) => {
|
|
109
|
+
switch (designMode) {
|
|
110
|
+
case "constrained":
|
|
111
|
+
return buildSystemPrompt(f.userRequest, f.shellType, f.screen);
|
|
112
|
+
case "free":
|
|
113
|
+
return buildSystemPrompt(f.userRequest, f.shellType, f.screen, void 0, void 0, void 0, "free");
|
|
114
|
+
}
|
|
115
|
+
}).join(TEMPLATE_FIXTURE_BOUNDARY);
|
|
116
|
+
}
|
|
117
|
+
function renderBoilerplateTemplates(designMode) {
|
|
118
|
+
return PIN_FIXTURES.map((f) => {
|
|
119
|
+
switch (designMode) {
|
|
120
|
+
case "constrained":
|
|
121
|
+
return generateBoilerplate(f.userRequest, f.contract, f.shellType, f.screen);
|
|
122
|
+
case "free":
|
|
123
|
+
return generateBoilerplate(f.userRequest, f.contract, f.shellType, f.screen, void 0, void 0, "free");
|
|
124
|
+
}
|
|
125
|
+
}).join(TEMPLATE_FIXTURE_BOUNDARY);
|
|
126
|
+
}
|
|
127
|
+
var PACKAGE_NAME = "@ggui-ai/ui-gen";
|
|
128
|
+
var MAX_PACKAGE_DEPTH = 6;
|
|
129
|
+
function parsePackageJson(text) {
|
|
130
|
+
try {
|
|
131
|
+
const parsed = JSON.parse(text);
|
|
132
|
+
return parsed;
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err instanceof SyntaxError) return void 0;
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function findPackageVersion(startDir = dirname(fileURLToPath(import.meta.url))) {
|
|
139
|
+
let dir = startDir;
|
|
140
|
+
for (let i = 0; i < MAX_PACKAGE_DEPTH; i++) {
|
|
141
|
+
const candidate = join(dir, "package.json");
|
|
142
|
+
const pkg = existsSync(candidate) ? parsePackageJson(readFileSync(candidate, "utf8")) : void 0;
|
|
143
|
+
if (pkg !== void 0) {
|
|
144
|
+
if (typeof pkg === "object" && pkg !== null && "name" in pkg && pkg.name === PACKAGE_NAME && "version" in pkg && typeof pkg.version === "string") {
|
|
145
|
+
return pkg.version;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const parent = dirname(dir);
|
|
149
|
+
if (parent === dir) break;
|
|
150
|
+
dir = parent;
|
|
151
|
+
}
|
|
152
|
+
return void 0;
|
|
153
|
+
}
|
|
154
|
+
var versionRead = false;
|
|
155
|
+
var packageVersion;
|
|
156
|
+
var identities = /* @__PURE__ */ new Map();
|
|
157
|
+
function generatorBuild(designMode) {
|
|
158
|
+
const key = `${designMode}|${process.env.GGUI_PITFALLS ?? ""}|${process.env.GGUI_NEW_PITFALLS ?? ""}`;
|
|
159
|
+
const known = identities.get(key);
|
|
160
|
+
if (known !== void 0) return known;
|
|
161
|
+
if (!versionRead) {
|
|
162
|
+
packageVersion = findPackageVersion();
|
|
163
|
+
versionRead = true;
|
|
164
|
+
}
|
|
165
|
+
const identity = {
|
|
166
|
+
...packageVersion !== void 0 ? { version: packageVersion } : {},
|
|
167
|
+
mode: designMode,
|
|
168
|
+
digests: {
|
|
169
|
+
promptTemplateSha256: templateSha256(renderPromptTemplates(designMode)),
|
|
170
|
+
boilerplateTemplateSha256: templateSha256(renderBoilerplateTemplates(designMode))
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
identities.set(key, identity);
|
|
174
|
+
return identity;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/effort.ts
|
|
178
|
+
var EFFORT_TABLE_VERSION = 1;
|
|
179
|
+
var EFFORT_DIALS = {
|
|
180
|
+
low: { maxAttempts: 5, maxEvalRounds: 1, selfEvalPassThreshold: 65, modelTier: "fast", judgeTier: "fast" },
|
|
181
|
+
medium: { maxAttempts: 8, maxEvalRounds: 2, selfEvalPassThreshold: 70, modelTier: "fast", judgeTier: "balanced" },
|
|
182
|
+
high: { maxAttempts: 8, maxEvalRounds: 3, selfEvalPassThreshold: 75, modelTier: "balanced", judgeTier: "balanced" },
|
|
183
|
+
xhigh: { maxAttempts: 10, maxEvalRounds: 3, selfEvalPassThreshold: 80, modelTier: "premium", judgeTier: "balanced" },
|
|
184
|
+
ultra: { maxAttempts: 12, maxEvalRounds: 4, selfEvalPassThreshold: 85, modelTier: "premium", judgeTier: "premium" }
|
|
185
|
+
};
|
|
186
|
+
function effortDials(effort) {
|
|
187
|
+
return effort === void 0 ? void 0 : EFFORT_DIALS[effort];
|
|
188
|
+
}
|
|
189
|
+
var DEFAULT_TIER = "default";
|
|
190
|
+
var DEFAULT_MODEL = DEFAULT_MODEL$1;
|
|
191
|
+
function createUiGenerator(options = {}) {
|
|
192
|
+
const {
|
|
193
|
+
enableRuntimeRender = false,
|
|
194
|
+
runtimeRenderProbe,
|
|
195
|
+
maxAttempts,
|
|
196
|
+
maxEvalRounds,
|
|
197
|
+
evaluation,
|
|
198
|
+
visualEvaluation,
|
|
199
|
+
visualEvalAgent,
|
|
200
|
+
qualityConfig,
|
|
201
|
+
gadgetCatalog,
|
|
202
|
+
disableEnvMutation = false,
|
|
203
|
+
onRetry,
|
|
204
|
+
onGenerated,
|
|
205
|
+
designMode
|
|
206
|
+
} = options;
|
|
207
|
+
const runtimeRender = enableRuntimeRender ? createRuntimeRenderCheck(runtimeRenderProbe) : void 0;
|
|
208
|
+
const identity = resolveIdentity(options);
|
|
209
|
+
return {
|
|
210
|
+
slug: identity.slug,
|
|
211
|
+
tier: identity.tier,
|
|
212
|
+
model: identity.model,
|
|
213
|
+
async generate(input) {
|
|
214
|
+
const startedAt = Date.now();
|
|
215
|
+
const provider = mapLlmProviderToDispatchProvider(input.llm.provider);
|
|
216
|
+
let route;
|
|
217
|
+
try {
|
|
218
|
+
const baseEnv = {};
|
|
219
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
220
|
+
if (v !== void 0) baseEnv[k] = v;
|
|
221
|
+
}
|
|
222
|
+
route = resolveRoute({
|
|
223
|
+
route: input.llm,
|
|
224
|
+
apiKey: input.providerKey.key,
|
|
225
|
+
env: baseEnv
|
|
226
|
+
});
|
|
227
|
+
} catch (err) {
|
|
228
|
+
return failWithoutMetadata(input, identity.slug, startedAt, {
|
|
229
|
+
code: "PRODUCTION_FAILED",
|
|
230
|
+
message: err instanceof Error ? err.message : String(err),
|
|
231
|
+
details: { kind: "route-resolution-failed" }
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const envBackup = {};
|
|
235
|
+
if (!disableEnvMutation) {
|
|
236
|
+
for (const k of Object.keys(route.env)) envBackup[k] = process.env[k];
|
|
237
|
+
const baseEnvForApply = {};
|
|
238
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
239
|
+
if (v !== void 0) baseEnvForApply[k] = v;
|
|
240
|
+
}
|
|
241
|
+
const routedEnv = applyRouteToEnv(baseEnvForApply, route);
|
|
242
|
+
for (const [k, v] of Object.entries(routedEnv)) process.env[k] = v;
|
|
243
|
+
for (const [k, v] of Object.entries(route.env)) {
|
|
244
|
+
if (v === void 0) delete process.env[k];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const routeOverride = route.auth === "claude-code-login" ? { claudeCodeLogin: true } : disableEnvMutation ? {
|
|
248
|
+
apiKey: route.env["ANTHROPIC_API_KEY"] ?? route.env["OPENAI_API_KEY"] ?? route.env["GEMINI_API_KEY"] ?? route.env["OPENROUTER_API_KEY"],
|
|
249
|
+
useBedrock: route.env["CLAUDE_CODE_USE_BEDROCK"] === "1"
|
|
250
|
+
} : void 0;
|
|
251
|
+
let effortRan;
|
|
252
|
+
try {
|
|
253
|
+
const tools = createGeneratorTools({
|
|
254
|
+
...input.contract ? { contract: input.contract } : {}
|
|
255
|
+
});
|
|
256
|
+
const rendering = mapRendering(input.rendering);
|
|
257
|
+
const promptWithRendering = rendering ? injectRenderingContext(input.request.prompt, rendering) : input.request.prompt;
|
|
258
|
+
const canvas = rendering ? canvasForRenderingContext(rendering) : void 0;
|
|
259
|
+
const shellType = harnessShellForRendering(rendering);
|
|
260
|
+
const promptWithVariance = injectVariance(promptWithRendering, input.variance, {
|
|
261
|
+
profileDeclared: hasProfile(input.profile)
|
|
262
|
+
});
|
|
263
|
+
const resolvedAppGadgets = input.appGadgets !== void 0 ? input.appGadgets : gadgetCatalog !== void 0 && input.appId !== void 0 ? await gadgetCatalog.list(input.appId) : void 0;
|
|
264
|
+
const userPrompt = injectContracts(promptWithVariance, input.contract, resolvedAppGadgets);
|
|
265
|
+
const dials = effortDials(input.profile?.effort);
|
|
266
|
+
if (dials !== void 0) effortRan = input.profile?.effort;
|
|
267
|
+
const effectiveMaxAttempts = dials?.maxAttempts ?? maxAttempts;
|
|
268
|
+
const effectiveMaxEvalRounds = dials?.maxEvalRounds ?? maxEvalRounds;
|
|
269
|
+
const effectiveEvaluation = dials !== void 0 && evaluation !== void 0 ? { ...evaluation, maxRounds: dials.maxEvalRounds } : evaluation;
|
|
270
|
+
const effectiveVisualEvaluation = dials !== void 0 && visualEvaluation !== void 0 ? { ...visualEvaluation, passThreshold: dials.selfEvalPassThreshold } : visualEvaluation;
|
|
271
|
+
const result = await dispatchGeneration({
|
|
272
|
+
provider,
|
|
273
|
+
userPrompt,
|
|
274
|
+
model: route.model,
|
|
275
|
+
tools,
|
|
276
|
+
...input.contract ? { contract: input.contract } : {},
|
|
277
|
+
originalPrompt: input.request.prompt,
|
|
278
|
+
...effectiveMaxAttempts !== void 0 ? { maxAttempts: effectiveMaxAttempts } : {},
|
|
279
|
+
...effectiveMaxEvalRounds !== void 0 ? { maxEvalRounds: effectiveMaxEvalRounds } : {},
|
|
280
|
+
...effectiveEvaluation !== void 0 ? { evaluation: effectiveEvaluation } : {},
|
|
281
|
+
...effectiveVisualEvaluation !== void 0 ? { visualEvaluation: effectiveVisualEvaluation } : {},
|
|
282
|
+
...qualityConfig !== void 0 ? { qualityConfig } : {},
|
|
283
|
+
...resolvedAppGadgets !== void 0 ? { appGadgets: resolvedAppGadgets } : {},
|
|
284
|
+
// Forward the third-party wrapper `.d.ts` map the render
|
|
285
|
+
// handler pre-fetched. Reaches both the code-gen prompt's
|
|
286
|
+
// `Type:` lines and the coding-agent typecheck overlay via
|
|
287
|
+
// `dispatchGeneration`.
|
|
288
|
+
...input.gadgetTypes !== void 0 ? { gadgetTypes: input.gadgetTypes } : {},
|
|
289
|
+
enableRuntimeRender,
|
|
290
|
+
...runtimeRender !== void 0 ? { runtimeRender } : {},
|
|
291
|
+
...routeOverride !== void 0 ? { routeOverride } : {},
|
|
292
|
+
...onRetry !== void 0 ? { onRetry } : {},
|
|
293
|
+
...designMode !== void 0 ? { designMode } : {},
|
|
294
|
+
...canvas !== void 0 ? { canvas } : {},
|
|
295
|
+
// ggui#1279 — the shell the declared rendering composes for (chat only; see harnessShellForRendering).
|
|
296
|
+
...shellType !== void 0 ? { shellType } : {},
|
|
297
|
+
...input.profile !== void 0 ? { profile: input.profile } : {},
|
|
298
|
+
// ggui#1250 — the named in-loop visual judge, when this generator was built with one.
|
|
299
|
+
...visualEvalAgent !== void 0 ? { visualEvalAgent } : {},
|
|
300
|
+
// Fixture props reach the in-loop probe + visual round only (never the prompt, never identity).
|
|
301
|
+
...input.fixtureProps !== void 0 ? { fixtureProps: input.fixtureProps } : {}
|
|
302
|
+
});
|
|
303
|
+
onGenerated?.(result);
|
|
304
|
+
const runtimeProbe = metadataRuntimeProbe(result);
|
|
305
|
+
const evalMs = metadataEvalMs(result);
|
|
306
|
+
const metadata = {
|
|
307
|
+
provider: input.llm.provider,
|
|
308
|
+
generator: identity.slug,
|
|
309
|
+
model: modelRefOfRoute(input.llm),
|
|
310
|
+
inputTokens: result.tokens.input,
|
|
311
|
+
outputTokens: result.tokens.output,
|
|
312
|
+
latencyMs: Date.now() - startedAt,
|
|
313
|
+
cacheHit: false,
|
|
314
|
+
attempts: result.turnsUsed,
|
|
315
|
+
// ggui#1280 — the build that made this generation (template keys, never per-request).
|
|
316
|
+
build: generatorBuild(designMode ?? DEFAULT_DESIGN_MODE),
|
|
317
|
+
// ggui#1459 — the level that ran; absent when none was applied.
|
|
318
|
+
...effortRan !== void 0 ? { effort: effortRan } : {},
|
|
319
|
+
// Prompt-cache counters are provider-specific (Claude reports
|
|
320
|
+
// them; others omit). Pass through truthfully — absent on the
|
|
321
|
+
// adapter result stays absent here, never defaulted to 0.
|
|
322
|
+
...result.cacheReadTokens !== void 0 ? { cacheReadTokens: result.cacheReadTokens } : {},
|
|
323
|
+
...result.cacheCreationTokens !== void 0 ? { cacheCreationTokens: result.cacheCreationTokens } : {},
|
|
324
|
+
// ggui#1380 — the runtime probe's record and the eval rounds' wall,
|
|
325
|
+
// when the harness ran a round; absent stays absent.
|
|
326
|
+
...runtimeProbe !== void 0 ? { runtimeProbe } : {},
|
|
327
|
+
...evalMs !== void 0 ? { evalMs } : {}
|
|
328
|
+
};
|
|
329
|
+
return {
|
|
330
|
+
ok: true,
|
|
331
|
+
response: {
|
|
332
|
+
sessionId: `session_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
333
|
+
componentCode: result.compiledCode,
|
|
334
|
+
...result.sourceCode ? { sourceCode: result.sourceCode } : {},
|
|
335
|
+
...input.contract ? { contract: input.contract } : {}
|
|
336
|
+
},
|
|
337
|
+
metadata
|
|
338
|
+
};
|
|
339
|
+
} catch (err) {
|
|
340
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
341
|
+
const details = { kind: "harness-failed" };
|
|
342
|
+
if (err instanceof Error && err.stack) details["stack"] = err.stack;
|
|
343
|
+
return {
|
|
344
|
+
ok: false,
|
|
345
|
+
error: {
|
|
346
|
+
code: "PRODUCTION_FAILED",
|
|
347
|
+
message,
|
|
348
|
+
details
|
|
349
|
+
},
|
|
350
|
+
metadata: {
|
|
351
|
+
provider: input.llm.provider,
|
|
352
|
+
generator: identity.slug,
|
|
353
|
+
model: modelRefOfRoute(input.llm),
|
|
354
|
+
inputTokens: 0,
|
|
355
|
+
outputTokens: 0,
|
|
356
|
+
latencyMs: Date.now() - startedAt,
|
|
357
|
+
cacheHit: false,
|
|
358
|
+
// ggui#1280 — a failed generation still names the build that failed.
|
|
359
|
+
build: generatorBuild(designMode ?? DEFAULT_DESIGN_MODE),
|
|
360
|
+
// ggui#1459 — and the level it ran, when one was applied.
|
|
361
|
+
...effortRan !== void 0 ? { effort: effortRan } : {}
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
} finally {
|
|
365
|
+
for (const [k, v] of Object.entries(envBackup)) {
|
|
366
|
+
if (v === void 0) delete process.env[k];
|
|
367
|
+
else process.env[k] = v;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function resolveIdentity(opts) {
|
|
374
|
+
const hasSlug = typeof opts.slug === "string" && opts.slug.length > 0;
|
|
375
|
+
if (hasSlug && opts.tier !== void 0) {
|
|
376
|
+
throw new Error("createUiGenerator: pass either { slug } or { tier } \u2014 not both.");
|
|
377
|
+
}
|
|
378
|
+
const model = opts.model ?? DEFAULT_MODEL;
|
|
379
|
+
if (hasSlug) {
|
|
380
|
+
const slug2 = opts.slug;
|
|
381
|
+
const parsed = parseGeneratorSlug(slug2);
|
|
382
|
+
if (!parsed || !isGeneratorId(slug2)) {
|
|
383
|
+
throw new Error(
|
|
384
|
+
`createUiGenerator: slug ${JSON.stringify(slug2)} is not a valid ui-gen-<tier> identifier.`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
return { slug: slug2, tier: parsed.tier, model };
|
|
388
|
+
}
|
|
389
|
+
const tier = opts.tier ?? DEFAULT_TIER;
|
|
390
|
+
const slug = formatGeneratorSlug({ tier });
|
|
391
|
+
if (!isValidGeneratorSlug(slug)) {
|
|
392
|
+
throw new Error(
|
|
393
|
+
`createUiGenerator: formatted slug ${JSON.stringify(slug)} round-trips as invalid \u2014 formatGeneratorSlug/isValidGeneratorSlug drift.`
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
return { slug, tier, model };
|
|
397
|
+
}
|
|
398
|
+
function metadataProbeOutcome(meta) {
|
|
399
|
+
const elapsed = {
|
|
400
|
+
...meta.elapsedMs !== void 0 ? { elapsedMs: meta.elapsedMs } : {},
|
|
401
|
+
...meta.queuedMs !== void 0 ? { queuedMs: meta.queuedMs } : {}
|
|
402
|
+
};
|
|
403
|
+
if (meta.status !== "ran") return { status: meta.status, ...elapsed };
|
|
404
|
+
if (meta.verdict === "pass") return { status: "ran", verdict: "pass", ...elapsed };
|
|
405
|
+
return { status: "ran", verdict: "fail", failChecks: meta.failChecks, ...elapsed };
|
|
406
|
+
}
|
|
407
|
+
function metadataProbeRepair(repair) {
|
|
408
|
+
return repair.compiled ? { attempted: true, compiled: true, trigger: metadataProbeOutcome(repair.trigger) } : { attempted: true, compiled: false };
|
|
409
|
+
}
|
|
410
|
+
function metadataRuntimeProbe(result) {
|
|
411
|
+
const probe = result.evalResult?.runtimeProbe;
|
|
412
|
+
if (probe === void 0) return void 0;
|
|
413
|
+
const repair = result.evalResult?.runtimeProbeRepair;
|
|
414
|
+
return {
|
|
415
|
+
...metadataProbeOutcome(probe),
|
|
416
|
+
...repair !== void 0 ? { repair: metadataProbeRepair(repair) } : {}
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
function metadataEvalMs(result) {
|
|
420
|
+
const breakdown = result.breakdown;
|
|
421
|
+
if (breakdown === void 0 || breakdown.evalRounds === 0) return void 0;
|
|
422
|
+
return breakdown.evalMs;
|
|
423
|
+
}
|
|
424
|
+
function mapLlmProviderToDispatchProvider(provider) {
|
|
425
|
+
switch (provider) {
|
|
426
|
+
case "anthropic":
|
|
427
|
+
case "bedrock":
|
|
428
|
+
return "claude";
|
|
429
|
+
case "openai":
|
|
430
|
+
return "openai";
|
|
431
|
+
case "google":
|
|
432
|
+
return "google";
|
|
433
|
+
case "openrouter":
|
|
434
|
+
return "openrouter";
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function harnessShellForRendering(rendering) {
|
|
438
|
+
if (rendering === void 0) return void 0;
|
|
439
|
+
switch (rendering.shell) {
|
|
440
|
+
case "chat":
|
|
441
|
+
return "chat";
|
|
442
|
+
case "fullscreen":
|
|
443
|
+
case "partial":
|
|
444
|
+
return void 0;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
function mapRendering(rendering) {
|
|
448
|
+
if (!rendering) return void 0;
|
|
449
|
+
return {
|
|
450
|
+
device: rendering.device,
|
|
451
|
+
shell: rendering.shell,
|
|
452
|
+
...rendering.viewport ? { viewport: rendering.viewport } : {}
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
function failWithoutMetadata(input, generatorSlug, startedAt, error) {
|
|
456
|
+
return {
|
|
457
|
+
ok: false,
|
|
458
|
+
error,
|
|
459
|
+
metadata: {
|
|
460
|
+
provider: input.llm.provider,
|
|
461
|
+
generator: generatorSlug,
|
|
462
|
+
model: modelRefOfRoute(input.llm),
|
|
463
|
+
inputTokens: 0,
|
|
464
|
+
outputTokens: 0,
|
|
465
|
+
latencyMs: Date.now() - startedAt,
|
|
466
|
+
cacheHit: false
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
var CODE_START_PATTERN = /^(import\s|export\s|const\s|function\s|class\s|\/\*|\/\/)/;
|
|
471
|
+
function extractComponentCode(raw) {
|
|
472
|
+
const fencePattern = /```([a-zA-Z0-9+\-_]*)\s*\n([\s\S]*?)```/g;
|
|
473
|
+
const fences = [];
|
|
474
|
+
let match;
|
|
475
|
+
while ((match = fencePattern.exec(raw)) !== null) {
|
|
476
|
+
const lang = (match[1] ?? "").toLowerCase();
|
|
477
|
+
const body = match[2] ?? "";
|
|
478
|
+
fences.push({ lang, body });
|
|
479
|
+
}
|
|
480
|
+
if (fences.length > 0) {
|
|
481
|
+
const priority = ["tsx", "jsx", "typescript", "ts", "javascript", "js", ""];
|
|
482
|
+
for (const preferred of priority) {
|
|
483
|
+
const hit = fences.find((f) => f.lang === preferred);
|
|
484
|
+
if (hit) return hit.body.trim();
|
|
485
|
+
}
|
|
486
|
+
const firstBody = fences[0]?.body ?? "";
|
|
487
|
+
return firstBody.trim();
|
|
488
|
+
}
|
|
489
|
+
const trimmed = raw.trim();
|
|
490
|
+
if (CODE_START_PATTERN.test(trimmed)) return trimmed;
|
|
491
|
+
const codeMarkerIndex = findCodeStart(raw);
|
|
492
|
+
if (codeMarkerIndex > 0) return raw.slice(codeMarkerIndex).trim();
|
|
493
|
+
return trimmed;
|
|
494
|
+
}
|
|
495
|
+
function findCodeStart(text) {
|
|
496
|
+
const markers = [
|
|
497
|
+
/\n\s*import\s/,
|
|
498
|
+
/\n\s*export\s/,
|
|
499
|
+
/\n\s*\/\*\s/,
|
|
500
|
+
/\n\s*const\s/,
|
|
501
|
+
/\n\s*function\s/
|
|
502
|
+
];
|
|
503
|
+
let earliest = -1;
|
|
504
|
+
for (const m of markers) {
|
|
505
|
+
const candidate = m.exec(text);
|
|
506
|
+
if (candidate && (earliest === -1 || candidate.index < earliest)) {
|
|
507
|
+
earliest = candidate.index;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return earliest;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export { EFFORT_DIALS, EFFORT_TABLE_VERSION, createUiGenerator, effortDials, extractComponentCode, generatorBuild };
|
|
514
|
+
//# sourceMappingURL=chunk-6KDDEING.js.map
|
|
515
|
+
//# sourceMappingURL=chunk-6KDDEING.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pin-fixtures.ts","../src/generator-build.ts","../src/effort.ts","../src/create-ui-generator.ts"],"names":["PROTOCOL_DEFAULT_MODEL","slug"],"mappings":"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","file":"chunk-6KDDEING.js","sourcesContent":["/**\n * The two fixed fixtures every prompt pin renders — one action-bearing\n * `chat`×`mobile` shell, one `fullscreen`×`desktop` board with a\n * `contextSpec` — shared by `design-mode.pin.test.ts` (the stable prefix)\n * and `shape-guidance.pin.test.ts` (the axis-conditioned Shape Guidance).\n */\nimport type { DataContract } from '@ggui-ai/protocol';\n\nexport interface PinFixture {\n readonly userRequest: string;\n readonly shellType: 'chat' | 'fullscreen' | 'spatial';\n readonly screen: 'mobile' | 'tablet' | 'desktop' | 'universal';\n readonly contract: DataContract;\n}\n\nexport const PIN_FIXTURES: readonly PinFixture[] = [\n {\n userRequest: 'A todo list where each item can be toggled done',\n shellType: 'chat',\n screen: 'mobile',\n contract: {\n propsSpec: {\n properties: {\n todos: {\n required: true,\n description: 'The todos to show',\n schema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n title: { type: 'string' },\n done: { type: 'boolean' },\n },\n },\n },\n },\n },\n },\n actionSpec: {\n toggleTodo: {\n label: 'Toggle',\n description: 'Flip the done state of one todo',\n schema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n },\n },\n },\n },\n {\n userRequest: 'A kanban board with live task updates and a selected card',\n shellType: 'fullscreen',\n screen: 'desktop',\n contract: {\n propsSpec: {\n properties: {\n columns: {\n required: true,\n schema: { type: 'array', items: { type: 'string' } },\n },\n tasks: {\n required: false,\n schema: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n column: { type: 'string' },\n title: { type: 'string' },\n },\n },\n },\n },\n },\n },\n streamSpec: {\n taskUpdates: {\n description: 'Task CRUD feed',\n schema: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['create', 'move', 'edit', 'delete'] },\n id: { type: 'string' },\n },\n },\n },\n },\n contextSpec: {\n selectedId: { schema: { type: 'string', nullable: true } },\n },\n },\n },\n];\n","/**\n * The generator's BUILD identity (ggui#1280): values that change when the\n * triad's templates change and never with the request, so generations group\n * by the build that produced them.\n *\n * - `promptTemplateSha256` / `boilerplateTemplateSha256` are sha256 over the\n * production system prompt and the boilerplate rendered on the design-mode\n * pin's FIXED fixtures (`PIN_FIXTURES`), in the live env, so an env-gated\n * block (the pitfalls) counts as it really is. The design-mode pin renders\n * the same functions and asserts these values equal its recorded constants\n * under the default env: the runtime key and the pin cannot drift.\n * - These are BUILD keys, not instance fingerprints. A hash of the prompt one\n * generation actually sent embeds the request and differs every time, so it\n * could never group two generations by build.\n * - `version` is the package's own version, read once from the nearest\n * `package.json` named `@ggui-ai/ui-gen` above this module. It is absent\n * when none is found (e.g. a consumer bundled this package into one file),\n * never guessed.\n */\nimport { createHash } from 'node:crypto';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { GeneratorBuild } from '@ggui-ai/mcp-server-core';\nimport { generateBoilerplate } from './boilerplate/generate.js';\nimport type { DesignMode } from './design-mode.js';\nimport { buildSystemPrompt } from './harness/runtime.js';\nimport { PIN_FIXTURES } from './pin-fixtures.js';\n\n/** The separator the rendered fixtures are joined with before hashing. */\nexport const TEMPLATE_FIXTURE_BOUNDARY = '\\n<<<pin-fixture-boundary>>>\\n';\n\n/** sha256 hex of a rendered template. */\nexport function templateSha256(text: string): string {\n return createHash('sha256').update(text, 'utf8').digest('hex');\n}\n\n/**\n * The production system prompt for every pin fixture, joined. The constrained\n * arm uses the positional default-path signature (no `designMode` argument),\n * which is what the pin has always recorded.\n */\nexport function renderPromptTemplates(designMode: DesignMode): string {\n return PIN_FIXTURES.map((f) => {\n switch (designMode) {\n case 'constrained':\n return buildSystemPrompt(f.userRequest, f.shellType, f.screen);\n case 'free':\n return buildSystemPrompt(f.userRequest, f.shellType, f.screen, undefined, undefined, undefined, 'free');\n }\n }).join(TEMPLATE_FIXTURE_BOUNDARY);\n}\n\n/** The boilerplate for every pin fixture, joined — same signature split as the prompt. */\nexport function renderBoilerplateTemplates(designMode: DesignMode): string {\n return PIN_FIXTURES.map((f) => {\n switch (designMode) {\n case 'constrained':\n return generateBoilerplate(f.userRequest, f.contract, f.shellType, f.screen);\n case 'free':\n return generateBoilerplate(f.userRequest, f.contract, f.shellType, f.screen, undefined, undefined, 'free');\n }\n }).join(TEMPLATE_FIXTURE_BOUNDARY);\n}\n\n/**\n * ui-gen's precise {@link GeneratorBuild}: the core port's generic shape with\n * ui-gen's own keys — `mode` is the design mode, and `digests` names the two\n * template digests (the keys a blueprint's build stamp copies).\n */\nexport interface UiGenBuild extends GeneratorBuild {\n /** This package's version; absent when its `package.json` cannot be found at runtime. */\n readonly version?: string;\n readonly mode: DesignMode;\n readonly digests: {\n readonly promptTemplateSha256: string;\n readonly boilerplateTemplateSha256: string;\n };\n}\n\nconst PACKAGE_NAME = '@ggui-ai/ui-gen';\n/** How far up from this module the package root can sit (`src/`, `dist/`, a nested entry). */\nconst MAX_PACKAGE_DEPTH = 6;\n\n/**\n * A `package.json` the walk meets may not be ours, and in a consumer's bundle\n * it may not even parse. A candidate that does not parse is skipped (as if\n * absent), so reading this package's version can never fail a generation —\n * the version is then absent, never guessed. Only a JSON `SyntaxError` is\n * handled here; any other error is a real fault and propagates.\n */\nfunction parsePackageJson(text: string): unknown {\n try {\n const parsed: unknown = JSON.parse(text);\n return parsed;\n } catch (err) {\n if (err instanceof SyntaxError) return undefined;\n throw err;\n }\n}\n\n/**\n * Walk up from `startDir` (this module's own directory by default) to the\n * nearest `package.json` named `@ggui-ai/ui-gen` and return its version;\n * `undefined` when none is found within reach.\n */\nexport function findPackageVersion(startDir: string = dirname(fileURLToPath(import.meta.url))): string | undefined {\n let dir = startDir;\n for (let i = 0; i < MAX_PACKAGE_DEPTH; i++) {\n const candidate = join(dir, 'package.json');\n const pkg = existsSync(candidate) ? parsePackageJson(readFileSync(candidate, 'utf8')) : undefined;\n if (pkg !== undefined) {\n if (\n typeof pkg === 'object' &&\n pkg !== null &&\n 'name' in pkg &&\n pkg.name === PACKAGE_NAME &&\n 'version' in pkg &&\n typeof pkg.version === 'string'\n ) {\n return pkg.version;\n }\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return undefined;\n}\n\nlet versionRead = false;\nlet packageVersion: string | undefined;\nconst identities = new Map<string, UiGenBuild>();\n\n/**\n * The build identity for `designMode`, computed once per process per design\n * mode and pitfalls env gate (the only env the templates read), so a changed\n * gate is never answered from a stale memo.\n */\nexport function generatorBuild(designMode: DesignMode): UiGenBuild {\n const key = `${designMode}|${process.env.GGUI_PITFALLS ?? ''}|${process.env.GGUI_NEW_PITFALLS ?? ''}`;\n const known = identities.get(key);\n if (known !== undefined) return known;\n if (!versionRead) {\n packageVersion = findPackageVersion();\n versionRead = true;\n }\n const identity: UiGenBuild = {\n ...(packageVersion !== undefined ? { version: packageVersion } : {}),\n mode: designMode,\n digests: {\n promptTemplateSha256: templateSha256(renderPromptTemplates(designMode)),\n boilerplateTemplateSha256: templateSha256(renderBoilerplateTemplates(designMode)),\n },\n };\n identities.set(key, identity);\n return identity;\n}\n","// The `effort` reader table (ggui#1059, A2). The wire carries ONLY the level\n// name (`generation.profile.effort`, protocol #1058); this table is the\n// cold-gen READER that maps a name onto the harness's dials, versioned here\n// so a level's meaning (and its price line) can move without a wire change.\n//\n// Boundaries, stated once:\n// - `effort` renders NO prompt text — the prompt is byte-identical under any\n// level (`profile-cross.pin.test.ts`). Dials only.\n// - Absent ⇒ the deployment's own options, untouched. The table is applied\n// only when a level is named.\n// - `selfEvalPassThreshold` is the GENERATOR's in-loop visual\n// self-evaluation threshold (`visualEvaluation.passThreshold`). A serving\n// layer's own acceptance bar is a different number and does not move with\n// `effort`.\n// - `modelTier` / `judgeTier` are REQUESTS to the deployment's router\n// (`fast | balanced | premium`), never a model id: a deployment with one\n// key is never promoted by a profile. The harness does not act on them;\n// the caller that owns model selection reads them from this table.\nimport type { AppGenerationProfileEffort, ModelTier } from \"@ggui-ai/protocol\";\n\n/** Bump when a level's meaning changes; the price line beside it follows. */\nexport const EFFORT_TABLE_VERSION = 1;\n\nexport interface EffortDials {\n /** Coding-loop turn cap (`maxAttempts`). */\n readonly maxAttempts: number;\n /** Evaluation rounds the harness may spend (`maxEvalRounds`). */\n readonly maxEvalRounds: number;\n /** The generator's in-loop visual self-evaluation threshold, 0–100 — not a serving layer's acceptance bar. */\n readonly selfEvalPassThreshold: number;\n /** Requested coding-model tier — a request to the deployment's router, never a model id. */\n readonly modelTier: ModelTier;\n /** Requested judge-model tier — same nature. */\n readonly judgeTier: ModelTier;\n}\n\nexport const EFFORT_DIALS: Readonly<Record<AppGenerationProfileEffort, EffortDials>> = {\n low: { maxAttempts: 5, maxEvalRounds: 1, selfEvalPassThreshold: 65, modelTier: \"fast\", judgeTier: \"fast\" },\n medium: { maxAttempts: 8, maxEvalRounds: 2, selfEvalPassThreshold: 70, modelTier: \"fast\", judgeTier: \"balanced\" },\n high: { maxAttempts: 8, maxEvalRounds: 3, selfEvalPassThreshold: 75, modelTier: \"balanced\", judgeTier: \"balanced\" },\n xhigh: { maxAttempts: 10, maxEvalRounds: 3, selfEvalPassThreshold: 80, modelTier: \"premium\", judgeTier: \"balanced\" },\n ultra: { maxAttempts: 12, maxEvalRounds: 4, selfEvalPassThreshold: 85, modelTier: \"premium\", judgeTier: \"premium\" },\n};\n\n/** The dials for a named level; `undefined` when no level is named (the deployment's options stand). */\nexport function effortDials(effort: AppGenerationProfileEffort | undefined): EffortDials | undefined {\n return effort === undefined ? undefined : EFFORT_DIALS[effort];\n}\n","/**\n * `createUiGenerator` — full-harness UI generation factory.\n *\n * Returns a {@link UiGenerator} backed by `dispatchGeneration` — the\n * same multi-turn coding-agent path the benchmark validates. OSS\n * production (`ggui serve`, hosted `ggui_render`) all route through\n * this seam, so bench == prod by construction.\n *\n * Pipeline:\n *\n * 1. `resolveRoute` + `applyRouteToEnv` — install BYOK key into\n * the process env so dispatch's adapters can read it.\n * 2. `createGeneratorTools` — assemble the coding-agent tool surface\n * (compile_component, validate_component, self_check,\n * get_primitives, get_design_system).\n * 3. `injectRenderingContext` + `injectContracts` — enrich the user\n * prompt with rendering hints + contract docs.\n * 4. `dispatchGeneration` — multi-turn loop with apply_changes,\n * self-check, evaluate, regenerate. The harness builds its own\n * rich system prompt with primitives doc + design-system docs +\n * pitfalls.\n *\n * This factory deliberately keeps a minimal surface — provider\n * routing, compilation, and the system prompt are all internal:\n *\n * - `adapter` option — provider routing is internal to dispatch\n * - `compileFn` option — `compile_component` tool runs inline\n * - `systemPromptBuilder` option — harness builds its own\n * - `withBrowserCompile` wrapper — dispatch returns compiled JS\n *\n * Callers who want a lightweight single-shot path can build it\n * themselves.\n */\nimport type { SingleComponentParams } from \"./harness/runtime.js\";\nimport type {\n GadgetDescriptor,\n GenerationError,\n JsonObject,\n GeneratorId,\n ModelRef,\n AppGenerationProfileEffort,\n} from \"@ggui-ai/protocol\";\nimport { DEFAULT_MODEL as PROTOCOL_DEFAULT_MODEL, isGeneratorId, modelRefOfRoute } from \"@ggui-ai/protocol\";\nimport type { GadgetCatalogAdapter } from \"@ggui-ai/gadgets\";\nimport type {\n GenerationMetadata,\n GenerationRuntimeProbe,\n GenerationRuntimeProbeOutcome,\n GenerationRuntimeProbeRepair,\n GeneratorTier,\n LlmProvider,\n UiGenerateInput,\n UiGenerateResult,\n UiGenerator,\n} from \"@ggui-ai/mcp-server-core\";\nimport {\n formatGeneratorSlug,\n isValidGeneratorSlug,\n parseGeneratorSlug,\n} from \"@ggui-ai/mcp-server-core\";\nimport { createGeneratorTools } from \"./adapters/index.js\";\nimport { dispatchGeneration, type VisualEvalAgentSpec } from \"./adapters/generation-dispatch.js\";\nimport {\n createRuntimeRenderCheck,\n type RuntimeRenderProbeConfig,\n} from \"./harness/check/runtime-render/adapter.js\";\nimport { generatorBuild } from \"./generator-build.js\";\nimport { hasProfile } from \"./boilerplate/styling-profile.js\";\nimport { effortDials } from \"./effort.js\";\nimport type { ProviderName } from \"./adapters/types.js\";\nimport type { GenerationResult } from \"./harness/result-types.js\";\nimport {\n canvasForRenderingContext,\n injectContracts,\n injectRenderingContext,\n injectVariance,\n} from \"./contract-context.js\";\nimport type { RenderingContext } from \"./contract-context.js\";\nimport type { DesignMode } from \"./design-mode.js\";\nimport { DEFAULT_DESIGN_MODE } from \"./design-mode.js\";\nimport { resolveRoute, applyRouteToEnv } from \"./adapters/provider-router.js\";\nimport type { QualityConfig, RuntimeProbeMeta, RuntimeProbeRepair } from \"./evaluation/types-public.js\";\nimport type { EvaluationConfig } from \"./evaluation/types.js\";\nimport type { AgentConfig } from \"./harness/llm-router.js\";\n\n/** The slug for the OSS default seed generator. */\nconst DEFAULT_TIER: GeneratorTier = \"default\";\n// ggui#1794 — the open-source default is protocol's, one source: a default switch moves one constant\n// (`@ggui-ai/protocol` `DEFAULT_MODEL`), never two. ggui#1743 moved it to Haiku 5.5 on benchmark's receipt.\nconst DEFAULT_MODEL: ModelRef = PROTOCOL_DEFAULT_MODEL;\n\nexport interface CreateUiGeneratorOptions {\n /**\n * Wire the runtime-render check into the harness's check leg — one\n * instance per generator, built from `runtimeRenderProbe` (the default\n * bounds when it is absent). When `true`, the runtime-render probe runs\n * ONCE at the exit decision,\n * after the coding turns, in an isolated subprocess: it mounts the\n * compiled component against the contract and catches crash-class and\n * contract-wiring bugs (a render that throws, a missing `useAction()`,\n * a wrong stream channel name). It is never on the per-turn hot path.\n *\n * Without an `evaluation` config the round is observe + one repair turn\n * (ggui#1380): a recoverable render crash buys exactly one repair turn\n * and one re-probe, then the generation serves what it has; a probe that\n * timed out, could not run, or had nothing to probe never blocks and\n * never repairs. The probe's status and timing ride the result's\n * metadata (`runtimeProbe`, `evalMs`). With an `evaluation` config the\n * probe is the evaluation round's exit gate instead.\n *\n * Default: `false` — keeps cold-start light. The probe pulls happy-dom\n * + @testing-library on first use (~700-1500ms cold). A serving\n * deployment that wants the probe's verdict on every card sets it.\n */\n readonly enableRuntimeRender?: boolean;\n /**\n * How the runtime-render probe runs its isolated worker (ggui#1380). A\n * serving deployment sets the probe's wall-clock bound, worker heap and\n * concurrency here; the defaults are the evaluation lane's (30 s, 512 MB,\n * no concurrency cap). The generator builds ONE check from it and hands\n * that instance to every generation it dispatches — the concurrency cap\n * lives on the instance, so it bounds the workers this generator has\n * live at once. Only read when `enableRuntimeRender` is on. Never part\n * of the prompt or the identity.\n */\n readonly runtimeRenderProbe?: RuntimeRenderProbeConfig;\n /** Maximum coding attempts per generation pass. */\n readonly maxAttempts?: number;\n /** Maximum evaluation rounds. */\n readonly maxEvalRounds?: number;\n /**\n * In-loop LLM evaluation config (ggui#1001). When set, every generation\n * runs the evaluator tiers after the coding leg (`maxRounds` defaults to\n * `maxEvalRounds`) and the harness result carries `evalResult` — the\n * probe verdict a downstream judge reads. Default: none, as today —\n * a serving deployment leaves it unset; offline minting jobs set a round.\n */\n readonly evaluation?: EvaluationConfig;\n /**\n * In-loop visual round config (per-canvas judging, a sample, the\n * stylesheet to render under). Forwarded verbatim; never part of the\n * prompt or the identity. Default: none — the round runs as today.\n */\n readonly visualEvaluation?: SingleComponentParams[\"visualEvaluation\"];\n /**\n * ggui#1250 — the in-loop VISUAL judge as its own agent (a vision provider, a model, and that\n * provider's key when the caller resolves keys itself). Absent (default): the judge is the\n * evaluation agent's provider, which on a lane without a vision path records the score half as\n * skipped (#1248). Forwarded verbatim to the dispatch; never part of the prompt or the identity.\n */\n readonly visualEvalAgent?: VisualEvalAgentSpec;\n /** Quality config controlling eval tiers + improvement behavior. */\n readonly qualityConfig?: QualityConfig;\n /**\n * Generator identity — registry key + declared model.\n *\n * The tier alone determines the {@link UiGenerator.slug} the factory\n * bakes onto the returned generator (`ui-gen-<tier>`); `model` is the\n * generator's declared model field and is never part of the slug\n * (ggui#923). Defaults to tier `'default'` → slug `ui-gen-default`,\n * the OSS seed, with the factory's default model.\n *\n * The actual model used per request still comes from\n * `UiGenerateInput.llm.model` (operators may override via BYOK).\n * The identity here is the registry-level handle, not a runtime\n * model constraint.\n *\n * Mutually-exclusive shortcut: pass `slug` instead of `tier` and the\n * factory parses the tier from it; `model` may accompany either form.\n * The factory throws if `slug` and `tier` are both supplied.\n */\n readonly tier?: GeneratorTier;\n readonly model?: ModelRef;\n readonly slug?: string;\n /**\n * Per-deployment gadget descriptor source. Wired once at factory\n * time; the generator resolves descriptors per-call via\n * `gadgetCatalog.list(input.appId)` when `input.appGadgets` is\n * absent. See {@link GadgetCatalogAdapter} (`@ggui-ai/gadgets`) for\n * the port + the two batteries-included implementations.\n *\n * Wiring patterns:\n *\n * ```ts\n * // OSS: stdlib seed, no app-specific catalogs.\n * createUiGenerator({\n * gadgetCatalog: InMemoryGadgetCatalog.withDefault(STDLIB_GADGETS),\n * });\n *\n * // Cloud / prod: TTL cache over a registry-backed adapter.\n * createUiGenerator({\n * gadgetCatalog: new CachingGadgetCatalog(\n * new DynamoGadgetCatalog(appMetadataStore),\n * { ttlMs: 30_000 },\n * ),\n * });\n * ```\n *\n * Per-call resolution precedence (in {@link UiGenerator.generate}):\n *\n * 1. `input.appGadgets` (pre-fetched by caller — handler-side path)\n * 2. `gadgetCatalog.list(input.appId)` (factory path, this option)\n * 3. empty list (legacy callers — no gadgets resolved)\n *\n * Optional. When omitted, callers MUST pre-fetch and pass\n * `appGadgets` themselves; the legacy handler path stays unchanged.\n */\n readonly gadgetCatalog?: GadgetCatalogAdapter;\n /**\n * When `true`, `generate()` never mutates `process.env` — the\n * resolved provider route is threaded structurally into the\n * dispatch call instead of being written to and restored from the\n * process environment. Use this when running concurrent\n * generations in one process (the default backup/mutate/restore\n * dance is NOT concurrency-safe: two simultaneous calls race on\n * the shared `process.env`).\n *\n * Default `false` — preserves the original env-mutation behavior\n * for callers that don't need concurrent generations in-process.\n */\n readonly disableEnvMutation?: boolean;\n /**\n * Retry observer (#489) — see `AgentConfig.onRetry`. Bound ONCE at\n * factory construction time (mirrors `disableEnvMutation`), not\n * per-call: `generate()` is invoked once per request, but the\n * generator instance itself is typically long-lived and cached by\n * the caller, so a single observer covers every generation it runs.\n * Fires whenever any agent's `apiCall()` retries a rate-limited\n * request. Absent (default) is a no-op — retries still happen and\n * still log via `console.warn`, just without a caller-side hook.\n */\n readonly onRetry?: AgentConfig[\"onRetry\"];\n /**\n * Generation observer. Invoked once per successful `generate()` with\n * the FULL harness result — source, compiled code, token counters,\n * timing breakdown, evaluation rounds and (when configured) the\n * per-canvas visual scores — before it is projected onto the\n * `UiGenerateResult` envelope, which carries only what the protocol\n * needs. Lets a host record or forward the complete run without\n * re-deriving it from the envelope. Bound ONCE at construction\n * (mirrors `onRetry`); not invoked when generation fails. An\n * exception thrown by the observer is the caller's own and fails\n * that generation like any other error on the path — keep it\n * non-throwing.\n */\n readonly onGenerated?: (result: GenerationResult) => void;\n /**\n * Which generation triad to run. `constrained` (default) is the\n * design-system triad — byte-identical to the generator's behaviour\n * before this option existed. `free` relaxes only the design\n * vocabulary (raw HTML, inline CSS, literal spacing / typography /\n * radius; the design package importable but optional) while keeping\n * every hard contract: the boilerplate-typed wire hooks, the import\n * allowlist + security bans, the host envelope, the budgets, the\n * blueprint-reuse shape, and brand-bearing color on the closed\n * `--ggui-color-*` token manifest. Reaches the prompt, boilerplate,\n * tier-0 gate, axis checks and evaluator criteria through the harness.\n * The rendering canvas the `free` prompt states is derived from\n * `input.rendering` (device × shell, refined by viewport width).\n */\n readonly designMode?: DesignMode;\n}\n\nexport function createUiGenerator(options: CreateUiGeneratorOptions = {}): UiGenerator {\n const {\n enableRuntimeRender = false,\n runtimeRenderProbe,\n maxAttempts,\n maxEvalRounds,\n evaluation,\n visualEvaluation,\n visualEvalAgent,\n qualityConfig,\n gadgetCatalog,\n disableEnvMutation = false,\n onRetry,\n onGenerated,\n designMode,\n } = options;\n // ggui#1380 — ONE runtime-render check per generator: the instance owns\n // the probe's concurrency cap, so it must outlive a single generation.\n const runtimeRender = enableRuntimeRender\n ? createRuntimeRenderCheck(runtimeRenderProbe)\n : undefined;\n\n const identity = resolveIdentity(options);\n\n return {\n slug: identity.slug,\n tier: identity.tier,\n model: identity.model,\n async generate(input: UiGenerateInput): Promise<UiGenerateResult> {\n const startedAt = Date.now();\n\n // Map LlmProvider → ProviderName. dispatch uses 'claude' where\n // mcp-server-core uses 'anthropic'; 'bedrock' also routes through\n // the claude adapter (route resolves the model to a bedrock\n // inference profile when needed).\n const provider = mapLlmProviderToDispatchProvider(input.llm.provider);\n\n // BYOK key injection. resolveRoute reads the typed route +\n // apiKey and returns env mutations (ANTHROPIC_API_KEY=<byok>).\n // dispatch's adapters read keys from process.env, so we\n // install the routed env for the duration of this call and\n // restore on exit. `input.llm` IS structurally an `LlmRoute`\n // (the typed `LlmSelection`), so we pass it as the route input\n // directly — no string threading.\n let route: ReturnType<typeof resolveRoute>;\n try {\n const baseEnv: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (v !== undefined) baseEnv[k] = v;\n }\n route = resolveRoute({\n route: input.llm,\n apiKey: input.providerKey.key,\n env: baseEnv,\n });\n } catch (err) {\n return failWithoutMetadata(input, identity.slug, startedAt, {\n code: \"PRODUCTION_FAILED\",\n message: err instanceof Error ? err.message : String(err),\n details: { kind: \"route-resolution-failed\" },\n });\n }\n\n const envBackup: Record<string, string | undefined> = {};\n if (!disableEnvMutation) {\n for (const k of Object.keys(route.env)) envBackup[k] = process.env[k];\n const baseEnvForApply: Record<string, string> = {};\n for (const [k, v] of Object.entries(process.env)) {\n if (v !== undefined) baseEnvForApply[k] = v;\n }\n const routedEnv = applyRouteToEnv(baseEnvForApply, route);\n for (const [k, v] of Object.entries(routedEnv)) process.env[k] = v;\n // Also delete any keys the route asked to clear (route.env values\n // marked undefined).\n for (const [k, v] of Object.entries(route.env)) {\n if (v === undefined) delete process.env[k];\n }\n }\n\n // #484 — when `disableEnvMutation` is set, skip the process-env\n // mutation above entirely and thread the resolved route\n // structurally into the dispatch call instead. `route.env`\n // already carries exactly the key(s) that would have gone into\n // `process.env`, so no extra resolution work is needed here.\n //\n // ggui#1185 — the login path has NO key to write anywhere: the\n // route decision `auth: 'claude-code-login'` is carried as\n // `routeOverride.claudeCodeLogin` in BOTH env modes, because the\n // flag is the only way the decision reaches `createAgent` /\n // `createVisionAgent` (which select the login client on it).\n const routeOverride =\n route.auth === \"claude-code-login\"\n ? { claudeCodeLogin: true }\n : disableEnvMutation\n ? {\n apiKey:\n route.env[\"ANTHROPIC_API_KEY\"] ??\n route.env[\"OPENAI_API_KEY\"] ??\n route.env[\"GEMINI_API_KEY\"] ??\n route.env[\"OPENROUTER_API_KEY\"],\n useBedrock: route.env[\"CLAUDE_CODE_USE_BEDROCK\"] === \"1\",\n }\n : undefined;\n\n // ggui#1459 — the named level whose dials this generation applied; set\n // where the dials are resolved, read by both metadata arms below.\n let effortRan: AppGenerationProfileEffort | undefined;\n try {\n const tools = createGeneratorTools({\n ...(input.contract ? { contract: input.contract } : {}),\n });\n\n // Build the user prompt: prompt → rendering context → variance\n // → contract block. Variance lands BEFORE the contract block so\n // the styling directive frames the structural spec that follows\n // (the LLM treats the last block read as most-authoritative for\n // shape, so contract goes last; variance frames \"how\" while\n // contract pins \"what\"). Mirrors what cloud's `generateWithSDK`\n // and the bench runner both produce, so the LLM sees identical\n // input across all three call sites.\n const rendering = mapRendering(input.rendering);\n const promptWithRendering = rendering\n ? injectRenderingContext(input.request.prompt, rendering)\n : input.request.prompt;\n // Canvas class for the `free` prompt — TOLD, never guessed.\n // Ignored by the constrained prompt (its shell/screen\n // descriptors stay byte-identical).\n const canvas = rendering ? canvasForRenderingContext(rendering) : undefined;\n const shellType = harnessShellForRendering(rendering);\n const promptWithVariance = injectVariance(promptWithRendering, input.variance, {\n profileDeclared: hasProfile(input.profile),\n });\n\n // Resolve appGadgets by precedence:\n // 1. input.appGadgets (caller pre-fetched, handler path)\n // 2. gadgetCatalog.list(input.appId) (factory wiring)\n // 3. undefined (no catalog)\n // Catalog errors propagate — a silent empty result would mask\n // broken catalogs as \"no gadgets registered\" and let renders\n // through with unresolved refs.\n const resolvedAppGadgets: readonly GadgetDescriptor[] | undefined =\n input.appGadgets !== undefined\n ? input.appGadgets\n : gadgetCatalog !== undefined && input.appId !== undefined\n ? await gadgetCatalog.list(input.appId)\n : undefined;\n\n const userPrompt = injectContracts(promptWithVariance, input.contract, resolvedAppGadgets);\n\n // `effort` (ggui#1059): a named level's dials override the\n // deployment's options for THIS generation; absent ⇒ untouched.\n // Prompt bytes never move with it (dials only).\n const dials = effortDials(input.profile?.effort);\n if (dials !== undefined) effortRan = input.profile?.effort;\n const effectiveMaxAttempts = dials?.maxAttempts ?? maxAttempts;\n const effectiveMaxEvalRounds = dials?.maxEvalRounds ?? maxEvalRounds;\n const effectiveEvaluation =\n dials !== undefined && evaluation !== undefined\n ? { ...evaluation, maxRounds: dials.maxEvalRounds }\n : evaluation;\n const effectiveVisualEvaluation =\n dials !== undefined && visualEvaluation !== undefined\n ? { ...visualEvaluation, passThreshold: dials.selfEvalPassThreshold }\n : visualEvaluation;\n\n const result = await dispatchGeneration({\n provider,\n userPrompt,\n model: route.model,\n tools,\n ...(input.contract ? { contract: input.contract } : {}),\n originalPrompt: input.request.prompt,\n ...(effectiveMaxAttempts !== undefined ? { maxAttempts: effectiveMaxAttempts } : {}),\n ...(effectiveMaxEvalRounds !== undefined\n ? { maxEvalRounds: effectiveMaxEvalRounds }\n : {}),\n ...(effectiveEvaluation !== undefined ? { evaluation: effectiveEvaluation } : {}),\n ...(effectiveVisualEvaluation !== undefined\n ? { visualEvaluation: effectiveVisualEvaluation }\n : {}),\n ...(qualityConfig !== undefined ? { qualityConfig } : {}),\n ...(resolvedAppGadgets !== undefined ? { appGadgets: resolvedAppGadgets } : {}),\n // Forward the third-party wrapper `.d.ts` map the render\n // handler pre-fetched. Reaches both the code-gen prompt's\n // `Type:` lines and the coding-agent typecheck overlay via\n // `dispatchGeneration`.\n ...(input.gadgetTypes !== undefined ? { gadgetTypes: input.gadgetTypes } : {}),\n enableRuntimeRender,\n ...(runtimeRender !== undefined ? { runtimeRender } : {}),\n ...(routeOverride !== undefined ? { routeOverride } : {}),\n ...(onRetry !== undefined ? { onRetry } : {}),\n ...(designMode !== undefined ? { designMode } : {}),\n ...(canvas !== undefined ? { canvas } : {}),\n // ggui#1279 — the shell the declared rendering composes for (chat only; see harnessShellForRendering).\n ...(shellType !== undefined ? { shellType } : {}),\n ...(input.profile !== undefined ? { profile: input.profile } : {}),\n // ggui#1250 — the named in-loop visual judge, when this generator was built with one.\n ...(visualEvalAgent !== undefined ? { visualEvalAgent } : {}),\n // Fixture props reach the in-loop probe + visual round only (never the prompt, never identity).\n ...(input.fixtureProps !== undefined ? { fixtureProps: input.fixtureProps } : {}),\n });\n\n onGenerated?.(result);\n\n const runtimeProbe = metadataRuntimeProbe(result);\n const evalMs = metadataEvalMs(result);\n const metadata: GenerationMetadata = {\n provider: input.llm.provider,\n generator: identity.slug,\n model: modelRefOfRoute(input.llm),\n inputTokens: result.tokens.input,\n outputTokens: result.tokens.output,\n latencyMs: Date.now() - startedAt,\n cacheHit: false,\n attempts: result.turnsUsed,\n // ggui#1280 — the build that made this generation (template keys, never per-request).\n build: generatorBuild(designMode ?? DEFAULT_DESIGN_MODE),\n // ggui#1459 — the level that ran; absent when none was applied.\n ...(effortRan !== undefined ? { effort: effortRan } : {}),\n // Prompt-cache counters are provider-specific (Claude reports\n // them; others omit). Pass through truthfully — absent on the\n // adapter result stays absent here, never defaulted to 0.\n ...(result.cacheReadTokens !== undefined\n ? { cacheReadTokens: result.cacheReadTokens }\n : {}),\n ...(result.cacheCreationTokens !== undefined\n ? { cacheCreationTokens: result.cacheCreationTokens }\n : {}),\n // ggui#1380 — the runtime probe's record and the eval rounds' wall,\n // when the harness ran a round; absent stays absent.\n ...(runtimeProbe !== undefined ? { runtimeProbe } : {}),\n ...(evalMs !== undefined ? { evalMs } : {}),\n };\n\n return {\n ok: true,\n response: {\n sessionId: `session_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n componentCode: result.compiledCode,\n ...(result.sourceCode ? { sourceCode: result.sourceCode } : {}),\n ...(input.contract ? { contract: input.contract } : {}),\n },\n metadata,\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const details: JsonObject = { kind: \"harness-failed\" };\n if (err instanceof Error && err.stack) details[\"stack\"] = err.stack;\n return {\n ok: false,\n error: {\n code: \"PRODUCTION_FAILED\",\n message,\n details,\n },\n metadata: {\n provider: input.llm.provider,\n generator: identity.slug,\n model: modelRefOfRoute(input.llm),\n inputTokens: 0,\n outputTokens: 0,\n latencyMs: Date.now() - startedAt,\n cacheHit: false,\n // ggui#1280 — a failed generation still names the build that failed.\n build: generatorBuild(designMode ?? DEFAULT_DESIGN_MODE),\n // ggui#1459 — and the level it ran, when one was applied.\n ...(effortRan !== undefined ? { effort: effortRan } : {}),\n },\n };\n } finally {\n // Restore env to its pre-call state.\n for (const [k, v] of Object.entries(envBackup)) {\n if (v === undefined) delete process.env[k];\n else process.env[k] = v;\n }\n }\n },\n };\n}\n\nfunction resolveIdentity(opts: CreateUiGeneratorOptions): {\n slug: GeneratorId;\n tier: GeneratorTier;\n model: ModelRef;\n} {\n const hasSlug = typeof opts.slug === \"string\" && opts.slug.length > 0;\n if (hasSlug && opts.tier !== undefined) {\n throw new Error(\"createUiGenerator: pass either { slug } or { tier } — not both.\");\n }\n const model = opts.model ?? DEFAULT_MODEL;\n if (hasSlug) {\n const slug = opts.slug!;\n const parsed = parseGeneratorSlug(slug);\n if (!parsed || !isGeneratorId(slug)) {\n throw new Error(\n `createUiGenerator: slug ${JSON.stringify(slug)} is not a valid ui-gen-<tier> identifier.`\n );\n }\n return { slug, tier: parsed.tier, model };\n }\n const tier = opts.tier ?? DEFAULT_TIER;\n const slug = formatGeneratorSlug({ tier });\n if (!isValidGeneratorSlug(slug)) {\n // Unreachable: formatGeneratorSlug throws on malformed components,\n // so a slug it returns must parse. Defensive check kept to surface\n // any future drift between the two helpers.\n throw new Error(\n `createUiGenerator: formatted slug ${JSON.stringify(slug)} round-trips as invalid — formatGeneratorSlug/isValidGeneratorSlug drift.`\n );\n }\n return { slug, tier, model };\n}\n\n/**\n * ggui#1380 — one probe's meta, projected onto the metadata's outcome ARM BY\n * ARM: the outcome fields (`status`, `verdict`, `failChecks`, `elapsedMs`)\n * are copied; the engine's own detail (`reason`, `renderMs`, `hostLoad`)\n * stays on the harness result. No cast — each arm is rebuilt as a literal of\n * the target arm, so a field the metadata does not carry cannot ride along\n * and a field the arm requires cannot be dropped. Absent stays absent.\n */\nfunction metadataProbeOutcome(meta: RuntimeProbeMeta): GenerationRuntimeProbeOutcome {\n const elapsed = {\n ...(meta.elapsedMs !== undefined ? { elapsedMs: meta.elapsedMs } : {}),\n ...(meta.queuedMs !== undefined ? { queuedMs: meta.queuedMs } : {}),\n };\n if (meta.status !== \"ran\") return { status: meta.status, ...elapsed };\n if (meta.verdict === \"pass\") return { status: \"ran\", verdict: \"pass\", ...elapsed };\n return { status: \"ran\", verdict: \"fail\", failChecks: meta.failChecks, ...elapsed };\n}\n\n/**\n * ggui#1380 — the repair record, arm by arm: `compiled: false` is carried as\n * is (no re-probe, so no after); `compiled: true` carries the re-probe's meta\n * projected with the same function as the record's own outcome.\n */\nfunction metadataProbeRepair(repair: RuntimeProbeRepair): GenerationRuntimeProbeRepair {\n return repair.compiled\n ? { attempted: true, compiled: true, trigger: metadataProbeOutcome(repair.trigger) }\n : { attempted: true, compiled: false };\n}\n\n/**\n * ggui#1380 — the harness result's probe record, projected onto the metadata\n * a host reads. The outcome fields are the LAST probe's (the re-probe's when\n * the repair compiled, else the pre-repair probe's — exactly what the harness\n * stamps on `evalResult.runtimeProbe`), and `repair` is present only when a\n * repair turn was bought. Absent when no probe ran — never a default status.\n */\nfunction metadataRuntimeProbe(result: GenerationResult): GenerationRuntimeProbe | undefined {\n const probe = result.evalResult?.runtimeProbe;\n if (probe === undefined) return undefined;\n const repair = result.evalResult?.runtimeProbeRepair;\n return {\n ...metadataProbeOutcome(probe),\n ...(repair !== undefined ? { repair: metadataProbeRepair(repair) } : {}),\n };\n}\n\n/**\n * ggui#1380 — the eval rounds' wall-clock, present only when a round ran:\n * a generation with no round has nothing to time, and the field stays\n * absent rather than reporting a structural 0.\n */\nfunction metadataEvalMs(result: GenerationResult): number | undefined {\n const breakdown = result.breakdown;\n if (breakdown === undefined || breakdown.evalRounds === 0) return undefined;\n return breakdown.evalMs;\n}\n\nfunction mapLlmProviderToDispatchProvider(provider: LlmProvider): ProviderName {\n switch (provider) {\n case \"anthropic\":\n case \"bedrock\":\n return \"claude\";\n case \"openai\":\n return \"openai\";\n case \"google\":\n return \"google\";\n case \"openrouter\":\n return \"openrouter\";\n }\n}\n\n/**\n * ggui#1279 — the harness shell a declared rendering composes for. The canvas\n * (`canvasForRenderingContext`) already follows the rendering; the WHAT leg's\n * layout and the HOW leg's shell descriptor did not, so a declared chat card\n * was scaffolded to \"fill the frame\" while the user prompt and the fit verdict\n * treated it as an inline card. Only a declared CHAT shell changes anything.\n * `fullscreen` IS the harness default, and `partial` has no layout of its own\n * yet, so both pass no shell and those generations stay byte-identical — named\n * here rather than guessed.\n */\nfunction harnessShellForRendering(rendering: RenderingContext | undefined): \"chat\" | undefined {\n if (rendering === undefined) return undefined;\n switch (rendering.shell) {\n case \"chat\":\n return \"chat\";\n case \"fullscreen\":\n case \"partial\":\n return undefined;\n }\n}\n\nfunction mapRendering(rendering: UiGenerateInput[\"rendering\"]): RenderingContext | undefined {\n if (!rendering) return undefined;\n return {\n device: rendering.device,\n shell: rendering.shell,\n ...(rendering.viewport ? { viewport: rendering.viewport } : {}),\n };\n}\n\nfunction failWithoutMetadata(\n input: UiGenerateInput,\n generatorSlug: GeneratorId,\n startedAt: number,\n error: GenerationError\n): UiGenerateResult {\n return {\n ok: false,\n error,\n metadata: {\n provider: input.llm.provider,\n generator: generatorSlug,\n model: modelRefOfRoute(input.llm),\n inputTokens: 0,\n outputTokens: 0,\n latencyMs: Date.now() - startedAt,\n cacheHit: false,\n },\n };\n}\n\n// ── Utility re-export ────────────────────────────────────────\n//\n// Callers (console, ad-hoc scripts, third-party integrations) sometimes\n// have a raw LLM response that includes ```tsx fences and want to\n// extract the code body. The new harness path doesn't use this — it\n// gets clean compiled JS back from `compile_component` — but the\n// utility is small and useful, so we keep it exported.\n\nconst CODE_START_PATTERN = /^(import\\s|export\\s|const\\s|function\\s|class\\s|\\/\\*|\\/\\/)/;\n\nexport function extractComponentCode(raw: string): string {\n const fencePattern = /```([a-zA-Z0-9+\\-_]*)\\s*\\n([\\s\\S]*?)```/g;\n const fences: Array<{ lang: string; body: string }> = [];\n let match: RegExpExecArray | null;\n while ((match = fencePattern.exec(raw)) !== null) {\n const lang = (match[1] ?? \"\").toLowerCase();\n const body = match[2] ?? \"\";\n fences.push({ lang, body });\n }\n\n if (fences.length > 0) {\n const priority = [\"tsx\", \"jsx\", \"typescript\", \"ts\", \"javascript\", \"js\", \"\"];\n for (const preferred of priority) {\n const hit = fences.find((f) => f.lang === preferred);\n if (hit) return hit.body.trim();\n }\n const firstBody = fences[0]?.body ?? \"\";\n return firstBody.trim();\n }\n\n const trimmed = raw.trim();\n if (CODE_START_PATTERN.test(trimmed)) return trimmed;\n const codeMarkerIndex = findCodeStart(raw);\n if (codeMarkerIndex > 0) return raw.slice(codeMarkerIndex).trim();\n return trimmed;\n}\n\nfunction findCodeStart(text: string): number {\n const markers = [\n /\\n\\s*import\\s/,\n /\\n\\s*export\\s/,\n /\\n\\s*\\/\\*\\s/,\n /\\n\\s*const\\s/,\n /\\n\\s*function\\s/,\n ];\n let earliest = -1;\n for (const m of markers) {\n const candidate = m.exec(text);\n if (candidate && (earliest === -1 || candidate.index < earliest)) {\n earliest = candidate.index;\n }\n }\n return earliest;\n}\n"]}
|