@yoqa/runner 0.3.21 → 0.3.22

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.
Files changed (2) hide show
  1. package/dist/index.js +246 -121
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16801,7 +16801,7 @@ function getCatalogDb() {
16801
16801
  // package.json
16802
16802
  var package_default = {
16803
16803
  name: "@yoqa/runner",
16804
- version: "0.3.21",
16804
+ version: "0.3.22",
16805
16805
  description: "Yoqa local runner \u2014 Appium + catalog HTTP API (Bun). Start with yoqa serve or the yoqa-runner bin.",
16806
16806
  license: "UNLICENSED",
16807
16807
  type: "module",
@@ -57546,6 +57546,195 @@ var originalGenerateCallId6 = createIdGenerator3({
57546
57546
  });
57547
57547
  var defaultDownload2 = createDownload();
57548
57548
 
57549
+ // src/domains/providers/json-salvage.ts
57550
+ function charAt(raw2, index) {
57551
+ return raw2[index];
57552
+ }
57553
+ function coerceLooseJson(raw2) {
57554
+ let out = "";
57555
+ let i = 0;
57556
+ while (i < raw2.length) {
57557
+ const c = charAt(raw2, i);
57558
+ if (c === undefined)
57559
+ break;
57560
+ if (c === '"') {
57561
+ out += c;
57562
+ i += 1;
57563
+ while (i < raw2.length) {
57564
+ const d = charAt(raw2, i);
57565
+ if (d === undefined)
57566
+ break;
57567
+ out += d;
57568
+ i += 1;
57569
+ if (d === "\\") {
57570
+ const escaped = charAt(raw2, i);
57571
+ if (escaped !== undefined) {
57572
+ out += escaped;
57573
+ i += 1;
57574
+ }
57575
+ continue;
57576
+ }
57577
+ if (d === '"')
57578
+ break;
57579
+ }
57580
+ continue;
57581
+ }
57582
+ if (c === "'") {
57583
+ i += 1;
57584
+ let content = "";
57585
+ while (i < raw2.length) {
57586
+ const d = charAt(raw2, i);
57587
+ if (d === undefined)
57588
+ break;
57589
+ if (d === "\\" && i + 1 < raw2.length) {
57590
+ const next = charAt(raw2, i + 1);
57591
+ if (next === undefined)
57592
+ break;
57593
+ if (next === "n")
57594
+ content += `
57595
+ `;
57596
+ else if (next === "t")
57597
+ content += "\t";
57598
+ else if (next === "r")
57599
+ content += "\r";
57600
+ else
57601
+ content += next;
57602
+ i += 2;
57603
+ continue;
57604
+ }
57605
+ if (d === "'") {
57606
+ i += 1;
57607
+ break;
57608
+ }
57609
+ content += d;
57610
+ i += 1;
57611
+ }
57612
+ out += JSON.stringify(content);
57613
+ continue;
57614
+ }
57615
+ if (c === ",") {
57616
+ let j = i + 1;
57617
+ while (j < raw2.length) {
57618
+ const ws = charAt(raw2, j);
57619
+ if (ws === undefined || !/\s/.test(ws))
57620
+ break;
57621
+ j += 1;
57622
+ }
57623
+ const closer = charAt(raw2, j);
57624
+ if (closer === "}" || closer === "]") {
57625
+ i += 1;
57626
+ continue;
57627
+ }
57628
+ }
57629
+ out += c;
57630
+ i += 1;
57631
+ }
57632
+ return out;
57633
+ }
57634
+ function tryParseJson(text3) {
57635
+ try {
57636
+ return JSON.parse(text3);
57637
+ } catch {
57638
+ return;
57639
+ }
57640
+ }
57641
+ function closeTruncatedJson(raw2) {
57642
+ let inString = false;
57643
+ let escaped = false;
57644
+ const stack = [];
57645
+ for (let i = 0;i < raw2.length; i += 1) {
57646
+ const c = charAt(raw2, i);
57647
+ if (c === undefined)
57648
+ break;
57649
+ if (inString) {
57650
+ if (escaped) {
57651
+ escaped = false;
57652
+ continue;
57653
+ }
57654
+ if (c === "\\") {
57655
+ escaped = true;
57656
+ continue;
57657
+ }
57658
+ if (c === '"')
57659
+ inString = false;
57660
+ continue;
57661
+ }
57662
+ if (c === '"') {
57663
+ inString = true;
57664
+ continue;
57665
+ }
57666
+ if (c === "{")
57667
+ stack.push("{");
57668
+ else if (c === "[")
57669
+ stack.push("[");
57670
+ else if (c === "}" || c === "]")
57671
+ stack.pop();
57672
+ }
57673
+ let out = raw2;
57674
+ if (inString) {
57675
+ if (escaped)
57676
+ out = out.slice(0, -1);
57677
+ out += '"';
57678
+ }
57679
+ while (stack.length > 0) {
57680
+ const open = stack.pop();
57681
+ out += open === "{" ? "}" : "]";
57682
+ }
57683
+ return out;
57684
+ }
57685
+ function salvageAgentJsonText(text3) {
57686
+ const trimmed = text3.trim();
57687
+ const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/);
57688
+ const inner = fenced?.[1]?.trim() ?? trimmed;
57689
+ const start = inner.indexOf("{");
57690
+ if (start < 0)
57691
+ return trimmed;
57692
+ const fromBrace = inner.slice(start);
57693
+ const lastBrace = fromBrace.lastIndexOf("}");
57694
+ const candidates = lastBrace > 0 ? [fromBrace.slice(0, lastBrace + 1), fromBrace] : [fromBrace];
57695
+ for (const candidate of candidates) {
57696
+ const variants = [
57697
+ candidate,
57698
+ coerceLooseJson(candidate),
57699
+ closeTruncatedJson(candidate),
57700
+ closeTruncatedJson(coerceLooseJson(candidate))
57701
+ ];
57702
+ for (const variant of variants) {
57703
+ if (tryParseJson(variant) !== undefined)
57704
+ return variant;
57705
+ }
57706
+ }
57707
+ return closeTruncatedJson(coerceLooseJson(fromBrace));
57708
+ }
57709
+ function clampNormCoord(n) {
57710
+ if (!Number.isFinite(n))
57711
+ return n;
57712
+ return Math.min(1000, Math.max(0, n));
57713
+ }
57714
+ function normalizeVisionJson(value) {
57715
+ if (!value || typeof value !== "object" || Array.isArray(value))
57716
+ return value;
57717
+ const out = { ...value };
57718
+ if (typeof out.x === "number")
57719
+ out.x = clampNormCoord(out.x);
57720
+ if (typeof out.y === "number")
57721
+ out.y = clampNormCoord(out.y);
57722
+ if (typeof out.ms === "number" && Number.isFinite(out.ms)) {
57723
+ out.ms = Math.min(1e4, Math.max(0, out.ms));
57724
+ }
57725
+ const reason = typeof out.reason === "string" ? out.reason.trim() : "";
57726
+ const thoughts = typeof out.thoughts === "string" ? out.thoughts.trim() : "";
57727
+ if (reason)
57728
+ out.reason = reason;
57729
+ if (thoughts)
57730
+ out.thoughts = thoughts;
57731
+ if (reason && !thoughts)
57732
+ out.thoughts = reason;
57733
+ if (thoughts && !reason)
57734
+ out.reason = thoughts;
57735
+ return out;
57736
+ }
57737
+
57549
57738
  // src/domains/providers/vision-model.ts
57550
57739
  class AgentProviderError extends Error {
57551
57740
  constructor(message) {
@@ -57646,20 +57835,27 @@ function mapProviderError(label, error40) {
57646
57835
  }
57647
57836
  throw new AgentProviderError(`Model did not return JSON (got: ${snippet}${text3.length > 160 ? "\u2026" : ""})`);
57648
57837
  }
57838
+ if (error40 instanceof exports_external.ZodError) {
57839
+ const first = error40.issues[0];
57840
+ const detail = first ? `${first.path.length > 0 ? `${first.path.join(".")}: ` : ""}${first.message}` : error40.message;
57841
+ throw new AgentProviderError(`${label} JSON was not a valid action: ${detail}`);
57842
+ }
57649
57843
  if (error40 instanceof Error) {
57650
57844
  throw new AgentProviderError(error40.message);
57651
57845
  }
57652
57846
  throw new AgentProviderError(String(error40));
57653
57847
  }
57654
- function repairModelJsonText(text3) {
57655
- const trimmed = text3.trim();
57656
- const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/);
57657
- const candidate = fenced?.[1]?.trim() ?? trimmed;
57658
- const start = candidate.indexOf("{");
57659
- const end = candidate.lastIndexOf("}");
57660
- if (start < 0 || end <= start)
57661
- return trimmed;
57662
- return candidate.slice(start, end + 1);
57848
+ function parseVisionSchema(schema, raw2, label) {
57849
+ try {
57850
+ return schema.parse(normalizeVisionJson(raw2));
57851
+ } catch (error40) {
57852
+ if (error40 instanceof exports_external.ZodError) {
57853
+ const first = error40.issues[0];
57854
+ const detail = first ? `${first.path.length > 0 ? `${first.path.join(".")}: ` : ""}${first.message}` : error40.message;
57855
+ throw new AgentProviderError(`${label} JSON was not a valid action: ${detail}`);
57856
+ }
57857
+ throw error40;
57858
+ }
57663
57859
  }
57664
57860
  async function completeWithAiSdk(input) {
57665
57861
  const run = async (prompt) => {
@@ -57669,7 +57865,7 @@ async function completeWithAiSdk(input) {
57669
57865
  schema: input.schema,
57670
57866
  system: input.system,
57671
57867
  maxOutputTokens: VISION_MAX_TOKENS,
57672
- experimental_repairText: async ({ text: text3 }) => repairModelJsonText(text3),
57868
+ experimental_repairText: async ({ text: text3 }) => salvageAgentJsonText(text3),
57673
57869
  messages: [
57674
57870
  {
57675
57871
  role: "user",
@@ -57684,12 +57880,18 @@ async function completeWithAiSdk(input) {
57684
57880
  }
57685
57881
  ]
57686
57882
  });
57687
- return object3;
57883
+ return parseVisionSchema(input.schema, object3, input.label);
57688
57884
  } catch (error40) {
57885
+ if (error40 instanceof AgentProviderError)
57886
+ throw error40;
57689
57887
  if (NoObjectGeneratedError.isInstance(error40) && error40.text?.trim()) {
57690
57888
  try {
57691
- return input.schema.parse(JSON.parse(repairModelJsonText(error40.text)));
57692
- } catch {}
57889
+ const salvaged = salvageAgentJsonText(error40.text);
57890
+ return parseVisionSchema(input.schema, JSON.parse(salvaged), input.label);
57891
+ } catch (salvageError) {
57892
+ if (salvageError instanceof AgentProviderError)
57893
+ throw salvageError;
57894
+ }
57693
57895
  }
57694
57896
  mapProviderError(input.label, error40);
57695
57897
  }
@@ -67601,108 +67803,37 @@ var google = createGoogle();
67601
67803
 
67602
67804
  // src/domains/providers/agent-json.ts
67603
67805
  function extractAgentJsonObject(text3, providerLabel) {
67604
- const trimmed = text3.trim();
67605
- const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/);
67606
- const candidate = fenced?.[1]?.trim() ?? trimmed;
67607
- const start = candidate.indexOf("{");
67608
- const end = candidate.lastIndexOf("}");
67609
- if (start < 0 || end <= start) {
67610
- throw new AgentProviderError(`${providerLabel} did not return JSON (got: ${trimmed.replace(/\s+/g, " ").slice(0, 160)})`);
67611
- }
67612
- const slice = candidate.slice(start, end + 1);
67806
+ const snippet = text3.trim().replace(/\s+/g, " ").slice(0, 160);
67807
+ const fail = () => {
67808
+ throw new AgentProviderError(`${providerLabel} did not return JSON (got: ${snippet})`);
67809
+ };
67810
+ const salvaged = salvageAgentJsonText(text3);
67811
+ let parsed;
67613
67812
  try {
67614
- return JSON.parse(slice);
67615
- } catch (strictError) {
67813
+ parsed = JSON.parse(salvaged);
67814
+ } catch {
67616
67815
  try {
67617
- return JSON.parse(coerceLooseJson(slice));
67816
+ parsed = JSON.parse(coerceLooseJson(salvaged));
67618
67817
  } catch {
67619
- throw strictError;
67818
+ fail();
67620
67819
  }
67621
67820
  }
67821
+ if (parsed === undefined || parsed === null || typeof parsed !== "object") {
67822
+ fail();
67823
+ }
67824
+ return parsed;
67622
67825
  }
