@posthog/agent 2.1.112 → 2.1.114

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.
@@ -904,7 +904,7 @@ var import_hono = require("hono");
904
904
  // package.json
905
905
  var package_default = {
906
906
  name: "@posthog/agent",
907
- version: "2.1.112",
907
+ version: "2.1.114",
908
908
  repository: "https://github.com/PostHog/twig",
909
909
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
910
910
  exports: {
@@ -1602,6 +1602,75 @@ var createPostToolUseHook = ({ onModeChange }) => async (input, toolUseID) => {
1602
1602
  return { continue: true };
1603
1603
  };
1604
1604
 
1605
+ // src/adapters/claude/mcp/tool-metadata.ts
1606
+ var mcpToolMetadataCache = /* @__PURE__ */ new Map();
1607
+ var PENDING_RETRY_INTERVAL_MS = 1e3;
1608
+ var PENDING_MAX_RETRIES = 10;
1609
+ function buildToolKey(serverName, toolName) {
1610
+ return `mcp__${serverName}__${toolName}`;
1611
+ }
1612
+ function delay(ms) {
1613
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
1614
+ }
1615
+ async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefix: "[McpToolMetadata]" })) {
1616
+ let retries = 0;
1617
+ while (retries <= PENDING_MAX_RETRIES) {
1618
+ let statuses;
1619
+ try {
1620
+ statuses = await q.mcpServerStatus();
1621
+ } catch (error) {
1622
+ logger.error("Failed to fetch MCP server status", {
1623
+ error: error instanceof Error ? error.message : String(error)
1624
+ });
1625
+ return;
1626
+ }
1627
+ const pendingServers = statuses.filter((s) => s.status === "pending");
1628
+ for (const server of statuses) {
1629
+ if (server.status !== "connected" || !server.tools) {
1630
+ continue;
1631
+ }
1632
+ let readOnlyCount = 0;
1633
+ for (const tool of server.tools) {
1634
+ const toolKey = buildToolKey(server.name, tool.name);
1635
+ const readOnly = tool.annotations?.readOnly === true;
1636
+ mcpToolMetadataCache.set(toolKey, {
1637
+ readOnly,
1638
+ name: tool.name,
1639
+ description: tool.description
1640
+ });
1641
+ if (readOnly) readOnlyCount++;
1642
+ }
1643
+ logger.info("Fetched MCP tool metadata", {
1644
+ serverName: server.name,
1645
+ toolCount: server.tools.length,
1646
+ readOnlyCount
1647
+ });
1648
+ }
1649
+ if (pendingServers.length === 0) {
1650
+ return;
1651
+ }
1652
+ retries++;
1653
+ if (retries > PENDING_MAX_RETRIES) {
1654
+ logger.warn("Gave up waiting for pending MCP servers", {
1655
+ pendingServers: pendingServers.map((s) => s.name)
1656
+ });
1657
+ return;
1658
+ }
1659
+ logger.info("Waiting for pending MCP servers", {
1660
+ pendingServers: pendingServers.map((s) => s.name),
1661
+ retry: retries
1662
+ });
1663
+ await delay(PENDING_RETRY_INTERVAL_MS);
1664
+ }
1665
+ }
1666
+ function getMcpToolMetadata(toolName) {
1667
+ return mcpToolMetadataCache.get(toolName);
1668
+ }
1669
+ function isMcpToolReadOnly(toolName) {
1670
+ const metadata = mcpToolMetadataCache.get(toolName);
1671
+ return metadata?.readOnly === true;
1672
+ }
1673
+
1605
1674
  // src/adapters/claude/conversion/tool-use-to-acp.ts
1606
1675
  var SYSTEM_REMINDER = `
1607
1676
 
@@ -1932,14 +2001,27 @@ function toolInfoFromToolUse(toolUse, cachedFileContent, logger = new Logger({ d
1932
2001
  ${output}\`\`\``).build()
1933
2002
  };
1934
2003
  }
1935
- default:
2004
+ default: {
2005
+ if (name?.startsWith("mcp__")) {
2006
+ return mcpToolInfo(name, input);
2007
+ }
1936
2008
  return {
1937
2009
  title: name || "Unknown Tool",
1938
2010
  kind: "other",
1939
2011
  content: []
1940
2012
  };
2013
+ }
1941
2014
  }
1942
2015
  }
2016
+ function mcpToolInfo(name, _input) {
2017
+ const metadata = getMcpToolMetadata(name);
2018
+ const title = metadata?.name ?? (name.split("__").slice(2).join("__") || name);
2019
+ return {
2020
+ title,
2021
+ kind: "other",
2022
+ content: []
2023
+ };
2024
+ }
1943
2025
  function toolUpdateFromToolResult(toolResult, toolUse) {
1944
2026
  switch (toolUse?.name) {
1945
2027
  case "Read":
@@ -2030,31 +2112,49 @@ function toolUpdateFromToolResult(toolResult, toolUse) {
2030
2112
  }
2031
2113
  }
2032
2114
  }
