@moda-ai/cli 1.55.81 → 1.55.83

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.
@@ -348,7 +348,7 @@ function hasProperty(object, key) {
348
348
  }
349
349
 
350
350
  // src/harness-extract/calls.ts
351
- var import_typescript3 = __toESM(require_typescript(), 1);
351
+ var import_typescript4 = __toESM(require_typescript(), 1);
352
352
 
353
353
  // src/harness-extract/trace.ts
354
354
  var import_typescript2 = __toESM(require_typescript(), 1);
@@ -1537,1710 +1537,1795 @@ function mayNotRun(at, declaration) {
1537
1537
  return false;
1538
1538
  }
1539
1539
 
1540
- // src/harness-extract/calls.ts
1541
- class CallIndex {
1542
- program;
1543
- checker;
1544
- byName;
1545
- aliases = new Map;
1546
- members = new Map;
1547
- checkingDefaults = new Set;
1548
- constructor(program, checker) {
1549
- this.program = program;
1550
- this.checker = checker;
1540
+ // src/harness-extract/sinks.ts
1541
+ var import_typescript3 = __toESM(require_typescript(), 1);
1542
+ var URL_MODEL_KEY = "?model";
1543
+ var ANTHROPIC_MODULE = /^@anthropic-ai\//;
1544
+ var OPENAI_MODULE = /^openai(?:\/|$)/;
1545
+ var OPENAI_COMPATIBLE_MODULE = /^(?:groq-sdk|together-ai|@cerebras\/cerebras_cloud_sdk|fireworks-ai|portkey-ai|@portkey-ai\/|@azure\/openai|deepseek|@helicone\/|cohere-ai)/;
1546
+ var AI_SDK_CALLS = new Set(["generateText", "streamText", "generateObject", "streamObject"]);
1547
+ var AI_SDK_DECIDE = new Set(["experimental_decide", "decide", "experimental_evaluate", "evaluate"]);
1548
+ var AI_SDK_AGENTS = new Set(["Agent", "Experimental_Agent", "ToolLoopAgent"]);
1549
+ var PROVIDER_MODULE = /^(?:@ai-sdk\/(?!react$|ui-utils$|rsc$|provider$|provider-utils$|svelte$|vue$|solid$|angular$|valibot$)[\w-]+|@openrouter\/ai-sdk-provider|workers-ai-provider|ollama-ai-provider(?:-v2)?|@requesty\/ai-sdk|@portkey-ai\/vercel-provider|@mistralai\/ai-sdk)$/;
1550
+ var MODEL_HOST = /^https?:\/\/(?:openrouter\.ai|api\.openai\.com|api\.anthropic\.com|generativelanguage\.googleapis\.com|api\.groq\.com|api\.together\.(?:xyz|ai)|api\.mistral\.ai|api\.deepseek\.com|api\.fireworks\.ai|api\.x\.ai|api\.perplexity\.ai|gateway\.ai\.cloudflare\.com)\//;
1551
+ var SPEECH_ENDPOINT = /^https?:\/\/api\.elevenlabs\.io\/v\d+\/(?:text-to-speech|speech-to-text|speech-to-speech|text-to-dialogue|sound-generation)\b/;
1552
+ var MODEL_PATH = /\/chat\/completions\b|\/v1\/messages\b|\/v1\/responses\b|:generateContent\b|:streamGenerateContent\b/;
1553
+ var FRAMEWORK_MODULE = /^(?:agents(?:\/.*)?|@cloudflare\/think|@cloudflare\/ai-chat|@cloudflare\/agents|cloudflare:workers|cloudflare:workflows)$/;
1554
+ var FRAMEWORK_BASES = new Set(["Think", "Agent", "AIChatAgent", "McpAgent", "DurableObject", "WorkflowEntrypoint", "AgentWorkflow"]);
1555
+ var HOOK_BASES = new Set(["Think", "Agent", "AIChatAgent", "McpAgent"]);
1556
+ var HOOK_METHODS = {
1557
+ getModel: "model",
1558
+ getTools: "tools",
1559
+ getSystemPrompt: "system",
1560
+ configureContext: "system",
1561
+ getInstructions: "system",
1562
+ instructions: "system",
1563
+ system: "system",
1564
+ systemPrompt: "system",
1565
+ buildSystemPrompt: "system",
1566
+ formatAgentToolInput: "messages"
1567
+ };
1568
+ var HOOK_PROPERTIES = { model: "model", systemPrompt: "system", instructions: "system", system: "system" };
1569
+ var TURN_HOOKS = new Set(["beforeTurn", "beforeStep", "prepareStep"]);
1570
+ var TURN_CONFIG_KEYS = { model: "model", system: "system", tools: "tools", messages: "messages" };
1571
+ function providerName(module) {
1572
+ if (module === "ai" || module === "@ai-sdk/gateway")
1573
+ return "ai-gateway";
1574
+ if (module === "@openrouter/ai-sdk-provider")
1575
+ return "openrouter";
1576
+ if (module === "workers-ai-provider")
1577
+ return "workers-ai";
1578
+ if (module.startsWith("ollama-ai-provider"))
1579
+ return "ollama";
1580
+ const scoped = /^@[\w-]+\/(?:ai-sdk-)?([\w-]+)$/.exec(module);
1581
+ return scoped ? scoped[1] : module;
1582
+ }
1583
+ function requestRoles(argument, keys, ctx) {
1584
+ if (!argument)
1585
+ return [];
1586
+ const object = objectLiteralOf(argument, ctx.checker);
1587
+ const roles = [];
1588
+ if (object && unwrap(argument) === object) {
1589
+ for (const [key, role] of Object.entries(keys)) {
1590
+ const value = propertyValue(object, key);
1591
+ if (value && !spreadAfter(object, key))
1592
+ roles.push({ role, node: value });
1593
+ else if ((value || !hasProperty(object, key)) && object.properties.some((property) => import_typescript3.default.isSpreadAssignment(property))) {
1594
+ roles.push({ role, node: argument, key });
1595
+ }
1596
+ }
1597
+ return dedupeRoles(roles);
1551
1598
  }
1552
- build() {
1553
- const byName = new Map;
1554
- for (const source of this.program.getSourceFiles()) {
1555
- if (source.isDeclarationFile || /[\\/]node_modules[\\/]/.test(source.fileName))
1556
- continue;
1557
- const imported = importAliases(source);
1599
+ for (const [key, role] of Object.entries(keys)) {
1600
+ if (!object || hasProperty(object, key) || object.properties.some((property) => import_typescript3.default.isSpreadAssignment(property))) {
1601
+ roles.push({ role, node: argument, key });
1602
+ }
1603
+ }
1604
+ return dedupeRoles(roles);
1605
+ }
1606
+ function spreadAfter(object, key) {
1607
+ let last = -1;
1608
+ object.properties.forEach((property, index) => {
1609
+ if (!import_typescript3.default.isSpreadAssignment(property) && property.name && propertyNameText(property.name) === key)
1610
+ last = index;
1611
+ });
1612
+ return object.properties.some((property, index) => index > last && import_typescript3.default.isSpreadAssignment(property));
1613
+ }
1614
+ function dedupeRoles(roles) {
1615
+ const seen = new Set;
1616
+ return roles.filter((role) => {
1617
+ if (seen.has(role.role))
1618
+ return false;
1619
+ seen.add(role.role);
1620
+ return true;
1621
+ });
1622
+ }
1623
+ function typeOrigin(type, checker) {
1624
+ if (!type)
1625
+ return;
1626
+ if (import_typescript3.default.isUnionTypeNode(type) || import_typescript3.default.isIntersectionTypeNode(type)) {
1627
+ for (const member of type.types) {
1628
+ const origin = typeOrigin(member, checker);
1629
+ if (origin)
1630
+ return origin;
1631
+ }
1632
+ return;
1633
+ }
1634
+ if (import_typescript3.default.isTypeReferenceNode(type)) {
1635
+ let name = type.typeName;
1636
+ while (import_typescript3.default.isQualifiedName(name))
1637
+ name = name.left;
1638
+ return importOrigin(name, checker);
1639
+ }
1640
+ return;
1641
+ }
1642
+ function valueOrigin(expression, checker, depth = 0, seen = new Set) {
1643
+ const expr = unwrap(expression);
1644
+ if (depth > 6 || seen.has(expr))
1645
+ return;
1646
+ seen.add(expr);
1647
+ if (import_typescript3.default.isNewExpression(expr) || import_typescript3.default.isCallExpression(expr)) {
1648
+ const root = rootIdentifier(expr.expression);
1649
+ const origin = root ? importOrigin(root, checker) : undefined;
1650
+ if (origin)
1651
+ return origin;
1652
+ const fn = resolvedFunction(expr.expression, checker);
1653
+ if (fn) {
1654
+ const declared = typeOrigin(fn.type, checker);
1655
+ if (declared)
1656
+ return declared;
1657
+ for (const ret of returnExpressions(fn)) {
1658
+ const found = valueOrigin(ret, checker, depth + 1, seen);
1659
+ if (found)
1660
+ return found;
1661
+ }
1662
+ }
1663
+ return;
1664
+ }
1665
+ let declaration;
1666
+ if (import_typescript3.default.isIdentifier(expr)) {
1667
+ const origin = importOrigin(expr, checker);
1668
+ if (origin)
1669
+ return origin;
1670
+ declaration = valueDeclaration(resolvedSymbol(expr, checker));
1671
+ } else if (import_typescript3.default.isPropertyAccessExpression(expr)) {
1672
+ declaration = valueDeclaration(resolvedSymbol(expr.name, checker));
1673
+ }
1674
+ if (!declaration)
1675
+ return;
1676
+ if (import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) || import_typescript3.default.isParameter(declaration) || import_typescript3.default.isPropertySignature(declaration) || import_typescript3.default.isPropertyAssignment(declaration)) {
1677
+ const declared = "type" in declaration ? typeOrigin(declaration.type, checker) : undefined;
1678
+ if (declared)
1679
+ return declared;
1680
+ const initializer = "initializer" in declaration ? declaration.initializer : undefined;
1681
+ if (initializer)
1682
+ return valueOrigin(initializer, checker, depth + 1, seen);
1683
+ if (import_typescript3.default.isPropertyDeclaration(declaration)) {
1684
+ const key = propertyNameText(declaration.name);
1685
+ let found;
1558
1686
  const visit = (node) => {
1559
- if ((import_typescript3.default.isParameter(node) || import_typescript3.default.isVariableDeclaration(node)) && node.initializer && import_typescript3.default.isIdentifier(node.name)) {
1560
- let init = unwrap(node.initializer);
1561
- if (import_typescript3.default.isBinaryExpression(init) && (init.operatorToken.kind === import_typescript3.default.SyntaxKind.QuestionQuestionToken || init.operatorToken.kind === import_typescript3.default.SyntaxKind.BarBarToken))
1562
- init = unwrap(init.right);
1563
- if (import_typescript3.default.isIdentifier(init)) {
1564
- const entry = { declaration: node, target: init };
1565
- const list = this.aliases.get(init.text);
1566
- if (list)
1567
- list.push(entry);
1568
- else
1569
- this.aliases.set(init.text, [entry]);
1570
- }
1571
- }
1572
- if ((import_typescript3.default.isPropertyAssignment(node) || import_typescript3.default.isShorthandPropertyAssignment(node)) && import_typescript3.default.isObjectLiteralExpression(node.parent)) {
1573
- const value = import_typescript3.default.isShorthandPropertyAssignment(node) ? node.name : unwrap(node.initializer);
1574
- const property = import_typescript3.default.isIdentifier(node.name) || import_typescript3.default.isStringLiteral(node.name) ? node.name.text : undefined;
1575
- if (property && import_typescript3.default.isIdentifier(value)) {
1576
- const entry = { property, literal: node.parent, target: value };
1577
- const list = this.members.get(value.text);
1578
- if (list)
1579
- list.push(entry);
1580
- else
1581
- this.members.set(value.text, [entry]);
1582
- }
1583
- }
1584
- if (import_typescript3.default.isCallExpression(node)) {
1585
- const callee = unwrap(node.expression);
1586
- const name = import_typescript3.default.isIdentifier(callee) ? callee.text : import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name.text : undefined;
1587
- if (name) {
1588
- const original = import_typescript3.default.isIdentifier(callee) ? imported.get(name) : undefined;
1589
- for (const key of original && original !== name ? [name, original] : [name]) {
1590
- const list = byName.get(key);
1591
- if (list)
1592
- list.push(node);
1593
- else
1594
- byName.set(key, [node]);
1595
- }
1596
- }
1687
+ if (found)
1688
+ return;
1689
+ if (import_typescript3.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript3.default.SyntaxKind.EqualsToken && import_typescript3.default.isPropertyAccessExpression(node.left) && node.left.expression.kind === import_typescript3.default.SyntaxKind.ThisKeyword && node.left.name.text === key) {
1690
+ found = valueOrigin(node.right, checker, depth + 1, seen);
1597
1691
  }
1598
1692
  import_typescript3.default.forEachChild(node, visit);
1599
1693
  };
1600
- visit(source);
1694
+ import_typescript3.default.forEachChild(declaration.parent, visit);
1695
+ return found;
1601
1696
  }
1602
- return byName;
1603
- }
1604
- callersOf(fn, name, limit, within) {
1605
- const all = this.allCallersOf(fn, name, within ? Number.MAX_SAFE_INTEGER : limit);
1606
- if (!within)
1607
- return all;
1608
- return all.filter((call) => within.getSourceFile(call.getSourceFile().fileName) === call.getSourceFile()).slice(0, limit);
1609
1697
  }
1610
- allCallersOf(fn, name, limit) {
1611
- this.byName ??= this.build();
1612
- const out = this.direct(name, limit, (declaration) => declares(declaration, fn));
1613
- if (isDefaultExport(fn) && name !== "default" && out.length < limit)
1614
- out.push(...this.direct("default", limit - out.length, (declaration) => declares(declaration, fn), new Set(out)));
1615
- for (const alias of this.aliases.get(name) ?? []) {
1616
- if (out.length >= limit)
1617
- break;
1618
- const symbol = resolvedSymbol(alias.target, this.checker);
1619
- if (!symbol?.declarations?.some((declaration) => declares(declaration, fn)))
1620
- continue;
1621
- if (!this.defaultCanApply(alias.declaration))
1622
- continue;
1623
- const aliasName = alias.declaration.name.text;
1624
- out.push(...this.direct(aliasName, limit - out.length, (declaration) => declaration === alias.declaration));
1698
+ return;
1699
+ }
1700
+ function providerInstance(expression, checker, depth = 0) {
1701
+ const expr = unwrap(expression);
1702
+ if (depth > 6)
1703
+ return;
1704
+ if (import_typescript3.default.isIdentifier(expr)) {
1705
+ const origin = importOrigin(expr, checker);
1706
+ if (origin) {
1707
+ if (origin.module === "ai" && origin.imported === "gateway")
1708
+ return "ai";
1709
+ return PROVIDER_MODULE.test(origin.module) && !/^create/.test(origin.imported) && origin.imported !== "*" ? origin.module : undefined;
1625
1710
  }
1626
- for (const member of this.members.get(name) ?? []) {
1627
- if (out.length >= limit)
1628
- break;
1629
- const symbol = resolvedSymbol(member.target, this.checker);
1630
- if (!symbol?.declarations?.some((declaration) => declares(declaration, fn)))
1631
- continue;
1632
- for (const param of this.holders(member.literal)) {
1633
- out.push(...this.memberCalls(param, member.property, limit - out.length));
1634
- }
1711
+ const declaration = valueDeclaration(resolvedSymbol(expr, checker));
1712
+ if (declaration && (import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyDeclaration(declaration)) && declaration.initializer) {
1713
+ const initializer = declaration.initializer;
1714
+ return memoized(declaration, () => providerInstance(initializer, checker, depth + 1));
1635
1715
  }
1636
- return out;
1716
+ return;
1637
1717
  }
1638
- holders(literal) {
1639
- let node = literal;
1640
- while (node.parent && (import_typescript3.default.isParenthesizedExpression(node.parent) || import_typescript3.default.isAsExpression(node.parent) || import_typescript3.default.isSatisfiesExpression(node.parent)))
1641
- node = node.parent;
1642
- const parent = node.parent;
1643
- const out = [];
1644
- if (parent && import_typescript3.default.isCallExpression(parent)) {
1645
- const index = parent.arguments.indexOf(node);
1646
- const fn = index >= 0 ? resolvedFunction(parent.expression, this.checker) : undefined;
1647
- if (fn && fn.parameters[index])
1648
- out.push(fn.parameters[index]);
1649
- } else if (parent && import_typescript3.default.isParameter(parent) && parent.initializer === node) {
1650
- out.push(parent);
1651
- } else if (parent && import_typescript3.default.isVariableDeclaration(parent) && parent.initializer === node && import_typescript3.default.isIdentifier(parent.name)) {
1652
- for (const alias of this.aliases.get(parent.name.text) ?? []) {
1653
- if (import_typescript3.default.isParameter(alias.declaration) && valueDeclaration(resolvedSymbol(alias.target, this.checker)) === parent)
1654
- out.push(alias.declaration);
1655
- }
1718
+ if (import_typescript3.default.isPropertyAccessExpression(expr)) {
1719
+ const declaration = valueDeclaration(resolvedSymbol(expr.name, checker));
1720
+ if (declaration && (import_typescript3.default.isPropertyDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isVariableDeclaration(declaration)) && declaration.initializer) {
1721
+ const initializer = declaration.initializer;
1722
+ return memoized(declaration, () => providerInstance(initializer, checker, depth + 1));
1656
1723
  }
1657
- return out;
1724
+ return;
1658
1725
  }
1659
- memberCalls(param, property, limit) {
1660
- const out = [];
1661
- for (const call of this.byName.get(property) ?? []) {
1662
- if (out.length >= limit)
1663
- break;
1664
- const callee = unwrap(call.expression);
1665
- if (import_typescript3.default.isPropertyAccessExpression(callee)) {
1666
- const receiver = unwrap(callee.expression);
1667
- if (import_typescript3.default.isIdentifier(receiver) && valueDeclaration(resolvedSymbol(receiver, this.checker)) === param)
1668
- out.push(call);
1669
- } else if (import_typescript3.default.isIdentifier(callee)) {
1670
- const declaration = valueDeclaration(resolvedSymbol(callee, this.checker));
1671
- if (!declaration || !import_typescript3.default.isBindingElement(declaration))
1672
- continue;
1673
- const holder = declaration.parent.parent;
1674
- const init = import_typescript3.default.isVariableDeclaration(holder) && holder.initializer ? unwrap(holder.initializer) : undefined;
1675
- if (holder === param || init && import_typescript3.default.isIdentifier(init) && valueDeclaration(resolvedSymbol(init, this.checker)) === param)
1676
- out.push(call);
1677
- }
1726
+ if (import_typescript3.default.isCallExpression(expr)) {
1727
+ const root = rootIdentifier(expr.expression);
1728
+ const origin = root ? importOrigin(root, checker) : undefined;
1729
+ if (origin) {
1730
+ if (PROVIDER_MODULE.test(origin.module) && /^create/.test(origin.imported))
1731
+ return origin.module;
1732
+ if (origin.module === "ai" && (origin.imported === "customProvider" || origin.imported === "createGateway"))
1733
+ return "ai";
1734
+ return;
1678
1735
  }
1679
- return out;
1680
- }
1681
- defaultCanApply(declaration) {
1682
- if (!import_typescript3.default.isParameter(declaration) || this.checkingDefaults.has(declaration))
1683
- return true;
1684
- const init = declaration.initializer ? unwrap(declaration.initializer) : undefined;
1685
- if (!init || !import_typescript3.default.isIdentifier(init))
1686
- return true;
1687
- const fn = declaration.parent;
1688
- const name = isFunctionLike(fn) ? functionName(fn) : undefined;
1689
- if (!name || !isFunctionLike(fn))
1690
- return true;
1691
- const index = fn.parameters.indexOf(declaration);
1692
- this.checkingDefaults.add(declaration);
1693
- try {
1694
- const callers = this.callersOf(fn, name, 20);
1695
- if (callers.length === 0 || callers.length >= 20)
1696
- return true;
1697
- return callers.some((call) => {
1698
- if (call.arguments.slice(0, index + 1).some((argument2) => import_typescript3.default.isSpreadElement(argument2)))
1699
- return true;
1700
- const argument = call.arguments[index];
1701
- if (!argument)
1702
- return true;
1703
- const inner = unwrap(argument);
1704
- if (import_typescript3.default.isIdentifier(inner) && inner.text === "undefined" || import_typescript3.default.isVoidExpression(inner))
1705
- return true;
1706
- const passed = import_typescript3.default.isIdentifier(inner) ? valueDeclaration(resolvedSymbol(inner, this.checker)) : undefined;
1707
- if (passed && declaration.initializer && declares(passed, resolvedFunction(declaration.initializer, this.checker) ?? fn))
1708
- return true;
1709
- return !definitelyDefined(inner, this.checker);
1736
+ const fn = resolvedFunction(expr.expression, checker);
1737
+ if (fn) {
1738
+ return memoized(fn, () => {
1739
+ for (const ret of returnExpressions(fn)) {
1740
+ const found = providerInstance(ret, checker, depth + 1);
1741
+ if (found)
1742
+ return found;
1743
+ }
1744
+ return;
1710
1745
  });
1711
- } finally {
1712
- this.checkingDefaults.delete(declaration);
1713
- }
1714
- }
1715
- direct(name, limit, matches, found) {
1716
- const candidates = this.byName.get(name) ?? [];
1717
- const out = [];
1718
- let checked = 0;
1719
- for (const call of candidates) {
1720
- if (found?.has(call))
1721
- continue;
1722
- if (out.length >= limit || checked >= limit * 20)
1723
- break;
1724
- checked += 1;
1725
- const callee = unwrap(call.expression);
1726
- const nameNode = import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name : callee;
1727
- const symbol = resolvedSymbol(nameNode, this.checker);
1728
- if (symbol?.declarations?.some(matches))
1729
- out.push(call);
1730
1746
  }
1731
- return out;
1732
1747
  }
1748
+ return;
1733
1749
  }
1734
-
1735
- class RepoCallIndex {
1736
- entries;
1737
- indexes = new Map;
1738
- owned = new Map;
1739
- constructor(entries) {
1740
- this.entries = entries;
1741
- }
1742
- indexFor(entry) {
1743
- let index = this.indexes.get(entry);
1744
- if (!index) {
1745
- index = new CallIndex(entry.program, entry.checker());
1746
- this.indexes.set(entry, index);
1747
- }
1748
- return index;
1749
- }
1750
- indexedCallersOf(fn, name, limit, within) {
1751
- const out = [];
1752
- const seen = new Set;
1753
- const fnFile = fn.getSourceFile().fileName;
1754
- for (const entry of this.entries) {
1755
- if (out.length >= limit)
1756
- break;
1757
- if (!entry.program.getSourceFile(fnFile))
1758
- continue;
1759
- let owned = this.owned.get(entry);
1760
- if (!owned) {
1761
- owned = new Set(entry.owned);
1762
- this.owned.set(entry, owned);
1763
- }
1764
- for (const call of this.indexFor(entry).callersOf(fn, name, Number.MAX_SAFE_INTEGER)) {
1765
- const source = call.getSourceFile();
1766
- if (!owned.has(source.fileName))
1767
- continue;
1768
- const key = `${source.fileName}:${call.pos}`;
1769
- if (seen.has(key))
1770
- continue;
1771
- if (within && within.getSourceFile(source.fileName) !== source)
1772
- continue;
1773
- seen.add(key);
1774
- out.push({ call, entry });
1775
- if (out.length >= limit)
1776
- break;
1777
- }
1778
- }
1779
- return out;
1780
- }
1781
- callersOf(fn, name, limit, within) {
1782
- const own = within ? this.entries.find((entry) => entry.program === within) : undefined;
1783
- if (own)
1784
- return this.indexFor(own).callersOf(fn, name, limit);
1785
- return this.indexedCallersOf(fn, name, limit, within).map((indexed) => indexed.call);
1786
- }
1750
+ var providerMemo = new WeakMap;
1751
+ function memoized(node, compute) {
1752
+ if (providerMemo.has(node))
1753
+ return providerMemo.get(node) ?? undefined;
1754
+ providerMemo.set(node, null);
1755
+ const value = compute();
1756
+ providerMemo.set(node, value ?? null);
1757
+ return value;
1787
1758
  }
1788
- function importAliases(source) {
1789
- const aliases = new Map;
1790
- for (const statement of source.statements) {
1791
- const clause = import_typescript3.default.isImportDeclaration(statement) ? statement.importClause : undefined;
1792
- if (!clause || clause.isTypeOnly)
1793
- continue;
1794
- if (clause.name)
1795
- aliases.set(clause.name.text, "default");
1796
- if (clause.namedBindings && import_typescript3.default.isNamedImports(clause.namedBindings)) {
1797
- for (const element of clause.namedBindings.elements) {
1798
- if (element.propertyName)
1799
- aliases.set(element.name.text, element.propertyName.text);
1800
- }
1801
- }
1759
+ var MODEL_METHOD = /model|chat|completion|responses|messages|image|embedding|speech|transcription/i;
1760
+ function providerModelCall(call, checker) {
1761
+ const model = call.arguments[0];
1762
+ if (!model || import_typescript3.default.isSpreadElement(model) || import_typescript3.default.isObjectLiteralExpression(unwrap(model)))
1763
+ return;
1764
+ const callee = unwrap(call.expression);
1765
+ if (import_typescript3.default.isIdentifier(callee)) {
1766
+ const module = providerInstance(callee, checker);
1767
+ return module ? { module, model } : undefined;
1802
1768
  }
1803
- return aliases;
1804
- }
1805
- function isDefaultExport(fn) {
1806
- const holder = import_typescript3.default.isVariableDeclaration(fn.parent) ? fn.parent : fn;
1807
- if (import_typescript3.default.canHaveModifiers(holder) && import_typescript3.default.getModifiers(holder)?.some((modifier) => modifier.kind === import_typescript3.default.SyntaxKind.DefaultKeyword))
1808
- return true;
1809
- if (import_typescript3.default.isExportAssignment(fn.parent))
1810
- return true;
1811
- const name = functionName(fn);
1812
- return Boolean(name && fn.getSourceFile().statements.some((statement) => import_typescript3.default.isExportAssignment(statement) && !statement.isExportEquals && import_typescript3.default.isIdentifier(statement.expression) && statement.expression.text === name));
1769
+ if (import_typescript3.default.isPropertyAccessExpression(callee) && MODEL_METHOD.test(callee.name.text)) {
1770
+ const module = providerInstance(callee.expression, checker);
1771
+ return module ? { module, method: callee.name.text, model } : undefined;
1772
+ }
1773
+ return;
1813
1774
  }
1814
- function sameNode(a, b) {
1815
- return a === b || a.kind === b.kind && a.pos === b.pos && a.end === b.end && a.getSourceFile().fileName === b.getSourceFile().fileName;
1775
+ function chainEndsWith(chain, tail) {
1776
+ if (!chain || chain.length <= tail.length)
1777
+ return false;
1778
+ return tail.every((part, index) => chain[chain.length - tail.length + index] === part);
1816
1779
  }
1817
- function declares(declaration, fn) {
1818
- if (sameNode(declaration, fn))
1819
- return true;
1820
- if ((import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration)) && declaration.initializer && sameNode(unwrap(declaration.initializer), fn))
1821
- return true;
1822
- if (import_typescript3.default.isExportAssignment(declaration) && sameNode(unwrap(declaration.expression), fn))
1823
- return true;
1824
- return false;
1780
+ function receiverOf(callee, tailLength) {
1781
+ let current = unwrap(callee);
1782
+ for (let index = 0;index < tailLength && import_typescript3.default.isPropertyAccessExpression(current); index += 1)
1783
+ current = unwrap(current.expression);
1784
+ return current;
1825
1785
  }
1826
- function definitelyDefined(expression, checker, seen = new Set) {
1827
- const node = unwrap(expression);
1828
- if (seen.has(node))
1829
- return false;
1830
- seen.add(node);
1831
- if (import_typescript3.default.isStringLiteralLike(node) || import_typescript3.default.isNumericLiteral(node) || import_typescript3.default.isObjectLiteralExpression(node) || import_typescript3.default.isArrayLiteralExpression(node) || import_typescript3.default.isArrowFunction(node) || import_typescript3.default.isFunctionExpression(node) || node.kind === import_typescript3.default.SyntaxKind.NullKeyword || node.kind === import_typescript3.default.SyntaxKind.TrueKeyword || node.kind === import_typescript3.default.SyntaxKind.FalseKeyword)
1832
- return true;
1833
- if (import_typescript3.default.isIdentifier(node)) {
1834
- const declaration = valueDeclaration(resolvedSymbol(node, checker));
1835
- if (declaration && (import_typescript3.default.isFunctionDeclaration(declaration) || import_typescript3.default.isClassDeclaration(declaration)))
1836
- return true;
1837
- if (declaration && import_typescript3.default.isVariableDeclaration(declaration) && declaration.initializer && import_typescript3.default.getCombinedNodeFlags(declaration) & import_typescript3.default.NodeFlags.Const)
1838
- return definitelyDefined(declaration.initializer, checker, seen);
1786
+ var anthropicSink = {
1787
+ id: "anthropic",
1788
+ sdk: "anthropic",
1789
+ match(call, ctx) {
1790
+ if (!import_typescript3.default.isCallExpression(call))
1791
+ return;
1792
+ const chain = calleeChain(call.expression);
1793
+ const tails = [["beta", "messages", "create"], ["beta", "messages", "stream"], ["messages", "create"], ["messages", "stream"]];
1794
+ const tail = tails.find((candidate) => chainEndsWith(chain, candidate));
1795
+ if (!tail || chain.includes("threads"))
1796
+ return;
1797
+ const receiver = receiverOf(call.expression, tail.length);
1798
+ const origin = valueOrigin(receiver, ctx.checker);
1799
+ const request = call.arguments[0];
1800
+ if (origin && !ANTHROPIC_MODULE.test(origin.module))
1801
+ return;
1802
+ if (!origin) {
1803
+ const object = objectLiteralOf(request, ctx.checker);
1804
+ const receiverName = receiver.getText();
1805
+ if (!object || !hasProperty(object, "model") || !hasProperty(object, "messages"))
1806
+ return;
1807
+ if (!/anthropic|claude|client|llm|openrouter/i.test(receiverName) && !hasProperty(object, "max_tokens"))
1808
+ return;
1809
+ }
1810
+ return {
1811
+ api: `anthropic.${tail.join(".")}`,
1812
+ provider: "anthropic",
1813
+ roles: requestRoles(request, { model: "model", system: "system", messages: "messages", tools: "tools" }, ctx)
1814
+ };
1839
1815
  }
1840
- return false;
1841
- }
1842
-
1843
- // src/harness-extract/messages.ts
1844
- var ROLE_LITERALS = {
1845
- system: "system",
1846
- developer: "system",
1847
- user: "user",
1848
- human: "user",
1849
- assistant: "assistant",
1850
- ai: "assistant",
1851
- model: "assistant",
1852
- tool: "tool",
1853
- function: "tool"
1854
1816
  };
1855
- var CONSTRUCTOR_ROLE = [
1856
- [/(?:^|\.)System(?:Message|MessagePromptTemplate)\b/, "system"],
1857
- [/(?:^|\.)(?:Human|User)(?:Message|MessagePromptTemplate)\b/, "user"],
1858
- [/(?:^|\.)(?:AI|Ai|Assistant)(?:Message|MessagePromptTemplate)\b/, "assistant"],
1859
- [/(?:^|\.)(?:Tool|Function)Message\b/, "tool"]
1860
- ];
1861
- var PASS_THROUGH = new Set(["ref", "lookup", "param", "call", "oneOf"]);
1862
- var STRINGY = new Set(["literal", "template", "concat", "arrayJoin"]);
1863
- var MAX_CONTAINERS = 16;
1864
- function singleLiteral(tree) {
1865
- if (!tree)
1817
+ var OPENAI_MODEL_ONLY_TAILS = [["embeddings", "create"], ["audio", "speech", "create"], ["audio", "transcriptions", "create"], ["audio", "translations", "create"], ["images", "generate"], ["images", "edit"]];
1818
+ function openaiModelOnly(call, chain, ctx) {
1819
+ const tail = OPENAI_MODEL_ONLY_TAILS.find((candidate) => chainEndsWith(chain, candidate));
1820
+ if (!tail)
1866
1821
  return;
1867
- if (tree.kind === "literal")
1868
- return tree.text;
1869
- if (PASS_THROUGH.has(tree.kind)) {
1870
- const flow = valueChildren(tree);
1871
- if (flow.length === 1)
1872
- return singleLiteral(flow[0]);
1873
- }
1874
- return;
1822
+ const origin = valueOrigin(receiverOf(call.expression, tail.length), ctx.checker);
1823
+ const object = objectLiteralOf(call.arguments[0], ctx.checker);
1824
+ if (origin ? !OPENAI_MODULE.test(origin.module) : !object || !hasProperty(object, "model"))
1825
+ return;
1826
+ return { api: `openai.${tail.join(".")}`, provider: "openai", roles: requestRoles(call.arguments[0], { model: "model" }, ctx) };
1875
1827
  }
1876
- function elementRole(element, depth = 0) {
1877
- if (depth > 6 || element.key === "...")
1878
- return "unknown";
1879
- if (element.kind === "object") {
1880
- const missing = { ...element, kind: "external", children: undefined, resolution: "unresolved" };
1881
- const text = singleLiteral(selectKey(element, "role", missing));
1882
- return text && ROLE_LITERALS[text.toLowerCase()] || "unknown";
1828
+ var openaiSink = {
1829
+ id: "openai",
1830
+ sdk: "openai",
1831
+ match(call, ctx) {
1832
+ if (!import_typescript3.default.isCallExpression(call))
1833
+ return;
1834
+ const chain = calleeChain(call.expression);
1835
+ const tails = [["chat", "completions", "create"], ["chat", "completions", "parse"], ["chat", "completions", "stream"], ["responses", "create"], ["responses", "stream"], ["responses", "parse"]];
1836
+ const tail = tails.find((candidate) => chainEndsWith(chain, candidate));
1837
+ if (!tail)
1838
+ return openaiModelOnly(call, chain, ctx);
1839
+ const receiver = receiverOf(call.expression, tail.length);
1840
+ const origin = valueOrigin(receiver, ctx.checker);
1841
+ if (origin && !OPENAI_MODULE.test(origin.module) && !(tail[0] === "chat" && !ANTHROPIC_MODULE.test(origin.module)))
1842
+ return;
1843
+ const request = call.arguments[0];
1844
+ if (!origin && tail[0] === "responses") {
1845
+ const object = objectLiteralOf(request, ctx.checker);
1846
+ if (!object || !hasProperty(object, "model") || !(hasProperty(object, "input") || hasProperty(object, "instructions")))
1847
+ return;
1848
+ }
1849
+ return {
1850
+ api: `openai.${tail.join(".")}`,
1851
+ provider: !origin || OPENAI_MODULE.test(origin.module) ? "openai" : OPENAI_COMPATIBLE_MODULE.test(origin.module) ? providerName(origin.module).replace(/-sdk$|_cloud_sdk$|-ai$/, "") : providerName(origin.module),
1852
+ roles: requestRoles(request, { model: "model", messages: "messages", input: "messages", instructions: "instructions", tools: "tools", functions: "tools" }, ctx)
1853
+ };
1883
1854
  }
1884
- if (element.kind === "array") {
1885
- const text = singleLiteral(element.children?.[0]);
1886
- return text && ROLE_LITERALS[text.toLowerCase()] || "unknown";
1855
+ };
1856
+ var aiSdkSink = {
1857
+ id: "ai-sdk",
1858
+ sdk: "ai-sdk",
1859
+ match(call, ctx) {
1860
+ const callee = unwrap(call.expression);
1861
+ const nameNode = import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name : import_typescript3.default.isIdentifier(callee) ? callee : undefined;
1862
+ const root = rootIdentifier(callee);
1863
+ if (!nameNode || !root)
1864
+ return;
1865
+ const origin = importOrigin(root, ctx.checker);
1866
+ if (!origin || origin.module !== "ai")
1867
+ return;
1868
+ const name = origin.imported === "*" ? nameNode.text : origin.imported;
1869
+ if (!import_typescript3.default.isNewExpression(call) && AI_SDK_DECIDE.has(name)) {
1870
+ return { api: `ai.${name}`, roles: requestRoles(call.arguments[0], { model: "model", questions: "questions", criteria: "questions" }, ctx) };
1871
+ }
1872
+ const known = import_typescript3.default.isNewExpression(call) ? AI_SDK_AGENTS.has(name) : AI_SDK_CALLS.has(name);
1873
+ if (!known)
1874
+ return;
1875
+ return {
1876
+ api: `ai.${name}`,
1877
+ roles: requestRoles(call.arguments?.[0], { model: "model", system: "system", instructions: "instructions", prompt: "prompt", messages: "messages", tools: "tools" }, ctx)
1878
+ };
1887
1879
  }
1888
- if ((element.kind === "call" || element.kind === "external") && element.name) {
1889
- for (const [pattern, role] of CONSTRUCTOR_ROLE)
1890
- if (pattern.test(element.name))
1891
- return role;
1880
+ };
1881
+ var providerFactorySink = {
1882
+ id: "provider-factory",
1883
+ sdk: "provider-factory",
1884
+ match(call, ctx) {
1885
+ if (!import_typescript3.default.isCallExpression(call))
1886
+ return;
1887
+ const found = providerModelCall(call, ctx.checker);
1888
+ if (!found)
1889
+ return;
1890
+ const provider = providerName(found.module);
1891
+ return { api: `${provider}${found.method ? `.${found.method}` : ""}(model)`, provider, roles: [{ role: "model", node: found.model }] };
1892
1892
  }
1893
- if (PASS_THROUGH.has(element.kind)) {
1894
- const roles = new Set(valueChildren(element).map((child) => elementRole(child, depth + 1)));
1895
- return roles.size === 1 ? [...roles][0] : "unknown";
1893
+ };
1894
+ var WORKERS_AI_MODEL = /^@(?:cf|hf)\/[\w.-]+\/[\w.:-]+$/;
1895
+ function isWorkersAiBinding(callee, checker) {
1896
+ const target = unwrap(callee);
1897
+ if (!import_typescript3.default.isPropertyAccessExpression(target))
1898
+ return false;
1899
+ const receiver = unwrap(target.expression);
1900
+ const declaration = import_typescript3.default.isIdentifier(receiver) || import_typescript3.default.isPropertyAccessExpression(receiver) ? valueDeclaration(resolvedSymbol(import_typescript3.default.isIdentifier(receiver) ? receiver : receiver.name, checker)) : undefined;
1901
+ const type = declaration && (import_typescript3.default.isParameter(declaration) || import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) || import_typescript3.default.isPropertySignature(declaration)) ? declaration.type : undefined;
1902
+ return Boolean(type && import_typescript3.default.isTypeReferenceNode(type) && type.typeName.getText() === "Ai");
1903
+ }
1904
+ var workersAiSink = {
1905
+ id: "workers-ai",
1906
+ sdk: "workers-ai",
1907
+ match(call, ctx) {
1908
+ if (!import_typescript3.default.isCallExpression(call))
1909
+ return;
1910
+ const chain = calleeChain(call.expression);
1911
+ if (!chain || chain[chain.length - 1] !== "run" || call.arguments.length === 0)
1912
+ return;
1913
+ const [model, input] = call.arguments;
1914
+ if (!chainEndsWith(chain, ["AI", "run"]) && !isWorkersAiBinding(call.expression, ctx.checker) && !ctx.urlTexts(model).some((text) => WORKERS_AI_MODEL.test(text)))
1915
+ return;
1916
+ return {
1917
+ api: "workers-ai.AI.run",
1918
+ provider: "workers-ai",
1919
+ roles: [{ role: "model", node: model }, ...requestRoles(input, { messages: "messages", prompt: "prompt", tools: "tools" }, ctx)]
1920
+ };
1896
1921
  }
1897
- return "unknown";
1922
+ };
1923
+ var REQUEST_KEYS = { model: "model", model_id: "model", system: "system", messages: "messages", input: "messages", instructions: "instructions", prompt: "prompt", tools: "tools" };
1924
+ var OPAQUE_BODY_KEYS = { model: "model", system: "system", messages: "messages", tools: "tools" };
1925
+ var FETCH_LIKE = /fetch|request|post/i;
1926
+ var NON_MODEL_PATH = /\/models\/?(?:\?|$|`)|\/generation\b|\/credits\b|\/auth\/|\/keys?\b|\/embeddings\b|\/files\b/;
1927
+ function bodyHasModel(init, checker) {
1928
+ const body = init ? propertyValue(init, "body") : undefined;
1929
+ let payload = body ? unwrap(body) : undefined;
1930
+ if (payload && import_typescript3.default.isCallExpression(payload) && payload.arguments[0])
1931
+ payload = payload.arguments[0];
1932
+ const object = objectLiteralOf(payload, checker);
1933
+ return Boolean(object && hasProperty(object, "model"));
1898
1934
  }
1899
- function containersOf(tree, containers, others, depth = 0) {
1900
- if (containers.length >= MAX_CONTAINERS)
1901
- return;
1902
- if (tree.kind === "array" || tree.kind === "assembled" && tree.text !== "string") {
1903
- containers.push(tree);
1904
- return;
1935
+ function urlTemplate(expression, checker, depth = 0) {
1936
+ const expr = unwrap(expression);
1937
+ if (import_typescript3.default.isTemplateExpression(expr))
1938
+ return expr;
1939
+ if (depth < 3 && import_typescript3.default.isIdentifier(expr)) {
1940
+ const declaration = valueDeclaration(resolvedSymbol(expr, checker));
1941
+ if (declaration && import_typescript3.default.isVariableDeclaration(declaration) && declaration.initializer)
1942
+ return urlTemplate(declaration.initializer, checker, depth + 1);
1905
1943
  }
1906
- const flow = PASS_THROUGH.has(tree.kind) ? valueChildren(tree) : [];
1907
- if (flow.length > 0 && depth < 12) {
1908
- for (const child of flow)
1909
- containersOf(child, containers, others, depth + 1);
1944
+ return;
1945
+ }
1946
+ var MODEL_SOCKET = /^wss:\/\/(?:api\.openai\.com\/v1\/realtime|[\w.-]+\.openai\.azure\.com\/openai\/realtime|generativelanguage\.googleapis\.com\/ws\/[\w.]+BidiGenerateContent|gateway\.ai\.cloudflare\.com\/)/;
1947
+ function urlModel(url, checker) {
1948
+ const template = urlTemplate(url, checker);
1949
+ if (!template)
1910
1950
  return;
1951
+ let before = template.head.text;
1952
+ for (const span of template.templateSpans) {
1953
+ if (/\/models\/$/.test(before) && /^[:/?#]/.test(span.literal.text) || /[?&]model=$/.test(before) && /^(?:[&#]|$)/.test(span.literal.text))
1954
+ return span.expression;
1955
+ before = span.literal.text;
1911
1956
  }
1912
- others.push(tree);
1957
+ return;
1913
1958
  }
1914
- function splitMessages(tree) {
1915
- const containers = [];
1916
- const others = [];
1917
- containersOf(tree, containers, others);
1918
- if (containers.length === 0) {
1919
- return [{ role: STRINGY.has(tree.kind) || others.length > 0 && others.every((other) => STRINGY.has(other.kind)) ? "user" : "unknown", tree }];
1959
+ var fetchSink = {
1960
+ id: "fetch",
1961
+ sdk: "fetch",
1962
+ match(call, ctx) {
1963
+ if (!import_typescript3.default.isCallExpression(call) || call.arguments.length < 2)
1964
+ return;
1965
+ const callee = unwrap(call.expression);
1966
+ const calleeText = import_typescript3.default.isCallExpression(callee) ? callee.expression.getText() : callee.getText();
1967
+ if (!FETCH_LIKE.test(calleeText))
1968
+ return;
1969
+ if (import_typescript3.default.isIdentifier(callee) && callee.text === "fetch" && resolvedFunction(callee, ctx.checker))
1970
+ return;
1971
+ const second = unwrap(call.arguments[1]);
1972
+ if (import_typescript3.default.isArrowFunction(second) || import_typescript3.default.isFunctionExpression(second))
1973
+ return;
1974
+ const first = unwrap(call.arguments[0]);
1975
+ if ((import_typescript3.default.isStringLiteral(first) || import_typescript3.default.isNoSubstitutionTemplateLiteral(first)) && !MODEL_HOST.test(first.text) && !MODEL_PATH.test(first.text) && !SPEECH_ENDPOINT.test(first.text))
1976
+ return;
1977
+ const urls = ctx.urlTexts(call.arguments[0]);
1978
+ const initArg = call.arguments[1];
1979
+ const init = objectLiteralOf(initArg, ctx.checker);
1980
+ const url = urls.find((candidate) => SPEECH_ENDPOINT.test(candidate) || !NON_MODEL_PATH.test(candidate) && (MODEL_HOST.test(candidate) || MODEL_PATH.test(candidate) && (/^https?:\/\//.test(candidate) || bodyHasModel(init, ctx.checker))));
1981
+ if (!url)
1982
+ return;
1983
+ const roles = [];
1984
+ if (init) {
1985
+ const body = propertyValue(init, "body");
1986
+ let payload = body ? unwrap(body) : undefined;
1987
+ if (payload && import_typescript3.default.isCallExpression(payload) && calleeChain(payload.expression)?.join(".") === "JSON.stringify")
1988
+ payload = payload.arguments[0];
1989
+ if (payload)
1990
+ roles.push(...requestRoles(payload, REQUEST_KEYS, ctx));
1991
+ } else {
1992
+ for (const [key, role] of Object.entries(OPAQUE_BODY_KEYS))
1993
+ roles.push({ role, node: initArg, key: `body.${key}` });
1994
+ }
1995
+ const modelInUrl = urlModel(call.arguments[0], ctx.checker);
1996
+ if (modelInUrl && !roles.some((role) => role.role === "model"))
1997
+ roles.unshift({ role: "model", node: modelInUrl });
1998
+ if (modelInUrl) {
1999
+ const index = roles.findIndex((role) => role.role === "model" && role.key?.startsWith("body."));
2000
+ if (index >= 0)
2001
+ roles[index] = { role: "model", node: modelInUrl };
2002
+ }
2003
+ return {
2004
+ api: "fetch",
2005
+ provider: /elevenlabs/.test(url) ? "elevenlabs" : /anthropic/.test(url) ? "anthropic" : /openrouter/.test(url) ? "openrouter" : /openai/.test(url) ? "openai" : /generativelanguage/.test(url) ? "google" : undefined,
2006
+ roles
2007
+ };
1920
2008
  }
1921
- const out = [];
1922
- for (const container of containers) {
1923
- (container.children ?? []).forEach((element, index) => {
1924
- out.push({ role: elementRole(element), tree: element, message: { arrayId: container.id, index } });
1925
- });
2009
+ };
2010
+ var AGENT_ENTRY_METHODS = new Set(["run", "runTurn", "executeRun", "chat", "saveMessages", "sendMessage", "submitMessage", "prompt", "runAgentTool"]);
2011
+ var AGENT_BASES = new Set(["Think", "Agent", "AIChatAgent"]);
2012
+ var ENTRY_FIELDS = ["message", "context", "brief"];
2013
+ var STUB_GETTERS = new Set(["get", "getByName", "getAgentByName", "getServerByName", "routeAgentRequest", "getStub"]);
2014
+ function classOfDeclaration(declaration) {
2015
+ if (!declaration)
2016
+ return;
2017
+ if (import_typescript3.default.isClassDeclaration(declaration) || import_typescript3.default.isClassExpression(declaration))
2018
+ return declaration;
2019
+ return;
2020
+ }
2021
+ function classesInType(type, checker, out = []) {
2022
+ if (!type || out.length > 4)
2023
+ return out;
2024
+ if (import_typescript3.default.isTypeReferenceNode(type)) {
2025
+ const name = import_typescript3.default.isQualifiedName(type.typeName) ? type.typeName.right : type.typeName;
2026
+ const cls = classOfDeclaration(valueDeclaration(resolvedSymbol(name, checker)));
2027
+ if (cls)
2028
+ out.push(cls);
2029
+ for (const argument of type.typeArguments ?? [])
2030
+ classesInType(argument, checker, out);
2031
+ } else if (import_typescript3.default.isUnionTypeNode(type) || import_typescript3.default.isIntersectionTypeNode(type)) {
2032
+ for (const member of type.types)
2033
+ classesInType(member, checker, out);
1926
2034
  }
1927
- for (const other of others)
1928
- out.push({ role: STRINGY.has(other.kind) ? "user" : "unknown", tree: other });
1929
2035
  return out;
1930
2036
  }
1931
-
1932
- // src/harness-extract/program.ts
1933
- var import_typescript4 = __toESM(require_typescript(), 1);
1934
- import { createHash } from "node:crypto";
1935
- import { readdirSync, statSync } from "node:fs";
1936
- import { dirname, join, relative as relative2, resolve } from "node:path";
1937
- var SKIPPED_DIRS2 = new Set(["node_modules", "dist", "build", "out", "vendor", "coverage", "graphify-out", "__pycache__"]);
1938
- var CODE_FILE = /\.(?:[cm]?[jt]sx?)$/i;
1939
- var SVELTE_FILE = /\.svelte$/i;
1940
- var SCRIPT_BLOCK = /(<script\b[^>]*>)([\s\S]*?)<\/script\s*>/gi;
1941
- function svelteScriptText(text) {
1942
- const out = text.replace(/[^\n]/g, " ").split("");
1943
- for (const match of text.matchAll(SCRIPT_BLOCK)) {
1944
- const start = (match.index ?? 0) + match[1].length;
1945
- for (let index = 0;index < match[2].length; index += 1)
1946
- out[start + index] = match[2][index];
2037
+ function receiverClasses(expression, checker, depth = 0) {
2038
+ const expr = unwrap(expression);
2039
+ if (depth > 4)
2040
+ return [];
2041
+ if (expr.kind === import_typescript3.default.SyntaxKind.ThisKeyword) {
2042
+ for (let current = expr.parent;current; current = current.parent) {
2043
+ if (import_typescript3.default.isClassDeclaration(current) || import_typescript3.default.isClassExpression(current))
2044
+ return [current];
2045
+ }
2046
+ return [];
1947
2047
  }
1948
- return out.join("");
1949
- }
1950
- var DECLARATION_FILE = /\.d\.[cm]?ts$/i;
1951
- var TEST_RUNNER_FILE = /(?:^|\/)__tests__\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
1952
- var TEST_PATH = /(?:^|\/)(?:test|tests|__tests__|test-fixtures|fixtures?|__fixtures__|__mocks__|e2e)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
1953
- var EVAL_PATH = /(?:^|\/)evals?\/|\.evals?\.[cm]?[jt]sx?$/i;
1954
- var MAX_FILE_BYTES = 1024 * 1024;
1955
- var DEFAULT_MAX_FILES = 20000;
1956
- function isTestPath(rel) {
1957
- return TEST_PATH.test(rel);
1958
- }
1959
- function isEvalPath(rel) {
1960
- return EVAL_PATH.test(rel);
1961
- }
1962
- function walkRepository(rootDir, maxFiles, includeTestRunnerFiles) {
1963
- const files = [];
1964
- const configs = [];
1965
- let truncated = false;
1966
- const walk = (abs, rel) => {
1967
- let entries;
1968
- try {
1969
- entries = readdirSync(abs, { withFileTypes: true });
1970
- } catch {
1971
- return;
2048
+ if (import_typescript3.default.isNewExpression(expr)) {
2049
+ const cls = classOfDeclaration(valueDeclaration(resolvedSymbol(import_typescript3.default.isPropertyAccessExpression(expr.expression) ? expr.expression.name : expr.expression, checker)));
2050
+ return cls ? [cls] : [];
2051
+ }
2052
+ if (import_typescript3.default.isCallExpression(expr)) {
2053
+ const callee = unwrap(expr.expression);
2054
+ const name = import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name.text : import_typescript3.default.isIdentifier(callee) ? callee.text : "";
2055
+ if (name === "get" && import_typescript3.default.isPropertyAccessExpression(callee) && import_typescript3.default.isPropertyAccessExpression(callee.expression) && callee.expression.name.text === "dynamicAgents" && expr.arguments[0]) {
2056
+ const target = classOfDeclaration(valueDeclaration(resolvedSymbol(expr.arguments[0], checker)));
2057
+ if (target)
2058
+ return [target];
1972
2059
  }
1973
- entries.sort((a, b) => a.name.localeCompare(b.name));
1974
- for (const entry of entries) {
1975
- if (files.length >= maxFiles) {
1976
- truncated = true;
1977
- return;
2060
+ if (!STUB_GETTERS.has(name)) {
2061
+ const fn = resolvedFunction(callee, checker);
2062
+ return fn ? returnExpressions(fn).flatMap((value) => receiverClasses(value, checker, depth + 1)) : [];
2063
+ }
2064
+ const fromTypeArgs = (expr.typeArguments ?? []).flatMap((argument) => classesInType(argument, checker));
2065
+ if (fromTypeArgs.length > 0)
2066
+ return fromTypeArgs;
2067
+ const namespace = import_typescript3.default.isPropertyAccessExpression(callee) && name !== "getAgentByName" && name !== "getServerByName" ? callee.expression : expr.arguments[0];
2068
+ return namespace ? receiverClasses(namespace, checker, depth + 1) : [];
2069
+ }
2070
+ const nameNode = import_typescript3.default.isPropertyAccessExpression(expr) ? expr.name : import_typescript3.default.isIdentifier(expr) ? expr : undefined;
2071
+ if (!nameNode)
2072
+ return [];
2073
+ const declaration = valueDeclaration(resolvedSymbol(nameNode, checker));
2074
+ if (!declaration)
2075
+ return [];
2076
+ if (import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isParameter(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) || import_typescript3.default.isPropertySignature(declaration)) {
2077
+ const declared = classesInType(declaration.type, checker);
2078
+ if (declared.length > 0)
2079
+ return declared;
2080
+ if ("initializer" in declaration && declaration.initializer)
2081
+ return receiverClasses(declaration.initializer, checker, depth + 1);
2082
+ }
2083
+ return [];
2084
+ }
2085
+ function firstParamType(declaration, checker) {
2086
+ if (!declaration)
2087
+ return;
2088
+ let parameters;
2089
+ if (import_typescript3.default.isMethodSignature(declaration) || import_typescript3.default.isMethodDeclaration(declaration))
2090
+ parameters = declaration.parameters;
2091
+ else if ((import_typescript3.default.isPropertySignature(declaration) || import_typescript3.default.isPropertyDeclaration(declaration)) && declaration.type && import_typescript3.default.isFunctionTypeNode(declaration.type))
2092
+ parameters = declaration.type.parameters;
2093
+ const type = parameters?.[0]?.type;
2094
+ if (!type || !import_typescript3.default.isTypeReferenceNode(type))
2095
+ return;
2096
+ const name = import_typescript3.default.isQualifiedName(type.typeName) ? type.typeName.right : type.typeName;
2097
+ return valueDeclarationOrType(resolvedSymbol(name, checker));
2098
+ }
2099
+ function valueDeclarationOrType(symbol) {
2100
+ return symbol?.declarations?.[0];
2101
+ }
2102
+ function structuralAgent(receiver, method, ctx) {
2103
+ let declaration;
2104
+ try {
2105
+ declaration = ctx.checker.getTypeAtLocation(receiver).getProperty(method)?.declarations?.[0];
2106
+ } catch {
2107
+ return;
2108
+ }
2109
+ declaration ??= declaredMethod(receiver, method, ctx.checker);
2110
+ if (!declaration)
2111
+ return;
2112
+ const owner = declaration.parent;
2113
+ if (owner && (import_typescript3.default.isClassDeclaration(owner) || import_typescript3.default.isClassExpression(owner))) {
2114
+ const base = ctx.frameworkBase(owner).base;
2115
+ return base && AGENT_BASES.has(base) ? owner : undefined;
2116
+ }
2117
+ const wanted = firstParamType(declaration, ctx.checker);
2118
+ if (!wanted)
2119
+ return;
2120
+ return ctx.agentClasses().find((cls) => cls.members.some((member) => import_typescript3.default.isMethodDeclaration(member) && propertyNameText(member.name) === method && firstParamType(member, ctx.checker) === wanted));
2121
+ }
2122
+ var agentEntrySink = {
2123
+ id: "agent-entry",
2124
+ sdk: "agent-entry",
2125
+ match(call, ctx) {
2126
+ if (!import_typescript3.default.isCallExpression(call) || call.arguments.length === 0)
2127
+ return;
2128
+ const callee = unwrap(call.expression);
2129
+ if (!import_typescript3.default.isPropertyAccessExpression(callee) || !AGENT_ENTRY_METHODS.has(callee.name.text))
2130
+ return;
2131
+ const method = callee.name.text;
2132
+ const cls = receiverClasses(callee.expression, ctx.checker).find((candidate) => {
2133
+ const base = ctx.frameworkBase(candidate).base;
2134
+ return base !== undefined && AGENT_BASES.has(base);
2135
+ });
2136
+ const seam = method === "runAgentTool" && !cls && hasMethod(callee.expression, method, ctx) ? callee.expression : undefined;
2137
+ const target = cls ?? structuralAgent(callee.expression, method, ctx);
2138
+ if (!target && !seam)
2139
+ return;
2140
+ const argument = method === "runAgentTool" ? call.arguments[1] : call.arguments[0];
2141
+ if (!argument || import_typescript3.default.isSpreadElement(argument))
2142
+ return;
2143
+ const roles = [];
2144
+ if (method === "runAgentTool") {
2145
+ const object = objectLiteralOf(argument, ctx.checker);
2146
+ const input = object ? propertyValue(object, "input") : undefined;
2147
+ roles.push(input ? { role: "user", node: input } : { role: "user", node: argument, key: "input" });
2148
+ } else if (method === "runTurn") {
2149
+ const object = objectLiteralOf(argument, ctx.checker);
2150
+ const input = object ? propertyValue(object, "input") : undefined;
2151
+ roles.push(input ? { role: "messages", node: input } : { role: "messages", node: argument, key: "input" });
2152
+ } else if (method === "saveMessages") {
2153
+ roles.push({ role: "messages", node: argument });
2154
+ } else {
2155
+ const object = objectLiteralOf(argument, ctx.checker);
2156
+ const fields = object ? ENTRY_FIELDS.filter((field) => propertyValue(object, field)) : [];
2157
+ if (object && unwrap(argument) === object && fields.length > 0) {
2158
+ for (const field of fields)
2159
+ roles.push({ role: "user", node: propertyValue(object, field) });
2160
+ } else {
2161
+ roles.push({ role: "user", node: argument });
1978
2162
  }
1979
- const childRel = rel ? `${rel}/${entry.name}` : entry.name;
1980
- const childAbs = join(abs, entry.name);
1981
- if (entry.isDirectory()) {
1982
- if (!entry.name.startsWith(".") && !SKIPPED_DIRS2.has(entry.name))
1983
- walk(childAbs, childRel);
1984
- } else if (entry.isFile()) {
1985
- if (entry.name === "tsconfig.json")
1986
- configs.push(childAbs);
1987
- else if (SVELTE_FILE.test(entry.name)) {
1988
- try {
1989
- if (statSync(childAbs).size <= MAX_FILE_BYTES)
1990
- files.push(svelteVirtualName(childAbs));
1991
- } catch {
1992
- continue;
1993
- }
1994
- } else if (CODE_FILE.test(entry.name) && !DECLARATION_FILE.test(entry.name) && !/\.min\.[cm]?js$/i.test(entry.name) && (includeTestRunnerFiles || !TEST_RUNNER_FILE.test(childRel))) {
1995
- try {
1996
- if (statSync(childAbs).size > MAX_FILE_BYTES)
1997
- continue;
1998
- } catch {
1999
- continue;
2000
- }
2001
- files.push(childAbs);
2002
- }
2163
+ }
2164
+ return { api: `${(target && className(target)) ?? "agent"}.${method}`, roles };
2165
+ }
2166
+ };
2167
+ function declaredMethod(receiver, method, checker) {
2168
+ const root = unwrap(receiver);
2169
+ if (!import_typescript3.default.isIdentifier(root))
2170
+ return;
2171
+ let annotation;
2172
+ try {
2173
+ const declaration = checker.getSymbolAtLocation(root)?.valueDeclaration;
2174
+ if (declaration && (import_typescript3.default.isParameter(declaration) || import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertySignature(declaration) || import_typescript3.default.isPropertyDeclaration(declaration)))
2175
+ annotation = declaration.type;
2176
+ } catch {
2177
+ return;
2178
+ }
2179
+ const seen = new Set;
2180
+ const search = (type, depth) => {
2181
+ if (!type || depth > 4 || seen.has(type))
2182
+ return;
2183
+ seen.add(type);
2184
+ if (import_typescript3.default.isIntersectionTypeNode(type) || import_typescript3.default.isUnionTypeNode(type)) {
2185
+ for (const member of type.types) {
2186
+ const found = search(member, depth + 1);
2187
+ if (found)
2188
+ return found;
2003
2189
  }
2190
+ return;
2004
2191
  }
2192
+ if (import_typescript3.default.isParenthesizedTypeNode(type))
2193
+ return search(type.type, depth + 1);
2194
+ const members = import_typescript3.default.isTypeLiteralNode(type) ? type.members : undefined;
2195
+ if (members)
2196
+ return members.find((member) => (import_typescript3.default.isMethodSignature(member) || import_typescript3.default.isPropertySignature(member)) && propertyNameText(member.name) === method);
2197
+ if (!import_typescript3.default.isTypeReferenceNode(type))
2198
+ return;
2199
+ return fromName(type.typeName, depth);
2005
2200
  };
2006
- walk(rootDir, "");
2007
- return { files, configs, truncated };
2008
- }
2009
- function sourceFingerprint(rootDir, options = {}) {
2010
- const walked = walkRepository(resolve(rootDir), options.maxFiles ?? DEFAULT_MAX_FILES, options.includeTestRunnerFiles ?? false);
2011
- const hash = createHash("sha1");
2012
- const inputs = new Set([...walked.configs, ...walked.files.map((file) => file.endsWith(SVELTE_VIRTUAL_SUFFIX) ? file.slice(0, -SVELTE_VIRTUAL_SUFFIX.length) : file)]);
2013
- for (const config of walked.configs) {
2014
- const host = { ...import_typescript4.default.sys, onUnRecoverableConfigFileDiagnostic: () => {}, readFile: (file) => {
2015
- inputs.add(file);
2016
- return import_typescript4.default.sys.readFile(file);
2017
- } };
2018
- import_typescript4.default.getParsedCommandLineOfConfigFile(config, {}, host);
2019
- }
2020
- const metadata = (directory) => {
2021
- let entries;
2201
+ const fromName = (name, depth) => {
2202
+ let symbol;
2022
2203
  try {
2023
- entries = readdirSync(directory, { withFileTypes: true });
2204
+ symbol = checker.getSymbolAtLocation(name);
2205
+ if (symbol && symbol.flags & import_typescript3.default.SymbolFlags.Alias)
2206
+ symbol = checker.getAliasedSymbol(symbol);
2024
2207
  } catch {
2025
2208
  return;
2026
2209
  }
2027
- for (const entry of entries) {
2028
- if (entry.isDirectory() && !entry.name.startsWith(".") && !SKIPPED_DIRS2.has(entry.name))
2029
- metadata(join(directory, entry.name));
2030
- else if (entry.isFile() && (entry.name === "package.json" || /^wrangler(?:\.[\w.-]+)?\.(?:json|jsonc|toml)$/.test(entry.name)))
2031
- inputs.add(join(directory, entry.name));
2210
+ for (const declaration of symbol?.declarations ?? []) {
2211
+ if (seen.has(declaration))
2212
+ continue;
2213
+ seen.add(declaration);
2214
+ if (import_typescript3.default.isInterfaceDeclaration(declaration)) {
2215
+ const own = declaration.members.find((member) => (import_typescript3.default.isMethodSignature(member) || import_typescript3.default.isPropertySignature(member)) && propertyNameText(member.name) === method);
2216
+ if (own)
2217
+ return own;
2218
+ for (const clause of declaration.heritageClauses ?? []) {
2219
+ for (const base of clause.types) {
2220
+ const found = fromName(base.expression, depth + 1);
2221
+ if (found)
2222
+ return found;
2223
+ }
2224
+ }
2225
+ }
2226
+ if (import_typescript3.default.isTypeAliasDeclaration(declaration)) {
2227
+ const found = search(declaration.type, depth + 1);
2228
+ if (found)
2229
+ return found;
2230
+ }
2032
2231
  }
2232
+ return;
2033
2233
  };
2034
- metadata(resolve(rootDir));
2035
- for (const file of [...inputs].sort()) {
2036
- const text = import_typescript4.default.sys.readFile(file);
2037
- hash.update(`${file}\x00${text ?? "missing"}
2038
- `);
2234
+ return search(annotation, 0);
2235
+ }
2236
+ function hasMethod(receiver, method, ctx) {
2237
+ try {
2238
+ return Boolean(ctx.checker.getTypeAtLocation(receiver).getProperty(method));
2239
+ } catch {
2240
+ return false;
2039
2241
  }
2040
- return hash.digest("hex");
2041
2242
  }
2042
- function extractorOptions(base) {
2043
- const options = {
2044
- ...base,
2045
- noEmit: true,
2046
- skipLibCheck: true,
2047
- noLib: true,
2048
- types: [],
2049
- noResolve: false,
2050
- allowJs: true,
2051
- checkJs: false,
2052
- resolveJsonModule: false,
2053
- declaration: false,
2054
- composite: false,
2055
- incremental: false,
2056
- tsBuildInfoFile: undefined,
2057
- plugins: undefined
2058
- };
2059
- if (options.moduleResolution === undefined) {
2060
- options.module = import_typescript4.default.ModuleKind.ESNext;
2061
- options.moduleResolution = import_typescript4.default.ModuleResolutionKind.Bundler;
2243
+ var CHAT_HOOK_MODULE = /^(?:@ai-sdk\/(?:react|svelte|vue|angular|solid)|ai\/(?:react|svelte|vue)|agents\/(?:ai-)?react|@cloudflare\/(?:think|ai-chat|agents)\/react)$/;
2244
+ var CHAT_HOOKS = new Set(["useChat", "useAgentChat", "Chat", "useCompletion"]);
2245
+ var CHAT_SEND = new Set(["sendMessage", "append", "submitMessage", "complete"]);
2246
+ function fromChatHook(expression, checker, depth = 0) {
2247
+ if (!expression || depth > 3)
2248
+ return false;
2249
+ const expr = unwrap(expression);
2250
+ if (import_typescript3.default.isCallExpression(expr) || import_typescript3.default.isNewExpression(expr)) {
2251
+ const root = rootIdentifier(expr.expression);
2252
+ const origin = root ? importOrigin(root, checker) : undefined;
2253
+ return Boolean(origin && CHAT_HOOK_MODULE.test(origin.module) && CHAT_HOOKS.has(origin.imported === "*" || origin.imported === "default" ? import_typescript3.default.isPropertyAccessExpression(expr.expression) ? expr.expression.name.text : "" : origin.imported));
2062
2254
  }
2063
- options.allowImportingTsExtensions = true;
2064
- return options;
2255
+ const nameNode = import_typescript3.default.isIdentifier(expr) ? expr : import_typescript3.default.isPropertyAccessExpression(expr) ? expr.name : undefined;
2256
+ const declaration = nameNode ? valueDeclaration(resolvedSymbol(nameNode, checker)) : undefined;
2257
+ if (!declaration)
2258
+ return false;
2259
+ if (import_typescript3.default.isBindingElement(declaration)) {
2260
+ const holder = declaration.parent.parent;
2261
+ return import_typescript3.default.isVariableDeclaration(holder) && fromChatHook(holder.initializer, checker, depth + 1);
2262
+ }
2263
+ if (import_typescript3.default.isVariableDeclaration(declaration))
2264
+ return fromChatHook(declaration.initializer, checker, depth + 1);
2265
+ return false;
2065
2266
  }
2066
- var FALLBACK_OPTIONS = extractorOptions({
2067
- target: import_typescript4.default.ScriptTarget.ES2022,
2068
- jsx: import_typescript4.default.JsxEmit.Preserve,
2069
- esModuleInterop: true
2070
- });
2071
- function sharedHost(options, cache) {
2072
- const host = import_typescript4.default.createCompilerHost(options, true);
2073
- const moduleCache = import_typescript4.default.createModuleResolutionCache(host.getCurrentDirectory(), (name) => name, options);
2074
- host.getSourceFile = (fileName, languageVersionOrOptions) => {
2075
- const version = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions.languageVersion : languageVersionOrOptions;
2076
- const key = `${version}:${fileName}`;
2077
- if (cache.has(key))
2078
- return cache.get(key);
2079
- let source;
2080
- const svelte = fileName.endsWith(SVELTE_VIRTUAL_SUFFIX);
2081
- const raw = import_typescript4.default.sys.readFile(svelte ? fileName.slice(0, -SVELTE_VIRTUAL_SUFFIX.length) : fileName);
2082
- const text = svelte && raw !== undefined ? svelteScriptText(raw) : raw;
2083
- if (text !== undefined && text.length <= MAX_FILE_BYTES) {
2084
- source = import_typescript4.default.createSourceFile(fileName, text, languageVersionOrOptions, true, svelte ? import_typescript4.default.ScriptKind.TS : undefined);
2085
- }
2086
- cache.set(key, source);
2087
- return source;
2088
- };
2089
- host.resolveModuleNameLiterals = (literals, containingFile, redirected, compilerOptions) => literals.map((literal) => {
2090
- const resolved = import_typescript4.default.resolveModuleName(literal.text, containingFile, compilerOptions, host, moduleCache, redirected).resolvedModule;
2091
- if (!resolved || resolved.isExternalLibraryImport || /[\\/]node_modules[\\/]/.test(resolved.resolvedFileName) || DECLARATION_FILE.test(resolved.resolvedFileName) || !CODE_FILE.test(resolved.resolvedFileName)) {
2092
- return { resolvedModule: undefined };
2093
- }
2094
- return { resolvedModule: resolved };
2095
- });
2096
- const fileExists = host.fileExists.bind(host);
2097
- host.fileExists = (fileName) => fileName.endsWith(SVELTE_VIRTUAL_SUFFIX) ? fileExists(fileName.slice(0, -SVELTE_VIRTUAL_SUFFIX.length)) : fileExists(fileName);
2098
- host.writeFile = () => {};
2099
- return host;
2100
- }
2101
- var NO_INPUTS_FOUND = 18003;
2102
- function parseConfig(configPath, warnings, rootDir) {
2103
- const rel = relative2(rootDir, configPath).split("\\").join("/");
2104
- const read = import_typescript4.default.readConfigFile(configPath, import_typescript4.default.sys.readFile);
2105
- if (read.error || !read.config || typeof read.config !== "object") {
2106
- warnings.push(`tsconfig ${rel}: unreadable, its files fall back to the default program`);
2107
- return;
2108
- }
2109
- const raw = read.config;
2110
- const parsed = import_typescript4.default.parseJsonConfigFileContent(read.config, import_typescript4.default.sys, dirname(configPath), undefined, configPath);
2111
- const errors = parsed.errors.filter((error) => error.code !== NO_INPUTS_FOUND);
2112
- if (errors.length > 0) {
2113
- const messages = errors.slice(0, 3).map((error) => import_typescript4.default.flattenDiagnosticMessageText(error.messageText, " "));
2114
- warnings.push(`tsconfig ${rel}: ${messages.join("; ")}${errors.length > 3 ? ` (+${errors.length - 3} more)` : ""}; extraction continues with the options that parsed`);
2267
+ function looksLikeUiMessage(argument) {
2268
+ const object = unwrap(argument);
2269
+ if (!import_typescript3.default.isObjectLiteralExpression(object))
2270
+ return false;
2271
+ const parts = propertyValue(object, "parts");
2272
+ if (parts) {
2273
+ const array = unwrap(parts);
2274
+ return import_typescript3.default.isArrayLiteralExpression(array) && array.elements.some((element) => {
2275
+ const part = unwrap(element);
2276
+ if (!import_typescript3.default.isObjectLiteralExpression(part))
2277
+ return false;
2278
+ const type = propertyValue(part, "type");
2279
+ return Boolean(type && import_typescript3.default.isStringLiteralLike(unwrap(type)) && unwrap(type).text === "text");
2280
+ });
2115
2281
  }
2116
- const explicit = raw.include !== undefined || raw.files !== undefined || parsed.raw && (parsed.raw.include !== undefined || parsed.raw.files !== undefined);
2117
- return { options: parsed.options, fileNames: explicit ? parsed.fileNames.map((name) => resolve(name)) : undefined };
2118
- }
2119
- function isUnder(file, dir) {
2120
- const rel = relative2(dir, file);
2121
- return rel !== "" && !rel.startsWith("..") && !rel.startsWith("/");
2282
+ if (propertyValue(object, "text") && object.properties.length <= 3)
2283
+ return true;
2284
+ const role = propertyValue(object, "role");
2285
+ return Boolean(role && import_typescript3.default.isStringLiteralLike(unwrap(role)) && unwrap(role).text === "user" && (propertyValue(object, "content") || propertyValue(object, "parts")));
2122
2286
  }
2123
- function buildPrograms(rootDir, options = {}) {
2124
- const root = resolve(rootDir);
2125
- const maxFiles = options.maxFiles ?? DEFAULT_MAX_FILES;
2126
- const warnings = [];
2127
- const walked = walkRepository(root, maxFiles, options.includeTestRunnerFiles ?? false);
2128
- if (walked.truncated)
2129
- warnings.push(`file cap reached: only the first ${maxFiles} code files are scanned`);
2130
- const known = new Set(walked.files);
2131
- const configDirs = walked.configs.map((path) => dirname(path));
2132
- const assigned = new Set;
2133
- const cache = new Map;
2134
- const entries = [];
2135
- const owner = new Map;
2136
- const create = (rootNames, owned, compilerOptions, configPath) => {
2137
- const host = sharedHost(compilerOptions, cache);
2138
- let program;
2139
- try {
2140
- program = import_typescript4.default.createProgram({ rootNames, options: compilerOptions, host });
2141
- } catch (error) {
2142
- warnings.push(`program ${configPath ?? "(fallback)"}: ${error.message}`);
2287
+ var clientChatSink = {
2288
+ id: "client-chat",
2289
+ sdk: "client-chat",
2290
+ match(call, ctx) {
2291
+ if (!import_typescript3.default.isCallExpression(call) || call.arguments.length === 0)
2143
2292
  return;
2144
- }
2145
- let checker;
2146
- const entry = {
2147
- program,
2148
- configPath,
2149
- owned,
2150
- checker: () => checker ??= program.getTypeChecker()
2151
- };
2152
- entries.push(entry);
2153
- for (const file of owned)
2154
- owner.set(file, entry);
2155
- };
2156
- const configs = [...walked.configs].sort((a, b) => b.split(/[\\/]/).length - a.split(/[\\/]/).length || a.localeCompare(b));
2157
- for (const configPath of configs) {
2158
- const parsed = parseConfig(configPath, warnings, root);
2159
- if (!parsed)
2160
- continue;
2161
- const dir = dirname(configPath);
2162
- const nested = configDirs.filter((other) => other !== dir && isUnder(other, dir));
2163
- const underDir = (file) => isUnder(file, dir) && !nested.some((other) => isUnder(file, other));
2164
- const included = parsed.fileNames ? [...parsed.fileNames.filter((file) => known.has(file)), ...walked.files.filter((file) => file.endsWith(SVELTE_VIRTUAL_SUFFIX) && underDir(file))] : walked.files.filter(underDir);
2165
- const owned = included.filter((file) => !assigned.has(file));
2166
- if (owned.length === 0)
2167
- continue;
2168
- for (const file of owned)
2169
- assigned.add(file);
2170
- create(included, owned, extractorOptions(parsed.options), relative2(root, configPath).split("\\").join("/"));
2293
+ const callee = unwrap(call.expression);
2294
+ const binding = import_typescript3.default.isIdentifier(callee) ? valueDeclaration(resolvedSymbol(callee, ctx.checker)) : undefined;
2295
+ const bound = binding && import_typescript3.default.isBindingElement(binding) && binding.propertyName ? propertyNameText(binding.propertyName) : undefined;
2296
+ const name = bound ?? (import_typescript3.default.isIdentifier(callee) ? callee.text : import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name.text : undefined);
2297
+ if (!name || !CHAT_SEND.has(name))
2298
+ return;
2299
+ const argument = call.arguments[0];
2300
+ if (import_typescript3.default.isSpreadElement(argument))
2301
+ return;
2302
+ const hooked = import_typescript3.default.isIdentifier(callee) ? fromChatHook(callee, ctx.checker) : fromChatHook(callee.expression, ctx.checker);
2303
+ if (!hooked && !((name === "sendMessage" || name === "append") && looksLikeUiMessage(argument)))
2304
+ return;
2305
+ return { api: `chat.${name}`, roles: [{ role: "user", node: argument }] };
2171
2306
  }
2172
- const rest = walked.files.filter((file) => !assigned.has(file));
2173
- if (rest.length > 0)
2174
- create(rest, rest, FALLBACK_OPTIONS);
2175
- return { rootDir: root, entries, owner, files: assigned.size + rest.length, warnings };
2176
- }
2177
-
2178
- // src/harness-extract/sinks.ts
2179
- var import_typescript5 = __toESM(require_typescript(), 1);
2180
- var URL_MODEL_KEY = "?model";
2181
- var ANTHROPIC_MODULE = /^@anthropic-ai\//;
2182
- var OPENAI_MODULE = /^openai(?:\/|$)/;
2183
- var OPENAI_COMPATIBLE_MODULE = /^(?:groq-sdk|together-ai|@cerebras\/cerebras_cloud_sdk|fireworks-ai|portkey-ai|@portkey-ai\/|@azure\/openai|deepseek|@helicone\/|cohere-ai)/;
2184
- var AI_SDK_CALLS = new Set(["generateText", "streamText", "generateObject", "streamObject"]);
2185
- var AI_SDK_DECIDE = new Set(["experimental_decide", "decide", "experimental_evaluate", "evaluate"]);
2186
- var AI_SDK_AGENTS = new Set(["Agent", "Experimental_Agent", "ToolLoopAgent"]);
2187
- var PROVIDER_MODULE = /^(?:@ai-sdk\/(?!react$|ui-utils$|rsc$|provider$|provider-utils$|svelte$|vue$|solid$|angular$|valibot$)[\w-]+|@openrouter\/ai-sdk-provider|workers-ai-provider|ollama-ai-provider(?:-v2)?|@requesty\/ai-sdk|@portkey-ai\/vercel-provider|@mistralai\/ai-sdk)$/;
2188
- var MODEL_HOST = /^https?:\/\/(?:openrouter\.ai|api\.openai\.com|api\.anthropic\.com|generativelanguage\.googleapis\.com|api\.groq\.com|api\.together\.(?:xyz|ai)|api\.mistral\.ai|api\.deepseek\.com|api\.fireworks\.ai|api\.x\.ai|api\.perplexity\.ai|gateway\.ai\.cloudflare\.com)\//;
2189
- var SPEECH_ENDPOINT = /^https?:\/\/api\.elevenlabs\.io\/v\d+\/(?:text-to-speech|speech-to-text|speech-to-speech|text-to-dialogue|sound-generation)\b/;
2190
- var MODEL_PATH = /\/chat\/completions\b|\/v1\/messages\b|\/v1\/responses\b|:generateContent\b|:streamGenerateContent\b/;
2191
- var FRAMEWORK_MODULE = /^(?:agents(?:\/.*)?|@cloudflare\/think|@cloudflare\/ai-chat|@cloudflare\/agents|cloudflare:workers|cloudflare:workflows)$/;
2192
- var FRAMEWORK_BASES = new Set(["Think", "Agent", "AIChatAgent", "McpAgent", "DurableObject", "WorkflowEntrypoint", "AgentWorkflow"]);
2193
- var HOOK_BASES = new Set(["Think", "Agent", "AIChatAgent", "McpAgent"]);
2194
- var HOOK_METHODS = {
2195
- getModel: "model",
2196
- getTools: "tools",
2197
- getSystemPrompt: "system",
2198
- configureContext: "system",
2199
- getInstructions: "system",
2200
- instructions: "system",
2201
- system: "system",
2202
- systemPrompt: "system",
2203
- buildSystemPrompt: "system",
2204
- formatAgentToolInput: "messages"
2205
2307
  };
2206
- var HOOK_PROPERTIES = { model: "model", systemPrompt: "system", instructions: "system", system: "system" };
2207
- var TURN_HOOKS = new Set(["beforeTurn", "beforeStep", "prepareStep"]);
2208
- var TURN_CONFIG_KEYS = { model: "model", system: "system", tools: "tools", messages: "messages" };
2209
- function providerName(module) {
2210
- if (module === "ai" || module === "@ai-sdk/gateway")
2211
- return "ai-gateway";
2212
- if (module === "@openrouter/ai-sdk-provider")
2213
- return "openrouter";
2214
- if (module === "workers-ai-provider")
2215
- return "workers-ai";
2216
- if (module.startsWith("ollama-ai-provider"))
2217
- return "ollama";
2218
- const scoped = /^@[\w-]+\/(?:ai-sdk-)?([\w-]+)$/.exec(module);
2219
- return scoped ? scoped[1] : module;
2220
- }
2221
- function requestRoles(argument, keys, ctx) {
2222
- if (!argument)
2223
- return [];
2224
- const object = objectLiteralOf(argument, ctx.checker);
2225
- const roles = [];
2226
- if (object && unwrap(argument) === object) {
2227
- for (const [key, role] of Object.entries(keys)) {
2228
- const value = propertyValue(object, key);
2229
- if (value && !spreadAfter(object, key))
2230
- roles.push({ role, node: value });
2231
- else if ((value || !hasProperty(object, key)) && object.properties.some((property) => import_typescript5.default.isSpreadAssignment(property))) {
2232
- roles.push({ role, node: argument, key });
2233
- }
2234
- }
2235
- return dedupeRoles(roles);
2236
- }
2237
- for (const [key, role] of Object.entries(keys)) {
2238
- if (!object || hasProperty(object, key) || object.properties.some((property) => import_typescript5.default.isSpreadAssignment(property))) {
2239
- roles.push({ role, node: argument, key });
2240
- }
2308
+ var websocketSink = {
2309
+ id: "websocket",
2310
+ sdk: "websocket",
2311
+ match(call, ctx) {
2312
+ if (!import_typescript3.default.isNewExpression(call) || !call.arguments?.length)
2313
+ return;
2314
+ const callee = unwrap(call.expression);
2315
+ if (!import_typescript3.default.isIdentifier(callee) || callee.text !== "WebSocket")
2316
+ return;
2317
+ const url = ctx.urlTexts(call.arguments[0]).find((candidate) => MODEL_SOCKET.test(candidate));
2318
+ if (!url)
2319
+ return;
2320
+ const modelInUrl = urlModel(call.arguments[0], ctx.checker);
2321
+ const roles = modelInUrl ? [{ role: "model", node: modelInUrl }] : /[?&]model=/.test(url) ? [{ role: "model", node: call.arguments[0], key: URL_MODEL_KEY }] : [];
2322
+ return {
2323
+ api: "websocket",
2324
+ provider: /openai/.test(url) ? "openai" : /generativelanguage/.test(url) ? "google" : undefined,
2325
+ roles
2326
+ };
2241
2327
  }
2242
- return dedupeRoles(roles);
2243
- }
2244
- function spreadAfter(object, key) {
2245
- let last = -1;
2246
- object.properties.forEach((property, index) => {
2247
- if (!import_typescript5.default.isSpreadAssignment(property) && property.name && propertyNameText(property.name) === key)
2248
- last = index;
2249
- });
2250
- return object.properties.some((property, index) => index > last && import_typescript5.default.isSpreadAssignment(property));
2251
- }
2252
- function dedupeRoles(roles) {
2253
- const seen = new Set;
2254
- return roles.filter((role) => {
2255
- if (seen.has(role.role))
2256
- return false;
2257
- seen.add(role.role);
2258
- return true;
2259
- });
2260
- }
2261
- function typeOrigin(type, checker) {
2262
- if (!type)
2263
- return;
2264
- if (import_typescript5.default.isUnionTypeNode(type) || import_typescript5.default.isIntersectionTypeNode(type)) {
2265
- for (const member of type.types) {
2266
- const origin = typeOrigin(member, checker);
2267
- if (origin)
2268
- return origin;
2269
- }
2328
+ };
2329
+ function frameworkName(identifier, checker, member) {
2330
+ if (!identifier)
2270
2331
  return;
2271
- }
2272
- if (import_typescript5.default.isTypeReferenceNode(type)) {
2273
- let name = type.typeName;
2274
- while (import_typescript5.default.isQualifiedName(name))
2275
- name = name.left;
2276
- return importOrigin(name, checker);
2332
+ const origin = importOrigin(identifier, checker);
2333
+ if (origin) {
2334
+ const name = origin.imported === "*" || origin.imported === "default" ? member ?? identifier.text : origin.imported;
2335
+ return FRAMEWORK_MODULE.test(origin.module) && FRAMEWORK_BASES.has(name) ? { base: name, module: origin.module } : undefined;
2277
2336
  }
2278
2337
  return;
2279
2338
  }
2280
- function valueOrigin(expression, checker, depth = 0, seen = new Set) {
2281
- const expr = unwrap(expression);
2282
- if (depth > 6 || seen.has(expr))
2283
- return;
2284
- seen.add(expr);
2285
- if (import_typescript5.default.isNewExpression(expr) || import_typescript5.default.isCallExpression(expr)) {
2286
- const root = rootIdentifier(expr.expression);
2287
- const origin = root ? importOrigin(root, checker) : undefined;
2288
- if (origin)
2289
- return origin;
2290
- const fn = resolvedFunction(expr.expression, checker);
2291
- if (fn) {
2292
- const declared = typeOrigin(fn.type, checker);
2293
- if (declared)
2294
- return declared;
2295
- for (const ret of returnExpressions(fn)) {
2296
- const found = valueOrigin(ret, checker, depth + 1, seen);
2297
- if (found)
2339
+ function frameworkBaseOf(cls, checker, memo, depth = 0) {
2340
+ const cached = memo.get(cls);
2341
+ if (cached)
2342
+ return cached;
2343
+ const self = className(cls) ?? "(anonymous)";
2344
+ const result = { chain: [self] };
2345
+ memo.set(cls, result);
2346
+ const heritage = cls.heritageClauses?.find((clause) => clause.token === import_typescript3.default.SyntaxKind.ExtendsKeyword)?.types[0];
2347
+ if (!heritage || depth > 8)
2348
+ return result;
2349
+ const resolveExpression = (expression) => {
2350
+ const expr = unwrap(expression);
2351
+ if (import_typescript3.default.isCallExpression(expr)) {
2352
+ for (const argument of expr.arguments) {
2353
+ const found = resolveExpression(argument);
2354
+ if (found?.base)
2298
2355
  return found;
2299
2356
  }
2357
+ return;
2300
2358
  }
2301
- return;
2302
- }
2303
- let declaration;
2304
- if (import_typescript5.default.isIdentifier(expr)) {
2305
- const origin = importOrigin(expr, checker);
2306
- if (origin)
2307
- return origin;
2308
- declaration = valueDeclaration(resolvedSymbol(expr, checker));
2309
- } else if (import_typescript5.default.isPropertyAccessExpression(expr)) {
2310
- declaration = valueDeclaration(resolvedSymbol(expr.name, checker));
2311
- }
2312
- if (!declaration)
2313
- return;
2314
- if (import_typescript5.default.isVariableDeclaration(declaration) || import_typescript5.default.isPropertyDeclaration(declaration) || import_typescript5.default.isParameter(declaration) || import_typescript5.default.isPropertySignature(declaration) || import_typescript5.default.isPropertyAssignment(declaration)) {
2315
- const declared = "type" in declaration ? typeOrigin(declaration.type, checker) : undefined;
2316
- if (declared)
2317
- return declared;
2318
- const initializer = "initializer" in declaration ? declaration.initializer : undefined;
2319
- if (initializer)
2320
- return valueOrigin(initializer, checker, depth + 1, seen);
2321
- if (import_typescript5.default.isPropertyDeclaration(declaration)) {
2322
- const key = propertyNameText(declaration.name);
2323
- let found;
2324
- const visit = (node) => {
2325
- if (found)
2326
- return;
2327
- if (import_typescript5.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript5.default.SyntaxKind.EqualsToken && import_typescript5.default.isPropertyAccessExpression(node.left) && node.left.expression.kind === import_typescript5.default.SyntaxKind.ThisKeyword && node.left.name.text === key) {
2328
- found = valueOrigin(node.right, checker, depth + 1, seen);
2359
+ const identifier = import_typescript3.default.isIdentifier(expr) ? expr : import_typescript3.default.isPropertyAccessExpression(expr) ? rootIdentifier(expr) : undefined;
2360
+ const member = import_typescript3.default.isPropertyAccessExpression(expr) ? expr.name.text : undefined;
2361
+ const direct = frameworkName(identifier, checker, member);
2362
+ if (direct)
2363
+ return { ...direct, chain: [direct.base] };
2364
+ const declaration = valueDeclaration(resolvedSymbol(import_typescript3.default.isPropertyAccessExpression(expr) ? expr.name : expr, checker));
2365
+ if (!declaration)
2366
+ return;
2367
+ if (import_typescript3.default.isClassDeclaration(declaration) || import_typescript3.default.isClassExpression(declaration))
2368
+ return frameworkBaseOf(declaration, checker, memo, depth + 1);
2369
+ const holder = import_typescript3.default.isBindingElement(declaration) ? declaration.parent.parent : declaration;
2370
+ const name = import_typescript3.default.isBindingElement(declaration) ? propertyNameText(declaration.propertyName ?? declaration.name) : undefined;
2371
+ if (import_typescript3.default.isVariableDeclaration(holder) && holder.initializer) {
2372
+ const init = unwrap(holder.initializer);
2373
+ if (import_typescript3.default.isClassExpression(init))
2374
+ return frameworkBaseOf(init, checker, memo, depth + 1);
2375
+ if (import_typescript3.default.isCallExpression(init)) {
2376
+ for (const argument of init.arguments) {
2377
+ const arg = unwrap(argument);
2378
+ if (!import_typescript3.default.isIdentifier(arg))
2379
+ continue;
2380
+ const found = frameworkName(arg, checker, name);
2381
+ if (found)
2382
+ return { ...found, chain: [found.base] };
2383
+ const nested = resolveExpression(arg);
2384
+ if (nested?.base)
2385
+ return nested;
2329
2386
  }
2330
- import_typescript5.default.forEachChild(node, visit);
2331
- };
2332
- import_typescript5.default.forEachChild(declaration.parent, visit);
2333
- return found;
2387
+ }
2388
+ if (import_typescript3.default.isIdentifier(init) || import_typescript3.default.isPropertyAccessExpression(init))
2389
+ return resolveExpression(init);
2334
2390
  }
2391
+ return;
2392
+ };
2393
+ const parent = resolveExpression(heritage.expression);
2394
+ if (parent) {
2395
+ result.base = parent.base;
2396
+ result.module = parent.module;
2397
+ result.chain = [self, ...parent.chain];
2398
+ } else {
2399
+ result.chain = [self, heritage.expression.getText()];
2335
2400
  }
2336
- return;
2401
+ return result;
2337
2402
  }
2338
- function providerInstance(expression, checker, depth = 0) {
2339
- const expr = unwrap(expression);
2340
- if (depth > 6)
2341
- return;
2342
- if (import_typescript5.default.isIdentifier(expr)) {
2343
- const origin = importOrigin(expr, checker);
2344
- if (origin) {
2345
- if (origin.module === "ai" && origin.imported === "gateway")
2346
- return "ai";
2347
- return PROVIDER_MODULE.test(origin.module) && !/^create/.test(origin.imported) && origin.imported !== "*" ? origin.module : undefined;
2348
- }
2349
- const declaration = valueDeclaration(resolvedSymbol(expr, checker));
2350
- if (declaration && (import_typescript5.default.isVariableDeclaration(declaration) || import_typescript5.default.isPropertyDeclaration(declaration)) && declaration.initializer) {
2351
- const initializer = declaration.initializer;
2352
- return memoized(declaration, () => providerInstance(initializer, checker, depth + 1));
2353
- }
2354
- return;
2403
+ function returnedField(expr, key, checker, seen = new Set, depth = 0) {
2404
+ expr = unwrap(expr);
2405
+ if (depth > 8 || seen.has(expr))
2406
+ return false;
2407
+ const next = new Set(seen).add(expr);
2408
+ const visit = (value) => returnedField(value, key, checker, next, depth + 1);
2409
+ if (import_typescript3.default.isObjectLiteralExpression(expr)) {
2410
+ return hasProperty(expr, key) || expr.properties.some((property) => import_typescript3.default.isSpreadAssignment(property) && visit(property.expression));
2355
2411
  }
2356
- if (import_typescript5.default.isPropertyAccessExpression(expr)) {
2357
- const declaration = valueDeclaration(resolvedSymbol(expr.name, checker));
2358
- if (declaration && (import_typescript5.default.isPropertyDeclaration(declaration) || import_typescript5.default.isPropertyAssignment(declaration) || import_typescript5.default.isVariableDeclaration(declaration)) && declaration.initializer) {
2359
- const initializer = declaration.initializer;
2360
- return memoized(declaration, () => providerInstance(initializer, checker, depth + 1));
2361
- }
2362
- return;
2412
+ if (import_typescript3.default.isConditionalExpression(expr))
2413
+ return visit(expr.whenTrue) || visit(expr.whenFalse);
2414
+ if (import_typescript3.default.isBinaryExpression(expr) && [import_typescript3.default.SyntaxKind.BarBarToken, import_typescript3.default.SyntaxKind.AmpersandAmpersandToken, import_typescript3.default.SyntaxKind.QuestionQuestionToken].includes(expr.operatorToken.kind)) {
2415
+ return visit(expr.left) || visit(expr.right);
2363
2416
  }
2364
- if (import_typescript5.default.isCallExpression(expr)) {
2365
- const root = rootIdentifier(expr.expression);
2366
- const origin = root ? importOrigin(root, checker) : undefined;
2367
- if (origin) {
2368
- if (PROVIDER_MODULE.test(origin.module) && /^create/.test(origin.imported))
2369
- return origin.module;
2370
- if (origin.module === "ai" && (origin.imported === "customProvider" || origin.imported === "createGateway"))
2371
- return "ai";
2372
- return;
2373
- }
2417
+ if (import_typescript3.default.isCallExpression(expr)) {
2374
2418
  const fn = resolvedFunction(expr.expression, checker);
2375
- if (fn) {
2376
- return memoized(fn, () => {
2377
- for (const ret of returnExpressions(fn)) {
2378
- const found = providerInstance(ret, checker, depth + 1);
2379
- if (found)
2380
- return found;
2381
- }
2382
- return;
2383
- });
2384
- }
2385
- }
2386
- return;
2387
- }
2388
- var providerMemo = new WeakMap;
2389
- function memoized(node, compute) {
2390
- if (providerMemo.has(node))
2391
- return providerMemo.get(node) ?? undefined;
2392
- providerMemo.set(node, null);
2393
- const value = compute();
2394
- providerMemo.set(node, value ?? null);
2395
- return value;
2396
- }
2397
- var MODEL_METHOD = /model|chat|completion|responses|messages|image|embedding|speech|transcription/i;
2398
- function providerModelCall(call, checker) {
2399
- const model = call.arguments[0];
2400
- if (!model || import_typescript5.default.isSpreadElement(model) || import_typescript5.default.isObjectLiteralExpression(unwrap(model)))
2401
- return;
2402
- const callee = unwrap(call.expression);
2403
- if (import_typescript5.default.isIdentifier(callee)) {
2404
- const module = providerInstance(callee, checker);
2405
- return module ? { module, model } : undefined;
2419
+ return !!fn && returnExpressions(fn).some(visit);
2406
2420
  }
2407
- if (import_typescript5.default.isPropertyAccessExpression(callee) && MODEL_METHOD.test(callee.name.text)) {
2408
- const module = providerInstance(callee.expression, checker);
2409
- return module ? { module, method: callee.name.text, model } : undefined;
2421
+ if (import_typescript3.default.isIdentifier(expr) || import_typescript3.default.isPropertyAccessExpression(expr)) {
2422
+ const declaration = valueDeclaration(resolvedSymbol(expr, checker));
2423
+ if (declaration && (import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration)) && declaration.initializer) {
2424
+ return visit(declaration.initializer);
2425
+ }
2410
2426
  }
2411
- return;
2427
+ return false;
2412
2428
  }
2413
- function chainEndsWith(chain, tail) {
2414
- if (!chain || chain.length <= tail.length)
2415
- return false;
2416
- return tail.every((part, index) => chain[chain.length - tail.length + index] === part);
2429
+ function hookSink(memo) {
2430
+ return {
2431
+ id: "think-hook",
2432
+ sdk: "think-hook",
2433
+ match(cls, ctx) {
2434
+ const info = frameworkBaseOf(cls, ctx.checker, memo);
2435
+ if (!info.base || !HOOK_BASES.has(info.base))
2436
+ return [];
2437
+ const roles = [];
2438
+ for (const member of cls.members) {
2439
+ const name = propertyNameText(member.name);
2440
+ if (!name || import_typescript3.default.getCombinedModifierFlags(member) & import_typescript3.default.ModifierFlags.Static)
2441
+ continue;
2442
+ if ((import_typescript3.default.isMethodDeclaration(member) || import_typescript3.default.isGetAccessorDeclaration(member)) && HOOK_METHODS[name] && member.body) {
2443
+ roles.push({ role: HOOK_METHODS[name], node: member, values: returnExpressions(member) });
2444
+ } else if (import_typescript3.default.isMethodDeclaration(member) && TURN_HOOKS.has(name) && member.body) {
2445
+ const returns = returnExpressions(member);
2446
+ for (const [key, role] of Object.entries(TURN_CONFIG_KEYS)) {
2447
+ if (returns.some((ret) => returnedField(ret, key, ctx.checker))) {
2448
+ roles.push({ role, node: member, values: returns, key });
2449
+ }
2450
+ }
2451
+ } else if (import_typescript3.default.isPropertyDeclaration(member) && HOOK_PROPERTIES[name] && member.initializer) {
2452
+ roles.push({ role: HOOK_PROPERTIES[name], node: member.initializer });
2453
+ }
2454
+ }
2455
+ if (roles.length === 0)
2456
+ return [];
2457
+ return [{ api: `${info.base === "Think" ? "think" : "agents"}.hook`, roles, anchor: cls.name ?? cls }];
2458
+ }
2459
+ };
2417
2460
  }
2418
- function receiverOf(callee, tailLength) {
2419
- let current = unwrap(callee);
2420
- for (let index = 0;index < tailLength && import_typescript5.default.isPropertyAccessExpression(current); index += 1)
2421
- current = unwrap(current.expression);
2422
- return current;
2461
+ function createFrameworkMemo() {
2462
+ return new Map;
2423
2463
  }
2424
- var anthropicSink = {
2425
- id: "anthropic",
2426
- sdk: "anthropic",
2464
+ var HOSTED_MODEL_SDKS = [
2465
+ { module: /^@fal-ai\/(?:client|serverless-client)$/, methods: new Set(["run", "subscribe", "stream"]), provider: "fal" },
2466
+ { module: /^replicate$/, methods: new Set(["run", "stream"]), provider: "replicate" }
2467
+ ];
2468
+ var hostedModelSink = {
2469
+ id: "hosted-model",
2470
+ sdk: "hosted-model",
2427
2471
  match(call, ctx) {
2428
- if (!import_typescript5.default.isCallExpression(call))
2472
+ if (!import_typescript3.default.isCallExpression(call) || call.arguments.length === 0)
2429
2473
  return;
2430
- const chain = calleeChain(call.expression);
2431
- const tails = [["beta", "messages", "create"], ["beta", "messages", "stream"], ["messages", "create"], ["messages", "stream"]];
2432
- const tail = tails.find((candidate) => chainEndsWith(chain, candidate));
2433
- if (!tail || chain.includes("threads"))
2474
+ const callee = unwrap(call.expression);
2475
+ if (!import_typescript3.default.isPropertyAccessExpression(callee))
2434
2476
  return;
2435
- const receiver = receiverOf(call.expression, tail.length);
2436
- const origin = valueOrigin(receiver, ctx.checker);
2437
- const request = call.arguments[0];
2438
- if (origin && !ANTHROPIC_MODULE.test(origin.module))
2477
+ const origin = valueOrigin(callee.expression, ctx.checker);
2478
+ const sdk = origin && HOSTED_MODEL_SDKS.find((candidate) => candidate.module.test(origin.module) && candidate.methods.has(callee.name.text));
2479
+ if (!sdk)
2439
2480
  return;
2440
- if (!origin) {
2441
- const object = objectLiteralOf(request, ctx.checker);
2442
- const receiverName = receiver.getText();
2443
- if (!object || !hasProperty(object, "model") || !hasProperty(object, "messages"))
2444
- return;
2445
- if (!/anthropic|claude|client|llm|openrouter/i.test(receiverName) && !hasProperty(object, "max_tokens"))
2446
- return;
2447
- }
2481
+ const [model, options] = call.arguments;
2482
+ const input = options ? objectLiteralOf(options, ctx.checker) : undefined;
2483
+ const inner = input ? propertyValue(input, "input") : undefined;
2448
2484
  return {
2449
- api: `anthropic.${tail.join(".")}`,
2450
- provider: "anthropic",
2451
- roles: requestRoles(request, { model: "model", system: "system", messages: "messages", tools: "tools" }, ctx)
2485
+ api: `${sdk.provider}.${callee.name.text}`,
2486
+ provider: sdk.provider,
2487
+ roles: [{ role: "model", node: model }, ...inner ? requestRoles(inner, { prompt: "prompt" }, ctx) : []]
2452
2488
  };
2453
2489
  }
2454
2490
  };
2455
- var OPENAI_MODEL_ONLY_TAILS = [["embeddings", "create"], ["audio", "speech", "create"], ["audio", "transcriptions", "create"], ["audio", "translations", "create"], ["images", "generate"], ["images", "edit"]];
2456
- function openaiModelOnly(call, chain, ctx) {
2457
- const tail = OPENAI_MODEL_ONLY_TAILS.find((candidate) => chainEndsWith(chain, candidate));
2458
- if (!tail)
2459
- return;
2460
- const origin = valueOrigin(receiverOf(call.expression, tail.length), ctx.checker);
2461
- const object = objectLiteralOf(call.arguments[0], ctx.checker);
2462
- if (origin ? !OPENAI_MODULE.test(origin.module) : !object || !hasProperty(object, "model"))
2463
- return;
2464
- return { api: `openai.${tail.join(".")}`, provider: "openai", roles: requestRoles(call.arguments[0], { model: "model" }, ctx) };
2465
- }
2466
- var openaiSink = {
2467
- id: "openai",
2468
- sdk: "openai",
2491
+ var REALTIME_SEND = /send|emit|transmit|dispatch/i;
2492
+ var realtimeEventSink = {
2493
+ id: "realtime-event",
2494
+ sdk: "realtime",
2469
2495
  match(call, ctx) {
2470
- if (!import_typescript5.default.isCallExpression(call))
2496
+ if (!import_typescript3.default.isCallExpression(call) || call.arguments.length !== 1)
2471
2497
  return;
2472
- const chain = calleeChain(call.expression);
2473
- const tails = [["chat", "completions", "create"], ["chat", "completions", "parse"], ["chat", "completions", "stream"], ["responses", "create"], ["responses", "stream"], ["responses", "parse"]];
2474
- const tail = tails.find((candidate) => chainEndsWith(chain, candidate));
2475
- if (!tail)
2476
- return openaiModelOnly(call, chain, ctx);
2477
- const receiver = receiverOf(call.expression, tail.length);
2478
- const origin = valueOrigin(receiver, ctx.checker);
2479
- if (origin && !OPENAI_MODULE.test(origin.module) && !(tail[0] === "chat" && !ANTHROPIC_MODULE.test(origin.module)))
2498
+ const callee = import_typescript3.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
2499
+ if (!import_typescript3.default.isIdentifier(callee) || !REALTIME_SEND.test(callee.text))
2480
2500
  return;
2481
- const request = call.arguments[0];
2482
- if (!origin && tail[0] === "responses") {
2483
- const object = objectLiteralOf(request, ctx.checker);
2484
- if (!object || !hasProperty(object, "model") || !(hasProperty(object, "input") || hasProperty(object, "instructions")))
2501
+ let sent = unwrap(call.arguments[0]);
2502
+ if (import_typescript3.default.isCallExpression(sent) && sent.expression.getText() === "JSON.stringify" && sent.arguments[0])
2503
+ sent = unwrap(sent.arguments[0]);
2504
+ const argument = objectLiteralOf(sent, ctx.checker);
2505
+ if (!argument)
2506
+ return;
2507
+ const type = propertyValue(argument, "type");
2508
+ const kind = type && (import_typescript3.default.isStringLiteral(type) || import_typescript3.default.isNoSubstitutionTemplateLiteral(type)) ? type.text : undefined;
2509
+ if (kind === "session.update") {
2510
+ const session = propertyValue(argument, "session");
2511
+ const object = session ? objectLiteralOf(session, ctx.checker) : undefined;
2512
+ const instructions = object ? propertyValue(object, "instructions") : undefined;
2513
+ return instructions ? { api: "realtime.session.update", provider: "openai", roles: [{ role: "system", node: instructions }] } : undefined;
2514
+ }
2515
+ if (kind === "conversation.item.create") {
2516
+ const item = propertyValue(argument, "item");
2517
+ const object = item ? objectLiteralOf(item, ctx.checker) : undefined;
2518
+ const role = object ? propertyValue(object, "role") : undefined;
2519
+ const roleText = role && import_typescript3.default.isStringLiteral(role) ? role.text : undefined;
2520
+ const content = object ? propertyValue(object, "content") : undefined;
2521
+ if (!content || roleText !== "system" && roleText !== "user")
2485
2522
  return;
2523
+ return { api: "realtime.conversation.item.create", provider: "openai", roles: [{ role: roleText === "system" ? "system" : "messages", node: content }] };
2486
2524
  }
2487
- return {
2488
- api: `openai.${tail.join(".")}`,
2489
- provider: !origin || OPENAI_MODULE.test(origin.module) ? "openai" : OPENAI_COMPATIBLE_MODULE.test(origin.module) ? providerName(origin.module).replace(/-sdk$|_cloud_sdk$|-ai$/, "") : providerName(origin.module),
2490
- roles: requestRoles(request, { model: "model", messages: "messages", input: "messages", instructions: "instructions", tools: "tools", functions: "tools" }, ctx)
2491
- };
2525
+ return;
2492
2526
  }
2493
2527
  };
2494
- var aiSdkSink = {
2495
- id: "ai-sdk",
2496
- sdk: "ai-sdk",
2497
- match(call, ctx) {
2498
- const callee = unwrap(call.expression);
2499
- const nameNode = import_typescript5.default.isPropertyAccessExpression(callee) ? callee.name : import_typescript5.default.isIdentifier(callee) ? callee : undefined;
2500
- const root = rootIdentifier(callee);
2501
- if (!nameNode || !root)
2502
- return;
2503
- const origin = importOrigin(root, ctx.checker);
2504
- if (!origin || origin.module !== "ai")
2505
- return;
2506
- const name = origin.imported === "*" ? nameNode.text : origin.imported;
2507
- if (!import_typescript5.default.isNewExpression(call) && AI_SDK_DECIDE.has(name)) {
2508
- return { api: `ai.${name}`, roles: requestRoles(call.arguments[0], { model: "model", questions: "questions", criteria: "questions" }, ctx) };
2509
- }
2510
- const known = import_typescript5.default.isNewExpression(call) ? AI_SDK_AGENTS.has(name) : AI_SDK_CALLS.has(name);
2511
- if (!known)
2512
- return;
2513
- return {
2514
- api: `ai.${name}`,
2515
- roles: requestRoles(call.arguments?.[0], { model: "model", system: "system", instructions: "instructions", prompt: "prompt", messages: "messages", tools: "tools" }, ctx)
2516
- };
2517
- }
2518
- };
2519
- var providerFactorySink = {
2520
- id: "provider-factory",
2521
- sdk: "provider-factory",
2522
- match(call, ctx) {
2523
- if (!import_typescript5.default.isCallExpression(call))
2524
- return;
2525
- const found = providerModelCall(call, ctx.checker);
2526
- if (!found)
2527
- return;
2528
- const provider = providerName(found.module);
2529
- return { api: `${provider}${found.method ? `.${found.method}` : ""}(model)`, provider, roles: [{ role: "model", node: found.model }] };
2530
- }
2531
- };
2532
- var WORKERS_AI_MODEL = /^@(?:cf|hf)\/[\w.-]+\/[\w.:-]+$/;
2533
- function isWorkersAiBinding(callee, checker) {
2534
- const target = unwrap(callee);
2535
- if (!import_typescript5.default.isPropertyAccessExpression(target))
2536
- return false;
2537
- const receiver = unwrap(target.expression);
2538
- const declaration = import_typescript5.default.isIdentifier(receiver) || import_typescript5.default.isPropertyAccessExpression(receiver) ? valueDeclaration(resolvedSymbol(import_typescript5.default.isIdentifier(receiver) ? receiver : receiver.name, checker)) : undefined;
2539
- const type = declaration && (import_typescript5.default.isParameter(declaration) || import_typescript5.default.isVariableDeclaration(declaration) || import_typescript5.default.isPropertyDeclaration(declaration) || import_typescript5.default.isPropertySignature(declaration)) ? declaration.type : undefined;
2540
- return Boolean(type && import_typescript5.default.isTypeReferenceNode(type) && type.typeName.getText() === "Ai");
2541
- }
2542
- var workersAiSink = {
2543
- id: "workers-ai",
2544
- sdk: "workers-ai",
2545
- match(call, ctx) {
2546
- if (!import_typescript5.default.isCallExpression(call))
2547
- return;
2548
- const chain = calleeChain(call.expression);
2549
- if (!chain || chain[chain.length - 1] !== "run" || call.arguments.length === 0)
2550
- return;
2551
- const [model, input] = call.arguments;
2552
- if (!chainEndsWith(chain, ["AI", "run"]) && !isWorkersAiBinding(call.expression, ctx.checker) && !ctx.urlTexts(model).some((text) => WORKERS_AI_MODEL.test(text)))
2553
- return;
2554
- return {
2555
- api: "workers-ai.AI.run",
2556
- provider: "workers-ai",
2557
- roles: [{ role: "model", node: model }, ...requestRoles(input, { messages: "messages", prompt: "prompt", tools: "tools" }, ctx)]
2558
- };
2559
- }
2560
- };
2561
- var REQUEST_KEYS = { model: "model", model_id: "model", system: "system", messages: "messages", input: "messages", instructions: "instructions", prompt: "prompt", tools: "tools" };
2562
- var OPAQUE_BODY_KEYS = { model: "model", system: "system", messages: "messages", tools: "tools" };
2563
- var FETCH_LIKE = /fetch|request|post/i;
2564
- var NON_MODEL_PATH = /\/models\/?(?:\?|$|`)|\/generation\b|\/credits\b|\/auth\/|\/keys?\b|\/embeddings\b|\/files\b/;
2565
- function bodyHasModel(init, checker) {
2566
- const body = init ? propertyValue(init, "body") : undefined;
2567
- let payload = body ? unwrap(body) : undefined;
2568
- if (payload && import_typescript5.default.isCallExpression(payload) && payload.arguments[0])
2569
- payload = payload.arguments[0];
2570
- const object = objectLiteralOf(payload, checker);
2571
- return Boolean(object && hasProperty(object, "model"));
2528
+ function effectiveField(object, key) {
2529
+ let last = -1;
2530
+ object.properties.forEach((property, index) => {
2531
+ if (!import_typescript3.default.isSpreadAssignment(property) && propertyNameText(property.name) === key)
2532
+ last = index;
2533
+ });
2534
+ const fields = [];
2535
+ const value = last >= 0 ? propertyValue(object, key) : undefined;
2536
+ if (value)
2537
+ fields.push({ node: value });
2538
+ object.properties.forEach((property, index) => {
2539
+ if (index > last && import_typescript3.default.isSpreadAssignment(property))
2540
+ fields.push({ node: property.expression, key });
2541
+ });
2542
+ return fields;
2572
2543
  }
2573
- function urlTemplate(expression, checker, depth = 0) {
2574
- const expr = unwrap(expression);
2575
- if (import_typescript5.default.isTemplateExpression(expr))
2576
- return expr;
2577
- if (depth < 3 && import_typescript5.default.isIdentifier(expr)) {
2578
- const declaration = valueDeclaration(resolvedSymbol(expr, checker));
2579
- if (declaration && import_typescript5.default.isVariableDeclaration(declaration) && declaration.initializer)
2580
- return urlTemplate(declaration.initializer, checker, depth + 1);
2581
- }
2582
- return;
2544
+ var WRITTEN_SYMBOLS = new WeakMap;
2545
+ function writtenSymbols(file, checker) {
2546
+ let written = WRITTEN_SYMBOLS.get(file);
2547
+ if (written)
2548
+ return written;
2549
+ const found = new Set;
2550
+ const add = (node) => {
2551
+ const root = rootIdentifier(node);
2552
+ const symbol = root ? resolvedSymbol(root, checker) : undefined;
2553
+ if (symbol)
2554
+ found.add(symbol);
2555
+ };
2556
+ const visit = (node) => {
2557
+ if (import_typescript3.default.isBinaryExpression(node) && node.operatorToken.kind >= import_typescript3.default.SyntaxKind.FirstAssignment && node.operatorToken.kind <= import_typescript3.default.SyntaxKind.LastAssignment)
2558
+ add(node.left);
2559
+ else if (import_typescript3.default.isDeleteExpression(node))
2560
+ add(node.expression);
2561
+ else if ((import_typescript3.default.isPrefixUnaryExpression(node) || import_typescript3.default.isPostfixUnaryExpression(node)) && (node.operator === import_typescript3.default.SyntaxKind.PlusPlusToken || node.operator === import_typescript3.default.SyntaxKind.MinusMinusToken))
2562
+ add(node.operand);
2563
+ else if (import_typescript3.default.isCallExpression(node) && node.arguments.length > 0) {
2564
+ const callee = unwrap(node.expression);
2565
+ if (import_typescript3.default.isPropertyAccessExpression(callee) && callee.name.text === "assign")
2566
+ add(node.arguments[0]);
2567
+ }
2568
+ import_typescript3.default.forEachChild(node, visit);
2569
+ };
2570
+ visit(file);
2571
+ written = found;
2572
+ WRITTEN_SYMBOLS.set(file, written);
2573
+ return written;
2583
2574
  }
2584
- var MODEL_SOCKET = /^wss:\/\/(?:api\.openai\.com\/v1\/realtime|[\w.-]+\.openai\.azure\.com\/openai\/realtime|generativelanguage\.googleapis\.com\/ws\/[\w.]+BidiGenerateContent|gateway\.ai\.cloudflare\.com\/)/;
2585
- function urlModel(url, checker) {
2586
- const template = urlTemplate(url, checker);
2587
- if (!template)
2575
+ function gatewayRequestLiteral(argument, checker) {
2576
+ const value = unwrap(argument);
2577
+ if (import_typescript3.default.isObjectLiteralExpression(value))
2578
+ return value;
2579
+ if (!import_typescript3.default.isIdentifier(value))
2588
2580
  return;
2589
- let before = template.head.text;
2590
- for (const span of template.templateSpans) {
2591
- if (/\/models\/$/.test(before) && /^[:/?#]/.test(span.literal.text) || /[?&]model=$/.test(before) && /^(?:[&#]|$)/.test(span.literal.text))
2592
- return span.expression;
2593
- before = span.literal.text;
2594
- }
2595
- return;
2581
+ const symbol = resolvedSymbol(value, checker);
2582
+ const declaration = valueDeclaration(symbol);
2583
+ if (!symbol || !declaration || !import_typescript3.default.isVariableDeclaration(declaration) || !declaration.initializer)
2584
+ return;
2585
+ if (!(import_typescript3.default.getCombinedNodeFlags(declaration) & import_typescript3.default.NodeFlags.Const))
2586
+ return;
2587
+ const literal = unwrap(declaration.initializer);
2588
+ if (!import_typescript3.default.isObjectLiteralExpression(literal))
2589
+ return;
2590
+ return writtenSymbols(declaration.getSourceFile(), checker).has(symbol) ? undefined : literal;
2596
2591
  }
2597
- var fetchSink = {
2598
- id: "fetch",
2599
- sdk: "fetch",
2592
+ var GATEWAY_METHODS = new Set(["call", "stream"]);
2593
+ var GATEWAY_BODY_KEYS = { system: "system", messages: "messages", prompt: "prompt", model: "model", tools: "tools" };
2594
+ var modelGatewaySink = {
2595
+ id: "model-gateway",
2596
+ sdk: "model-gateway",
2600
2597
  match(call, ctx) {
2601
- if (!import_typescript5.default.isCallExpression(call) || call.arguments.length < 2)
2598
+ if (!import_typescript3.default.isCallExpression(call) || call.arguments.length !== 1)
2602
2599
  return;
2603
2600
  const callee = unwrap(call.expression);
2604
- const calleeText = import_typescript5.default.isCallExpression(callee) ? callee.expression.getText() : callee.getText();
2605
- if (!FETCH_LIKE.test(calleeText))
2606
- return;
2607
- if (import_typescript5.default.isIdentifier(callee) && callee.text === "fetch" && resolvedFunction(callee, ctx.checker))
2608
- return;
2609
- const second = unwrap(call.arguments[1]);
2610
- if (import_typescript5.default.isArrowFunction(second) || import_typescript5.default.isFunctionExpression(second))
2601
+ if (!import_typescript3.default.isPropertyAccessExpression(callee) || !GATEWAY_METHODS.has(callee.name.text))
2611
2602
  return;
2612
- const first = unwrap(call.arguments[0]);
2613
- if ((import_typescript5.default.isStringLiteral(first) || import_typescript5.default.isNoSubstitutionTemplateLiteral(first)) && !MODEL_HOST.test(first.text) && !MODEL_PATH.test(first.text) && !SPEECH_ENDPOINT.test(first.text))
2603
+ const receiver = unwrap(callee.expression);
2604
+ if (!import_typescript3.default.isPropertyAccessExpression(receiver) || receiver.name.text !== "models")
2614
2605
  return;
2615
- const urls = ctx.urlTexts(call.arguments[0]);
2616
- const initArg = call.arguments[1];
2617
- const init = objectLiteralOf(initArg, ctx.checker);
2618
- const url = urls.find((candidate) => SPEECH_ENDPOINT.test(candidate) || !NON_MODEL_PATH.test(candidate) && (MODEL_HOST.test(candidate) || MODEL_PATH.test(candidate) && (/^https?:\/\//.test(candidate) || bodyHasModel(init, ctx.checker))));
2619
- if (!url)
2606
+ const request = gatewayRequestLiteral(call.arguments[0], ctx.checker);
2607
+ if (!request || !propertyValue(request, "kind"))
2620
2608
  return;
2621
2609
  const roles = [];
2622
- if (init) {
2623
- const body = propertyValue(init, "body");
2624
- let payload = body ? unwrap(body) : undefined;
2625
- if (payload && import_typescript5.default.isCallExpression(payload) && calleeChain(payload.expression)?.join(".") === "JSON.stringify")
2626
- payload = payload.arguments[0];
2627
- if (payload)
2628
- roles.push(...requestRoles(payload, REQUEST_KEYS, ctx));
2629
- } else {
2630
- for (const [key, role] of Object.entries(OPAQUE_BODY_KEYS))
2631
- roles.push({ role, node: initArg, key: `body.${key}` });
2632
- }
2633
- const modelInUrl = urlModel(call.arguments[0], ctx.checker);
2634
- if (modelInUrl && !roles.some((role) => role.role === "model"))
2635
- roles.unshift({ role: "model", node: modelInUrl });
2636
- if (modelInUrl) {
2637
- const index = roles.findIndex((role) => role.role === "model" && role.key?.startsWith("body."));
2638
- if (index >= 0)
2639
- roles[index] = { role: "model", node: modelInUrl };
2610
+ for (const body of effectiveField(request, "body")) {
2611
+ for (const [key, role] of Object.entries(GATEWAY_BODY_KEYS)) {
2612
+ if (body.key) {
2613
+ roles.push({ role, node: body.node, key: `${body.key}.${key}` });
2614
+ continue;
2615
+ }
2616
+ const literal = unwrap(body.node);
2617
+ if (!import_typescript3.default.isObjectLiteralExpression(literal)) {
2618
+ roles.push({ role, node: body.node, key });
2619
+ continue;
2620
+ }
2621
+ for (const field of effectiveField(literal, key))
2622
+ roles.push({ role, ...field });
2623
+ }
2640
2624
  }
2641
- return {
2642
- api: "fetch",
2643
- provider: /elevenlabs/.test(url) ? "elevenlabs" : /anthropic/.test(url) ? "anthropic" : /openrouter/.test(url) ? "openrouter" : /openai/.test(url) ? "openai" : /generativelanguage/.test(url) ? "google" : undefined,
2644
- roles
2645
- };
2625
+ for (const field of effectiveField(request, "prompt"))
2626
+ roles.push({ role: "prompt", ...field });
2627
+ return roles.length > 0 ? { api: `models.${callee.name.text}`, roles } : undefined;
2646
2628
  }
2647
2629
  };
2648
- var AGENT_ENTRY_METHODS = new Set(["run", "executeRun", "chat", "saveMessages", "sendMessage", "submitMessage", "prompt", "runAgentTool"]);
2649
- var AGENT_BASES = new Set(["Think", "Agent", "AIChatAgent"]);
2650
- var ENTRY_FIELDS = ["message", "context", "brief"];
2651
- var STUB_GETTERS = new Set(["get", "getByName", "getAgentByName", "getServerByName", "routeAgentRequest", "getStub"]);
2652
- function classOfDeclaration(declaration) {
2653
- if (!declaration)
2654
- return;
2655
- if (import_typescript5.default.isClassDeclaration(declaration) || import_typescript5.default.isClassExpression(declaration))
2656
- return declaration;
2657
- return;
2630
+ var CALL_SINKS = [modelGatewaySink, realtimeEventSink, anthropicSink, openaiSink, aiSdkSink, workersAiSink, fetchSink, websocketSink, providerFactorySink, agentEntrySink, clientChatSink, hostedModelSink];
2631
+ function registerCallSink(recognizer) {
2632
+ CALL_SINKS.push(recognizer);
2658
2633
  }
2659
- function classesInType(type, checker, out = []) {
2660
- if (!type || out.length > 4)
2634
+ function classSinks(memo) {
2635
+ return [hookSink(memo), ...EXTRA_CLASS_SINKS];
2636
+ }
2637
+ var EXTRA_CLASS_SINKS = [];
2638
+ function registerClassSink(recognizer) {
2639
+ EXTRA_CLASS_SINKS.push(recognizer);
2640
+ }
2641
+
2642
+ // src/harness-extract/calls.ts
2643
+ class CallIndex {
2644
+ program;
2645
+ checker;
2646
+ byName;
2647
+ aliases = new Map;
2648
+ members = new Map;
2649
+ checkingDefaults = new Set;
2650
+ constructor(program, checker) {
2651
+ this.program = program;
2652
+ this.checker = checker;
2653
+ }
2654
+ build() {
2655
+ const byName = new Map;
2656
+ for (const source of this.program.getSourceFiles()) {
2657
+ if (source.isDeclarationFile || /[\\/]node_modules[\\/]/.test(source.fileName))
2658
+ continue;
2659
+ const imported = importAliases(source);
2660
+ const visit = (node) => {
2661
+ if ((import_typescript4.default.isParameter(node) || import_typescript4.default.isVariableDeclaration(node)) && node.initializer && import_typescript4.default.isIdentifier(node.name)) {
2662
+ let init = unwrap(node.initializer);
2663
+ if (import_typescript4.default.isBinaryExpression(init) && (init.operatorToken.kind === import_typescript4.default.SyntaxKind.QuestionQuestionToken || init.operatorToken.kind === import_typescript4.default.SyntaxKind.BarBarToken))
2664
+ init = unwrap(init.right);
2665
+ if (import_typescript4.default.isIdentifier(init)) {
2666
+ const entry = { declaration: node, target: init };
2667
+ const list = this.aliases.get(init.text);
2668
+ if (list)
2669
+ list.push(entry);
2670
+ else
2671
+ this.aliases.set(init.text, [entry]);
2672
+ }
2673
+ }
2674
+ if ((import_typescript4.default.isPropertyAssignment(node) || import_typescript4.default.isShorthandPropertyAssignment(node)) && import_typescript4.default.isObjectLiteralExpression(node.parent)) {
2675
+ const value = import_typescript4.default.isShorthandPropertyAssignment(node) ? node.name : unwrap(node.initializer);
2676
+ const property = import_typescript4.default.isIdentifier(node.name) || import_typescript4.default.isStringLiteral(node.name) ? node.name.text : undefined;
2677
+ if (property && import_typescript4.default.isIdentifier(value)) {
2678
+ const entry = { property, literal: node.parent, target: value };
2679
+ const list = this.members.get(value.text);
2680
+ if (list)
2681
+ list.push(entry);
2682
+ else
2683
+ this.members.set(value.text, [entry]);
2684
+ }
2685
+ }
2686
+ if (import_typescript4.default.isCallExpression(node)) {
2687
+ const callee = unwrap(node.expression);
2688
+ const name = import_typescript4.default.isIdentifier(callee) ? callee.text : import_typescript4.default.isPropertyAccessExpression(callee) ? callee.name.text : undefined;
2689
+ if (name) {
2690
+ const original = import_typescript4.default.isIdentifier(callee) ? imported.get(name) : undefined;
2691
+ for (const key of original && original !== name ? [name, original] : [name]) {
2692
+ const list = byName.get(key);
2693
+ if (list)
2694
+ list.push(node);
2695
+ else
2696
+ byName.set(key, [node]);
2697
+ }
2698
+ }
2699
+ }
2700
+ import_typescript4.default.forEachChild(node, visit);
2701
+ };
2702
+ visit(source);
2703
+ }
2704
+ return byName;
2705
+ }
2706
+ callersOf(fn, name, limit, within) {
2707
+ const all = this.allCallersOf(fn, name, within ? Number.MAX_SAFE_INTEGER : limit);
2708
+ if (!within)
2709
+ return all;
2710
+ return all.filter((call) => within.getSourceFile(call.getSourceFile().fileName) === call.getSourceFile()).slice(0, limit);
2711
+ }
2712
+ allCallersOf(fn, name, limit) {
2713
+ this.byName ??= this.build();
2714
+ const signatures = contextualSignatures(fn, name, this.checker);
2715
+ const out = this.direct(name, limit, (declaration, call) => declares(declaration, fn) || signatures.has(declaration) && contextualReceiverMatches(call, fn, this.checker));
2716
+ if (isDefaultExport(fn) && name !== "default" && out.length < limit)
2717
+ out.push(...this.direct("default", limit - out.length, (declaration) => declares(declaration, fn), new Set(out)));
2718
+ for (const alias of this.aliases.get(name) ?? []) {
2719
+ if (out.length >= limit)
2720
+ break;
2721
+ const symbol = resolvedSymbol(alias.target, this.checker);
2722
+ if (!symbol?.declarations?.some((declaration) => declares(declaration, fn)))
2723
+ continue;
2724
+ if (!this.defaultCanApply(alias.declaration))
2725
+ continue;
2726
+ const aliasName = alias.declaration.name.text;
2727
+ out.push(...this.direct(aliasName, limit - out.length, (declaration) => declaration === alias.declaration));
2728
+ }
2729
+ for (const member of this.members.get(name) ?? []) {
2730
+ if (out.length >= limit)
2731
+ break;
2732
+ const symbol = resolvedSymbol(member.target, this.checker);
2733
+ if (!symbol?.declarations?.some((declaration) => declares(declaration, fn)))
2734
+ continue;
2735
+ for (const param of this.holders(member.literal)) {
2736
+ out.push(...this.memberCalls(param, member.property, limit - out.length));
2737
+ }
2738
+ }
2661
2739
  return out;
2662
- if (import_typescript5.default.isTypeReferenceNode(type)) {
2663
- const name = import_typescript5.default.isQualifiedName(type.typeName) ? type.typeName.right : type.typeName;
2664
- const cls = classOfDeclaration(valueDeclaration(resolvedSymbol(name, checker)));
2665
- if (cls)
2666
- out.push(cls);
2667
- for (const argument of type.typeArguments ?? [])
2668
- classesInType(argument, checker, out);
2669
- } else if (import_typescript5.default.isUnionTypeNode(type) || import_typescript5.default.isIntersectionTypeNode(type)) {
2670
- for (const member of type.types)
2671
- classesInType(member, checker, out);
2672
2740
  }
2673
- return out;
2674
- }
2675
- function receiverClasses(expression, checker, depth = 0) {
2676
- const expr = unwrap(expression);
2677
- if (depth > 4)
2678
- return [];
2679
- if (expr.kind === import_typescript5.default.SyntaxKind.ThisKeyword) {
2680
- for (let current = expr.parent;current; current = current.parent) {
2681
- if (import_typescript5.default.isClassDeclaration(current) || import_typescript5.default.isClassExpression(current))
2682
- return [current];
2741
+ holders(literal) {
2742
+ let node = literal;
2743
+ while (node.parent && (import_typescript4.default.isParenthesizedExpression(node.parent) || import_typescript4.default.isAsExpression(node.parent) || import_typescript4.default.isSatisfiesExpression(node.parent)))
2744
+ node = node.parent;
2745
+ const parent = node.parent;
2746
+ const out = [];
2747
+ if (parent && import_typescript4.default.isCallExpression(parent)) {
2748
+ const index = parent.arguments.indexOf(node);
2749
+ const fn = index >= 0 ? resolvedFunction(parent.expression, this.checker) : undefined;
2750
+ if (fn && fn.parameters[index])
2751
+ out.push(fn.parameters[index]);
2752
+ } else if (parent && import_typescript4.default.isParameter(parent) && parent.initializer === node) {
2753
+ out.push(parent);
2754
+ } else if (parent && import_typescript4.default.isVariableDeclaration(parent) && parent.initializer === node && import_typescript4.default.isIdentifier(parent.name)) {
2755
+ for (const alias of this.aliases.get(parent.name.text) ?? []) {
2756
+ if (import_typescript4.default.isParameter(alias.declaration) && valueDeclaration(resolvedSymbol(alias.target, this.checker)) === parent)
2757
+ out.push(alias.declaration);
2758
+ }
2683
2759
  }
2684
- return [];
2760
+ return out;
2685
2761
  }
2686
- if (import_typescript5.default.isNewExpression(expr)) {
2687
- const cls = classOfDeclaration(valueDeclaration(resolvedSymbol(import_typescript5.default.isPropertyAccessExpression(expr.expression) ? expr.expression.name : expr.expression, checker)));
2688
- return cls ? [cls] : [];
2762
+ memberCalls(param, property, limit) {
2763
+ const out = [];
2764
+ for (const call of this.byName.get(property) ?? []) {
2765
+ if (out.length >= limit)
2766
+ break;
2767
+ const callee = unwrap(call.expression);
2768
+ if (import_typescript4.default.isPropertyAccessExpression(callee)) {
2769
+ const receiver = unwrap(callee.expression);
2770
+ if (import_typescript4.default.isIdentifier(receiver) && valueDeclaration(resolvedSymbol(receiver, this.checker)) === param)
2771
+ out.push(call);
2772
+ } else if (import_typescript4.default.isIdentifier(callee)) {
2773
+ const declaration = valueDeclaration(resolvedSymbol(callee, this.checker));
2774
+ if (!declaration || !import_typescript4.default.isBindingElement(declaration))
2775
+ continue;
2776
+ const holder = declaration.parent.parent;
2777
+ const init = import_typescript4.default.isVariableDeclaration(holder) && holder.initializer ? unwrap(holder.initializer) : undefined;
2778
+ if (holder === param || init && import_typescript4.default.isIdentifier(init) && valueDeclaration(resolvedSymbol(init, this.checker)) === param)
2779
+ out.push(call);
2780
+ }
2781
+ }
2782
+ return out;
2689
2783
  }
2690
- if (import_typescript5.default.isCallExpression(expr)) {
2691
- const callee = unwrap(expr.expression);
2692
- const name = import_typescript5.default.isPropertyAccessExpression(callee) ? callee.name.text : import_typescript5.default.isIdentifier(callee) ? callee.text : "";
2693
- if (!STUB_GETTERS.has(name))
2694
- return [];
2695
- const fromTypeArgs = (expr.typeArguments ?? []).flatMap((argument) => classesInType(argument, checker));
2696
- if (fromTypeArgs.length > 0)
2697
- return fromTypeArgs;
2698
- const namespace = import_typescript5.default.isPropertyAccessExpression(callee) && name !== "getAgentByName" && name !== "getServerByName" ? callee.expression : expr.arguments[0];
2699
- return namespace ? receiverClasses(namespace, checker, depth + 1) : [];
2784
+ defaultCanApply(declaration) {
2785
+ if (!import_typescript4.default.isParameter(declaration) || this.checkingDefaults.has(declaration))
2786
+ return true;
2787
+ const init = declaration.initializer ? unwrap(declaration.initializer) : undefined;
2788
+ if (!init || !import_typescript4.default.isIdentifier(init))
2789
+ return true;
2790
+ const fn = declaration.parent;
2791
+ const name = isFunctionLike(fn) ? functionName(fn) : undefined;
2792
+ if (!name || !isFunctionLike(fn))
2793
+ return true;
2794
+ const index = fn.parameters.indexOf(declaration);
2795
+ this.checkingDefaults.add(declaration);
2796
+ try {
2797
+ const callers = this.callersOf(fn, name, 20);
2798
+ if (callers.length === 0 || callers.length >= 20)
2799
+ return true;
2800
+ return callers.some((call) => {
2801
+ if (call.arguments.slice(0, index + 1).some((argument2) => import_typescript4.default.isSpreadElement(argument2)))
2802
+ return true;
2803
+ const argument = call.arguments[index];
2804
+ if (!argument)
2805
+ return true;
2806
+ const inner = unwrap(argument);
2807
+ if (import_typescript4.default.isIdentifier(inner) && inner.text === "undefined" || import_typescript4.default.isVoidExpression(inner))
2808
+ return true;
2809
+ const passed = import_typescript4.default.isIdentifier(inner) ? valueDeclaration(resolvedSymbol(inner, this.checker)) : undefined;
2810
+ if (passed && declaration.initializer && declares(passed, resolvedFunction(declaration.initializer, this.checker) ?? fn))
2811
+ return true;
2812
+ return !definitelyDefined(inner, this.checker);
2813
+ });
2814
+ } finally {
2815
+ this.checkingDefaults.delete(declaration);
2816
+ }
2700
2817
  }
2701
- const nameNode = import_typescript5.default.isPropertyAccessExpression(expr) ? expr.name : import_typescript5.default.isIdentifier(expr) ? expr : undefined;
2702
- if (!nameNode)
2703
- return [];
2704
- const declaration = valueDeclaration(resolvedSymbol(nameNode, checker));
2705
- if (!declaration)
2706
- return [];
2707
- if (import_typescript5.default.isVariableDeclaration(declaration) || import_typescript5.default.isParameter(declaration) || import_typescript5.default.isPropertyDeclaration(declaration) || import_typescript5.default.isPropertySignature(declaration)) {
2708
- const declared = classesInType(declaration.type, checker);
2709
- if (declared.length > 0)
2710
- return declared;
2711
- if ("initializer" in declaration && declaration.initializer)
2712
- return receiverClasses(declaration.initializer, checker, depth + 1);
2818
+ direct(name, limit, matches, found) {
2819
+ const candidates = this.byName.get(name) ?? [];
2820
+ const out = [];
2821
+ let checked = 0;
2822
+ for (const call of candidates) {
2823
+ if (found?.has(call))
2824
+ continue;
2825
+ if (out.length >= limit || checked >= limit * 20)
2826
+ break;
2827
+ checked += 1;
2828
+ const callee = unwrap(call.expression);
2829
+ const nameNode = import_typescript4.default.isPropertyAccessExpression(callee) ? callee.name : callee;
2830
+ const symbol = resolvedSymbol(nameNode, this.checker);
2831
+ const members = import_typescript4.default.isPropertyAccessExpression(callee) ? receiverClasses(callee.expression, this.checker).flatMap((cls) => cls.members.filter((member) => member.name?.getText() === name)) : [];
2832
+ if (symbol?.declarations?.some((declaration) => matches(declaration, call)) || members.some((declaration) => matches(declaration, call)))
2833
+ out.push(call);
2834
+ }
2835
+ return out;
2713
2836
  }
2714
- return [];
2715
- }
2716
- function firstParamType(declaration, checker) {
2717
- if (!declaration)
2718
- return;
2719
- let parameters;
2720
- if (import_typescript5.default.isMethodSignature(declaration) || import_typescript5.default.isMethodDeclaration(declaration))
2721
- parameters = declaration.parameters;
2722
- else if ((import_typescript5.default.isPropertySignature(declaration) || import_typescript5.default.isPropertyDeclaration(declaration)) && declaration.type && import_typescript5.default.isFunctionTypeNode(declaration.type))
2723
- parameters = declaration.type.parameters;
2724
- const type = parameters?.[0]?.type;
2725
- if (!type || !import_typescript5.default.isTypeReferenceNode(type))
2726
- return;
2727
- const name = import_typescript5.default.isQualifiedName(type.typeName) ? type.typeName.right : type.typeName;
2728
- return valueDeclarationOrType(resolvedSymbol(name, checker));
2729
2837
  }
2730
- function valueDeclarationOrType(symbol) {
2731
- return symbol?.declarations?.[0];
2732
- }
2733
- function structuralAgent(receiver, method, ctx) {
2734
- let declaration;
2735
- try {
2736
- declaration = ctx.checker.getTypeAtLocation(receiver).getProperty(method)?.declarations?.[0];
2737
- } catch {
2738
- return;
2838
+
2839
+ class RepoCallIndex {
2840
+ entries;
2841
+ indexes = new Map;
2842
+ owned = new Map;
2843
+ constructor(entries) {
2844
+ this.entries = entries;
2739
2845
  }
2740
- declaration ??= declaredMethod(receiver, method, ctx.checker);
2741
- if (!declaration)
2742
- return;
2743
- const owner = declaration.parent;
2744
- if (owner && (import_typescript5.default.isClassDeclaration(owner) || import_typescript5.default.isClassExpression(owner))) {
2745
- const base = ctx.frameworkBase(owner).base;
2746
- return base && AGENT_BASES.has(base) ? owner : undefined;
2846
+ indexFor(entry) {
2847
+ let index = this.indexes.get(entry);
2848
+ if (!index) {
2849
+ index = new CallIndex(entry.program, entry.checker());
2850
+ this.indexes.set(entry, index);
2851
+ }
2852
+ return index;
2747
2853
  }
2748
- const wanted = firstParamType(declaration, ctx.checker);
2749
- if (!wanted)
2750
- return;
2751
- return ctx.agentClasses().find((cls) => cls.members.some((member) => import_typescript5.default.isMethodDeclaration(member) && propertyNameText(member.name) === method && firstParamType(member, ctx.checker) === wanted));
2752
- }
2753
- var agentEntrySink = {
2754
- id: "agent-entry",
2755
- sdk: "agent-entry",
2756
- match(call, ctx) {
2757
- if (!import_typescript5.default.isCallExpression(call) || call.arguments.length === 0)
2758
- return;
2759
- const callee = unwrap(call.expression);
2760
- if (!import_typescript5.default.isPropertyAccessExpression(callee) || !AGENT_ENTRY_METHODS.has(callee.name.text))
2761
- return;
2762
- const method = callee.name.text;
2763
- const cls = receiverClasses(callee.expression, ctx.checker).find((candidate) => {
2764
- const base = ctx.frameworkBase(candidate).base;
2765
- return base !== undefined && AGENT_BASES.has(base);
2766
- });
2767
- const seam = method === "runAgentTool" && !cls && hasMethod(callee.expression, method, ctx) ? callee.expression : undefined;
2768
- const target = cls ?? structuralAgent(callee.expression, method, ctx);
2769
- if (!target && !seam)
2770
- return;
2771
- const argument = method === "runAgentTool" ? call.arguments[1] : call.arguments[0];
2772
- if (!argument || import_typescript5.default.isSpreadElement(argument))
2773
- return;
2774
- const roles = [];
2775
- if (method === "runAgentTool") {
2776
- const object = objectLiteralOf(argument, ctx.checker);
2777
- const input = object ? propertyValue(object, "input") : undefined;
2778
- roles.push(input ? { role: "user", node: input } : { role: "user", node: argument, key: "input" });
2779
- } else if (method === "saveMessages") {
2780
- roles.push({ role: "messages", node: argument });
2781
- } else {
2782
- const object = objectLiteralOf(argument, ctx.checker);
2783
- const fields = object ? ENTRY_FIELDS.filter((field) => propertyValue(object, field)) : [];
2784
- if (object && unwrap(argument) === object && fields.length > 0) {
2785
- for (const field of fields)
2786
- roles.push({ role: "user", node: propertyValue(object, field) });
2787
- } else {
2788
- roles.push({ role: "user", node: argument });
2854
+ indexedCallersOf(fn, name, limit, within) {
2855
+ const out = [];
2856
+ const seen = new Set;
2857
+ const fnFile = fn.getSourceFile().fileName;
2858
+ for (const entry of this.entries) {
2859
+ if (out.length >= limit)
2860
+ break;
2861
+ if (!entry.program.getSourceFile(fnFile))
2862
+ continue;
2863
+ let owned = this.owned.get(entry);
2864
+ if (!owned) {
2865
+ owned = new Set(entry.owned);
2866
+ this.owned.set(entry, owned);
2867
+ }
2868
+ for (const call of this.indexFor(entry).callersOf(fn, name, Number.MAX_SAFE_INTEGER)) {
2869
+ const source = call.getSourceFile();
2870
+ if (!owned.has(source.fileName))
2871
+ continue;
2872
+ const key = `${source.fileName}:${call.pos}`;
2873
+ if (seen.has(key))
2874
+ continue;
2875
+ if (within && within.getSourceFile(source.fileName) !== source)
2876
+ continue;
2877
+ seen.add(key);
2878
+ out.push({ call, entry });
2879
+ if (out.length >= limit)
2880
+ break;
2789
2881
  }
2790
2882
  }
2791
- return { api: `${(target && className(target)) ?? "agent"}.${method}`, roles };
2883
+ return out;
2792
2884
  }
2793
- };
2794
- function declaredMethod(receiver, method, checker) {
2795
- const root = unwrap(receiver);
2796
- if (!import_typescript5.default.isIdentifier(root))
2797
- return;
2798
- let annotation;
2799
- try {
2800
- const declaration = checker.getSymbolAtLocation(root)?.valueDeclaration;
2801
- if (declaration && (import_typescript5.default.isParameter(declaration) || import_typescript5.default.isVariableDeclaration(declaration) || import_typescript5.default.isPropertySignature(declaration) || import_typescript5.default.isPropertyDeclaration(declaration)))
2802
- annotation = declaration.type;
2803
- } catch {
2804
- return;
2885
+ callersOf(fn, name, limit, within) {
2886
+ const own = within ? this.entries.find((entry) => entry.program === within) : undefined;
2887
+ if (own)
2888
+ return this.indexFor(own).callersOf(fn, name, limit);
2889
+ return this.indexedCallersOf(fn, name, limit, within).map((indexed) => indexed.call);
2805
2890
  }
2806
- const seen = new Set;
2807
- const search = (type, depth) => {
2808
- if (!type || depth > 4 || seen.has(type))
2809
- return;
2810
- seen.add(type);
2811
- if (import_typescript5.default.isIntersectionTypeNode(type) || import_typescript5.default.isUnionTypeNode(type)) {
2812
- for (const member of type.types) {
2813
- const found = search(member, depth + 1);
2814
- if (found)
2815
- return found;
2891
+ }
2892
+ function importAliases(source) {
2893
+ const aliases = new Map;
2894
+ for (const statement of source.statements) {
2895
+ const clause = import_typescript4.default.isImportDeclaration(statement) ? statement.importClause : undefined;
2896
+ if (!clause || clause.isTypeOnly)
2897
+ continue;
2898
+ if (clause.name)
2899
+ aliases.set(clause.name.text, "default");
2900
+ if (clause.namedBindings && import_typescript4.default.isNamedImports(clause.namedBindings)) {
2901
+ for (const element of clause.namedBindings.elements) {
2902
+ if (element.propertyName)
2903
+ aliases.set(element.name.text, element.propertyName.text);
2816
2904
  }
2817
- return;
2818
2905
  }
2819
- if (import_typescript5.default.isParenthesizedTypeNode(type))
2820
- return search(type.type, depth + 1);
2821
- const members = import_typescript5.default.isTypeLiteralNode(type) ? type.members : undefined;
2822
- if (members)
2823
- return members.find((member) => (import_typescript5.default.isMethodSignature(member) || import_typescript5.default.isPropertySignature(member)) && propertyNameText(member.name) === method);
2824
- if (!import_typescript5.default.isTypeReferenceNode(type))
2906
+ }
2907
+ return aliases;
2908
+ }
2909
+ function isDefaultExport(fn) {
2910
+ const holder = import_typescript4.default.isVariableDeclaration(fn.parent) ? fn.parent : fn;
2911
+ if (import_typescript4.default.canHaveModifiers(holder) && import_typescript4.default.getModifiers(holder)?.some((modifier) => modifier.kind === import_typescript4.default.SyntaxKind.DefaultKeyword))
2912
+ return true;
2913
+ if (import_typescript4.default.isExportAssignment(fn.parent))
2914
+ return true;
2915
+ const name = functionName(fn);
2916
+ return Boolean(name && fn.getSourceFile().statements.some((statement) => import_typescript4.default.isExportAssignment(statement) && !statement.isExportEquals && import_typescript4.default.isIdentifier(statement.expression) && statement.expression.text === name));
2917
+ }
2918
+ function sameNode(a, b) {
2919
+ return a === b || a.kind === b.kind && a.pos === b.pos && a.end === b.end && a.getSourceFile().fileName === b.getSourceFile().fileName;
2920
+ }
2921
+ function declares(declaration, fn) {
2922
+ if (sameNode(declaration, fn))
2923
+ return true;
2924
+ if ((import_typescript4.default.isVariableDeclaration(declaration) || import_typescript4.default.isPropertyAssignment(declaration) || import_typescript4.default.isPropertyDeclaration(declaration)) && declaration.initializer && sameNode(unwrap(declaration.initializer), fn))
2925
+ return true;
2926
+ if (import_typescript4.default.isExportAssignment(declaration) && sameNode(unwrap(declaration.expression), fn))
2927
+ return true;
2928
+ return false;
2929
+ }
2930
+ function definitelyDefined(expression, checker, seen = new Set) {
2931
+ const node = unwrap(expression);
2932
+ if (seen.has(node))
2933
+ return false;
2934
+ seen.add(node);
2935
+ if (import_typescript4.default.isStringLiteralLike(node) || import_typescript4.default.isNumericLiteral(node) || import_typescript4.default.isObjectLiteralExpression(node) || import_typescript4.default.isArrayLiteralExpression(node) || import_typescript4.default.isArrowFunction(node) || import_typescript4.default.isFunctionExpression(node) || node.kind === import_typescript4.default.SyntaxKind.NullKeyword || node.kind === import_typescript4.default.SyntaxKind.TrueKeyword || node.kind === import_typescript4.default.SyntaxKind.FalseKeyword)
2936
+ return true;
2937
+ if (import_typescript4.default.isIdentifier(node)) {
2938
+ const declaration = valueDeclaration(resolvedSymbol(node, checker));
2939
+ if (declaration && (import_typescript4.default.isFunctionDeclaration(declaration) || import_typescript4.default.isClassDeclaration(declaration)))
2940
+ return true;
2941
+ if (declaration && import_typescript4.default.isVariableDeclaration(declaration) && declaration.initializer && import_typescript4.default.getCombinedNodeFlags(declaration) & import_typescript4.default.NodeFlags.Const)
2942
+ return definitelyDefined(declaration.initializer, checker, seen);
2943
+ }
2944
+ return false;
2945
+ }
2946
+ function contextualSignatures(fn, name, checker) {
2947
+ const member = import_typescript4.default.isArrowFunction(fn) || import_typescript4.default.isFunctionExpression(fn) ? fn.parent : fn;
2948
+ if (!(import_typescript4.default.isMethodDeclaration(member) || import_typescript4.default.isPropertyAssignment(member)) || !import_typescript4.default.isObjectLiteralExpression(member.parent))
2949
+ return new Set;
2950
+ const property = checker.getContextualType(member.parent)?.getProperty(name);
2951
+ return new Set((property?.declarations ?? []).filter((declaration) => import_typescript4.default.isMethodSignature(declaration) || import_typescript4.default.isPropertySignature(declaration)));
2952
+ }
2953
+ function contextualReceiverMatches(call, fn, checker) {
2954
+ const member = import_typescript4.default.isArrowFunction(fn) || import_typescript4.default.isFunctionExpression(fn) ? fn.parent : fn;
2955
+ const callee = unwrap(call.expression);
2956
+ if (!import_typescript4.default.isPropertyAccessExpression(callee))
2957
+ return true;
2958
+ const seen = new Set;
2959
+ const objectOf = (expression) => {
2960
+ const node = unwrap(expression);
2961
+ if (seen.has(node))
2825
2962
  return;
2826
- return fromName(type.typeName, depth);
2963
+ seen.add(node);
2964
+ if (import_typescript4.default.isObjectLiteralExpression(node))
2965
+ return node;
2966
+ const declaration = valueDeclaration(resolvedSymbol(import_typescript4.default.isPropertyAccessExpression(node) ? node.name : node, checker));
2967
+ if (declaration && (import_typescript4.default.isVariableDeclaration(declaration) || import_typescript4.default.isPropertyAssignment(declaration)) && declaration.initializer)
2968
+ return objectOf(declaration.initializer);
2969
+ return;
2827
2970
  };
2828
- const fromName = (name, depth) => {
2829
- let symbol;
2830
- try {
2831
- symbol = checker.getSymbolAtLocation(name);
2832
- if (symbol && symbol.flags & import_typescript5.default.SymbolFlags.Alias)
2833
- symbol = checker.getAliasedSymbol(symbol);
2834
- } catch {
2835
- return;
2836
- }
2837
- for (const declaration of symbol?.declarations ?? []) {
2838
- if (seen.has(declaration))
2839
- continue;
2840
- seen.add(declaration);
2841
- if (import_typescript5.default.isInterfaceDeclaration(declaration)) {
2842
- const own = declaration.members.find((member) => (import_typescript5.default.isMethodSignature(member) || import_typescript5.default.isPropertySignature(member)) && propertyNameText(member.name) === method);
2843
- if (own)
2844
- return own;
2845
- for (const clause of declaration.heritageClauses ?? []) {
2846
- for (const base of clause.types) {
2847
- const found = fromName(base.expression, depth + 1);
2848
- if (found)
2849
- return found;
2850
- }
2851
- }
2852
- }
2853
- if (import_typescript5.default.isTypeAliasDeclaration(declaration)) {
2854
- const found = search(declaration.type, depth + 1);
2855
- if (found)
2856
- return found;
2971
+ const object = objectOf(callee.expression);
2972
+ if (!object || object === member.parent)
2973
+ return true;
2974
+ const origin = (literal, visited = new Set) => {
2975
+ if (visited.has(literal))
2976
+ return;
2977
+ const next = new Set(visited).add(literal);
2978
+ for (const property of [...literal.properties].reverse()) {
2979
+ if (import_typescript4.default.isSpreadAssignment(property)) {
2980
+ const spread = objectOf(property.expression);
2981
+ if (!spread)
2982
+ return;
2983
+ const inherited = origin(spread, next);
2984
+ if (inherited !== null)
2985
+ return inherited;
2986
+ } else if (property.name?.getText().replace(/^['"]|['"]$/g, "") === callee.name.text) {
2987
+ return property;
2857
2988
  }
2858
2989
  }
2859
- return;
2990
+ return null;
2860
2991
  };
2861
- return search(annotation, 0);
2992
+ const implementation = origin(object);
2993
+ return implementation === undefined || implementation === member;
2862
2994
  }
2863
- function hasMethod(receiver, method, ctx) {
2864
- try {
2865
- return Boolean(ctx.checker.getTypeAtLocation(receiver).getProperty(method));
2866
- } catch {
2867
- return false;
2995
+
2996
+ // src/harness-extract/messages.ts
2997
+ var ROLE_LITERALS = {
2998
+ system: "system",
2999
+ developer: "system",
3000
+ user: "user",
3001
+ human: "user",
3002
+ assistant: "assistant",
3003
+ ai: "assistant",
3004
+ model: "assistant",
3005
+ tool: "tool",
3006
+ function: "tool"
3007
+ };
3008
+ var CONSTRUCTOR_ROLE = [
3009
+ [/(?:^|\.)System(?:Message|MessagePromptTemplate)\b/, "system"],
3010
+ [/(?:^|\.)(?:Human|User)(?:Message|MessagePromptTemplate)\b/, "user"],
3011
+ [/(?:^|\.)(?:AI|Ai|Assistant)(?:Message|MessagePromptTemplate)\b/, "assistant"],
3012
+ [/(?:^|\.)(?:Tool|Function)Message\b/, "tool"]
3013
+ ];
3014
+ var PASS_THROUGH = new Set(["ref", "lookup", "param", "call", "oneOf"]);
3015
+ var STRINGY = new Set(["literal", "template", "concat", "arrayJoin"]);
3016
+ var MAX_CONTAINERS = 16;
3017
+ function singleLiteral(tree) {
3018
+ if (!tree)
3019
+ return;
3020
+ if (tree.kind === "literal")
3021
+ return tree.text;
3022
+ if (PASS_THROUGH.has(tree.kind)) {
3023
+ const flow = valueChildren(tree);
3024
+ if (flow.length === 1)
3025
+ return singleLiteral(flow[0]);
2868
3026
  }
3027
+ return;
2869
3028
  }
2870
- var CHAT_HOOK_MODULE = /^(?:@ai-sdk\/(?:react|svelte|vue|angular|solid)|ai\/(?:react|svelte|vue)|agents\/(?:ai-)?react|@cloudflare\/(?:think|ai-chat|agents)\/react)$/;
2871
- var CHAT_HOOKS = new Set(["useChat", "useAgentChat", "Chat", "useCompletion"]);
2872
- var CHAT_SEND = new Set(["sendMessage", "append", "submitMessage", "complete"]);
2873
- function fromChatHook(expression, checker, depth = 0) {
2874
- if (!expression || depth > 3)
2875
- return false;
2876
- const expr = unwrap(expression);
2877
- if (import_typescript5.default.isCallExpression(expr) || import_typescript5.default.isNewExpression(expr)) {
2878
- const root = rootIdentifier(expr.expression);
2879
- const origin = root ? importOrigin(root, checker) : undefined;
2880
- return Boolean(origin && CHAT_HOOK_MODULE.test(origin.module) && CHAT_HOOKS.has(origin.imported === "*" || origin.imported === "default" ? import_typescript5.default.isPropertyAccessExpression(expr.expression) ? expr.expression.name.text : "" : origin.imported));
3029
+ function elementRole(element, depth = 0) {
3030
+ if (depth > 6 || element.key === "...")
3031
+ return "unknown";
3032
+ if (element.kind === "object") {
3033
+ const missing = { ...element, kind: "external", children: undefined, resolution: "unresolved" };
3034
+ const text = singleLiteral(selectKey(element, "role", missing));
3035
+ return text && ROLE_LITERALS[text.toLowerCase()] || "unknown";
2881
3036
  }
2882
- const nameNode = import_typescript5.default.isIdentifier(expr) ? expr : import_typescript5.default.isPropertyAccessExpression(expr) ? expr.name : undefined;
2883
- const declaration = nameNode ? valueDeclaration(resolvedSymbol(nameNode, checker)) : undefined;
2884
- if (!declaration)
2885
- return false;
2886
- if (import_typescript5.default.isBindingElement(declaration)) {
2887
- const holder = declaration.parent.parent;
2888
- return import_typescript5.default.isVariableDeclaration(holder) && fromChatHook(holder.initializer, checker, depth + 1);
3037
+ if (element.kind === "array") {
3038
+ const text = singleLiteral(element.children?.[0]);
3039
+ return text && ROLE_LITERALS[text.toLowerCase()] || "unknown";
2889
3040
  }
2890
- if (import_typescript5.default.isVariableDeclaration(declaration))
2891
- return fromChatHook(declaration.initializer, checker, depth + 1);
2892
- return false;
2893
- }
2894
- function looksLikeUiMessage(argument) {
2895
- const object = unwrap(argument);
2896
- if (!import_typescript5.default.isObjectLiteralExpression(object))
2897
- return false;
2898
- const parts = propertyValue(object, "parts");
2899
- if (parts) {
2900
- const array = unwrap(parts);
2901
- return import_typescript5.default.isArrayLiteralExpression(array) && array.elements.some((element) => {
2902
- const part = unwrap(element);
2903
- if (!import_typescript5.default.isObjectLiteralExpression(part))
2904
- return false;
2905
- const type = propertyValue(part, "type");
2906
- return Boolean(type && import_typescript5.default.isStringLiteralLike(unwrap(type)) && unwrap(type).text === "text");
2907
- });
3041
+ if ((element.kind === "call" || element.kind === "external") && element.name) {
3042
+ for (const [pattern, role] of CONSTRUCTOR_ROLE)
3043
+ if (pattern.test(element.name))
3044
+ return role;
2908
3045
  }
2909
- if (propertyValue(object, "text") && object.properties.length <= 3)
2910
- return true;
2911
- const role = propertyValue(object, "role");
2912
- return Boolean(role && import_typescript5.default.isStringLiteralLike(unwrap(role)) && unwrap(role).text === "user" && (propertyValue(object, "content") || propertyValue(object, "parts")));
2913
- }
2914
- var clientChatSink = {
2915
- id: "client-chat",
2916
- sdk: "client-chat",
2917
- match(call, ctx) {
2918
- if (!import_typescript5.default.isCallExpression(call) || call.arguments.length === 0)
2919
- return;
2920
- const callee = unwrap(call.expression);
2921
- const binding = import_typescript5.default.isIdentifier(callee) ? valueDeclaration(resolvedSymbol(callee, ctx.checker)) : undefined;
2922
- const bound = binding && import_typescript5.default.isBindingElement(binding) && binding.propertyName ? propertyNameText(binding.propertyName) : undefined;
2923
- const name = bound ?? (import_typescript5.default.isIdentifier(callee) ? callee.text : import_typescript5.default.isPropertyAccessExpression(callee) ? callee.name.text : undefined);
2924
- if (!name || !CHAT_SEND.has(name))
2925
- return;
2926
- const argument = call.arguments[0];
2927
- if (import_typescript5.default.isSpreadElement(argument))
2928
- return;
2929
- const hooked = import_typescript5.default.isIdentifier(callee) ? fromChatHook(callee, ctx.checker) : fromChatHook(callee.expression, ctx.checker);
2930
- if (!hooked && !((name === "sendMessage" || name === "append") && looksLikeUiMessage(argument)))
2931
- return;
2932
- return { api: `chat.${name}`, roles: [{ role: "user", node: argument }] };
3046
+ if (PASS_THROUGH.has(element.kind)) {
3047
+ const roles = new Set(valueChildren(element).map((child) => elementRole(child, depth + 1)));
3048
+ return roles.size === 1 ? [...roles][0] : "unknown";
2933
3049
  }
2934
- };
2935
- var websocketSink = {
2936
- id: "websocket",
2937
- sdk: "websocket",
2938
- match(call, ctx) {
2939
- if (!import_typescript5.default.isNewExpression(call) || !call.arguments?.length)
2940
- return;
2941
- const callee = unwrap(call.expression);
2942
- if (!import_typescript5.default.isIdentifier(callee) || callee.text !== "WebSocket")
2943
- return;
2944
- const url = ctx.urlTexts(call.arguments[0]).find((candidate) => MODEL_SOCKET.test(candidate));
2945
- if (!url)
2946
- return;
2947
- const modelInUrl = urlModel(call.arguments[0], ctx.checker);
2948
- const roles = modelInUrl ? [{ role: "model", node: modelInUrl }] : /[?&]model=/.test(url) ? [{ role: "model", node: call.arguments[0], key: URL_MODEL_KEY }] : [];
2949
- return {
2950
- api: "websocket",
2951
- provider: /openai/.test(url) ? "openai" : /generativelanguage/.test(url) ? "google" : undefined,
2952
- roles
2953
- };
3050
+ return "unknown";
3051
+ }
3052
+ function containersOf(tree, containers, others, depth = 0) {
3053
+ if (containers.length >= MAX_CONTAINERS)
3054
+ return;
3055
+ if (tree.kind === "array" || tree.kind === "assembled" && tree.text !== "string") {
3056
+ containers.push(tree);
3057
+ return;
2954
3058
  }
2955
- };
2956
- function frameworkName(identifier, checker, member) {
2957
- if (!identifier)
3059
+ const flow = PASS_THROUGH.has(tree.kind) ? valueChildren(tree) : [];
3060
+ if (flow.length > 0 && depth < 12) {
3061
+ for (const child of flow)
3062
+ containersOf(child, containers, others, depth + 1);
2958
3063
  return;
2959
- const origin = importOrigin(identifier, checker);
2960
- if (origin) {
2961
- const name = origin.imported === "*" || origin.imported === "default" ? member ?? identifier.text : origin.imported;
2962
- return FRAMEWORK_MODULE.test(origin.module) && FRAMEWORK_BASES.has(name) ? { base: name, module: origin.module } : undefined;
2963
3064
  }
2964
- return;
3065
+ others.push(tree);
3066
+ }
3067
+ function splitMessages(tree) {
3068
+ const containers = [];
3069
+ const others = [];
3070
+ containersOf(tree, containers, others);
3071
+ if (containers.length === 0) {
3072
+ return [{ role: STRINGY.has(tree.kind) || others.length > 0 && others.every((other) => STRINGY.has(other.kind)) ? "user" : "unknown", tree }];
3073
+ }
3074
+ const out = [];
3075
+ for (const container of containers) {
3076
+ (container.children ?? []).forEach((element, index) => {
3077
+ out.push({ role: elementRole(element), tree: element, message: { arrayId: container.id, index } });
3078
+ });
3079
+ }
3080
+ for (const other of others)
3081
+ out.push({ role: STRINGY.has(other.kind) ? "user" : "unknown", tree: other });
3082
+ return out;
2965
3083
  }
2966
- function frameworkBaseOf(cls, checker, memo, depth = 0) {
2967
- const cached = memo.get(cls);
2968
- if (cached)
2969
- return cached;
2970
- const self = className(cls) ?? "(anonymous)";
2971
- const result = { chain: [self] };
2972
- memo.set(cls, result);
2973
- const heritage = cls.heritageClauses?.find((clause) => clause.token === import_typescript5.default.SyntaxKind.ExtendsKeyword)?.types[0];
2974
- if (!heritage || depth > 8)
2975
- return result;
2976
- const resolveExpression = (expression) => {
2977
- const expr = unwrap(expression);
2978
- if (import_typescript5.default.isCallExpression(expr)) {
2979
- for (const argument of expr.arguments) {
2980
- const found = resolveExpression(argument);
2981
- if (found?.base)
2982
- return found;
2983
- }
3084
+
3085
+ // src/harness-extract/program.ts
3086
+ var import_typescript5 = __toESM(require_typescript(), 1);
3087
+ import { createHash } from "node:crypto";
3088
+ import { readdirSync, statSync } from "node:fs";
3089
+ import { dirname, join, relative as relative2, resolve } from "node:path";
3090
+ var SKIPPED_DIRS2 = new Set(["node_modules", "dist", "build", "out", "vendor", "coverage", "graphify-out", "__pycache__"]);
3091
+ var CODE_FILE = /\.(?:[cm]?[jt]sx?)$/i;
3092
+ var SVELTE_FILE = /\.svelte$/i;
3093
+ var SCRIPT_BLOCK = /(<script\b[^>]*>)([\s\S]*?)<\/script\s*>/gi;
3094
+ function svelteScriptText(text) {
3095
+ const out = text.replace(/[^\n]/g, " ").split("");
3096
+ for (const match of text.matchAll(SCRIPT_BLOCK)) {
3097
+ const start = (match.index ?? 0) + match[1].length;
3098
+ for (let index = 0;index < match[2].length; index += 1)
3099
+ out[start + index] = match[2][index];
3100
+ }
3101
+ return out.join("");
3102
+ }
3103
+ var DECLARATION_FILE = /\.d\.[cm]?ts$/i;
3104
+ var TEST_RUNNER_FILE = /(?:^|\/)__tests__\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
3105
+ var TEST_PATH = /(?:^|\/)(?:test|tests|__tests__|test-fixtures|fixtures?|__fixtures__|__mocks__|e2e)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
3106
+ var EVAL_PATH = /(?:^|\/)evals?\/|\.evals?\.[cm]?[jt]sx?$/i;
3107
+ var MAX_FILE_BYTES = 1024 * 1024;
3108
+ var DEFAULT_MAX_FILES = 20000;
3109
+ function isTestPath(rel) {
3110
+ return TEST_PATH.test(rel);
3111
+ }
3112
+ function isEvalPath(rel) {
3113
+ return EVAL_PATH.test(rel);
3114
+ }
3115
+ function walkRepository(rootDir, maxFiles, includeTestRunnerFiles) {
3116
+ const files = [];
3117
+ const configs = [];
3118
+ let truncated = false;
3119
+ const walk = (abs, rel) => {
3120
+ let entries;
3121
+ try {
3122
+ entries = readdirSync(abs, { withFileTypes: true });
3123
+ } catch {
2984
3124
  return;
2985
3125
  }
2986
- const identifier = import_typescript5.default.isIdentifier(expr) ? expr : import_typescript5.default.isPropertyAccessExpression(expr) ? rootIdentifier(expr) : undefined;
2987
- const member = import_typescript5.default.isPropertyAccessExpression(expr) ? expr.name.text : undefined;
2988
- const direct = frameworkName(identifier, checker, member);
2989
- if (direct)
2990
- return { ...direct, chain: [direct.base] };
2991
- const declaration = valueDeclaration(resolvedSymbol(import_typescript5.default.isPropertyAccessExpression(expr) ? expr.name : expr, checker));
2992
- if (!declaration)
2993
- return;
2994
- if (import_typescript5.default.isClassDeclaration(declaration) || import_typescript5.default.isClassExpression(declaration))
2995
- return frameworkBaseOf(declaration, checker, memo, depth + 1);
2996
- const holder = import_typescript5.default.isBindingElement(declaration) ? declaration.parent.parent : declaration;
2997
- const name = import_typescript5.default.isBindingElement(declaration) ? propertyNameText(declaration.propertyName ?? declaration.name) : undefined;
2998
- if (import_typescript5.default.isVariableDeclaration(holder) && holder.initializer) {
2999
- const init = unwrap(holder.initializer);
3000
- if (import_typescript5.default.isClassExpression(init))
3001
- return frameworkBaseOf(init, checker, memo, depth + 1);
3002
- if (import_typescript5.default.isCallExpression(init)) {
3003
- for (const argument of init.arguments) {
3004
- const arg = unwrap(argument);
3005
- if (!import_typescript5.default.isIdentifier(arg))
3006
- continue;
3007
- const found = frameworkName(arg, checker, name);
3008
- if (found)
3009
- return { ...found, chain: [found.base] };
3010
- const nested = resolveExpression(arg);
3011
- if (nested?.base)
3012
- return nested;
3013
- }
3126
+ entries.sort((a, b) => a.name.localeCompare(b.name));
3127
+ for (const entry of entries) {
3128
+ if (files.length >= maxFiles) {
3129
+ truncated = true;
3130
+ return;
3014
3131
  }
3015
- if (import_typescript5.default.isIdentifier(init) || import_typescript5.default.isPropertyAccessExpression(init))
3016
- return resolveExpression(init);
3017
- }
3018
- return;
3019
- };
3020
- const parent = resolveExpression(heritage.expression);
3021
- if (parent) {
3022
- result.base = parent.base;
3023
- result.module = parent.module;
3024
- result.chain = [self, ...parent.chain];
3025
- } else {
3026
- result.chain = [self, heritage.expression.getText()];
3027
- }
3028
- return result;
3029
- }
3030
- function hookSink(memo) {
3031
- return {
3032
- id: "think-hook",
3033
- sdk: "think-hook",
3034
- match(cls, ctx) {
3035
- const info = frameworkBaseOf(cls, ctx.checker, memo);
3036
- if (!info.base || !HOOK_BASES.has(info.base))
3037
- return [];
3038
- const roles = [];
3039
- for (const member of cls.members) {
3040
- const name = propertyNameText(member.name);
3041
- if (!name || import_typescript5.default.getCombinedModifierFlags(member) & import_typescript5.default.ModifierFlags.Static)
3042
- continue;
3043
- if ((import_typescript5.default.isMethodDeclaration(member) || import_typescript5.default.isGetAccessorDeclaration(member)) && HOOK_METHODS[name] && member.body) {
3044
- roles.push({ role: HOOK_METHODS[name], node: member, values: returnExpressions(member) });
3045
- } else if (import_typescript5.default.isMethodDeclaration(member) && TURN_HOOKS.has(name) && member.body) {
3046
- const returns = returnExpressions(member);
3047
- for (const [key, role] of Object.entries(TURN_CONFIG_KEYS)) {
3048
- if (returns.some((ret) => {
3049
- const value = objectLiteralOf(ret, ctx.checker);
3050
- return value !== undefined && hasProperty(value, key);
3051
- })) {
3052
- roles.push({ role, node: member, values: returns, key });
3053
- }
3132
+ const childRel = rel ? `${rel}/${entry.name}` : entry.name;
3133
+ const childAbs = join(abs, entry.name);
3134
+ if (entry.isDirectory()) {
3135
+ if (!entry.name.startsWith(".") && !SKIPPED_DIRS2.has(entry.name))
3136
+ walk(childAbs, childRel);
3137
+ } else if (entry.isFile()) {
3138
+ if (entry.name === "tsconfig.json")
3139
+ configs.push(childAbs);
3140
+ else if (SVELTE_FILE.test(entry.name)) {
3141
+ try {
3142
+ if (statSync(childAbs).size <= MAX_FILE_BYTES)
3143
+ files.push(svelteVirtualName(childAbs));
3144
+ } catch {
3145
+ continue;
3054
3146
  }
3055
- } else if (import_typescript5.default.isPropertyDeclaration(member) && HOOK_PROPERTIES[name] && member.initializer) {
3056
- roles.push({ role: HOOK_PROPERTIES[name], node: member.initializer });
3147
+ } else if (CODE_FILE.test(entry.name) && !DECLARATION_FILE.test(entry.name) && !/\.min\.[cm]?js$/i.test(entry.name) && (includeTestRunnerFiles || !TEST_RUNNER_FILE.test(childRel))) {
3148
+ try {
3149
+ if (statSync(childAbs).size > MAX_FILE_BYTES)
3150
+ continue;
3151
+ } catch {
3152
+ continue;
3153
+ }
3154
+ files.push(childAbs);
3057
3155
  }
3058
3156
  }
3059
- if (roles.length === 0)
3060
- return [];
3061
- return [{ api: `${info.base === "Think" ? "think" : "agents"}.hook`, roles, anchor: cls.name ?? cls }];
3062
3157
  }
3063
3158
  };
3159
+ walk(rootDir, "");
3160
+ return { files, configs, truncated };
3064
3161
  }
3065
- function createFrameworkMemo() {
3066
- return new Map;
3067
- }
3068
- var HOSTED_MODEL_SDKS = [
3069
- { module: /^@fal-ai\/(?:client|serverless-client)$/, methods: new Set(["run", "subscribe", "stream"]), provider: "fal" },
3070
- { module: /^replicate$/, methods: new Set(["run", "stream"]), provider: "replicate" }
3071
- ];
3072
- var hostedModelSink = {
3073
- id: "hosted-model",
3074
- sdk: "hosted-model",
3075
- match(call, ctx) {
3076
- if (!import_typescript5.default.isCallExpression(call) || call.arguments.length === 0)
3077
- return;
3078
- const callee = unwrap(call.expression);
3079
- if (!import_typescript5.default.isPropertyAccessExpression(callee))
3080
- return;
3081
- const origin = valueOrigin(callee.expression, ctx.checker);
3082
- const sdk = origin && HOSTED_MODEL_SDKS.find((candidate) => candidate.module.test(origin.module) && candidate.methods.has(callee.name.text));
3083
- if (!sdk)
3084
- return;
3085
- const [model, options] = call.arguments;
3086
- const input = options ? objectLiteralOf(options, ctx.checker) : undefined;
3087
- const inner = input ? propertyValue(input, "input") : undefined;
3088
- return {
3089
- api: `${sdk.provider}.${callee.name.text}`,
3090
- provider: sdk.provider,
3091
- roles: [{ role: "model", node: model }, ...inner ? requestRoles(inner, { prompt: "prompt" }, ctx) : []]
3092
- };
3162
+ function sourceFingerprint(rootDir, options = {}) {
3163
+ const walked = walkRepository(resolve(rootDir), options.maxFiles ?? DEFAULT_MAX_FILES, options.includeTestRunnerFiles ?? false);
3164
+ const hash = createHash("sha1");
3165
+ const inputs = new Set([...walked.configs, ...walked.files.map((file) => file.endsWith(SVELTE_VIRTUAL_SUFFIX) ? file.slice(0, -SVELTE_VIRTUAL_SUFFIX.length) : file)]);
3166
+ for (const config of walked.configs) {
3167
+ const host = { ...import_typescript5.default.sys, onUnRecoverableConfigFileDiagnostic: () => {}, readFile: (file) => {
3168
+ inputs.add(file);
3169
+ return import_typescript5.default.sys.readFile(file);
3170
+ } };
3171
+ import_typescript5.default.getParsedCommandLineOfConfigFile(config, {}, host);
3093
3172
  }
3094
- };
3095
- var REALTIME_SEND = /send|emit|transmit|dispatch/i;
3096
- var realtimeEventSink = {
3097
- id: "realtime-event",
3098
- sdk: "realtime",
3099
- match(call, ctx) {
3100
- if (!import_typescript5.default.isCallExpression(call) || call.arguments.length !== 1)
3101
- return;
3102
- const callee = import_typescript5.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
3103
- if (!import_typescript5.default.isIdentifier(callee) || !REALTIME_SEND.test(callee.text))
3104
- return;
3105
- let sent = unwrap(call.arguments[0]);
3106
- if (import_typescript5.default.isCallExpression(sent) && sent.expression.getText() === "JSON.stringify" && sent.arguments[0])
3107
- sent = unwrap(sent.arguments[0]);
3108
- const argument = objectLiteralOf(sent, ctx.checker);
3109
- if (!argument)
3173
+ const metadata = (directory) => {
3174
+ let entries;
3175
+ try {
3176
+ entries = readdirSync(directory, { withFileTypes: true });
3177
+ } catch {
3110
3178
  return;
3111
- const type = propertyValue(argument, "type");
3112
- const kind = type && (import_typescript5.default.isStringLiteral(type) || import_typescript5.default.isNoSubstitutionTemplateLiteral(type)) ? type.text : undefined;
3113
- if (kind === "session.update") {
3114
- const session = propertyValue(argument, "session");
3115
- const object = session ? objectLiteralOf(session, ctx.checker) : undefined;
3116
- const instructions = object ? propertyValue(object, "instructions") : undefined;
3117
- return instructions ? { api: "realtime.session.update", provider: "openai", roles: [{ role: "system", node: instructions }] } : undefined;
3118
3179
  }
3119
- if (kind === "conversation.item.create") {
3120
- const item = propertyValue(argument, "item");
3121
- const object = item ? objectLiteralOf(item, ctx.checker) : undefined;
3122
- const role = object ? propertyValue(object, "role") : undefined;
3123
- const roleText = role && import_typescript5.default.isStringLiteral(role) ? role.text : undefined;
3124
- const content = object ? propertyValue(object, "content") : undefined;
3125
- if (!content || roleText !== "system" && roleText !== "user")
3126
- return;
3127
- return { api: "realtime.conversation.item.create", provider: "openai", roles: [{ role: roleText === "system" ? "system" : "messages", node: content }] };
3180
+ for (const entry of entries) {
3181
+ if (entry.isDirectory() && !entry.name.startsWith(".") && !SKIPPED_DIRS2.has(entry.name))
3182
+ metadata(join(directory, entry.name));
3183
+ else if (entry.isFile() && (entry.name === "package.json" || /^wrangler(?:\.[\w.-]+)?\.(?:json|jsonc|toml)$/.test(entry.name)))
3184
+ inputs.add(join(directory, entry.name));
3128
3185
  }
3129
- return;
3186
+ };
3187
+ metadata(resolve(rootDir));
3188
+ for (const file of [...inputs].sort()) {
3189
+ const text = import_typescript5.default.sys.readFile(file);
3190
+ hash.update(`${file}\x00${text ?? "missing"}
3191
+ `);
3130
3192
  }
3131
- };
3132
- function effectiveField(object, key) {
3133
- let last = -1;
3134
- object.properties.forEach((property, index) => {
3135
- if (!import_typescript5.default.isSpreadAssignment(property) && propertyNameText(property.name) === key)
3136
- last = index;
3137
- });
3138
- const fields = [];
3139
- const value = last >= 0 ? propertyValue(object, key) : undefined;
3140
- if (value)
3141
- fields.push({ node: value });
3142
- object.properties.forEach((property, index) => {
3143
- if (index > last && import_typescript5.default.isSpreadAssignment(property))
3144
- fields.push({ node: property.expression, key });
3145
- });
3146
- return fields;
3193
+ return hash.digest("hex");
3147
3194
  }
3148
- var WRITTEN_SYMBOLS = new WeakMap;
3149
- function writtenSymbols(file, checker) {
3150
- let written = WRITTEN_SYMBOLS.get(file);
3151
- if (written)
3152
- return written;
3153
- const found = new Set;
3154
- const add = (node) => {
3155
- const root = rootIdentifier(node);
3156
- const symbol = root ? resolvedSymbol(root, checker) : undefined;
3157
- if (symbol)
3158
- found.add(symbol);
3195
+ function extractorOptions(base) {
3196
+ const options = {
3197
+ ...base,
3198
+ noEmit: true,
3199
+ skipLibCheck: true,
3200
+ noLib: true,
3201
+ types: [],
3202
+ noResolve: false,
3203
+ allowJs: true,
3204
+ checkJs: false,
3205
+ resolveJsonModule: false,
3206
+ declaration: false,
3207
+ composite: false,
3208
+ incremental: false,
3209
+ tsBuildInfoFile: undefined,
3210
+ plugins: undefined
3159
3211
  };
3160
- const visit = (node) => {
3161
- if (import_typescript5.default.isBinaryExpression(node) && node.operatorToken.kind >= import_typescript5.default.SyntaxKind.FirstAssignment && node.operatorToken.kind <= import_typescript5.default.SyntaxKind.LastAssignment)
3162
- add(node.left);
3163
- else if (import_typescript5.default.isDeleteExpression(node))
3164
- add(node.expression);
3165
- else if ((import_typescript5.default.isPrefixUnaryExpression(node) || import_typescript5.default.isPostfixUnaryExpression(node)) && (node.operator === import_typescript5.default.SyntaxKind.PlusPlusToken || node.operator === import_typescript5.default.SyntaxKind.MinusMinusToken))
3166
- add(node.operand);
3167
- else if (import_typescript5.default.isCallExpression(node) && node.arguments.length > 0) {
3168
- const callee = unwrap(node.expression);
3169
- if (import_typescript5.default.isPropertyAccessExpression(callee) && callee.name.text === "assign")
3170
- add(node.arguments[0]);
3212
+ if (options.moduleResolution === undefined) {
3213
+ options.module = import_typescript5.default.ModuleKind.ESNext;
3214
+ options.moduleResolution = import_typescript5.default.ModuleResolutionKind.Bundler;
3215
+ }
3216
+ options.allowImportingTsExtensions = true;
3217
+ return options;
3218
+ }
3219
+ var FALLBACK_OPTIONS = extractorOptions({
3220
+ target: import_typescript5.default.ScriptTarget.ES2022,
3221
+ jsx: import_typescript5.default.JsxEmit.Preserve,
3222
+ esModuleInterop: true
3223
+ });
3224
+ function sharedHost(options, cache) {
3225
+ const host = import_typescript5.default.createCompilerHost(options, true);
3226
+ const moduleCache = import_typescript5.default.createModuleResolutionCache(host.getCurrentDirectory(), (name) => name, options);
3227
+ host.getSourceFile = (fileName, languageVersionOrOptions) => {
3228
+ const version = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions.languageVersion : languageVersionOrOptions;
3229
+ const key = `${version}:${fileName}`;
3230
+ if (cache.has(key))
3231
+ return cache.get(key);
3232
+ let source;
3233
+ const svelte = fileName.endsWith(SVELTE_VIRTUAL_SUFFIX);
3234
+ const raw = import_typescript5.default.sys.readFile(svelte ? fileName.slice(0, -SVELTE_VIRTUAL_SUFFIX.length) : fileName);
3235
+ const text = svelte && raw !== undefined ? svelteScriptText(raw) : raw;
3236
+ if (text !== undefined && text.length <= MAX_FILE_BYTES) {
3237
+ source = import_typescript5.default.createSourceFile(fileName, text, languageVersionOrOptions, true, svelte ? import_typescript5.default.ScriptKind.TS : undefined);
3171
3238
  }
3172
- import_typescript5.default.forEachChild(node, visit);
3239
+ cache.set(key, source);
3240
+ return source;
3173
3241
  };
3174
- visit(file);
3175
- written = found;
3176
- WRITTEN_SYMBOLS.set(file, written);
3177
- return written;
3242
+ host.resolveModuleNameLiterals = (literals, containingFile, redirected, compilerOptions) => literals.map((literal) => {
3243
+ const resolved = import_typescript5.default.resolveModuleName(literal.text, containingFile, compilerOptions, host, moduleCache, redirected).resolvedModule;
3244
+ if (!resolved || resolved.isExternalLibraryImport || /[\\/]node_modules[\\/]/.test(resolved.resolvedFileName) || DECLARATION_FILE.test(resolved.resolvedFileName) || !CODE_FILE.test(resolved.resolvedFileName)) {
3245
+ return { resolvedModule: undefined };
3246
+ }
3247
+ return { resolvedModule: resolved };
3248
+ });
3249
+ const fileExists = host.fileExists.bind(host);
3250
+ host.fileExists = (fileName) => fileName.endsWith(SVELTE_VIRTUAL_SUFFIX) ? fileExists(fileName.slice(0, -SVELTE_VIRTUAL_SUFFIX.length)) : fileExists(fileName);
3251
+ host.writeFile = () => {};
3252
+ return host;
3178
3253
  }
3179
- function gatewayRequestLiteral(argument, checker) {
3180
- const value = unwrap(argument);
3181
- if (import_typescript5.default.isObjectLiteralExpression(value))
3182
- return value;
3183
- if (!import_typescript5.default.isIdentifier(value))
3184
- return;
3185
- const symbol = resolvedSymbol(value, checker);
3186
- const declaration = valueDeclaration(symbol);
3187
- if (!symbol || !declaration || !import_typescript5.default.isVariableDeclaration(declaration) || !declaration.initializer)
3188
- return;
3189
- if (!(import_typescript5.default.getCombinedNodeFlags(declaration) & import_typescript5.default.NodeFlags.Const))
3190
- return;
3191
- const literal = unwrap(declaration.initializer);
3192
- if (!import_typescript5.default.isObjectLiteralExpression(literal))
3254
+ var NO_INPUTS_FOUND = 18003;
3255
+ function parseConfig(configPath, warnings, rootDir) {
3256
+ const rel = relative2(rootDir, configPath).split("\\").join("/");
3257
+ const read = import_typescript5.default.readConfigFile(configPath, import_typescript5.default.sys.readFile);
3258
+ if (read.error || !read.config || typeof read.config !== "object") {
3259
+ warnings.push(`tsconfig ${rel}: unreadable, its files fall back to the default program`);
3193
3260
  return;
3194
- return writtenSymbols(declaration.getSourceFile(), checker).has(symbol) ? undefined : literal;
3261
+ }
3262
+ const raw = read.config;
3263
+ const parsed = import_typescript5.default.parseJsonConfigFileContent(read.config, import_typescript5.default.sys, dirname(configPath), undefined, configPath);
3264
+ const errors = parsed.errors.filter((error) => error.code !== NO_INPUTS_FOUND);
3265
+ if (errors.length > 0) {
3266
+ const messages = errors.slice(0, 3).map((error) => import_typescript5.default.flattenDiagnosticMessageText(error.messageText, " "));
3267
+ warnings.push(`tsconfig ${rel}: ${messages.join("; ")}${errors.length > 3 ? ` (+${errors.length - 3} more)` : ""}; extraction continues with the options that parsed`);
3268
+ }
3269
+ const explicit = raw.include !== undefined || raw.files !== undefined || parsed.raw && (parsed.raw.include !== undefined || parsed.raw.files !== undefined);
3270
+ return { options: parsed.options, fileNames: explicit ? parsed.fileNames.map((name) => resolve(name)) : undefined };
3195
3271
  }
3196
- var GATEWAY_METHODS = new Set(["call", "stream"]);
3197
- var GATEWAY_BODY_KEYS = { system: "system", messages: "messages", prompt: "prompt", model: "model", tools: "tools" };
3198
- var modelGatewaySink = {
3199
- id: "model-gateway",
3200
- sdk: "model-gateway",
3201
- match(call, ctx) {
3202
- if (!import_typescript5.default.isCallExpression(call) || call.arguments.length !== 1)
3203
- return;
3204
- const callee = unwrap(call.expression);
3205
- if (!import_typescript5.default.isPropertyAccessExpression(callee) || !GATEWAY_METHODS.has(callee.name.text))
3206
- return;
3207
- const receiver = unwrap(callee.expression);
3208
- if (!import_typescript5.default.isPropertyAccessExpression(receiver) || receiver.name.text !== "models")
3209
- return;
3210
- const request = gatewayRequestLiteral(call.arguments[0], ctx.checker);
3211
- if (!request || !propertyValue(request, "kind"))
3272
+ function isUnder(file, dir) {
3273
+ const rel = relative2(dir, file);
3274
+ return rel !== "" && !rel.startsWith("..") && !rel.startsWith("/");
3275
+ }
3276
+ function buildPrograms(rootDir, options = {}) {
3277
+ const root = resolve(rootDir);
3278
+ const maxFiles = options.maxFiles ?? DEFAULT_MAX_FILES;
3279
+ const warnings = [];
3280
+ const walked = walkRepository(root, maxFiles, options.includeTestRunnerFiles ?? false);
3281
+ if (walked.truncated)
3282
+ warnings.push(`file cap reached: only the first ${maxFiles} code files are scanned`);
3283
+ const known = new Set(walked.files);
3284
+ const configDirs = walked.configs.map((path) => dirname(path));
3285
+ const assigned = new Set;
3286
+ const cache = new Map;
3287
+ const entries = [];
3288
+ const owner = new Map;
3289
+ const create = (rootNames, owned, compilerOptions, configPath) => {
3290
+ const host = sharedHost(compilerOptions, cache);
3291
+ let program;
3292
+ try {
3293
+ program = import_typescript5.default.createProgram({ rootNames, options: compilerOptions, host });
3294
+ } catch (error) {
3295
+ warnings.push(`program ${configPath ?? "(fallback)"}: ${error.message}`);
3212
3296
  return;
3213
- const roles = [];
3214
- for (const body of effectiveField(request, "body")) {
3215
- for (const [key, role] of Object.entries(GATEWAY_BODY_KEYS)) {
3216
- if (body.key) {
3217
- roles.push({ role, node: body.node, key: `${body.key}.${key}` });
3218
- continue;
3219
- }
3220
- const literal = unwrap(body.node);
3221
- if (!import_typescript5.default.isObjectLiteralExpression(literal)) {
3222
- roles.push({ role, node: body.node, key });
3223
- continue;
3224
- }
3225
- for (const field of effectiveField(literal, key))
3226
- roles.push({ role, ...field });
3227
- }
3228
3297
  }
3229
- for (const field of effectiveField(request, "prompt"))
3230
- roles.push({ role: "prompt", ...field });
3231
- return roles.length > 0 ? { api: `models.${callee.name.text}`, roles } : undefined;
3298
+ let checker;
3299
+ const entry = {
3300
+ program,
3301
+ configPath,
3302
+ owned,
3303
+ checker: () => checker ??= program.getTypeChecker()
3304
+ };
3305
+ entries.push(entry);
3306
+ for (const file of owned)
3307
+ owner.set(file, entry);
3308
+ };
3309
+ const configs = [...walked.configs].sort((a, b) => b.split(/[\\/]/).length - a.split(/[\\/]/).length || a.localeCompare(b));
3310
+ for (const configPath of configs) {
3311
+ const parsed = parseConfig(configPath, warnings, root);
3312
+ if (!parsed)
3313
+ continue;
3314
+ const dir = dirname(configPath);
3315
+ const nested = configDirs.filter((other) => other !== dir && isUnder(other, dir));
3316
+ const underDir = (file) => isUnder(file, dir) && !nested.some((other) => isUnder(file, other));
3317
+ const included = parsed.fileNames ? [...parsed.fileNames.filter((file) => known.has(file)), ...walked.files.filter((file) => file.endsWith(SVELTE_VIRTUAL_SUFFIX) && underDir(file))] : walked.files.filter(underDir);
3318
+ const owned = included.filter((file) => !assigned.has(file));
3319
+ if (owned.length === 0)
3320
+ continue;
3321
+ for (const file of owned)
3322
+ assigned.add(file);
3323
+ create(included, owned, extractorOptions(parsed.options), relative2(root, configPath).split("\\").join("/"));
3232
3324
  }
3233
- };
3234
- var CALL_SINKS = [modelGatewaySink, realtimeEventSink, anthropicSink, openaiSink, aiSdkSink, workersAiSink, fetchSink, websocketSink, providerFactorySink, agentEntrySink, clientChatSink, hostedModelSink];
3235
- function registerCallSink(recognizer) {
3236
- CALL_SINKS.push(recognizer);
3237
- }
3238
- function classSinks(memo) {
3239
- return [hookSink(memo), ...EXTRA_CLASS_SINKS];
3240
- }
3241
- var EXTRA_CLASS_SINKS = [];
3242
- function registerClassSink(recognizer) {
3243
- EXTRA_CLASS_SINKS.push(recognizer);
3325
+ const rest = walked.files.filter((file) => !assigned.has(file));
3326
+ if (rest.length > 0)
3327
+ create(rest, rest, FALLBACK_OPTIONS);
3328
+ return { rootDir: root, entries, owner, files: assigned.size + rest.length, warnings };
3244
3329
  }
3245
3330
 
3246
3331
  // src/harness-extract/emit-models.ts
@@ -17638,9 +17723,10 @@ function promoteEvalSuites(files, confidence2, naming) {
17638
17723
  var import_typescript8 = __toESM(require_typescript(), 1);
17639
17724
  import { dirname as dirname7, relative as relative8, resolve as resolvePath } from "node:path";
17640
17725
  var DEFAULT_MAX_DEPTH = 24;
17641
- var DEFAULT_MAX_PARAM_LEVELS = 3;
17726
+ var DEFAULT_MAX_PARAM_LEVELS = 8;
17642
17727
  var PROMPT_FIELDS = new Set([
17643
17728
  "content",
17729
+ "parts",
17644
17730
  "text",
17645
17731
  "system",
17646
17732
  "prompt",
@@ -18020,6 +18106,18 @@ class PromptResolver {
18020
18106
  return;
18021
18107
  }
18022
18108
  if (import_typescript8.default.isArrayLiteralExpression(expr)) {
18109
+ if (/^\d+$/.test(walk.project[0] ?? "")) {
18110
+ const [index, ...rest] = walk.project;
18111
+ const selected = Number(index);
18112
+ if (expr.elements.slice(0, selected + 1).some(import_typescript8.default.isSpreadElement)) {
18113
+ this.markUnresolved(expr, "dynamic-key", walk);
18114
+ return;
18115
+ }
18116
+ const element = expr.elements[selected];
18117
+ if (element)
18118
+ this.value(element, owner, { ...walk, project: rest });
18119
+ return;
18120
+ }
18023
18121
  for (const element of expr.elements) {
18024
18122
  this.value(import_typescript8.default.isSpreadElement(element) ? element.expression : element, owner, walk);
18025
18123
  }
@@ -18077,6 +18175,48 @@ class PromptResolver {
18077
18175
  }
18078
18176
  return;
18079
18177
  }
18178
+ if (walk.messageParts) {
18179
+ const field = (expression, key, seen = new Set) => {
18180
+ const node = unwrap2(expression);
18181
+ if (seen.has(node))
18182
+ return { known: false };
18183
+ const next = new Set(seen).add(node);
18184
+ if (import_typescript8.default.isIdentifier(node)) {
18185
+ const declaration = this.declarationsOf(node).find((entry) => import_typescript8.default.isVariableDeclaration(entry) && entry.initializer);
18186
+ return declaration && import_typescript8.default.isVariableDeclaration(declaration) && declaration.initializer ? field(declaration.initializer, key, next) : { known: false };
18187
+ }
18188
+ if (!import_typescript8.default.isObjectLiteralExpression(node))
18189
+ return { known: false };
18190
+ for (const property of [...node.properties].reverse()) {
18191
+ if (import_typescript8.default.isSpreadAssignment(property)) {
18192
+ const spread = field(property.expression, key, next);
18193
+ if (spread.value || !spread.known)
18194
+ return spread;
18195
+ } else if (propertyName(property) === key) {
18196
+ return { known: true, value: import_typescript8.default.isPropertyAssignment(property) ? property.initializer : import_typescript8.default.isShorthandPropertyAssignment(property) ? property.name : undefined };
18197
+ }
18198
+ }
18199
+ return { known: true };
18200
+ };
18201
+ const literalString = (expression, seen = new Set) => {
18202
+ if (!expression || seen.has(expression))
18203
+ return;
18204
+ const node = unwrap2(expression);
18205
+ if (import_typescript8.default.isStringLiteralLike(node))
18206
+ return node.text;
18207
+ if (!import_typescript8.default.isIdentifier(node))
18208
+ return;
18209
+ const declaration = this.declarationsOf(node).find((entry) => import_typescript8.default.isVariableDeclaration(entry) && entry.initializer);
18210
+ return declaration && import_typescript8.default.isVariableDeclaration(declaration) ? literalString(declaration.initializer, new Set(seen).add(expression)) : undefined;
18211
+ };
18212
+ const partType = literalString(field(object, "type").value);
18213
+ if (partType === "text" || partType === "input_text") {
18214
+ const text = field(object, "text").value;
18215
+ if (text)
18216
+ this.value(text, { node: text, kind: "message" }, { ...walk, messageParts: false, promptObject: false });
18217
+ }
18218
+ return;
18219
+ }
18080
18220
  const role = stringField(object, "role");
18081
18221
  if (role && /^(?:assistant|tool|function|model)$/.test(role))
18082
18222
  return;
@@ -18095,7 +18235,7 @@ class PromptResolver {
18095
18235
  }
18096
18236
  continue;
18097
18237
  }
18098
- const inner = PROMPT_FIELDS.has(key) && !/^(?:content|text|messages|user|system|prompt)$/.test(key) ? { ...walk, promptObject: true } : walk;
18238
+ const inner = key === "parts" ? { ...walk, messageParts: true, promptObject: false } : PROMPT_FIELDS.has(key) && !/^(?:content|text|messages|user|system|prompt)$/.test(key) ? { ...walk, promptObject: true } : walk;
18099
18239
  if (import_typescript8.default.isPropertyAssignment(property)) {
18100
18240
  const kind = role ? "message" : "literal";
18101
18241
  this.value(property.initializer, { node: property, name: role ? undefined : key, kind }, this.messageRole(inner, role));
@@ -18143,7 +18283,7 @@ class PromptResolver {
18143
18283
  this.declaration(declaration, access, owner, walk);
18144
18284
  return;
18145
18285
  }
18146
- if (walk.project.length === 0 && !PROMPT_FIELD_NAME.test(access.name.text))
18286
+ if (walk.project.length === 0 && !PROMPT_FIELD_NAME.test(access.name.text) && !(walk.role !== "tool-result" && /^messages?$/.test(access.name.text)))
18147
18287
  return;
18148
18288
  this.value(access.expression, owner, { ...flag(walk, "projected"), project: [access.name.text, ...walk.project] });
18149
18289
  }
@@ -18185,7 +18325,7 @@ class PromptResolver {
18185
18325
  }
18186
18326
  }
18187
18327
  call(call, owner, walk) {
18188
- const callee = call.expression;
18328
+ const callee = unwrap2(call.expression);
18189
18329
  if (import_typescript8.default.isPropertyAccessExpression(callee)) {
18190
18330
  const method = callee.name.text;
18191
18331
  if (method === "finally") {
@@ -18220,7 +18360,24 @@ class PromptResolver {
18220
18360
  this.value(argument, owner, walk);
18221
18361
  return;
18222
18362
  }
18363
+ if (import_typescript8.default.isArrowFunction(callee) || import_typescript8.default.isFunctionExpression(callee)) {
18364
+ const next = this.step(walk, callee, `immediately invoked builder at ${this.where(call)}`);
18365
+ if (!next || walk.seen.has(callee))
18366
+ return;
18367
+ next.bindings = new Map(next.bindings);
18368
+ bindParameters(callee, call.arguments, walk.bindings, next.bindings);
18369
+ this.builderBody(callee, { node: callee, kind: "builder" }, next);
18370
+ return;
18371
+ }
18372
+ if (import_typescript8.default.isPropertyAccessExpression(callee) && /^Promise\.(?:resolve|all)$/.test(callee.getText()) && call.arguments[0]) {
18373
+ this.value(call.arguments[0], owner, walk);
18374
+ return;
18375
+ }
18223
18376
  const declarations = this.declarationsOf(import_typescript8.default.isPropertyAccessExpression(callee) ? callee.name : callee);
18377
+ if (call.arguments.length === 0 && declarations.some((declaration) => import_typescript8.default.isParameter(declaration) || import_typescript8.default.isBindingElement(declaration) && isParameterBinding(declaration))) {
18378
+ this.value(callee, owner, walk);
18379
+ return;
18380
+ }
18224
18381
  let functions = declarations.map(functionOf).filter((fn) => Boolean(fn));
18225
18382
  if (functions.length === 0 && import_typescript8.default.isPropertyAccessExpression(callee)) {
18226
18383
  const methods = this.methodsNamed(callee.name.text);
@@ -18279,16 +18436,110 @@ class PromptResolver {
18279
18436
  if (!next)
18280
18437
  return;
18281
18438
  next.seen = new Set(next.seen).add(declaration);
18439
+ if (import_typescript8.default.isBindingElement(declaration)) {
18440
+ const fields = [];
18441
+ let current = declaration;
18442
+ let root;
18443
+ for (;; ) {
18444
+ const pattern = current.parent;
18445
+ if (!import_typescript8.default.isObjectBindingPattern(pattern) && !import_typescript8.default.isArrayBindingPattern(pattern))
18446
+ break;
18447
+ if (current.dotDotDotToken) {
18448
+ if (!import_typescript8.default.isObjectBindingPattern(pattern) || next.project.length === 0 || pattern.elements.some((entry) => entry !== current && bindingField(entry) === next.project[0])) {
18449
+ this.markUnresolved(at, "dynamic-key", next);
18450
+ return;
18451
+ }
18452
+ } else {
18453
+ const field = import_typescript8.default.isArrayBindingPattern(pattern) ? String(pattern.elements.indexOf(current)) : bindingField(current);
18454
+ if (field === undefined)
18455
+ break;
18456
+ fields.unshift(field);
18457
+ }
18458
+ const holder = pattern.parent;
18459
+ if (import_typescript8.default.isVariableDeclaration(holder)) {
18460
+ root = holder;
18461
+ break;
18462
+ }
18463
+ if (!import_typescript8.default.isBindingElement(holder))
18464
+ break;
18465
+ current = holder;
18466
+ }
18467
+ if (declaration.initializer) {
18468
+ const checker = this.context.checkerFor(this.relative(declaration.getSourceFile().fileName));
18469
+ let selected = root?.initializer && checker?.getTypeAtLocation(root.initializer);
18470
+ let optional = false;
18471
+ for (const field of fields) {
18472
+ const property = selected?.getProperty(field);
18473
+ optional ||= !!property && (property.flags & import_typescript8.default.SymbolFlags.Optional) !== 0 && !(root?.initializer && import_typescript8.default.isObjectLiteralExpression(unwrap2(root.initializer)));
18474
+ selected = property && checker ? checker.getTypeOfSymbolAtLocation(property, root.initializer) : undefined;
18475
+ }
18476
+ let literal = root?.initializer ? unwrap2(root.initializer) : undefined;
18477
+ for (const field of fields) {
18478
+ if (literal && import_typescript8.default.isObjectLiteralExpression(literal)) {
18479
+ const property = literal.properties.find((entry) => propertyName(entry) === field);
18480
+ literal = property && import_typescript8.default.isPropertyAssignment(property) ? unwrap2(property.initializer) : property && import_typescript8.default.isShorthandPropertyAssignment(property) ? property.name : undefined;
18481
+ } else if (literal && import_typescript8.default.isArrayLiteralExpression(literal)) {
18482
+ const element = literal.elements[Number(field)];
18483
+ literal = element && !import_typescript8.default.isOmittedExpression(element) && !import_typescript8.default.isSpreadElement(element) ? unwrap2(element) : undefined;
18484
+ } else
18485
+ literal = undefined;
18486
+ }
18487
+ if (literal && checker) {
18488
+ selected = checker.getTypeAtLocation(literal);
18489
+ optional = false;
18490
+ }
18491
+ const mayBeUndefined = optional || !selected || (selected.flags & (import_typescript8.default.TypeFlags.Any | import_typescript8.default.TypeFlags.Unknown | import_typescript8.default.TypeFlags.Undefined | import_typescript8.default.TypeFlags.Void)) !== 0 || selected.isUnion() && selected.types.some((type) => (type.flags & (import_typescript8.default.TypeFlags.Undefined | import_typescript8.default.TypeFlags.Void)) !== 0);
18492
+ if (mayBeUndefined)
18493
+ this.value(declaration.initializer, owner, next);
18494
+ }
18495
+ if (root?.initializer)
18496
+ this.value(root.initializer, owner, { ...next, project: [...fields, ...next.project] });
18497
+ else
18498
+ this.markUnresolved(at, "param-unbound", next);
18499
+ return;
18500
+ }
18282
18501
  if (import_typescript8.default.isVariableDeclaration(declaration)) {
18502
+ if (!owner && next.flags.includes("interpolated") && declaration.initializer) {
18503
+ let scope = declaration.parent;
18504
+ while (scope && !import_typescript8.default.isFunctionLike(scope))
18505
+ scope = scope.parent;
18506
+ const pieces = [];
18507
+ const fragment = (node) => {
18508
+ const value = unwrap2(node);
18509
+ if (import_typescript8.default.isStringLiteral(value) || import_typescript8.default.isNoSubstitutionTemplateLiteral(value)) {
18510
+ pieces.push(value.text);
18511
+ return true;
18512
+ }
18513
+ if (import_typescript8.default.isTemplateExpression(value)) {
18514
+ pieces.push(value.head.text, ...value.templateSpans.map((span) => span.literal.text));
18515
+ return true;
18516
+ }
18517
+ if (import_typescript8.default.isConditionalExpression(value))
18518
+ return fragment(value.whenTrue) && fragment(value.whenFalse);
18519
+ return false;
18520
+ };
18521
+ const localFragment = fragment(declaration.initializer);
18522
+ const instructionPieces = pieces.map((piece) => piece.replace(/\byou\b(?!['’](?:re|ve|ll|d)\b|\s+(?:are|must|should|need|will|can|may|have to)\b)/gi, ""));
18523
+ if (scope && import_typescript8.default.isFunctionLike(scope) && contains(scope, at) && localFragment && !hasDirective(instructionPieces.join(`
18524
+ `)) && !toolResultIsPrompt(declaration, instructionPieces)) {
18525
+ const fnName = scope.name && import_typescript8.default.isIdentifier(scope.name) ? scope.name.text : undefined;
18526
+ owner = { node: scope, name: fnName, kind: "builder" };
18527
+ }
18528
+ }
18283
18529
  if (declaration.initializer) {
18284
18530
  const fn2 = unwrap2(declaration.initializer);
18285
18531
  if (import_typescript8.default.isArrowFunction(fn2) || import_typescript8.default.isFunctionExpression(fn2)) {
18286
18532
  this.builderBody(fn2, { node: declaration, name, kind: "builder" }, next);
18287
18533
  } else {
18288
- this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
18534
+ const source = unwrap2(declaration.initializer);
18535
+ const checker = this.context.checkerFor(this.relative(source.getSourceFile().fileName));
18536
+ const sourceType = checker?.getTypeAtLocation(source);
18537
+ const sharesArray = sourceType && checker && (sourceType.isUnion() ? sourceType.types : [sourceType]).every((type) => checker.isArrayType(type) || checker.isTupleType(type));
18538
+ const aliasWalk = import_typescript8.default.isIdentifier(source) && sharesArray ? { ...next, assemblyReadAt: next.assemblyReadAt ?? at } : { ...next, assemblyReadAt: undefined };
18539
+ this.value(declaration.initializer, ownerFor(declaration, name, owner), aliasWalk);
18289
18540
  }
18290
18541
  }
18291
- this.assembly(declaration, ownerFor(declaration, name, owner), next);
18542
+ this.assembly(declaration, ownerFor(declaration, name, owner), next, at);
18292
18543
  return;
18293
18544
  }
18294
18545
  if (import_typescript8.default.isPropertyAssignment(declaration)) {
@@ -18321,21 +18572,177 @@ class PromptResolver {
18321
18572
  if (fn)
18322
18573
  this.builderBody(fn, { node: declaration, name, kind: "builder" }, next);
18323
18574
  }
18324
- assembly(declaration, owner, walk) {
18575
+ assembly(declaration, owner, walk, at) {
18325
18576
  if (!import_typescript8.default.isIdentifier(declaration.name))
18326
18577
  return;
18327
- const name = declaration.name.text;
18328
18578
  const scope = enclosingScope2(declaration);
18329
18579
  if (!scope)
18330
18580
  return;
18331
- const isThis = (identifier) => identifier.text === name && this.declarationsOf(identifier).includes(declaration);
18581
+ const assignments = [];
18582
+ const findRebinding = (node) => {
18583
+ if (import_typescript8.default.isFunctionLike(node))
18584
+ return;
18585
+ if (import_typescript8.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript8.default.SyntaxKind.EqualsToken && import_typescript8.default.isIdentifier(node.left) && this.declarationsOf(node.left).includes(declaration))
18586
+ assignments.push(node);
18587
+ import_typescript8.default.forEachChild(node, findRebinding);
18588
+ };
18589
+ findRebinding(scope);
18590
+ const conditional = (assignment) => {
18591
+ for (let node = assignment.parent;node && node !== scope; node = node.parent) {
18592
+ if (import_typescript8.default.isIfStatement(node) || import_typescript8.default.isConditionalExpression(node) || import_typescript8.default.isSwitchStatement(node) || import_typescript8.default.isIterationStatement(node, false) || import_typescript8.default.isTryStatement(node))
18593
+ return true;
18594
+ }
18595
+ return false;
18596
+ };
18597
+ const loopAncestors = (node) => {
18598
+ const loops = new Set;
18599
+ for (let parent = node.parent;parent && parent !== scope; parent = parent.parent) {
18600
+ if (import_typescript8.default.isFunctionLike(parent))
18601
+ break;
18602
+ if (import_typescript8.default.isIterationStatement(parent, false))
18603
+ loops.add(parent);
18604
+ }
18605
+ return loops;
18606
+ };
18607
+ const versionsAt = (node) => {
18608
+ const versions = new Set([declaration]);
18609
+ const loops = loopAncestors(node);
18610
+ for (const assignment of assignments) {
18611
+ const loopBack = [...loopAncestors(assignment)].some((loop) => loops.has(loop));
18612
+ if (assignment.end > node.getStart() && !loopBack)
18613
+ continue;
18614
+ if (!conditional(assignment))
18615
+ versions.clear();
18616
+ versions.add(assignment);
18617
+ }
18618
+ return versions;
18619
+ };
18620
+ const identities = (expression, seen = new Set) => {
18621
+ const value = unwrap2(expression);
18622
+ if (seen.has(value))
18623
+ return new Set;
18624
+ const next = new Set(seen).add(value);
18625
+ if (import_typescript8.default.isIdentifier(value)) {
18626
+ const entry = this.declarationsOf(value).find((item) => import_typescript8.default.isVariableDeclaration(item));
18627
+ if (entry === declaration)
18628
+ return versionsAt(value);
18629
+ if (entry && import_typescript8.default.isVariableDeclaration(entry) && entry.initializer && entry.parent.flags & import_typescript8.default.NodeFlags.Const)
18630
+ return identities(entry.initializer, next);
18631
+ return new Set;
18632
+ }
18633
+ if (import_typescript8.default.isConditionalExpression(value))
18634
+ return new Set([...identities(value.whenTrue, next), ...identities(value.whenFalse, next)]);
18635
+ if (import_typescript8.default.isBinaryExpression(value) && (value.operatorToken.kind === import_typescript8.default.SyntaxKind.BarBarToken || value.operatorToken.kind === import_typescript8.default.SyntaxKind.QuestionQuestionToken))
18636
+ return new Set([...identities(value.left, next), ...identities(value.right, next)]);
18637
+ return new Set;
18638
+ };
18639
+ const readVersions = new Map([...versionsAt(at)].map((version) => [version, (walk.assemblyReadAt ?? at).getStart()]));
18640
+ for (let round = 0;round < 8; round += 1) {
18641
+ let changed = false;
18642
+ for (const [version] of [...readVersions]) {
18643
+ if (!import_typescript8.default.isBinaryExpression(version))
18644
+ continue;
18645
+ const predecessors = new Set;
18646
+ const visit2 = (node) => {
18647
+ if (import_typescript8.default.isFunctionLike(node))
18648
+ return;
18649
+ if (import_typescript8.default.isIdentifier(node))
18650
+ for (const identity2 of identities(node))
18651
+ predecessors.add(identity2);
18652
+ import_typescript8.default.forEachChild(node, visit2);
18653
+ };
18654
+ visit2(version.right);
18655
+ for (const previous of predecessors) {
18656
+ const cutoff = version.getStart();
18657
+ if ((readVersions.get(previous) ?? -1) < cutoff) {
18658
+ readVersions.set(previous, cutoff);
18659
+ changed = true;
18660
+ }
18661
+ }
18662
+ }
18663
+ if (!changed)
18664
+ break;
18665
+ }
18666
+ const references = (expression) => [...identities(expression)].some((version) => (readVersions.get(version) ?? -1) >= expression.getStart());
18667
+ const invoked = (fn, seen = new Set) => {
18668
+ if (seen.has(fn))
18669
+ return false;
18670
+ const next = new Set(seen).add(fn);
18671
+ let expression = fn;
18672
+ while (import_typescript8.default.isParenthesizedExpression(expression.parent))
18673
+ expression = expression.parent;
18674
+ const parentCall = expression.parent;
18675
+ const reachableCall = (call) => {
18676
+ if (call.getSourceFile() !== scope.getSourceFile() || !contains(scope, call))
18677
+ return false;
18678
+ for (let parent = call.parent;parent && parent !== scope; parent = parent.parent) {
18679
+ if (import_typescript8.default.isFunctionLike(parent))
18680
+ return invoked(parent, next);
18681
+ }
18682
+ return true;
18683
+ };
18684
+ if (import_typescript8.default.isCallExpression(parentCall)) {
18685
+ if (parentCall.expression === expression)
18686
+ return reachableCall(parentCall);
18687
+ if (import_typescript8.default.isPropertyAccessExpression(parentCall.expression) && parentCall.arguments.some((argument) => argument === expression)) {
18688
+ const method = parentCall.expression.name.text;
18689
+ if (/^(?:forEach|map|flatMap|filter|reduce|reduceRight|some|every|find|findIndex)$/.test(method)) {
18690
+ return reachableCall(parentCall);
18691
+ }
18692
+ if (/^(?:then|catch|finally)$/.test(method)) {
18693
+ const completed = (value, seen2 = new Set) => {
18694
+ if (seen2.has(value))
18695
+ return false;
18696
+ const visited = new Set(seen2).add(value);
18697
+ let completion = value;
18698
+ while (import_typescript8.default.isParenthesizedExpression(completion.parent))
18699
+ completion = completion.parent;
18700
+ const parent = completion.parent;
18701
+ if (import_typescript8.default.isAwaitExpression(parent)) {
18702
+ return parent.end <= (walk.assemblyReadAt ?? at).getStart();
18703
+ }
18704
+ if (import_typescript8.default.isPropertyAccessExpression(parent) && parent.expression === completion && /^(?:then|catch|finally)$/.test(parent.name.text) && import_typescript8.default.isCallExpression(parent.parent) && parent.parent.expression === parent) {
18705
+ return completed(parent.parent, visited);
18706
+ }
18707
+ if (!import_typescript8.default.isVariableDeclaration(parent) || parent.initializer !== completion || !import_typescript8.default.isIdentifier(parent.name) || !(parent.parent.flags & import_typescript8.default.NodeFlags.Const))
18708
+ return false;
18709
+ let found = false;
18710
+ const findCompletion = (node) => {
18711
+ if (found || import_typescript8.default.isFunctionLike(node))
18712
+ return;
18713
+ if (import_typescript8.default.isIdentifier(node) && node !== parent.name && node.getStart() > parent.end && this.declarationsOf(node).includes(parent) && completed(node, visited)) {
18714
+ found = true;
18715
+ return;
18716
+ }
18717
+ import_typescript8.default.forEachChild(node, findCompletion);
18718
+ };
18719
+ findCompletion(scope);
18720
+ return found;
18721
+ };
18722
+ return completed(parentCall) && reachableCall(parentCall);
18723
+ }
18724
+ }
18725
+ }
18726
+ return this.callersOf(fn).some((call) => {
18727
+ if (call.getSourceFile() !== scope.getSourceFile() || !contains(scope, call))
18728
+ return false;
18729
+ for (let parent = call.parent;parent && parent !== scope; parent = parent.parent) {
18730
+ if (import_typescript8.default.isFunctionLike(parent))
18731
+ return invoked(parent, next);
18732
+ }
18733
+ return true;
18734
+ });
18735
+ };
18736
+ const isThis = (identifier) => references(identifier);
18332
18737
  const visit = (node) => {
18333
- if (import_typescript8.default.isCallExpression(node) && import_typescript8.default.isPropertyAccessExpression(node.expression) && import_typescript8.default.isIdentifier(node.expression.expression) && isThis(node.expression.expression) && /^(?:push|unshift|splice)$/.test(node.expression.name.text)) {
18738
+ if (import_typescript8.default.isFunctionLike(node) && !invoked(node))
18739
+ return;
18740
+ if (import_typescript8.default.isCallExpression(node) && import_typescript8.default.isPropertyAccessExpression(node.expression) && references(node.expression.expression) && /^(?:push|unshift|splice)$/.test(node.expression.name.text)) {
18334
18741
  const args = node.expression.name.text === "splice" ? node.arguments.slice(2) : node.arguments;
18335
18742
  for (const argument of args)
18336
18743
  this.value(argument, owner, walk);
18337
18744
  }
18338
- if (import_typescript8.default.isBinaryExpression(node) && import_typescript8.default.isIdentifier(node.left) && isThis(node.left)) {
18745
+ if (import_typescript8.default.isBinaryExpression(node) && import_typescript8.default.isIdentifier(node.left) && (isThis(node.left) || readVersions.has(node))) {
18339
18746
  if (node.operatorToken.kind === import_typescript8.default.SyntaxKind.PlusEqualsToken)
18340
18747
  this.value(node.right, owner, walk);
18341
18748
  if (node.operatorToken.kind === import_typescript8.default.SyntaxKind.EqualsToken && node.right !== declaration.initializer)
@@ -18404,15 +18811,14 @@ class PromptResolver {
18404
18811
  const signatures = this.implementedSignatures(fn, name);
18405
18812
  return candidates.filter((call) => {
18406
18813
  const callee = import_typescript8.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
18407
- return this.declarationsOf(callee).some((declaration) => functionOf(declaration) === fn || declaration === fn || signatures.has(declaration));
18814
+ const checker = this.context.checkerFor(this.relative(call.getSourceFile().fileName));
18815
+ const members = checker && import_typescript8.default.isPropertyAccessExpression(call.expression) ? receiverClasses(call.expression.expression, checker).flatMap((cls) => cls.members.filter((member) => member.name?.getText() === name)) : [];
18816
+ return [...this.declarationsOf(callee), ...members].some((declaration) => functionOf(declaration) === fn || declaration === fn || signatures.has(declaration) && !!checker && contextualReceiverMatches(call, fn, checker));
18408
18817
  });
18409
18818
  }
18410
18819
  implementedSignatures(fn, name) {
18411
- if (!import_typescript8.default.isMethodDeclaration(fn) || !import_typescript8.default.isObjectLiteralExpression(fn.parent))
18412
- return new Set;
18413
18820
  const checker = this.context.checkerFor(this.relative(fn.getSourceFile().fileName));
18414
- const property = checker?.getContextualType(fn.parent)?.getProperty(name);
18415
- return new Set((property?.declarations ?? []).filter(import_typescript8.default.isMethodSignature));
18821
+ return checker ? contextualSignatures(fn, name, checker) : new Set;
18416
18822
  }
18417
18823
  sourceFiles() {
18418
18824
  const byName = new Map;
@@ -19224,7 +19630,7 @@ async function runHarnessCommand(context) {
19224
19630
  throw new CliInputError("Focused remote prompt analysis is not supported yet.", "Use local --analyst=claude|codex|cursor|local-scan, or drop --concern for a full remote report.");
19225
19631
  }
19226
19632
  if (context.flags["github-actions"] === "true") {
19227
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-51v5jbtn.js");
19633
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-gt4qawvp.js");
19228
19634
  const result = await runGithubActionsAnalyze(rootDir, {
19229
19635
  writeReport: (report2) => {
19230
19636
  const normalized = normalizeHarnessReport(report2);
@@ -19375,8 +19781,8 @@ async function runHarnessCommand(context) {
19375
19781
  }
19376
19782
  const { artifacts, unknowns } = deterministicGraphItems(rootDir, promote === "all" ? undefined : promote);
19377
19783
  tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
19378
- const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-yax78wy5.js");
19379
- const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-ejy18zzk.js");
19784
+ const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-xhcqg43k.js");
19785
+ const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-n43wbr24.js");
19380
19786
  let components = { runtimeAgents: [], artifacts: [], warnings: [] };
19381
19787
  if (promote === "all" || promote === "topology" || promote === "tools") {
19382
19788
  const { result, ctx } = extractHarnessWithContext2(rootDir);
@@ -19410,8 +19816,8 @@ async function runHarnessCommand(context) {
19410
19816
  }
19411
19817
  case "extract": {
19412
19818
  writeHumanProgress(context, "Harness extract: tracing model call sites (no LLM, no network)...");
19413
- const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-yax78wy5.js");
19414
- const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-ejy18zzk.js");
19819
+ const { extractHarnessWithContext: extractHarnessWithContext2, serializeExtractResult } = await import("./index-xhcqg43k.js");
19820
+ const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-n43wbr24.js");
19415
19821
  const { result, ctx } = extractHarnessWithContext2(rootDir, { fresh: true });
19416
19822
  const artifacts = deterministicArtifacts(rootDir);
19417
19823
  tagComponentStatus({ runtimeAgents: [], artifacts }, rootDir);
@@ -20290,8 +20696,8 @@ var CONCERN_PROMOTED_ARTIFACT_TYPES = {
20290
20696
  evals: new Set(["model_config", "eval"])
20291
20697
  };
20292
20698
  async function deterministicFloorGraph(rootDir, options = {}) {
20293
- const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-yax78wy5.js");
20294
- const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-ejy18zzk.js");
20699
+ const { extractHarnessWithContext: extractHarnessWithContext2 } = await import("./index-xhcqg43k.js");
20700
+ const { enumerateHarnessComponents, mergeEnumeratedComponents } = await import("./index-n43wbr24.js");
20295
20701
  const { result, ctx } = extractHarnessWithContext2(rootDir);
20296
20702
  const items = deterministicGraphItems(rootDir);
20297
20703
  const components = mergeEnumeratedComponents(items.artifacts, enumerateHarnessComponents(result, ctx));