@ggui-ai/ui-gen 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{adapter-Du7P_5Fx.d.ts → adapter-BJwn74rx.d.ts} +49 -1
- package/dist/adapters/generation-dispatch.d.ts +32 -7
- package/dist/adapters/generation-dispatch.js +1997 -216
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.js +29 -6
- package/dist/adapters/index.js.map +1 -1
- package/dist/advanced/index.d.ts +15 -12
- package/dist/advanced/index.js +2013 -270
- package/dist/advanced/index.js.map +1 -1
- package/dist/{axes-CzLEMDeB.d.ts → axes-CKVCzR_x.d.ts} +1 -1
- package/dist/bank-Ctdp3FUA.d.ts +118 -0
- package/dist/blueprint-validator.js +416 -92
- package/dist/blueprint-validator.js.map +1 -1
- package/dist/boilerplate.d.ts +2 -2
- package/dist/boilerplate.js +34 -15
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +13 -5
- package/dist/check/index.js +56 -3
- package/dist/check/index.js.map +1 -1
- package/dist/classifier/index.d.ts +2 -2
- package/dist/compose.d.ts +2 -2
- package/dist/{create-ui-generator-GIhzx08x.d.ts → create-ui-generator-N4gRXpcL.d.ts} +11 -4
- package/dist/{design-mode-DLufhrNp.d.ts → design-mode-DGWN_Gkm.d.ts} +1 -1
- package/dist/{dispatch-BnAH56p4.d.ts → dispatch-BUoXRj_r.d.ts} +6 -4
- package/dist/evaluation/axis-checks/index.d.ts +7 -6
- package/dist/evaluation/axis-checks/index.js +90 -2
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.d.ts +6 -5
- package/dist/evaluation/axis-checks/registry.js +88 -1
- package/dist/evaluation/axis-checks/registry.js.map +1 -1
- package/dist/evaluation/index.d.ts +189 -344
- package/dist/evaluation/index.js +1272 -59
- package/dist/evaluation/index.js.map +1 -1
- package/dist/evaluation/types.d.ts +26 -1
- package/dist/evaluation/types.js.map +1 -1
- package/dist/fragments/index.d.ts +3 -3
- package/dist/{generate-9IeNT4ZY.d.ts → generate-tSO_shQ0.d.ts} +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +7 -7
- package/dist/harness/check/runtime-render/index.js +416 -92
- package/dist/harness/check/runtime-render/index.js.map +1 -1
- package/dist/harness/check/runtime-render/render-check-worker.js +393 -88
- package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
- package/dist/harness/index.d.ts +5 -6
- package/dist/harness/index.js +69 -20
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/prompts.d.ts +2 -2
- package/dist/harness/prompts.js +10 -1
- package/dist/harness/prompts.js.map +1 -1
- package/dist/harness/result-types.d.ts +19 -5
- package/dist/harness/result-types.js.map +1 -1
- package/dist/harness/runtime.d.ts +21 -7
- package/dist/harness/runtime.js +36 -17
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +6 -4
- package/dist/harness/types-public.js +43 -18
- package/dist/harness/types-public.js.map +1 -1
- package/dist/harness/validator-trace-sink.d.ts +6 -5
- package/dist/hash.d.ts +1 -1
- package/dist/index.d.ts +64 -13
- package/dist/index.js +2023 -270
- package/dist/index.js.map +1 -1
- package/dist/patch.d.ts +5 -5
- package/dist/policy.d.ts +1 -1
- package/dist/{prompts-YU9piOgs.d.ts → prompts-BhNUuRoZ.d.ts} +1 -1
- package/dist/tools/get-primitives-ts.d.ts +1 -1
- package/dist/tools/get-primitives-ts.js +1 -1
- package/dist/tools/get-primitives-ts.js.map +1 -1
- package/dist/tools/render-check-worker.js +8 -1
- package/dist/tools/render-check-worker.js.map +1 -1
- package/dist/{types-BOvHNG7K.d.ts → types-Dh1s4K9j.d.ts} +1 -1
- package/dist/types-public-B7wn4ce5.d.ts +959 -0
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/visual-evaluator-C9L-o6ap.d.ts +639 -0
- package/dist/workflows.d.ts +5 -5
- package/package.json +12 -12
- package/src/adapters/generation-dispatch.ts +38 -2
- package/src/adapters/tools.ts +2 -1
- package/src/boilerplate/free-design-prompt.ts +4 -4
- package/src/boilerplate/generate.ts +26 -1
- package/src/boilerplate/hard-sections.ts +14 -14
- package/src/boilerplate/system-prompt.ts +1 -1
- package/src/boilerplate/templates/layouts/chat-mobile.tsx.tmpl +3 -1
- package/src/boilerplate/templates/layouts/chat-universal.tsx.tmpl +3 -1
- package/src/boilerplate/templates/layouts/fullscreen-desktop.tsx.tmpl +3 -1
- package/src/boilerplate/templates/layouts/fullscreen-universal.tsx.tmpl +3 -1
- package/src/check/index.ts +1 -0
- package/src/check/run-tier0.ts +6 -3
- package/src/check/sample-props.ts +63 -0
- package/src/coding-agent/tools.ts +4 -1
- package/src/contract-context.ts +1 -1
- package/src/create-harness.ts +3 -3
- package/src/create-ui-generator.ts +20 -1
- package/src/evaluation/__fixtures__/png.ts +100 -0
- package/src/evaluation/axis-checks/checks/state-merge.ts +1 -1
- package/src/evaluation/axis-checks/checks/universal.ts +111 -0
- package/src/evaluation/axis-checks/dispatch.ts +4 -1
- package/src/evaluation/cost-tracker.ts +54 -6
- package/src/evaluation/criteria/bank.ts +85 -0
- package/src/evaluation/criteria/context.ts +52 -0
- package/src/evaluation/criteria/edge-probe.ts +286 -0
- package/src/evaluation/criteria/edge.ts +202 -0
- package/src/evaluation/criteria/resolve.ts +207 -0
- package/src/evaluation/criteria/select.ts +79 -0
- package/src/evaluation/index.ts +27 -0
- package/src/evaluation/ink-extent.ts +200 -0
- package/src/evaluation/judge-spend.ts +48 -0
- package/src/evaluation/theme-css.ts +12 -5
- package/src/evaluation/types-public.ts +221 -3
- package/src/evaluation/types.ts +19 -0
- package/src/evaluation/visual-evaluator.ts +853 -51
- package/src/harness/check/runtime-render/adapter.ts +18 -0
- package/src/harness/check/runtime-render/probe-pending.ts +111 -0
- package/src/harness/check/runtime-render/render-check-host.ts +10 -6
- package/src/harness/check/runtime-render/render-check-worker.ts +6 -3
- package/src/harness/check/runtime-render/render-check.ts +417 -133
- package/src/harness/check/runtime-render/walk.ts +200 -0
- package/src/harness/coding/assemble-result.ts +2 -0
- package/src/harness/coding/generate-task-runner.ts +30 -0
- package/src/harness/coding/init-session.ts +5 -3
- package/src/harness/coding/run-coding-turn.ts +12 -4
- package/src/harness/coding/run-eval-round.ts +82 -3
- package/src/harness/in-loop-evaluation.ts +39 -0
- package/src/harness/llm-router.ts +58 -1
- package/src/harness/result-types.ts +9 -0
- package/src/harness/runtime.ts +14 -0
- package/src/harness/types-public.ts +10 -1
- package/src/harness-tool-names.ts +38 -0
- package/src/index.ts +17 -0
- package/src/internal/verdict-line.ts +33 -0
- package/src/run-check.ts +2 -0
- package/src/taught-tokens.ts +32 -0
- package/src/tools/get-primitives-ts.ts +1 -1
- package/src/tools/get-wire.ts +1 -1
- package/src/tools/render-check-worker.ts +2 -1
- package/src/tools/render-check.ts +8 -67
- package/src/tools.ts +11 -1
- package/src/validation/primitives.ts +1 -1
- package/dist/llm-router-DwwUK1bz.d.ts +0 -265
- package/dist/types-public-Bk6d1WLN.d.ts +0 -451
|
@@ -198,6 +198,8 @@ export function createRuntimeRenderCheck(
|
|
|
198
198
|
...queuedField(queuedMs),
|
|
199
199
|
renderMs: result.stats.renderMs,
|
|
200
200
|
...load,
|
|
201
|
+
// ggui#1398: report-only — carried to the probe's meta for the bench, never an issue.
|
|
202
|
+
...(result.stats.pendingAffordance !== undefined ? { pendingAffordance: result.stats.pendingAffordance } : {}),
|
|
201
203
|
};
|
|
202
204
|
},
|
|
203
205
|
};
|
|
@@ -376,6 +378,22 @@ export function toEvalIssue(issue: RenderCheckIssue): EvalIssue | null {
|
|
|
376
378
|
: `input priming failed: ${diag.inputPriming.error}`
|
|
377
379
|
);
|
|
378
380
|
}
|
|
381
|
+
if (diag?.walk) {
|
|
382
|
+
// ggui#1652: how far the walk over the card's screens got, so a
|
|
383
|
+
// multi-step card reads differently from a control that never rendered.
|
|
384
|
+
const w = diag.walk;
|
|
385
|
+
const stopped = {
|
|
386
|
+
explored: "every reachable control pressed",
|
|
387
|
+
"press-cap": "stopped at the press cap",
|
|
388
|
+
deadline: "stopped at the time budget",
|
|
389
|
+
"no-mount": "the card could not be mounted for the walk",
|
|
390
|
+
}[w.stoppedBy];
|
|
391
|
+
const named = w.namedControlSeen
|
|
392
|
+
? "a control naming the action rendered, but pressing it did not dispatch the action"
|
|
393
|
+
: "no screen rendered a control naming the action";
|
|
394
|
+
const last = w.lastPressed.length ? `; last pressed: ${w.lastPressed.join(", ")}` : "";
|
|
395
|
+
diagParts.push(`walk: ${w.presses} press(es) across ${w.screens} screen(s), ${stopped}; ${named}${last}`);
|
|
396
|
+
}
|
|
379
397
|
const diagSuffix = diagParts.length ? ` [observed: ${diagParts.join("; ")}]` : "";
|
|
380
398
|
|
|
381
399
|
switch (issue.check) {
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ggui#1398 leg 3 — the render check's stand-in for the runtime's pending
|
|
3
|
+
* state, and the rule for "the control visibly changed".
|
|
4
|
+
*
|
|
5
|
+
* In a served card, the runtime marks an action pending when the card's
|
|
6
|
+
* dispatch of it commits, and clears it when the session's next frame lands;
|
|
7
|
+
* `useActionPending` reads that state through wire's `ActionPendingContext`.
|
|
8
|
+
* The probe has no transport and no next frame, so it marks an action pending
|
|
9
|
+
* right after its own synthetic click really fired the action, looks at the
|
|
10
|
+
* clicked control, then clears it: one dispatch, one answer.
|
|
11
|
+
*/
|
|
12
|
+
import type { ActionPendingSource } from "@ggui-ai/wire";
|
|
13
|
+
|
|
14
|
+
/** An {@link ActionPendingSource} the probe drives by hand. */
|
|
15
|
+
export interface ProbePendingSource extends ActionPendingSource {
|
|
16
|
+
/** Mark `actionName` pending and notify subscribers. */
|
|
17
|
+
mark(actionName: string): void;
|
|
18
|
+
/** Clear every pending action (the "answer landed"), notifying only if something was pending. */
|
|
19
|
+
clear(): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createProbePendingSource(): ProbePendingSource {
|
|
23
|
+
const pending = new Set<string>();
|
|
24
|
+
const listeners = new Set<() => void>();
|
|
25
|
+
const notify = (): void => {
|
|
26
|
+
for (const listener of [...listeners]) listener();
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
isPending: (actionName) => pending.has(actionName),
|
|
30
|
+
subscribe: (listener) => {
|
|
31
|
+
listeners.add(listener);
|
|
32
|
+
return () => {
|
|
33
|
+
listeners.delete(listener);
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
mark: (actionName) => {
|
|
37
|
+
pending.add(actionName);
|
|
38
|
+
notify();
|
|
39
|
+
},
|
|
40
|
+
clear: () => {
|
|
41
|
+
if (pending.size === 0) return;
|
|
42
|
+
pending.clear();
|
|
43
|
+
notify();
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** What a control shows, for a before/after comparison around a dispatch. */
|
|
49
|
+
export interface ControlLook {
|
|
50
|
+
/** Still in the document; `false` when the card replaced the control. */
|
|
51
|
+
readonly connected: boolean;
|
|
52
|
+
/** `disabled`, or `aria-disabled="true"`. */
|
|
53
|
+
readonly disabled: boolean;
|
|
54
|
+
/** `aria-busy="true"`. */
|
|
55
|
+
readonly ariaBusy: boolean;
|
|
56
|
+
/** The control's text. */
|
|
57
|
+
readonly text: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The DOM surface {@link lookOf} reads: the probe's `MinimalElement` plus
|
|
62
|
+
* the optional `isConnected` a live DOM node carries, and an input's live
|
|
63
|
+
* `value` (an `<input type="submit">` shows its label through it).
|
|
64
|
+
*/
|
|
65
|
+
export interface LookableElement {
|
|
66
|
+
readonly tagName?: string;
|
|
67
|
+
readonly textContent: string | null;
|
|
68
|
+
getAttribute(name: string): string | null;
|
|
69
|
+
readonly isConnected?: boolean;
|
|
70
|
+
readonly value?: unknown;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function lookOf(el: LookableElement): ControlLook {
|
|
74
|
+
return {
|
|
75
|
+
connected: el.isConnected !== false,
|
|
76
|
+
// React renders `disabled={true}` as `disabled=""`, so presence is the test.
|
|
77
|
+
disabled: el.getAttribute("disabled") !== null || el.getAttribute("aria-disabled") === "true",
|
|
78
|
+
ariaBusy: el.getAttribute("aria-busy") === "true",
|
|
79
|
+
text:
|
|
80
|
+
el.tagName?.toLowerCase() === "input"
|
|
81
|
+
? String(typeof el.value === "string" ? el.value : (el.getAttribute("value") ?? ""))
|
|
82
|
+
: (el.textContent ?? ""),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Whether `work` settles within `ms`. It never cancels `work`; it only stops
|
|
88
|
+
* waiting for it, so a phase can give up on a card that stalls.
|
|
89
|
+
*/
|
|
90
|
+
export async function settlesWithin(ms: number, work: Promise<unknown>): Promise<boolean> {
|
|
91
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
92
|
+
const expired = new Promise<false>((resolve) => {
|
|
93
|
+
timer = setTimeout(() => resolve(false), Math.max(0, ms));
|
|
94
|
+
});
|
|
95
|
+
try {
|
|
96
|
+
return await Promise.race([work.then(() => true), expired]);
|
|
97
|
+
} finally {
|
|
98
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Whether the control visibly changed between two looks: it became disabled
|
|
104
|
+
* or busy, its text changed (whitespace aside), or the card replaced it.
|
|
105
|
+
*/
|
|
106
|
+
export function lookChanged(before: ControlLook, after: ControlLook): boolean {
|
|
107
|
+
if (before.connected && !after.connected) return true;
|
|
108
|
+
if (!before.disabled && after.disabled) return true;
|
|
109
|
+
if (!before.ariaBusy && after.ariaBusy) return true;
|
|
110
|
+
return before.text.trim() !== after.text.trim();
|
|
111
|
+
}
|
|
@@ -46,6 +46,7 @@ import { runSandboxed } from '@ggui-ai/sandbox';
|
|
|
46
46
|
import type { SandboxResult } from '@ggui-ai/sandbox';
|
|
47
47
|
import type { ProbeHostLoad } from '../../../evaluation/types-public.js';
|
|
48
48
|
import type { RenderCheckResult, RunRenderCheckInput } from './render-check.js';
|
|
49
|
+
import { parseVerdictLine } from '../../../internal/verdict-line.js';
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
52
|
* The subprocess bounds of one isolated check (ggui#1380). They are
|
|
@@ -227,12 +228,9 @@ export function mapSandboxResultToCheckResult(
|
|
|
227
228
|
t0,
|
|
228
229
|
);
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
-
if (stdout.length === 0) {
|
|
232
|
-
return unverified('render check worker exited without producing a verdict.', t0);
|
|
233
|
-
}
|
|
231
|
+
let verdict: RenderCheckResult | undefined;
|
|
234
232
|
try {
|
|
235
|
-
|
|
233
|
+
verdict = parseVerdictLine<RenderCheckResult>(result.stdout);
|
|
236
234
|
} catch (err) {
|
|
237
235
|
return unverified(
|
|
238
236
|
`render check worker verdict was not valid JSON — ${
|
|
@@ -241,6 +239,10 @@ export function mapSandboxResultToCheckResult(
|
|
|
241
239
|
t0,
|
|
242
240
|
);
|
|
243
241
|
}
|
|
242
|
+
if (verdict === undefined) {
|
|
243
|
+
return unverified('render check worker exited without producing a verdict.', t0);
|
|
244
|
+
}
|
|
245
|
+
return verdict;
|
|
244
246
|
}
|
|
245
247
|
|
|
246
248
|
/**
|
|
@@ -269,7 +271,9 @@ export async function runRenderCheckViaWorker(
|
|
|
269
271
|
gracePeriodMs: bounds.gracePeriodMs,
|
|
270
272
|
maxStdoutBytes: CHECK_STDOUT_CAP,
|
|
271
273
|
nodeHeapMb: bounds.heapMb,
|
|
272
|
-
|
|
274
|
+
// ggui#1398: the check learns its own deadline, so its report-only
|
|
275
|
+
// pending phase can step aside instead of pushing it past the bound.
|
|
276
|
+
stdin: JSON.stringify({ ...input, deadlineAt: t0 + bounds.timeoutMs }),
|
|
273
277
|
// NODE_ENV steers React's production vs development build — keep
|
|
274
278
|
// parity with the caller; everything else stays on the sandbox's
|
|
275
279
|
// default allowlist.
|
|
@@ -43,7 +43,8 @@ import { resolve as resolvePath } from 'node:path';
|
|
|
43
43
|
import { fileURLToPath } from 'node:url';
|
|
44
44
|
import * as esbuild from 'esbuild';
|
|
45
45
|
import { runRenderCheckInProcess } from './render-check.js';
|
|
46
|
-
import type { RunRenderCheckInput } from './render-check.js';
|
|
46
|
+
import type { RenderCheckResult, RunRenderCheckInput } from './render-check.js';
|
|
47
|
+
import { formatVerdictLine } from '../../../internal/verdict-line.js';
|
|
47
48
|
|
|
48
49
|
async function readAllStdin(): Promise<string> {
|
|
49
50
|
const chunks: Buffer[] = [];
|
|
@@ -53,8 +54,10 @@ async function readAllStdin(): Promise<string> {
|
|
|
53
54
|
return Buffer.concat(chunks).toString('utf8');
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
function emit(value:
|
|
57
|
-
|
|
57
|
+
function emit(value: RenderCheckResult): void {
|
|
58
|
+
// One prefixed line: the host reads the last such line, so a card that
|
|
59
|
+
// writes to stdout while it is checked cannot corrupt the verdict.
|
|
60
|
+
process.stdout.write(formatVerdictLine(value));
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
/**
|