2115
+ function itemToText(item) {
2116
+ if (!item || typeof item !== "object") return null;
2117
+ const obj = item;
2118
+ if (obj.type === "text" && typeof obj.text === "string") {
2119
+ return obj.text;
2120
+ }
2121
+ try {
2122
+ return JSON.stringify(obj, null, 2);
2123
+ } catch {
2124
+ return null;
2125
+ }
2126
+ }
2033
2127
  function toAcpContentUpdate(content, isError = false) {
2034
2128
  if (Array.isArray(content) && content.length > 0) {
2035
- return {
2036
- content: content.map((item) => {
2037
- const itemObj = item;
2038
- if (isError && itemObj.type === "text") {
2039
- return {
2040
- type: "content",
2041
- content: text(`\`\`\`
2042
- ${itemObj.text ?? ""}
2043
- \`\`\``)
2044
- };
2045
- }
2046
- return {
2047
- type: "content",
2048
- content: item
2049
- };
2050
- })
2051
- };
2129
+ const texts = [];
2130
+ for (const item of content) {
2131
+ const t = itemToText(item);
2132
+ if (t) texts.push(t);
2133
+ }
2134
+ if (texts.length > 0) {
2135
+ const combined = texts.join("\n");
2136
+ return {
2137
+ content: toolContent().text(isError ? `\`\`\`
2138
+ ${combined}
2139
+ \`\`\`` : combined).build()
2140
+ };
2141
+ }
2052
2142
  } else if (typeof content === "string" && content.length > 0) {
2053
2143
  return {
2054
2144
  content: toolContent().text(isError ? `\`\`\`
2055
2145
  ${content}
2056
2146
  \`\`\`` : content).build()
2057
2147
  };
2148
+ } else if (content && typeof content === "object") {
2149
+ try {
2150
+ const json = JSON.stringify(content, null, 2);
2151
+ if (json && json !== "{}") {
2152
+ return {
2153
+ content: toolContent().text(json).build()
2154
+ };
2155
+ }
2156
+ } catch {
2157
+ }
2058
2158
  }
2059
2159
  return {};
2060
2160
  }
@@ -2475,68 +2575,6 @@ async function handleUserAssistantMessage(message, context) {
2475
2575
  return {};
2476
2576
  }
2477
2577
 
2478
- // src/adapters/claude/mcp/tool-metadata.ts
2479
- var mcpToolMetadataCache = /* @__PURE__ */ new Map();
2480
- var PENDING_RETRY_INTERVAL_MS = 1e3;
2481
- var PENDING_MAX_RETRIES = 10;
2482
- function buildToolKey(serverName, toolName) {
2483
- return `mcp__${serverName}__${toolName}`;
2484
- }
2485
- function delay(ms) {
2486
- return new Promise((resolve4) => setTimeout(resolve4, ms));
2487
- }
2488
- async function fetchMcpToolMetadata(q, logger = new Logger({ debug: false, prefix: "[McpToolMetadata]" })) {
2489
- let retries = 0;
2490
- while (retries <= PENDING_MAX_RETRIES) {
2491
- let statuses;
2492
- try {
2493
- statuses = await q.mcpServerStatus();
2494
- } catch (error) {
2495
- logger.error("Failed to fetch MCP server status", {
2496
- error: error instanceof Error ? error.message : String(error)
2497
- });
2498
- return;
2499
- }
2500
- const pendingServers = statuses.filter((s) => s.status === "pending");
2501
- for (const server of statuses) {
2502
- if (server.status !== "connected" || !server.tools) {
2503
- continue;
2504
- }
2505
- let readOnlyCount = 0;
2506
- for (const tool of server.tools) {
2507
- const toolKey = buildToolKey(server.name, tool.name);
2508
- const readOnly = tool.annotations?.readOnly === true;
2509
- mcpToolMetadataCache.set(toolKey, { readOnly });
2510
- if (readOnly) readOnlyCount++;
2511
- }
2512
- logger.info("Fetched MCP tool metadata", {
2513
- serverName: server.name,
2514
- toolCount: server.tools.length,
2515
- readOnlyCount
2516
- });
2517
- }
2518
- if (pendingServers.length === 0) {
2519
- return;
2520
- }
2521
- retries++;
2522
- if (retries > PENDING_MAX_RETRIES) {
2523
- logger.warn("Gave up waiting for pending MCP servers", {
2524
- pendingServers: pendingServers.map((s) => s.name)
2525
- });
2526
- return;
2527
- }
2528
- logger.info("Waiting for pending MCP servers", {
2529
- pendingServers: pendingServers.map((s) => s.name),
2530
- retry: retries
2531
- });
2532
- await delay(PENDING_RETRY_INTERVAL_MS);
2533
- }
2534
- }
2535
- function isMcpToolReadOnly(toolName) {
2536
- const metadata = mcpToolMetadataCache.get(toolName);
2537
- return metadata?.readOnly === true;
2538
- }
2539
-
2540
2578
  // src/adapters/claude/plan/utils.ts
2541
2579
  var os = __toESM(require("os"), 1);
2542
2580
  var path = __toESM(require("path"), 1);