67623
- function charAt(raw2, index) {
67624
- return raw2[index];
67625
- }
67626
- function coerceLooseJson(raw2) {
67627
- let out = "";
67628
- let i = 0;
67629
- while (i < raw2.length) {
67630
- const c = charAt(raw2, i);
67631
- if (c === undefined)
67632
- break;
67633
- if (c === '"') {
67634
- out += c;
67635
- i += 1;
67636
- while (i < raw2.length) {
67637
- const d = charAt(raw2, i);
67638
- if (d === undefined)
67639
- break;
67640
- out += d;
67641
- i += 1;
67642
- if (d === "\\") {
67643
- const escaped = charAt(raw2, i);
67644
- if (escaped !== undefined) {
67645
- out += escaped;
67646
- i += 1;
67647
- }
67648
- continue;
67649
- }
67650
- if (d === '"')
67651
- break;
67652
- }
67653
- continue;
67654
- }
67655
- if (c === "'") {
67656
- i += 1;
67657
- let content = "";
67658
- while (i < raw2.length) {
67659
- const d = charAt(raw2, i);
67660
- if (d === undefined)
67661
- break;
67662
- if (d === "\\" && i + 1 < raw2.length) {
67663
- const next = charAt(raw2, i + 1);
67664
- if (next === undefined)
67665
- break;
67666
- if (next === "n")
67667
- content += `
67668
- `;
67669
- else if (next === "t")
67670
- content += "\t";
67671
- else if (next === "r")
67672
- content += "\r";
67673
- else
67674
- content += next;
67675
- i += 2;
67676
- continue;
67677
- }
67678
- if (d === "'") {
67679
- i += 1;
67680
- break;
67681
- }
67682
- content += d;
67683
- i += 1;
67684
- }
67685
- out += JSON.stringify(content);
67686
- continue;
67687
- }
67688
- if (c === ",") {
67689
- let j = i + 1;
67690
- while (j < raw2.length) {
67691
- const ws = charAt(raw2, j);
67692
- if (ws === undefined || !/\s/.test(ws))
67693
- break;
67694
- j += 1;
67695
- }
67696
- const closer = charAt(raw2, j);
67697
- if (closer === "}" || closer === "]") {
67698
- i += 1;
67699
- continue;
67700
- }
67826
+ function parseVisionObject(schema, raw2, providerLabel) {
67827
+ try {
67828
+ return schema.parse(normalizeVisionJson(raw2));
67829
+ } catch (error40) {
67830
+ if (error40 instanceof exports_external.ZodError) {
67831
+ const first = error40.issues[0];
67832
+ const detail = first ? `${first.path.length > 0 ? `${first.path.join(".")}: ` : ""}${first.message}` : error40.message;
67833
+ throw new AgentProviderError(`${providerLabel} JSON was not a valid action: ${detail}`);
67701
67834
  }
67702
- out += c;
67703
- i += 1;
67835
+ throw error40;
67704
67836
  }
67705
- return out;
67706
67837
  }
67707
67838
 
67708
67839
  // src/domains/providers/drivers/antigravity-vision.ts
@@ -67748,13 +67879,10 @@ ${result.stderr}`.trim();
67748
67879
  if (result.exitCode !== 0 && !result.stdout.trim()) {
67749
67880
  throw new AgentProviderError(combined ? `Antigravity CLI failed: ${combined.slice(0, 400)}` : `Antigravity CLI exited ${result.exitCode}`);
67750
67881
  }
67751
- return input.schema.parse(extractAgentJsonObject(result.stdout || combined, "Antigravity CLI"));
67882
+ return parseVisionObject(input.schema, extractAgentJsonObject(result.stdout || combined, "Antigravity CLI"), "Antigravity CLI");
67752
67883
  } catch (error40) {
67753
67884
  if (error40 instanceof AgentProviderError)
67754
67885
  throw error40;
67755
- if (error40 instanceof exports_external.ZodError) {
67756
- throw new AgentProviderError(`Antigravity JSON was not a valid action: ${error40.message}`);
67757
- }
67758
67886
  if (error40 instanceof SyntaxError) {
67759
67887
  throw new AgentProviderError(`Antigravity CLI returned invalid JSON: ${error40.message}`);
67760
67888
  }
@@ -76312,13 +76440,10 @@ Screenshot file (open and look at it): ${shotName}`,
76312
76440
  imageBase64: image.base64,
76313
76441
  mediaType: image.mediaType
76314
76442
  });
76315
- return input.schema.parse(extractAgentJsonObject(stdout, "Cursor Agent CLI"));
76443
+ return parseVisionObject(input.schema, extractAgentJsonObject(stdout, "Cursor Agent CLI"), "Cursor Agent CLI");
76316
76444
  } catch (error40) {
76317
76445
  if (error40 instanceof AgentProviderError)
76318
76446
  throw error40;
76319
- if (error40 instanceof exports_external.ZodError) {
76320
- throw new AgentProviderError(`Cursor JSON was not a valid action: ${error40.message}`);
76321
- }
76322
76447
  if (error40 instanceof SyntaxError) {
76323
76448
  throw new AgentProviderError(`Cursor Agent CLI returned invalid JSON: ${error40.message}`);
76324
76449
  }
@@ -97459,10 +97584,10 @@ var agentDecisionSchema = exports_external.object({
97459
97584
  exports_external.literal("done"),
97460
97585
  exports_external.literal("fail")
97461
97586
  ]),
97462
- x: exports_external.number().min(0).max(1000).optional(),
97463
- y: exports_external.number().min(0).max(1000).optional(),
97587
+ x: exports_external.number().optional(),
97588
+ y: exports_external.number().optional(),
97464
97589
  text: exports_external.string().optional(),
97465
- ms: exports_external.number().min(0).max(1e4).optional(),
97590
+ ms: exports_external.number().optional(),
97466
97591
  reason: exports_external.string().min(1),
97467
97592
  thoughts: exports_external.string().min(1)
97468
97593
  });
@@ -97658,8 +97783,8 @@ function cleanPageSource(xml, window2) {
97658
97783
 
97659
97784
  // src/domains/devices/grounding.ts
97660
97785
  var groundResultSchema = exports_external.object({
97661
- x: exports_external.number().min(0).max(1000),
97662
- y: exports_external.number().min(0).max(1000)
97786
+ x: exports_external.number(),
97787
+ y: exports_external.number()
97663
97788
  });
97664
97789
  var GROUND_SYSTEM = `You locate UI elements on a mobile screen.
97665
97790
  Respond with ONLY JSON: {"x":0-1000,"y":0-1000} for the center of the best match.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yoqa/runner",
3
- "version": "0.3.21",
3
+ "version": "0.3.22",
4
4
  "description": "Yoqa local runner — Appium + catalog HTTP API (Bun). Start with yoqa serve or the yoqa-runner bin.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",