@ggui-ai/ui-gen 0.27.0 → 0.28.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/adapters/generation-dispatch.js +172 -7
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/advanced/index.js +174 -9
- package/dist/advanced/index.js.map +1 -1
- package/dist/evaluation/axis-checks/index.js +97 -1
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.js +97 -1
- package/dist/evaluation/axis-checks/registry.js.map +1 -1
- package/dist/evaluation/index.js +102 -4
- package/dist/evaluation/index.js.map +1 -1
- package/dist/harness/index.js +2 -0
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/result-types.d.ts +12 -1
- package/dist/harness/result-types.js.map +1 -1
- package/dist/harness/types-public.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +174 -9
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
- package/src/adapters/provider-router.ts +1 -0
- package/src/create-ui-generator.ts +4 -2
- package/src/evaluation/axis-checks/checks/state-merge.ts +1 -1
- package/src/evaluation/axis-checks/helpers.ts +125 -0
- package/src/evaluation/evaluator.ts +2 -2
- package/src/evaluation/llm-evaluator.ts +2 -2
- package/src/evaluation/visual-evaluator.ts +1 -1
- package/src/harness/coding/assemble-result.ts +1 -0
- package/src/harness/coding/dupe-break.ts +70 -0
- package/src/harness/coding/generate-task-runner.ts +5 -1
- package/src/harness/coding/run-coding-turn.ts +56 -1
- package/src/harness/result-types.ts +12 -0
- package/src/index.ts +1 -1
|
@@ -711,6 +711,8 @@ var init_claude_code_login = __esm({
|
|
|
711
711
|
function getBedrockModelId(model) {
|
|
712
712
|
const BEDROCK_MAP = {
|
|
713
713
|
"anthropic/claude-haiku-4-5": "us.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
714
|
+
"anthropic/claude-haiku-5-5": "us.anthropic.claude-haiku-5-5",
|
|
715
|
+
// listed ACTIVE in us-east-1 (ggui#1743)
|
|
714
716
|
"anthropic/claude-sonnet-4-6": "us.anthropic.claude-sonnet-4-6",
|
|
715
717
|
"anthropic/claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1:0",
|
|
716
718
|
// Claude 5-family (ggui#706, strings verified 2026-09-02 against
|
|
@@ -5695,10 +5697,16 @@ var dupe_break_exports = {};
|
|
|
5695
5697
|
__export(dupe_break_exports, {
|
|
5696
5698
|
SAME_EXCHANGE_BREAK_AT: () => SAME_EXCHANGE_BREAK_AT,
|
|
5697
5699
|
SAME_EXCHANGE_NUDGE: () => SAME_EXCHANGE_NUDGE,
|
|
5700
|
+
SAME_FAILURE_BREAK_AT: () => SAME_FAILURE_BREAK_AT,
|
|
5701
|
+
SAME_FAILURE_NUDGE: () => SAME_FAILURE_NUDGE,
|
|
5702
|
+
SAME_FAILURE_NUDGE_AT: () => SAME_FAILURE_NUDGE_AT,
|
|
5703
|
+
clearWriteFailures: () => clearWriteFailures,
|
|
5698
5704
|
computePatchFingerprint: () => computePatchFingerprint,
|
|
5699
5705
|
createDupeBreakState: () => createDupeBreakState,
|
|
5700
5706
|
errorClassBucket: () => errorClassBucket,
|
|
5701
|
-
|
|
5707
|
+
failureSignatures: () => failureSignatures,
|
|
5708
|
+
recordToolExchange: () => recordToolExchange,
|
|
5709
|
+
recordWriteFailure: () => recordWriteFailure
|
|
5702
5710
|
});
|
|
5703
5711
|
function recordToolExchange(state, name, input, resultText) {
|
|
5704
5712
|
const key = createHash("sha256").update(name).update("\0").update(JSON.stringify(input) ?? "undefined").update("\0").update(resultText).digest("hex");
|
|
@@ -5710,6 +5718,25 @@ function recordToolExchange(state, name, input, resultText) {
|
|
|
5710
5718
|
}
|
|
5711
5719
|
return state.consecutiveIdenticalExchanges;
|
|
5712
5720
|
}
|
|
5721
|
+
function failureSignatures(resultText) {
|
|
5722
|
+
const norm = (text) => text.replace(/[0-9]+/g, "#").replace(/\s+/g, " ").trim();
|
|
5723
|
+
const violations = [...resultText.matchAll(/^\[[^\]\n]+\] [^\n]+/gm)].map((m) => norm(m[0]));
|
|
5724
|
+
if (violations.length > 0) return [...new Set(violations)];
|
|
5725
|
+
const rest = norm(resultText.replace(/^Committed [^\n]*\n/, ""));
|
|
5726
|
+
return rest.length > 0 ? [rest] : [];
|
|
5727
|
+
}
|
|
5728
|
+
function recordWriteFailure(state, resultText) {
|
|
5729
|
+
let top;
|
|
5730
|
+
for (const signature of failureSignatures(resultText)) {
|
|
5731
|
+
const repeats = (state.failureCounts.get(signature) ?? 0) + 1;
|
|
5732
|
+
state.failureCounts.set(signature, repeats);
|
|
5733
|
+
if (top === void 0 || repeats > top.repeats) top = { signature, repeats };
|
|
5734
|
+
}
|
|
5735
|
+
return top;
|
|
5736
|
+
}
|
|
5737
|
+
function clearWriteFailures(state) {
|
|
5738
|
+
state.failureCounts.clear();
|
|
5739
|
+
}
|
|
5713
5740
|
function createDupeBreakState() {
|
|
5714
5741
|
return {
|
|
5715
5742
|
lastFailedPatchFingerprint: null,
|
|
@@ -5726,7 +5753,8 @@ function createDupeBreakState() {
|
|
|
5726
5753
|
consecutiveBrokenApplies: 0,
|
|
5727
5754
|
consecutiveNoToolCalls: 0,
|
|
5728
5755
|
lastExchangeKey: null,
|
|
5729
|
-
consecutiveIdenticalExchanges: 0
|
|
5756
|
+
consecutiveIdenticalExchanges: 0,
|
|
5757
|
+
failureCounts: /* @__PURE__ */ new Map()
|
|
5730
5758
|
};
|
|
5731
5759
|
}
|
|
5732
5760
|
function errorClassBucket(errText) {
|
|
@@ -5751,11 +5779,14 @@ function computePatchFingerprint(changes, errText) {
|
|
|
5751
5779
|
h.update(errBucket);
|
|
5752
5780
|
return h.digest("hex");
|
|
5753
5781
|
}
|
|
5754
|
-
var SAME_EXCHANGE_BREAK_AT, SAME_EXCHANGE_NUDGE;
|
|
5782
|
+
var SAME_EXCHANGE_BREAK_AT, SAME_EXCHANGE_NUDGE, SAME_FAILURE_NUDGE_AT, SAME_FAILURE_BREAK_AT, SAME_FAILURE_NUDGE;
|
|
5755
5783
|
var init_dupe_break = __esm({
|
|
5756
5784
|
"src/harness/coding/dupe-break.ts"() {
|
|
5757
5785
|
SAME_EXCHANGE_BREAK_AT = 3;
|
|
5758
5786
|
SAME_EXCHANGE_NUDGE = "\n\n[harness] This is the SAME tool call with the SAME result as your previous turn \u2014 repeating it cannot produce new information. Use what you already have and emit an apply_changes (or scoped) call now; one more identical repeat terminates the run.";
|
|
5787
|
+
SAME_FAILURE_NUDGE_AT = 3;
|
|
5788
|
+
SAME_FAILURE_BREAK_AT = 5;
|
|
5789
|
+
SAME_FAILURE_NUDGE = "\n\n[harness] This same failure has now been reported for three of your patches. Changing other code does not clear it: re-read that check above and change exactly what it names. Two more reports of it end the run.";
|
|
5759
5790
|
}
|
|
5760
5791
|
});
|
|
5761
5792
|
|
|
@@ -6147,13 +6178,13 @@ Return your evaluation using the evaluate_${criterion} tool.`;
|
|
|
6147
6178
|
function getDefaultEvalModel(provider) {
|
|
6148
6179
|
switch (provider) {
|
|
6149
6180
|
case "claude":
|
|
6150
|
-
return "claude-haiku-
|
|
6181
|
+
return "claude-haiku-5-5";
|
|
6151
6182
|
case "openai":
|
|
6152
6183
|
return "gpt-5.6-luna";
|
|
6153
6184
|
case "google":
|
|
6154
6185
|
return "gemini-3.5-flash-lite";
|
|
6155
6186
|
default:
|
|
6156
|
-
return "claude-haiku-
|
|
6187
|
+
return "claude-haiku-5-5";
|
|
6157
6188
|
}
|
|
6158
6189
|
}
|
|
6159
6190
|
function callTokens(response) {
|
|
@@ -8231,7 +8262,7 @@ function parseCriteriaAnswers(raw) {
|
|
|
8231
8262
|
function getDefaultVisualModel(provider) {
|
|
8232
8263
|
switch (provider) {
|
|
8233
8264
|
case "claude":
|
|
8234
|
-
return "claude-haiku-
|
|
8265
|
+
return "claude-haiku-5-5";
|
|
8235
8266
|
case "google":
|
|
8236
8267
|
return "gemini-3-flash-preview";
|
|
8237
8268
|
}
|
|
@@ -9500,10 +9531,96 @@ function getInitialValuePropNames(contract) {
|
|
|
9500
9531
|
}
|
|
9501
9532
|
return names;
|
|
9502
9533
|
}
|
|
9534
|
+
function objectLiteralKeysAt(src, open) {
|
|
9535
|
+
if (src[open] !== "{") return void 0;
|
|
9536
|
+
const keys = [];
|
|
9537
|
+
let depth = 0;
|
|
9538
|
+
let expectKey = true;
|
|
9539
|
+
for (let i = open; i < src.length; i++) {
|
|
9540
|
+
const c = src[i];
|
|
9541
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
9542
|
+
let j = i + 1;
|
|
9543
|
+
while (j < src.length && src[j] !== c) j += src[j] === "\\" ? 2 : 1;
|
|
9544
|
+
if (depth === 1 && expectKey && /^\s*:/.test(src.slice(j + 1))) keys.push(src.slice(i + 1, j));
|
|
9545
|
+
i = j;
|
|
9546
|
+
expectKey = false;
|
|
9547
|
+
continue;
|
|
9548
|
+
}
|
|
9549
|
+
if (c === "{" || c === "[" || c === "(") {
|
|
9550
|
+
depth++;
|
|
9551
|
+
if (depth === 1) expectKey = true;
|
|
9552
|
+
continue;
|
|
9553
|
+
}
|
|
9554
|
+
if (c === "}" || c === "]" || c === ")") {
|
|
9555
|
+
depth--;
|
|
9556
|
+
if (depth === 0) return keys;
|
|
9557
|
+
continue;
|
|
9558
|
+
}
|
|
9559
|
+
if (depth !== 1) continue;
|
|
9560
|
+
if (c === ",") {
|
|
9561
|
+
expectKey = true;
|
|
9562
|
+
continue;
|
|
9563
|
+
}
|
|
9564
|
+
if (expectKey && /[A-Za-z_$]/.test(c ?? "")) {
|
|
9565
|
+
const m = /^([A-Za-z_$][\w$]*)\s*(:|,|\})/.exec(src.slice(i));
|
|
9566
|
+
if (m !== null && m[1] !== void 0) keys.push(m[1]);
|
|
9567
|
+
expectKey = false;
|
|
9568
|
+
}
|
|
9569
|
+
}
|
|
9570
|
+
return keys;
|
|
9571
|
+
}
|
|
9572
|
+
function callArgsAt(src, open) {
|
|
9573
|
+
const args = [];
|
|
9574
|
+
let depth = 0;
|
|
9575
|
+
let start = open + 1;
|
|
9576
|
+
for (let i = open; i < src.length; i++) {
|
|
9577
|
+
const c = src[i];
|
|
9578
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
9579
|
+
let j = i + 1;
|
|
9580
|
+
while (j < src.length && src[j] !== c) j += src[j] === "\\" ? 2 : 1;
|
|
9581
|
+
i = j;
|
|
9582
|
+
continue;
|
|
9583
|
+
}
|
|
9584
|
+
if (c === "(" || c === "{" || c === "[") depth++;
|
|
9585
|
+
else if (c === ")" || c === "}" || c === "]") {
|
|
9586
|
+
depth--;
|
|
9587
|
+
if (depth === 0) {
|
|
9588
|
+
args.push(src.slice(start, i));
|
|
9589
|
+
return args;
|
|
9590
|
+
}
|
|
9591
|
+
} else if (c === "," && depth === 1) {
|
|
9592
|
+
args.push(src.slice(start, i));
|
|
9593
|
+
start = i + 1;
|
|
9594
|
+
}
|
|
9595
|
+
}
|
|
9596
|
+
return args;
|
|
9597
|
+
}
|
|
9598
|
+
function initialStateKeys(src, argStart, argText) {
|
|
9599
|
+
const lead = argText.length - argText.trimStart().length;
|
|
9600
|
+
let at = argStart + lead;
|
|
9601
|
+
let text = argText.trim();
|
|
9602
|
+
const lazy = /^\(\s*\)\s*=>\s*\(?\s*/.exec(text);
|
|
9603
|
+
if (lazy !== null) {
|
|
9604
|
+
at += lazy[0].length;
|
|
9605
|
+
text = text.slice(lazy[0].length);
|
|
9606
|
+
}
|
|
9607
|
+
if (text.startsWith("{")) return objectLiteralKeysAt(src, at) ?? [];
|
|
9608
|
+
const ident = /^([A-Za-z_$][\w$]*)\s*\)?\s*$/.exec(text);
|
|
9609
|
+
if (ident === null || ident[1] === void 0) return [];
|
|
9610
|
+
const decls = [...src.matchAll(new RegExp(`(?:const|let|var)\\s+${ident[1]}\\s*(?::[^=]{1,200})?=\\s*`, "g"))];
|
|
9611
|
+
const decl = decls.length === 1 ? decls[0] : void 0;
|
|
9612
|
+
if (decl === void 0) return [];
|
|
9613
|
+
return objectLiteralKeysAt(src, (decl.index ?? 0) + decl[0].length) ?? [];
|
|
9614
|
+
}
|
|
9503
9615
|
function collectStateKeys(src) {
|
|
9504
9616
|
const keys = /* @__PURE__ */ new Set();
|
|
9505
9617
|
const varRe = /const\s*\[\s*(\w+)\s*,\s*(\w+)\s*\]\s*=\s*useState/g;
|
|
9506
9618
|
for (const m of src.matchAll(varRe)) keys.add(m[1]);
|
|
9619
|
+
const contextRe = /const\s*\[\s*(\w+)\s*,\s*\w+\s*\]\s*=\s*useGguiContext\s*(?:<[^>]*>)?\s*\(\s*['"`](\w+)['"`]/g;
|
|
9620
|
+
for (const m of src.matchAll(contextRe)) {
|
|
9621
|
+
keys.add(m[1]);
|
|
9622
|
+
keys.add(m[2]);
|
|
9623
|
+
}
|
|
9507
9624
|
const objRe = /useState(?:<[^>]*>)?\s*\(\s*\{([\s\S]*?)\}\s*\)/g;
|
|
9508
9625
|
for (const m of src.matchAll(objRe)) {
|
|
9509
9626
|
const keyRe = /(?:^|,)\s*(\w+)\s*:/g;
|
|
@@ -9514,6 +9631,16 @@ function collectStateKeys(src) {
|
|
|
9514
9631
|
const keyRe = /(?:^|,)\s*(\w+)\s*:/g;
|
|
9515
9632
|
for (const km of m[1].matchAll(keyRe)) keys.add(km[1]);
|
|
9516
9633
|
}
|
|
9634
|
+
for (const m of src.matchAll(/\b(useState|useReducer)\s*(?:<[^>]*>)?\s*\(/g)) {
|
|
9635
|
+
const open = (m.index ?? 0) + m[0].length - 1;
|
|
9636
|
+
const args = callArgsAt(src, open);
|
|
9637
|
+
const which = m[1] === "useReducer" ? 1 : 0;
|
|
9638
|
+
const arg = args[which];
|
|
9639
|
+
if (arg === void 0) continue;
|
|
9640
|
+
let argStart = open + 1;
|
|
9641
|
+
for (let k = 0; k < which; k++) argStart += (args[k]?.length ?? 0) + 1;
|
|
9642
|
+
for (const key of initialStateKeys(src, argStart, arg)) keys.add(key);
|
|
9643
|
+
}
|
|
9517
9644
|
return keys;
|
|
9518
9645
|
}
|
|
9519
9646
|
function mkIssue(subcategory, description, fix, result = "fail") {
|
|
@@ -10126,7 +10253,7 @@ function runNoHardcodedEntities(input) {
|
|
|
10126
10253
|
mkIssue(
|
|
10127
10254
|
"state.merge.no_hardcoded_entities",
|
|
10128
10255
|
`Hardcoded entity array literal (multiple objects with "${idField}") in the component \u2014 entity data should come from state/props.`,
|
|
10129
|
-
`Remove the literal array
|
|
10256
|
+
`Remove the literal array: this data comes from ${all.filter((e) => e.idField === idField).map((e) => `props.${e.name}`).join(" / ") || "props"}. Read it there (\`?? []\` for an absent value, never a literal default), seed state from it, and merge updates via stream.`
|
|
10130
10257
|
)
|
|
10131
10258
|
);
|
|
10132
10259
|
}
|
|
@@ -16346,6 +16473,7 @@ async function assembleGenerationResult(input) {
|
|
|
16346
16473
|
evalResult: telemetry.evalResult !== void 0 && telemetry.contractFeedback !== void 0 ? { ...telemetry.evalResult, contractFeedback: telemetry.contractFeedback } : telemetry.evalResult,
|
|
16347
16474
|
// ggui#404 — present only when the same-exchange guard ended the run.
|
|
16348
16475
|
...telemetry.sameExchangeBreak !== void 0 ? { sameExchangeBreak: telemetry.sameExchangeBreak } : {},
|
|
16476
|
+
...telemetry.sameFailureBreak !== void 0 ? { sameFailureBreak: telemetry.sameFailureBreak } : {},
|
|
16349
16477
|
needsBackgroundImprovement,
|
|
16350
16478
|
selfCheckPassed: telemetry.selfCheckPassed,
|
|
16351
16479
|
timing,
|
|
@@ -17299,6 +17427,18 @@ Repeated error: ${errText}
|
|
|
17299
17427
|
augmentedResultText += SAME_EXCHANGE_NUDGE;
|
|
17300
17428
|
}
|
|
17301
17429
|
}
|
|
17430
|
+
const isWrite = call.name === "apply_changes" || call.name === "rewrite";
|
|
17431
|
+
let repeatedFailure;
|
|
17432
|
+
if (ctx.dupeBreak && isWrite) {
|
|
17433
|
+
if (result.done) {
|
|
17434
|
+
clearWriteFailures(ctx.dupeBreak);
|
|
17435
|
+
} else {
|
|
17436
|
+
repeatedFailure = recordWriteFailure(ctx.dupeBreak, result.result);
|
|
17437
|
+
if (repeatedFailure?.repeats === SAME_FAILURE_NUDGE_AT) {
|
|
17438
|
+
augmentedResultText += SAME_FAILURE_NUDGE;
|
|
17439
|
+
}
|
|
17440
|
+
}
|
|
17441
|
+
}
|
|
17302
17442
|
await codingAgent.sendToolResult([{
|
|
17303
17443
|
callId: call.id,
|
|
17304
17444
|
name: call.name,
|
|
@@ -17327,6 +17467,29 @@ Repeated error: ${errText}
|
|
|
17327
17467
|
sameExchangeBreak: { tool: call.name, repeats: sameExchangeRepeats }
|
|
17328
17468
|
};
|
|
17329
17469
|
}
|
|
17470
|
+
if (repeatedFailure !== void 0 && repeatedFailure.repeats >= SAME_FAILURE_BREAK_AT) {
|
|
17471
|
+
const signature = repeatedFailure.signature.slice(0, 160);
|
|
17472
|
+
console.log(
|
|
17473
|
+
`[coding-agent] SAME_FAILURE_BREAK | tool=${call.name} | repeats=${repeatedFailure.repeats} | failure=${JSON.stringify(signature.slice(0, 80))} \u2014 terminating run (ggui#1791)`
|
|
17474
|
+
);
|
|
17475
|
+
return {
|
|
17476
|
+
control: "break",
|
|
17477
|
+
compiledCode: "",
|
|
17478
|
+
selfCheckPassed: false,
|
|
17479
|
+
outcome: void 0,
|
|
17480
|
+
phase: void 0,
|
|
17481
|
+
tokens,
|
|
17482
|
+
...cacheTokens,
|
|
17483
|
+
llmMs,
|
|
17484
|
+
toolMs,
|
|
17485
|
+
lastResultText: augmentedResultText,
|
|
17486
|
+
lastDiffFailed: false,
|
|
17487
|
+
isEvalFeedback: false,
|
|
17488
|
+
iconNamesCache,
|
|
17489
|
+
preWarmedContext,
|
|
17490
|
+
sameFailureBreak: { signature, repeats: repeatedFailure.repeats }
|
|
17491
|
+
};
|
|
17492
|
+
}
|
|
17330
17493
|
const turnDiffFailed = !!result.error && result.result.includes("DIFF");
|
|
17331
17494
|
const isDiffFail = turnDiffFailed && !isPatchInvalid;
|
|
17332
17495
|
const outcome = result.done ? "PASS" : isPatchInvalid ? "PATCH_INVALID" : isDiffFail ? "DIFF_FAIL" : "SELF_CHECK_FAIL";
|
|
@@ -18314,6 +18477,7 @@ function createTelemetry() {
|
|
|
18314
18477
|
probeRepairTrigger: void 0,
|
|
18315
18478
|
contractFeedback: void 0,
|
|
18316
18479
|
sameExchangeBreak: void 0,
|
|
18480
|
+
sameFailureBreak: void 0,
|
|
18317
18481
|
compiledCode: "",
|
|
18318
18482
|
pairedSource: "",
|
|
18319
18483
|
selfCheckPassed: false,
|
|
@@ -18369,6 +18533,7 @@ function absorbTurn(telemetry, turn) {
|
|
|
18369
18533
|
else telemetry.counters.outcomes.selfCheckFail++;
|
|
18370
18534
|
}
|
|
18371
18535
|
if (turn.sameExchangeBreak !== void 0) telemetry.sameExchangeBreak = turn.sameExchangeBreak;
|
|
18536
|
+
if (turn.sameFailureBreak !== void 0) telemetry.sameFailureBreak = turn.sameFailureBreak;
|
|
18372
18537
|
}
|
|
18373
18538
|
function createGenerateTaskRunner(input) {
|
|
18374
18539
|
const { session, params, classification, telemetry } = input;
|