@dogpile/sdk 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/browser/index.js +784 -562
  3. package/dist/browser/index.js.map +1 -1
  4. package/dist/index.d.ts +4 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/runtime/broadcast.d.ts.map +1 -1
  9. package/dist/runtime/broadcast.js +1 -13
  10. package/dist/runtime/broadcast.js.map +1 -1
  11. package/dist/runtime/coordinator.d.ts.map +1 -1
  12. package/dist/runtime/coordinator.js +1 -13
  13. package/dist/runtime/coordinator.js.map +1 -1
  14. package/dist/runtime/ids.d.ts +19 -0
  15. package/dist/runtime/ids.d.ts.map +1 -0
  16. package/dist/runtime/ids.js +36 -0
  17. package/dist/runtime/ids.js.map +1 -0
  18. package/dist/runtime/logger.d.ts +61 -0
  19. package/dist/runtime/logger.d.ts.map +1 -0
  20. package/dist/runtime/logger.js +114 -0
  21. package/dist/runtime/logger.js.map +1 -0
  22. package/dist/runtime/retry.d.ts +99 -0
  23. package/dist/runtime/retry.d.ts.map +1 -0
  24. package/dist/runtime/retry.js +181 -0
  25. package/dist/runtime/retry.js.map +1 -0
  26. package/dist/runtime/sequential.d.ts.map +1 -1
  27. package/dist/runtime/sequential.js +1 -10
  28. package/dist/runtime/sequential.js.map +1 -1
  29. package/dist/runtime/shared.d.ts.map +1 -1
  30. package/dist/runtime/shared.js +1 -13
  31. package/dist/runtime/shared.js.map +1 -1
  32. package/dist/runtime/tools/built-in.d.ts +99 -0
  33. package/dist/runtime/tools/built-in.d.ts.map +1 -0
  34. package/dist/runtime/tools/built-in.js +577 -0
  35. package/dist/runtime/tools/built-in.js.map +1 -0
  36. package/dist/runtime/tools/vercel-ai.d.ts +67 -0
  37. package/dist/runtime/tools/vercel-ai.d.ts.map +1 -0
  38. package/dist/runtime/tools/vercel-ai.js +148 -0
  39. package/dist/runtime/tools/vercel-ai.js.map +1 -0
  40. package/dist/runtime/tools.d.ts +5 -268
  41. package/dist/runtime/tools.d.ts.map +1 -1
  42. package/dist/runtime/tools.js +7 -770
  43. package/dist/runtime/tools.js.map +1 -1
  44. package/dist/types/benchmark.d.ts +276 -0
  45. package/dist/types/benchmark.d.ts.map +1 -0
  46. package/dist/types/benchmark.js +2 -0
  47. package/dist/types/benchmark.js.map +1 -0
  48. package/dist/types/events.d.ts +495 -0
  49. package/dist/types/events.d.ts.map +1 -0
  50. package/dist/types/events.js +2 -0
  51. package/dist/types/events.js.map +1 -0
  52. package/dist/types/replay.d.ts +169 -0
  53. package/dist/types/replay.d.ts.map +1 -0
  54. package/dist/types/replay.js +2 -0
  55. package/dist/types/replay.js.map +1 -0
  56. package/dist/types.d.ts +6 -935
  57. package/dist/types.d.ts.map +1 -1
  58. package/package.json +27 -1
  59. package/src/index.ts +4 -0
  60. package/src/runtime/broadcast.ts +1 -16
  61. package/src/runtime/coordinator.ts +1 -16
  62. package/src/runtime/ids.ts +41 -0
  63. package/src/runtime/logger.ts +152 -0
  64. package/src/runtime/retry.ts +270 -0
  65. package/src/runtime/sequential.ts +1 -12
  66. package/src/runtime/shared.ts +1 -16
  67. package/src/runtime/tools/built-in.ts +875 -0
  68. package/src/runtime/tools/vercel-ai.ts +269 -0
  69. package/src/runtime/tools.ts +60 -1255
  70. package/src/types/benchmark.ts +300 -0
  71. package/src/types/events.ts +544 -0
  72. package/src/types/replay.ts +201 -0
  73. package/src/types.ts +104 -994
@@ -67,6 +67,39 @@ function isRecord$2(value) {
67
67
  return typeof value === "object" && value !== null && !Array.isArray(value);
68
68
  }
69
69
  //#endregion
70
+ //#region src/runtime/ids.ts
71
+ /**
72
+ * Repo-internal id and timing helpers used across all four protocols.
73
+ *
74
+ * Centralized here so a change to id format or fallback semantics happens in
75
+ * exactly one place — switching `protocol` must not change the run-id contract.
76
+ */
77
+ /**
78
+ * Generates a fresh run id using `globalThis.crypto.randomUUID`.
79
+ *
80
+ * Throws a `DogpileError` when no UUID source is available rather than falling
81
+ * back to a millisecond-based id (which collides under back-to-back runs in
82
+ * the same tick). Node 22+, Bun latest, and modern browsers all expose
83
+ * `crypto.randomUUID`; environments without it are unsupported by Dogpile.
84
+ */
85
+ function createRunId() {
86
+ const random = globalThis.crypto?.randomUUID?.();
87
+ if (typeof random === "string" && random.length > 0) return random;
88
+ throw new DogpileError({
89
+ code: "invalid-configuration",
90
+ message: "Dogpile requires globalThis.crypto.randomUUID to mint a run id. Run on Node 22+, Bun latest, or a modern browser ESM environment."
91
+ });
92
+ }
93
+ function nowMs() {
94
+ return globalThis.performance?.now() ?? Date.now();
95
+ }
96
+ function elapsedMs(startedAtMs) {
97
+ return Math.max(0, nowMs() - startedAtMs);
98
+ }
99
+ function providerCallIdFor(runId, oneBasedIndex) {
100
+ return `${runId}:provider-call:${oneBasedIndex}`;
101
+ }
102
+ //#endregion
70
103
  //#region src/runtime/defaults.ts
71
104
  function normalizeProtocol(protocol) {
72
105
  if (typeof protocol !== "string") return protocol;
@@ -1402,7 +1435,7 @@ function describeValue(value) {
1402
1435
  return typeof value;
1403
1436
  }
1404
1437
  //#endregion
1405
- //#region src/runtime/tools.ts
1438
+ //#region src/runtime/tools/built-in.ts
1406
1439
  var webSearchIdentity = {
1407
1440
  id: "dogpile.tools.webSearch",
1408
1441
  namespace: "dogpile",
@@ -1488,9 +1521,6 @@ function builtInDogpileToolIdentity(name) {
1488
1521
  function builtInDogpileToolInputSchema(name) {
1489
1522
  return name === "webSearch" ? webSearchInputSchema : codeExecInputSchema;
1490
1523
  }
1491
- /**
1492
- * Return the default permission declarations for one built-in tool name.
1493
- */
1494
1524
  function builtInDogpileToolPermissions(name) {
1495
1525
  return name === "webSearch" ? webSearchPermissions : codeExecPermissions;
1496
1526
  }
@@ -1501,130 +1531,168 @@ function validateBuiltInDogpileToolInput(name, input) {
1501
1531
  issues
1502
1532
  };
1503
1533
  }
1504
- /**
1505
- * Create the shared runtime tool executor used by every first-party protocol.
1506
- *
1507
- * @remarks
1508
- * The executor owns call id generation, read-only trace context construction,
1509
- * adapter validation, error normalization, and matched `tool-call` /
1510
- * `tool-result` events. Protocols only supply a normalized
1511
- * {@link RuntimeToolExecutionRequest}, which keeps tool execution independent
1512
- * of Coordinator, Sequential, Broadcast, or Shared control flow.
1513
- */
1514
- function createRuntimeToolExecutor(options) {
1515
- validateRuntimeToolRegistrations(options.tools);
1516
- const tools = Array.from(options.tools);
1517
- let callCount = 0;
1518
- return {
1519
- tools,
1520
- async execute(request) {
1521
- const tool = tools.find((candidate) => candidate.identity.id === request.toolId);
1522
- const identity = tool?.identity ?? {
1523
- id: request.toolId,
1524
- name: request.toolId
1525
- };
1526
- const callIndex = callCount;
1527
- callCount += 1;
1528
- const toolCallId = request.toolCallId ?? options.makeToolCallId?.(identity, callIndex) ?? defaultToolCallId(options.runId, callIndex);
1529
- const context = createExecutionContext(options, request, toolCallId);
1530
- options.emit?.({
1531
- type: "tool-call",
1532
- runId: options.runId,
1533
- at: (/* @__PURE__ */ new Date()).toISOString(),
1534
- toolCallId,
1534
+ function createWebSearchToolAdapter(options) {
1535
+ const identity = mergeIdentity(webSearchIdentity, options.identity);
1536
+ return normalizeBuiltInDogpileTool({
1537
+ name: "webSearch",
1538
+ ...options.identity ? { identity: options.identity } : {},
1539
+ ...options.permissions ? { permissions: options.permissions } : {},
1540
+ async execute(input, context) {
1541
+ const fetchImplementation = options.fetch ?? globalThis.fetch;
1542
+ if (!fetchImplementation) return {
1543
+ type: "error",
1544
+ toolCallId: context.toolCallId,
1535
1545
  tool: identity,
1536
- input: request.input,
1537
- ...request.agentId ? { agentId: request.agentId } : {},
1538
- ...request.role ? { role: request.role } : {}
1546
+ error: {
1547
+ code: "unavailable",
1548
+ message: "No fetch implementation is available for webSearch.",
1549
+ retryable: false
1550
+ }
1551
+ };
1552
+ const request = options.buildRequest ? options.buildRequest(input, context) : defaultWebSearchRequest(options, input, context);
1553
+ const response = await fetchImplementation(request.url, {
1554
+ ...request.init,
1555
+ ...context.abortSignal ? { signal: context.abortSignal } : {}
1539
1556
  });
1540
- const result = await executeRuntimeTool(tool, identity, request.input, context);
1541
- options.emit?.({
1542
- type: "tool-result",
1543
- runId: options.runId,
1544
- at: (/* @__PURE__ */ new Date()).toISOString(),
1545
- toolCallId,
1557
+ if (!response.ok) throw {
1558
+ code: response.status >= 500 ? "unavailable" : "backend-error",
1559
+ message: `Web search backend returned HTTP ${response.status}.`,
1560
+ retryable: response.status === 408 || response.status === 429 || response.status >= 500,
1561
+ detail: {
1562
+ status: response.status,
1563
+ statusText: response.statusText
1564
+ }
1565
+ };
1566
+ const output = options.parseResponse ? await options.parseResponse(response, input, context) : await defaultWebSearchResponseParser(response);
1567
+ return {
1568
+ type: "success",
1569
+ toolCallId: context.toolCallId,
1546
1570
  tool: identity,
1547
- result,
1548
- ...request.agentId ? { agentId: request.agentId } : {},
1549
- ...request.role ? { role: request.role } : {}
1550
- });
1551
- return result;
1571
+ output
1572
+ };
1573
+ }
1574
+ });
1575
+ }
1576
+ function createCodeExecToolAdapter(options) {
1577
+ const identity = mergeIdentity(codeExecIdentity, options.identity);
1578
+ const permissions = options.permissions ?? codeExecPermissionsFor(options.languages ?? codeExecLanguages, options.allowNetwork ?? false);
1579
+ return {
1580
+ identity,
1581
+ inputSchema: codeExecInputSchemaFor(options.languages ?? codeExecLanguages),
1582
+ permissions,
1583
+ validateInput: (input) => validateCodeExecAdapterInput(input, options),
1584
+ async execute(input, context) {
1585
+ const validation = validateCodeExecAdapterInput(input, options);
1586
+ if (validation.type === "invalid") return {
1587
+ type: "error",
1588
+ toolCallId: context.toolCallId,
1589
+ tool: identity,
1590
+ error: {
1591
+ code: "invalid-input",
1592
+ message: "Invalid codeExec tool input.",
1593
+ retryable: false,
1594
+ detail: { issues: serializeValidationIssues(validation.issues) }
1595
+ }
1596
+ };
1597
+ const timeoutMs = input.timeoutMs ?? options.defaultTimeoutMs;
1598
+ const executionInput = timeoutMs === void 0 ? input : {
1599
+ ...input,
1600
+ timeoutMs
1601
+ };
1602
+ try {
1603
+ const output = await executeSandboxWithPolicy(options.execute, executionInput, context, timeoutMs);
1604
+ return {
1605
+ type: "success",
1606
+ toolCallId: context.toolCallId,
1607
+ tool: identity,
1608
+ output
1609
+ };
1610
+ } catch (error) {
1611
+ return {
1612
+ type: "error",
1613
+ toolCallId: context.toolCallId,
1614
+ tool: identity,
1615
+ error: normalizeRuntimeToolAdapterError(error)
1616
+ };
1617
+ }
1552
1618
  }
1553
1619
  };
1554
1620
  }
1555
- /**
1556
- * Return a JSON-serializable manifest for tools visible to a protocol run.
1557
- */
1558
- function runtimeToolManifest(tools) {
1559
- return tools.map((tool) => {
1560
- const inputSchema = {
1561
- kind: tool.inputSchema.kind,
1562
- schema: tool.inputSchema.schema,
1563
- ...tool.inputSchema.description ? { description: tool.inputSchema.description } : {}
1564
- };
1621
+ function normalizeBuiltInDogpileTool(definition) {
1622
+ switch (definition.name) {
1623
+ case "webSearch": {
1624
+ const identity = mergeIdentity(webSearchIdentity, definition.identity);
1625
+ const permissions = definition.permissions ?? webSearchPermissions;
1626
+ return {
1627
+ identity,
1628
+ inputSchema: definition.inputSchema ?? webSearchInputSchema,
1629
+ permissions,
1630
+ validateInput: (input) => validateBuiltInDogpileToolInput("webSearch", input),
1631
+ execute: (input, context) => executeBuiltInTool(identity, definition.execute, input, context, "webSearch")
1632
+ };
1633
+ }
1634
+ case "codeExec": {
1635
+ const identity = mergeIdentity(codeExecIdentity, definition.identity);
1636
+ const permissions = definition.permissions ?? codeExecPermissions;
1637
+ return {
1638
+ identity,
1639
+ inputSchema: definition.inputSchema ?? codeExecInputSchema,
1640
+ permissions,
1641
+ validateInput: (input) => validateBuiltInDogpileToolInput("codeExec", input),
1642
+ execute: (input, context) => executeBuiltInTool(identity, definition.execute, input, context, "codeExec")
1643
+ };
1644
+ }
1645
+ }
1646
+ }
1647
+ function normalizeBuiltInDogpileTools(tools) {
1648
+ const normalized = [];
1649
+ if (tools.webSearch) normalized.push(normalizeBuiltInDogpileTool(asWebSearchDefinition(tools.webSearch)));
1650
+ if (tools.codeExec) normalized.push(normalizeBuiltInDogpileTool(asCodeExecDefinition(tools.codeExec)));
1651
+ return normalized;
1652
+ }
1653
+ async function executeBuiltInTool(identity, execute, input, context, name) {
1654
+ const validation = validateBuiltInDogpileToolInput(name, input);
1655
+ if (validation.type === "invalid") return {
1656
+ type: "error",
1657
+ toolCallId: context.toolCallId,
1658
+ tool: identity,
1659
+ error: {
1660
+ code: "invalid-input",
1661
+ message: `Invalid ${name} tool input.`,
1662
+ retryable: false,
1663
+ detail: { issues: serializeValidationIssues(validation.issues) }
1664
+ }
1665
+ };
1666
+ try {
1667
+ return await execute(input, context);
1668
+ } catch (error) {
1565
1669
  return {
1566
- identity: runtimeToolIdentityManifest(tool.identity),
1567
- inputSchema,
1568
- permissions: Array.from(tool.permissions ?? []).map(runtimeToolPermissionManifest)
1670
+ type: "error",
1671
+ toolCallId: context.toolCallId,
1672
+ tool: identity,
1673
+ error: normalizeRuntimeToolAdapterError(error)
1569
1674
  };
1570
- });
1675
+ }
1571
1676
  }
1572
- /**
1573
- * Return request metadata that makes runtime tools visible to provider
1574
- * adapters, or an empty object when no tools are available.
1575
- */
1576
- function runtimeToolAvailability(tools) {
1577
- const manifest = runtimeToolManifest(tools);
1578
- return manifest.length > 0 ? { tools: manifest } : {};
1677
+ function asWebSearchDefinition(tool) {
1678
+ return typeof tool === "function" ? {
1679
+ name: "webSearch",
1680
+ execute: tool
1681
+ } : tool;
1579
1682
  }
1580
- /**
1581
- * Execute normalized tool requests returned by a provider response.
1582
- */
1583
- async function executeModelResponseToolRequests(options) {
1584
- const toolCalls = [];
1585
- for (const request of options.response.toolRequests ?? []) {
1586
- const result = await options.executor.execute({
1587
- ...request,
1588
- agentId: request.agentId ?? options.agentId,
1589
- role: request.role ?? options.role,
1590
- turn: request.turn ?? options.turn,
1591
- metadata: mergeToolMetadata(options.metadata, request.metadata)
1592
- });
1593
- toolCalls.push({
1594
- toolCallId: result.toolCallId,
1595
- tool: result.tool,
1596
- input: request.input,
1597
- result
1598
- });
1599
- }
1600
- return toolCalls;
1683
+ function asCodeExecDefinition(tool) {
1684
+ return typeof tool === "function" ? {
1685
+ name: "codeExec",
1686
+ execute: tool
1687
+ } : tool;
1601
1688
  }
1602
- function runtimeToolIdentityManifest(identity) {
1689
+ function mergeIdentity(defaultIdentity, options) {
1690
+ if (!options) return defaultIdentity;
1603
1691
  return {
1604
- id: identity.id,
1605
- name: identity.name,
1606
- ...identity.namespace ? { namespace: identity.namespace } : {},
1607
- ...identity.version ? { version: identity.version } : {},
1608
- ...identity.description ? { description: identity.description } : {}
1609
- };
1610
- }
1611
- function runtimeToolPermissionManifest(permission) {
1612
- if (permission.kind === "network") return {
1613
- kind: permission.kind,
1614
- ...permission.allowHosts ? { allowHosts: Array.from(permission.allowHosts) } : {},
1615
- ...permission.allowPrivateNetwork === void 0 ? {} : { allowPrivateNetwork: permission.allowPrivateNetwork }
1616
- };
1617
- if (permission.kind === "code-execution") return {
1618
- kind: permission.kind,
1619
- sandbox: permission.sandbox,
1620
- ...permission.languages ? { languages: Array.from(permission.languages) } : {},
1621
- ...permission.allowNetwork === void 0 ? {} : { allowNetwork: permission.allowNetwork }
1622
- };
1623
- return {
1624
- kind: permission.kind,
1625
- name: permission.name,
1626
- ...permission.description ? { description: permission.description } : {},
1627
- ...permission.metadata ? { metadata: permission.metadata } : {}
1692
+ ...defaultIdentity,
1693
+ ...options.namespace !== void 0 ? { namespace: options.namespace } : {},
1694
+ ...options.version !== void 0 ? { version: options.version } : {},
1695
+ ...options.description !== void 0 ? { description: options.description } : {}
1628
1696
  };
1629
1697
  }
1630
1698
  function validateCodeExecAdapterInput(input, options) {
@@ -1633,296 +1701,19 @@ function validateCodeExecAdapterInput(input, options) {
1633
1701
  if (typeof input.language === "string" && isCodeExecLanguage(input.language) && !languages.includes(input.language)) issues.push({
1634
1702
  code: "invalid-value",
1635
1703
  path: "language",
1636
- message: "codeExec.language is not enabled for this adapter.",
1637
- detail: { allowed: Array.from(languages) }
1638
- });
1639
- const effectiveTimeoutMs = input.timeoutMs ?? options.defaultTimeoutMs;
1640
- if (effectiveTimeoutMs !== void 0 && options.maxTimeoutMs !== void 0 && Number.isFinite(effectiveTimeoutMs) && Number.isFinite(options.maxTimeoutMs) && effectiveTimeoutMs > options.maxTimeoutMs) issues.push({
1641
- code: "out-of-range",
1642
- path: input.timeoutMs === void 0 ? "defaultTimeoutMs" : "timeoutMs",
1643
- message: `codeExec.timeoutMs must be less than or equal to ${options.maxTimeoutMs}.`,
1644
- detail: { maximum: options.maxTimeoutMs }
1645
- });
1646
- return issues.length === 0 ? { type: "valid" } : {
1647
- type: "invalid",
1648
- issues
1649
- };
1650
- }
1651
- function createExecutionContext(options, request, toolCallId) {
1652
- return {
1653
- runId: options.runId,
1654
- toolCallId,
1655
- protocol: options.protocol,
1656
- tier: options.tier,
1657
- ...request.agentId ? { agentId: request.agentId } : {},
1658
- ...request.role ? { role: request.role } : {},
1659
- ...request.turn !== void 0 ? { turn: request.turn } : {},
1660
- ...options.getTrace ? { trace: options.getTrace() } : {},
1661
- ...request.abortSignal ?? options.abortSignal ? { abortSignal: request.abortSignal ?? options.abortSignal } : {},
1662
- ...options.metadata || request.metadata ? { metadata: mergeToolMetadata(options.metadata, request.metadata) } : {}
1663
- };
1664
- }
1665
- async function executeRuntimeTool(tool, identity, input, context) {
1666
- if (!tool) return {
1667
- type: "error",
1668
- toolCallId: context.toolCallId,
1669
- tool: identity,
1670
- error: {
1671
- code: "unavailable",
1672
- message: `Runtime tool "${identity.id}" is not registered.`,
1673
- retryable: false
1674
- }
1675
- };
1676
- const validation = validateRuntimeToolInput(tool, input);
1677
- if (validation.type === "invalid") return {
1678
- type: "error",
1679
- toolCallId: context.toolCallId,
1680
- tool: identity,
1681
- error: {
1682
- code: "invalid-input",
1683
- message: "Runtime tool input failed validation.",
1684
- retryable: false,
1685
- detail: { issues: validation.issues.map((issue) => ({
1686
- code: issue.code,
1687
- path: issue.path,
1688
- message: issue.message,
1689
- ...issue.detail ? { detail: issue.detail } : {}
1690
- })) }
1691
- }
1692
- };
1693
- try {
1694
- return await tool.execute(input, context);
1695
- } catch (error) {
1696
- return {
1697
- type: "error",
1698
- toolCallId: context.toolCallId,
1699
- tool: identity,
1700
- error: normalizeRuntimeToolAdapterError(error)
1701
- };
1702
- }
1703
- }
1704
- function validateRuntimeToolInput(tool, input) {
1705
- if (typeof tool.validateInput !== "function") return { type: "valid" };
1706
- return tool.validateInput(input);
1707
- }
1708
- function mergeToolMetadata(base, request) {
1709
- return {
1710
- ...base ?? {},
1711
- ...request ?? {}
1712
- };
1713
- }
1714
- function defaultToolCallId(runId, callIndex) {
1715
- return `${runId}:tool-${callIndex + 1}`;
1716
- }
1717
- /**
1718
- * Convert an unknown adapter failure into Dogpile's serializable error data.
1719
- */
1720
- function normalizeRuntimeToolAdapterError(error) {
1721
- if (isRuntimeToolAdapterError(error)) return error;
1722
- if (error instanceof DOMException && error.name === "AbortError") return {
1723
- code: "aborted",
1724
- message: error.message || "Tool execution was aborted.",
1725
- retryable: true,
1726
- detail: { name: error.name }
1727
- };
1728
- if (error instanceof Error) return {
1729
- code: "backend-error",
1730
- message: error.message,
1731
- retryable: false,
1732
- detail: { name: error.name }
1733
- };
1734
- return {
1735
- code: "unknown",
1736
- message: "Tool execution failed with a non-Error value.",
1737
- retryable: false,
1738
- detail: { valueType: typeof error }
1739
- };
1740
- }
1741
- /**
1742
- * Create Dogpile's built-in fetch-based web search adapter.
1743
- *
1744
- * @remarks
1745
- * The adapter is backend-neutral: by default it sends a GET request with
1746
- * `q` and `limit` query parameters, then accepts either `{ results: [...] }`
1747
- * or a bare array of result objects from the response JSON. Callers can replace
1748
- * request construction or response parsing for a specific search API while
1749
- * keeping Dogpile's shared runtime tool contract, identity, permissions, input
1750
- * validation, and serializable errors.
1751
- */
1752
- function createWebSearchToolAdapter(options) {
1753
- const identity = mergeIdentity(webSearchIdentity, options.identity);
1754
- return normalizeBuiltInDogpileTool({
1755
- name: "webSearch",
1756
- ...options.identity ? { identity: options.identity } : {},
1757
- ...options.permissions ? { permissions: options.permissions } : {},
1758
- async execute(input, context) {
1759
- const fetchImplementation = options.fetch ?? globalThis.fetch;
1760
- if (!fetchImplementation) return {
1761
- type: "error",
1762
- toolCallId: context.toolCallId,
1763
- tool: identity,
1764
- error: {
1765
- code: "unavailable",
1766
- message: "No fetch implementation is available for webSearch.",
1767
- retryable: false
1768
- }
1769
- };
1770
- const request = options.buildRequest ? options.buildRequest(input, context) : defaultWebSearchRequest(options, input, context);
1771
- const response = await fetchImplementation(request.url, {
1772
- ...request.init,
1773
- ...context.abortSignal ? { signal: context.abortSignal } : {}
1774
- });
1775
- if (!response.ok) throw {
1776
- code: response.status >= 500 ? "unavailable" : "backend-error",
1777
- message: `Web search backend returned HTTP ${response.status}.`,
1778
- retryable: response.status === 408 || response.status === 429 || response.status >= 500,
1779
- detail: {
1780
- status: response.status,
1781
- statusText: response.statusText
1782
- }
1783
- };
1784
- const output = options.parseResponse ? await options.parseResponse(response, input, context) : await defaultWebSearchResponseParser(response);
1785
- return {
1786
- type: "success",
1787
- toolCallId: context.toolCallId,
1788
- tool: identity,
1789
- output
1790
- };
1791
- }
1792
- });
1793
- }
1794
- /**
1795
- * Create Dogpile's built-in code execution adapter around a caller-owned sandbox.
1796
- *
1797
- * @remarks
1798
- * Dogpile core stays runtime-portable and never evaluates code itself. This
1799
- * adapter supplies the stable `codeExec` identity, schema, permissions,
1800
- * validation, timeout defaults, abort handling, and serializable errors while
1801
- * the host application owns the sandbox boundary.
1802
- */
1803
- function createCodeExecToolAdapter(options) {
1804
- const identity = mergeIdentity(codeExecIdentity, options.identity);
1805
- const permissions = options.permissions ?? codeExecPermissionsFor(options.languages ?? codeExecLanguages, options.allowNetwork ?? false);
1806
- return {
1807
- identity,
1808
- inputSchema: codeExecInputSchemaFor(options.languages ?? codeExecLanguages),
1809
- permissions,
1810
- validateInput: (input) => validateCodeExecAdapterInput(input, options),
1811
- async execute(input, context) {
1812
- const validation = validateCodeExecAdapterInput(input, options);
1813
- if (validation.type === "invalid") return {
1814
- type: "error",
1815
- toolCallId: context.toolCallId,
1816
- tool: identity,
1817
- error: {
1818
- code: "invalid-input",
1819
- message: "Invalid codeExec tool input.",
1820
- retryable: false,
1821
- detail: { issues: validation.issues }
1822
- }
1823
- };
1824
- const timeoutMs = input.timeoutMs ?? options.defaultTimeoutMs;
1825
- const executionInput = timeoutMs === void 0 ? input : {
1826
- ...input,
1827
- timeoutMs
1828
- };
1829
- try {
1830
- const output = await executeSandboxWithPolicy(options.execute, executionInput, context, timeoutMs);
1831
- return {
1832
- type: "success",
1833
- toolCallId: context.toolCallId,
1834
- tool: identity,
1835
- output
1836
- };
1837
- } catch (error) {
1838
- return {
1839
- type: "error",
1840
- toolCallId: context.toolCallId,
1841
- tool: identity,
1842
- error: normalizeRuntimeToolAdapterError(error)
1843
- };
1844
- }
1845
- }
1846
- };
1847
- }
1848
- function normalizeBuiltInDogpileTool(definition) {
1849
- switch (definition.name) {
1850
- case "webSearch": {
1851
- const identity = mergeIdentity(webSearchIdentity, definition.identity);
1852
- const permissions = definition.permissions ?? webSearchPermissions;
1853
- return {
1854
- identity,
1855
- inputSchema: definition.inputSchema ?? webSearchInputSchema,
1856
- permissions,
1857
- validateInput: (input) => validateBuiltInDogpileToolInput("webSearch", input),
1858
- execute: (input, context) => executeBuiltInTool(identity, definition.execute, input, context, "webSearch")
1859
- };
1860
- }
1861
- case "codeExec": {
1862
- const identity = mergeIdentity(codeExecIdentity, definition.identity);
1863
- const permissions = definition.permissions ?? codeExecPermissions;
1864
- return {
1865
- identity,
1866
- inputSchema: definition.inputSchema ?? codeExecInputSchema,
1867
- permissions,
1868
- validateInput: (input) => validateBuiltInDogpileToolInput("codeExec", input),
1869
- execute: (input, context) => executeBuiltInTool(identity, definition.execute, input, context, "codeExec")
1870
- };
1871
- }
1872
- }
1873
- }
1874
- /**
1875
- * Normalize configured built-in Dogpile tool executors into runtime tools.
1876
- */
1877
- function normalizeBuiltInDogpileTools(tools) {
1878
- const normalized = [];
1879
- if (tools.webSearch) normalized.push(normalizeBuiltInDogpileTool(asWebSearchDefinition(tools.webSearch)));
1880
- if (tools.codeExec) normalized.push(normalizeBuiltInDogpileTool(asCodeExecDefinition(tools.codeExec)));
1881
- return normalized;
1882
- }
1883
- async function executeBuiltInTool(identity, execute, input, context, name) {
1884
- const validation = validateBuiltInDogpileToolInput(name, input);
1885
- if (validation.type === "invalid") return {
1886
- type: "error",
1887
- toolCallId: context.toolCallId,
1888
- tool: identity,
1889
- error: {
1890
- code: "invalid-input",
1891
- message: `Invalid ${name} tool input.`,
1892
- retryable: false,
1893
- detail: { issues: validation.issues }
1894
- }
1895
- };
1896
- try {
1897
- return await execute(input, context);
1898
- } catch (error) {
1899
- return {
1900
- type: "error",
1901
- toolCallId: context.toolCallId,
1902
- tool: identity,
1903
- error: normalizeRuntimeToolAdapterError(error)
1904
- };
1905
- }
1906
- }
1907
- function asWebSearchDefinition(tool) {
1908
- return typeof tool === "function" ? {
1909
- name: "webSearch",
1910
- execute: tool
1911
- } : tool;
1912
- }
1913
- function asCodeExecDefinition(tool) {
1914
- return typeof tool === "function" ? {
1915
- name: "codeExec",
1916
- execute: tool
1917
- } : tool;
1918
- }
1919
- function mergeIdentity(defaultIdentity, options) {
1920
- if (!options) return defaultIdentity;
1921
- return {
1922
- ...defaultIdentity,
1923
- ...options.namespace !== void 0 ? { namespace: options.namespace } : {},
1924
- ...options.version !== void 0 ? { version: options.version } : {},
1925
- ...options.description !== void 0 ? { description: options.description } : {}
1704
+ message: "codeExec.language is not enabled for this adapter.",
1705
+ detail: { allowed: Array.from(languages) }
1706
+ });
1707
+ const effectiveTimeoutMs = input.timeoutMs ?? options.defaultTimeoutMs;
1708
+ if (effectiveTimeoutMs !== void 0 && options.maxTimeoutMs !== void 0 && Number.isFinite(effectiveTimeoutMs) && Number.isFinite(options.maxTimeoutMs) && effectiveTimeoutMs > options.maxTimeoutMs) issues.push({
1709
+ code: "out-of-range",
1710
+ path: input.timeoutMs === void 0 ? "defaultTimeoutMs" : "timeoutMs",
1711
+ message: `codeExec.timeoutMs must be less than or equal to ${options.maxTimeoutMs}.`,
1712
+ detail: { maximum: options.maxTimeoutMs }
1713
+ });
1714
+ return issues.length === 0 ? { type: "valid" } : {
1715
+ type: "invalid",
1716
+ issues
1926
1717
  };
1927
1718
  }
1928
1719
  function defaultWebSearchRequest(options, input, _context) {
@@ -2041,105 +1832,324 @@ function jsonString(value, fieldName) {
2041
1832
  message: `Web search result ${fieldName} must be a non-empty string.`,
2042
1833
  retryable: false
2043
1834
  };
2044
- return value;
1835
+ return value;
1836
+ }
1837
+ function optionalJsonString(value, fieldName) {
1838
+ if (value === void 0) return void 0;
1839
+ if (typeof value !== "string") throw {
1840
+ code: "backend-error",
1841
+ message: `Web search result ${fieldName} must be a string when present.`,
1842
+ retryable: false
1843
+ };
1844
+ return value;
1845
+ }
1846
+ function optionalJsonObject(value, fieldName) {
1847
+ if (value === void 0) return void 0;
1848
+ if (!isJsonObject(value)) throw {
1849
+ code: "backend-error",
1850
+ message: `Web search result ${fieldName} must be a JSON object when present.`,
1851
+ retryable: false
1852
+ };
1853
+ return value;
1854
+ }
1855
+ function isJsonObject(value) {
1856
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1857
+ }
1858
+ function validateWebSearchInput(input) {
1859
+ const issues = [];
1860
+ if (typeof input.query !== "string") issues.push({
1861
+ code: input.query === void 0 ? "missing-field" : "invalid-type",
1862
+ path: "query",
1863
+ message: "webSearch.query must be a string."
1864
+ });
1865
+ else if (input.query.trim().length === 0) issues.push({
1866
+ code: "invalid-value",
1867
+ path: "query",
1868
+ message: "webSearch.query must not be empty."
1869
+ });
1870
+ if (input.maxResults !== void 0) {
1871
+ if (typeof input.maxResults !== "number" || !Number.isFinite(input.maxResults)) issues.push({
1872
+ code: "invalid-type",
1873
+ path: "maxResults",
1874
+ message: "webSearch.maxResults must be a finite number."
1875
+ });
1876
+ else if (input.maxResults < 1) issues.push({
1877
+ code: "out-of-range",
1878
+ path: "maxResults",
1879
+ message: "webSearch.maxResults must be greater than or equal to 1.",
1880
+ detail: { minimum: 1 }
1881
+ });
1882
+ }
1883
+ return issues;
1884
+ }
1885
+ function validateCodeExecInput(input) {
1886
+ const issues = [];
1887
+ if (typeof input.language !== "string") issues.push({
1888
+ code: input.language === void 0 ? "missing-field" : "invalid-type",
1889
+ path: "language",
1890
+ message: "codeExec.language must be a string."
1891
+ });
1892
+ else if (!isCodeExecLanguage(input.language)) issues.push({
1893
+ code: "invalid-value",
1894
+ path: "language",
1895
+ message: "codeExec.language must be one of javascript, typescript, python, bash, or shell.",
1896
+ detail: { allowed: [
1897
+ "javascript",
1898
+ "typescript",
1899
+ "python",
1900
+ "bash",
1901
+ "shell"
1902
+ ] }
1903
+ });
1904
+ if (typeof input.code !== "string") issues.push({
1905
+ code: input.code === void 0 ? "missing-field" : "invalid-type",
1906
+ path: "code",
1907
+ message: "codeExec.code must be a string."
1908
+ });
1909
+ if (input.timeoutMs !== void 0) {
1910
+ if (typeof input.timeoutMs !== "number" || !Number.isFinite(input.timeoutMs)) issues.push({
1911
+ code: "invalid-type",
1912
+ path: "timeoutMs",
1913
+ message: "codeExec.timeoutMs must be a finite number."
1914
+ });
1915
+ else if (input.timeoutMs < 1) issues.push({
1916
+ code: "out-of-range",
1917
+ path: "timeoutMs",
1918
+ message: "codeExec.timeoutMs must be greater than or equal to 1.",
1919
+ detail: { minimum: 1 }
1920
+ });
1921
+ }
1922
+ return issues;
1923
+ }
1924
+ function isCodeExecLanguage(value) {
1925
+ return value === "javascript" || value === "typescript" || value === "python" || value === "bash" || value === "shell";
1926
+ }
1927
+ function normalizeRuntimeToolAdapterError(error) {
1928
+ if (isRuntimeToolAdapterError(error)) return error;
1929
+ if (error instanceof DOMException && error.name === "AbortError") return {
1930
+ code: "aborted",
1931
+ message: error.message || "Tool execution was aborted.",
1932
+ retryable: true,
1933
+ detail: { name: error.name }
1934
+ };
1935
+ if (error instanceof Error) return {
1936
+ code: "backend-error",
1937
+ message: error.message,
1938
+ retryable: false,
1939
+ detail: { name: error.name }
1940
+ };
1941
+ return {
1942
+ code: "unknown",
1943
+ message: "Tool execution failed with a non-Error value.",
1944
+ retryable: false,
1945
+ detail: { valueType: typeof error }
1946
+ };
1947
+ }
1948
+ function isRuntimeToolAdapterError(error) {
1949
+ if (typeof error !== "object" || error === null || !("code" in error) || !("message" in error)) return false;
1950
+ const candidate = error;
1951
+ return isRuntimeToolAdapterErrorCode(candidate.code) && typeof candidate.message === "string";
1952
+ }
1953
+ function isRuntimeToolAdapterErrorCode(value) {
1954
+ return value === "invalid-input" || value === "permission-denied" || value === "timeout" || value === "aborted" || value === "unavailable" || value === "backend-error" || value === "unknown";
1955
+ }
1956
+ function serializeValidationIssues(issues) {
1957
+ return issues.map((issue) => ({
1958
+ code: issue.code,
1959
+ path: issue.path,
1960
+ message: issue.message,
1961
+ ...issue.detail !== void 0 ? { detail: issue.detail } : {}
1962
+ }));
1963
+ }
1964
+ //#endregion
1965
+ //#region src/runtime/tools.ts
1966
+ /**
1967
+ * Create the shared runtime tool executor used by every first-party protocol.
1968
+ *
1969
+ * @remarks
1970
+ * The executor owns call id generation, read-only trace context construction,
1971
+ * adapter validation, error normalization, and matched `tool-call` /
1972
+ * `tool-result` events. Protocols only supply a normalized
1973
+ * {@link RuntimeToolExecutionRequest}, which keeps tool execution independent
1974
+ * of Coordinator, Sequential, Broadcast, or Shared control flow.
1975
+ */
1976
+ function createRuntimeToolExecutor(options) {
1977
+ validateRuntimeToolRegistrations(options.tools);
1978
+ const tools = Array.from(options.tools);
1979
+ let callCount = 0;
1980
+ return {
1981
+ tools,
1982
+ async execute(request) {
1983
+ const tool = tools.find((candidate) => candidate.identity.id === request.toolId);
1984
+ const identity = tool?.identity ?? {
1985
+ id: request.toolId,
1986
+ name: request.toolId
1987
+ };
1988
+ const callIndex = callCount;
1989
+ callCount += 1;
1990
+ const toolCallId = request.toolCallId ?? options.makeToolCallId?.(identity, callIndex) ?? defaultToolCallId(options.runId, callIndex);
1991
+ const context = createExecutionContext(options, request, toolCallId);
1992
+ options.emit?.({
1993
+ type: "tool-call",
1994
+ runId: options.runId,
1995
+ at: (/* @__PURE__ */ new Date()).toISOString(),
1996
+ toolCallId,
1997
+ tool: identity,
1998
+ input: request.input,
1999
+ ...request.agentId ? { agentId: request.agentId } : {},
2000
+ ...request.role ? { role: request.role } : {}
2001
+ });
2002
+ const result = await executeRuntimeTool(tool, identity, request.input, context);
2003
+ options.emit?.({
2004
+ type: "tool-result",
2005
+ runId: options.runId,
2006
+ at: (/* @__PURE__ */ new Date()).toISOString(),
2007
+ toolCallId,
2008
+ tool: identity,
2009
+ result,
2010
+ ...request.agentId ? { agentId: request.agentId } : {},
2011
+ ...request.role ? { role: request.role } : {}
2012
+ });
2013
+ return result;
2014
+ }
2015
+ };
2016
+ }
2017
+ /**
2018
+ * Return a JSON-serializable manifest for tools visible to a protocol run.
2019
+ */
2020
+ function runtimeToolManifest(tools) {
2021
+ return tools.map((tool) => {
2022
+ const inputSchema = {
2023
+ kind: tool.inputSchema.kind,
2024
+ schema: tool.inputSchema.schema,
2025
+ ...tool.inputSchema.description ? { description: tool.inputSchema.description } : {}
2026
+ };
2027
+ return {
2028
+ identity: runtimeToolIdentityManifest(tool.identity),
2029
+ inputSchema,
2030
+ permissions: Array.from(tool.permissions ?? []).map(runtimeToolPermissionManifest)
2031
+ };
2032
+ });
2033
+ }
2034
+ /**
2035
+ * Return request metadata that makes runtime tools visible to provider
2036
+ * adapters, or an empty object when no tools are available.
2037
+ */
2038
+ function runtimeToolAvailability(tools) {
2039
+ const manifest = runtimeToolManifest(tools);
2040
+ return manifest.length > 0 ? { tools: manifest } : {};
2041
+ }
2042
+ /**
2043
+ * Execute normalized tool requests returned by a provider response.
2044
+ */
2045
+ async function executeModelResponseToolRequests(options) {
2046
+ const toolCalls = [];
2047
+ for (const request of options.response.toolRequests ?? []) {
2048
+ const result = await options.executor.execute({
2049
+ ...request,
2050
+ agentId: request.agentId ?? options.agentId,
2051
+ role: request.role ?? options.role,
2052
+ turn: request.turn ?? options.turn,
2053
+ metadata: mergeToolMetadata(options.metadata, request.metadata)
2054
+ });
2055
+ toolCalls.push({
2056
+ toolCallId: result.toolCallId,
2057
+ tool: result.tool,
2058
+ input: request.input,
2059
+ result
2060
+ });
2061
+ }
2062
+ return toolCalls;
2063
+ }
2064
+ function runtimeToolIdentityManifest(identity) {
2065
+ return {
2066
+ id: identity.id,
2067
+ name: identity.name,
2068
+ ...identity.namespace ? { namespace: identity.namespace } : {},
2069
+ ...identity.version ? { version: identity.version } : {},
2070
+ ...identity.description ? { description: identity.description } : {}
2071
+ };
2072
+ }
2073
+ function runtimeToolPermissionManifest(permission) {
2074
+ if (permission.kind === "network") return {
2075
+ kind: permission.kind,
2076
+ ...permission.allowHosts ? { allowHosts: Array.from(permission.allowHosts) } : {},
2077
+ ...permission.allowPrivateNetwork === void 0 ? {} : { allowPrivateNetwork: permission.allowPrivateNetwork }
2078
+ };
2079
+ if (permission.kind === "code-execution") return {
2080
+ kind: permission.kind,
2081
+ sandbox: permission.sandbox,
2082
+ ...permission.languages ? { languages: Array.from(permission.languages) } : {},
2083
+ ...permission.allowNetwork === void 0 ? {} : { allowNetwork: permission.allowNetwork }
2084
+ };
2085
+ return {
2086
+ kind: permission.kind,
2087
+ name: permission.name,
2088
+ ...permission.description ? { description: permission.description } : {},
2089
+ ...permission.metadata ? { metadata: permission.metadata } : {}
2090
+ };
2045
2091
  }
2046
- function optionalJsonString(value, fieldName) {
2047
- if (value === void 0) return;
2048
- if (typeof value !== "string") throw {
2049
- code: "backend-error",
2050
- message: `Web search result ${fieldName} must be a string when present.`,
2051
- retryable: false
2092
+ function createExecutionContext(options, request, toolCallId) {
2093
+ return {
2094
+ runId: options.runId,
2095
+ toolCallId,
2096
+ protocol: options.protocol,
2097
+ tier: options.tier,
2098
+ ...request.agentId ? { agentId: request.agentId } : {},
2099
+ ...request.role ? { role: request.role } : {},
2100
+ ...request.turn !== void 0 ? { turn: request.turn } : {},
2101
+ ...options.getTrace ? { trace: options.getTrace() } : {},
2102
+ ...request.abortSignal ?? options.abortSignal ? { abortSignal: request.abortSignal ?? options.abortSignal } : {},
2103
+ ...options.metadata || request.metadata ? { metadata: mergeToolMetadata(options.metadata, request.metadata) } : {}
2052
2104
  };
2053
- return value;
2054
2105
  }
2055
- function optionalJsonObject(value, fieldName) {
2056
- if (value === void 0) return;
2057
- if (!isJsonObject(value)) throw {
2058
- code: "backend-error",
2059
- message: `Web search result ${fieldName} must be a JSON object when present.`,
2060
- retryable: false
2106
+ async function executeRuntimeTool(tool, identity, input, context) {
2107
+ if (!tool) return {
2108
+ type: "error",
2109
+ toolCallId: context.toolCallId,
2110
+ tool: identity,
2111
+ error: {
2112
+ code: "unavailable",
2113
+ message: `Runtime tool "${identity.id}" is not registered.`,
2114
+ retryable: false
2115
+ }
2061
2116
  };
2062
- return value;
2063
- }
2064
- function isJsonObject(value) {
2065
- return typeof value === "object" && value !== null && !Array.isArray(value);
2066
- }
2067
- function validateWebSearchInput(input) {
2068
- const issues = [];
2069
- if (typeof input.query !== "string") issues.push({
2070
- code: input.query === void 0 ? "missing-field" : "invalid-type",
2071
- path: "query",
2072
- message: "webSearch.query must be a string."
2073
- });
2074
- else if (input.query.trim().length === 0) issues.push({
2075
- code: "invalid-value",
2076
- path: "query",
2077
- message: "webSearch.query must not be empty."
2078
- });
2079
- if (input.maxResults !== void 0) {
2080
- if (typeof input.maxResults !== "number" || !Number.isFinite(input.maxResults)) issues.push({
2081
- code: "invalid-type",
2082
- path: "maxResults",
2083
- message: "webSearch.maxResults must be a finite number."
2084
- });
2085
- else if (input.maxResults < 1) issues.push({
2086
- code: "out-of-range",
2087
- path: "maxResults",
2088
- message: "webSearch.maxResults must be greater than or equal to 1.",
2089
- detail: { minimum: 1 }
2090
- });
2091
- }
2092
- return issues;
2093
- }
2094
- function validateCodeExecInput(input) {
2095
- const issues = [];
2096
- if (typeof input.language !== "string") issues.push({
2097
- code: input.language === void 0 ? "missing-field" : "invalid-type",
2098
- path: "language",
2099
- message: "codeExec.language must be a string."
2100
- });
2101
- else if (!isCodeExecLanguage(input.language)) issues.push({
2102
- code: "invalid-value",
2103
- path: "language",
2104
- message: "codeExec.language must be one of javascript, typescript, python, bash, or shell.",
2105
- detail: { allowed: [
2106
- "javascript",
2107
- "typescript",
2108
- "python",
2109
- "bash",
2110
- "shell"
2111
- ] }
2112
- });
2113
- if (typeof input.code !== "string") issues.push({
2114
- code: input.code === void 0 ? "missing-field" : "invalid-type",
2115
- path: "code",
2116
- message: "codeExec.code must be a string."
2117
- });
2118
- if (input.timeoutMs !== void 0) {
2119
- if (typeof input.timeoutMs !== "number" || !Number.isFinite(input.timeoutMs)) issues.push({
2120
- code: "invalid-type",
2121
- path: "timeoutMs",
2122
- message: "codeExec.timeoutMs must be a finite number."
2123
- });
2124
- else if (input.timeoutMs < 1) issues.push({
2125
- code: "out-of-range",
2126
- path: "timeoutMs",
2127
- message: "codeExec.timeoutMs must be greater than or equal to 1.",
2128
- detail: { minimum: 1 }
2129
- });
2117
+ const validation = tool.validateInput?.(input);
2118
+ if (validation?.type === "invalid") return {
2119
+ type: "error",
2120
+ toolCallId: context.toolCallId,
2121
+ tool: identity,
2122
+ error: {
2123
+ code: "invalid-input",
2124
+ message: "Runtime tool input failed validation.",
2125
+ retryable: false,
2126
+ detail: { issues: validation.issues.map((issue) => ({
2127
+ code: issue.code,
2128
+ path: issue.path,
2129
+ message: issue.message,
2130
+ ...issue.detail ? { detail: issue.detail } : {}
2131
+ })) }
2132
+ }
2133
+ };
2134
+ try {
2135
+ return await tool.execute(input, context);
2136
+ } catch (error) {
2137
+ return {
2138
+ type: "error",
2139
+ toolCallId: context.toolCallId,
2140
+ tool: identity,
2141
+ error: normalizeRuntimeToolAdapterError(error)
2142
+ };
2130
2143
  }
2131
- return issues;
2132
- }
2133
- function isCodeExecLanguage(value) {
2134
- return value === "javascript" || value === "typescript" || value === "python" || value === "bash" || value === "shell";
2135
2144
  }
2136
- function isRuntimeToolAdapterError(error) {
2137
- if (typeof error !== "object" || error === null || !("code" in error) || !("message" in error)) return false;
2138
- const candidate = error;
2139
- return isRuntimeToolAdapterErrorCode(candidate.code) && typeof candidate.message === "string";
2145
+ function mergeToolMetadata(base, request) {
2146
+ return {
2147
+ ...base ?? {},
2148
+ ...request ?? {}
2149
+ };
2140
2150
  }
2141
- function isRuntimeToolAdapterErrorCode(value) {
2142
- return value === "invalid-input" || value === "permission-denied" || value === "timeout" || value === "aborted" || value === "unavailable" || value === "backend-error" || value === "unknown";
2151
+ function defaultToolCallId(runId, callIndex) {
2152
+ return `${runId}:tool-${callIndex + 1}`;
2143
2153
  }
2144
2154
  //#endregion
2145
2155
  //#region src/runtime/wrap-up.ts
@@ -2289,7 +2299,7 @@ function minCap(left, right) {
2289
2299
  //#endregion
2290
2300
  //#region src/runtime/broadcast.ts
2291
2301
  async function runBroadcast(options) {
2292
- const runId = createRunId$3();
2302
+ const runId = createRunId();
2293
2303
  const events = [];
2294
2304
  const transcript = [];
2295
2305
  const protocolDecisions = [];
@@ -2298,7 +2308,7 @@ async function runBroadcast(options) {
2298
2308
  const maxRounds = options.protocol.maxRounds ?? 2;
2299
2309
  let firstRoundContributions = [];
2300
2310
  let lastContributions = [];
2301
- const startedAtMs = nowMs$3();
2311
+ const startedAtMs = nowMs();
2302
2312
  let stopped = false;
2303
2313
  let termination;
2304
2314
  const wrapUpHint = createWrapUpHintController({
@@ -2375,7 +2385,7 @@ async function runBroadcast(options) {
2375
2385
  events,
2376
2386
  transcript,
2377
2387
  iteration: transcript.length,
2378
- elapsedMs: elapsedMs$3(startedAtMs)
2388
+ elapsedMs: elapsedMs(startedAtMs)
2379
2389
  })
2380
2390
  };
2381
2391
  const response = await generateModelTurn({
@@ -2385,7 +2395,7 @@ async function runBroadcast(options) {
2385
2395
  agent,
2386
2396
  input,
2387
2397
  emit,
2388
- callId: providerCallIdFor$2(runId, providerCalls.length + agentIndex + 1),
2398
+ callId: providerCallIdFor(runId, providerCalls.length + agentIndex + 1),
2389
2399
  onProviderCall(call) {
2390
2400
  providerCallSlots[agentIndex] = call;
2391
2401
  }
@@ -2550,7 +2560,7 @@ async function runBroadcast(options) {
2550
2560
  events,
2551
2561
  transcript,
2552
2562
  iteration: transcript.length,
2553
- elapsedMs: elapsedMs$3(startedAtMs)
2563
+ elapsedMs: elapsedMs(startedAtMs)
2554
2564
  }));
2555
2565
  if (!stopRecord) return false;
2556
2566
  stopped = true;
@@ -2566,7 +2576,7 @@ async function runBroadcast(options) {
2566
2576
  reason: record.budgetReason ?? "cost",
2567
2577
  cost: totalCost,
2568
2578
  iteration: transcript.length,
2569
- elapsedMs: elapsedMs$3(startedAtMs),
2579
+ elapsedMs: elapsedMs(startedAtMs),
2570
2580
  detail: record.detail ?? {}
2571
2581
  };
2572
2582
  emit(event);
@@ -2596,22 +2606,10 @@ function responseCost$3(response) {
2596
2606
  totalTokens: response.usage?.totalTokens ?? 0
2597
2607
  };
2598
2608
  }
2599
- function createRunId$3() {
2600
- return globalThis.crypto?.randomUUID?.() ?? `run-${Date.now().toString(36)}`;
2601
- }
2602
- function nowMs$3() {
2603
- return globalThis.performance?.now() ?? Date.now();
2604
- }
2605
- function elapsedMs$3(startedAtMs) {
2606
- return Math.max(0, nowMs$3() - startedAtMs);
2607
- }
2608
- function providerCallIdFor$2(runId, oneBasedIndex) {
2609
- return `${runId}:provider-call:${oneBasedIndex}`;
2610
- }
2611
2609
  //#endregion
2612
2610
  //#region src/runtime/coordinator.ts
2613
2611
  async function runCoordinator(options) {
2614
- const runId = createRunId$2();
2612
+ const runId = createRunId();
2615
2613
  const events = [];
2616
2614
  const transcript = [];
2617
2615
  const protocolDecisions = [];
@@ -2620,7 +2618,7 @@ async function runCoordinator(options) {
2620
2618
  const maxTurns = options.protocol.maxTurns ?? options.agents.length;
2621
2619
  const activeAgents = options.agents.slice(0, maxTurns);
2622
2620
  const coordinator = activeAgents[0];
2623
- const startedAtMs = nowMs$2();
2621
+ const startedAtMs = nowMs();
2624
2622
  let stopped = false;
2625
2623
  let termination;
2626
2624
  const wrapUpHint = createWrapUpHintController({
@@ -2699,7 +2697,7 @@ async function runCoordinator(options) {
2699
2697
  options,
2700
2698
  runId,
2701
2699
  turn: transcript.length + index + 1,
2702
- providerCallId: providerCallIdFor$1(runId, providerCalls.length + index + 1),
2700
+ providerCallId: providerCallIdFor(runId, providerCalls.length + index + 1),
2703
2701
  providerCallIndex: index,
2704
2702
  providerCallSlots,
2705
2703
  toolExecutor,
@@ -2847,7 +2845,7 @@ async function runCoordinator(options) {
2847
2845
  events,
2848
2846
  transcript,
2849
2847
  iteration: transcript.length,
2850
- elapsedMs: elapsedMs$2(startedAtMs)
2848
+ elapsedMs: elapsedMs(startedAtMs)
2851
2849
  }));
2852
2850
  if (!stopRecord) return false;
2853
2851
  stopped = true;
@@ -2863,7 +2861,7 @@ async function runCoordinator(options) {
2863
2861
  reason: record.budgetReason ?? "cost",
2864
2862
  cost: totalCost,
2865
2863
  iteration: transcript.length,
2866
- elapsedMs: elapsedMs$2(startedAtMs),
2864
+ elapsedMs: elapsedMs(startedAtMs),
2867
2865
  detail: record.detail ?? {}
2868
2866
  };
2869
2867
  emit(event);
@@ -2898,7 +2896,7 @@ async function runCoordinatorTurn(turn) {
2898
2896
  events: turn.events,
2899
2897
  transcript: turn.transcript,
2900
2898
  iteration: turn.transcript.length,
2901
- elapsedMs: elapsedMs$2(turn.startedAtMs)
2899
+ elapsedMs: elapsedMs(turn.startedAtMs)
2902
2900
  })
2903
2901
  };
2904
2902
  const response = await generateModelTurn({
@@ -2979,7 +2977,7 @@ async function runCoordinatorWorkerTurn(turn) {
2979
2977
  events: turn.events,
2980
2978
  transcript: turn.transcript,
2981
2979
  iteration: turn.turn - 1,
2982
- elapsedMs: elapsedMs$2(turn.startedAtMs)
2980
+ elapsedMs: elapsedMs(turn.startedAtMs)
2983
2981
  })
2984
2982
  };
2985
2983
  const response = await generateModelTurn({
@@ -3037,22 +3035,10 @@ function responseCost$2(response) {
3037
3035
  totalTokens: response.usage?.totalTokens ?? 0
3038
3036
  };
3039
3037
  }
3040
- function createRunId$2() {
3041
- return globalThis.crypto?.randomUUID?.() ?? `run-${Date.now().toString(36)}`;
3042
- }
3043
- function nowMs$2() {
3044
- return globalThis.performance?.now() ?? Date.now();
3045
- }
3046
- function elapsedMs$2(startedAtMs) {
3047
- return Math.max(0, nowMs$2() - startedAtMs);
3048
- }
3049
- function providerCallIdFor$1(runId, oneBasedIndex) {
3050
- return `${runId}:provider-call:${oneBasedIndex}`;
3051
- }
3052
3038
  //#endregion
3053
3039
  //#region src/runtime/sequential.ts
3054
3040
  async function runSequential(options) {
3055
- const runId = createRunId$1();
3041
+ const runId = createRunId();
3056
3042
  const events = [];
3057
3043
  const transcript = [];
3058
3044
  const protocolDecisions = [];
@@ -3060,7 +3046,7 @@ async function runSequential(options) {
3060
3046
  let totalCost = emptyCost();
3061
3047
  const maxTurns = options.protocol.maxTurns ?? options.agents.length;
3062
3048
  const activeAgents = options.agents.slice(0, maxTurns);
3063
- const startedAtMs = nowMs$1();
3049
+ const startedAtMs = nowMs();
3064
3050
  let stopped = false;
3065
3051
  let termination;
3066
3052
  const wrapUpHint = createWrapUpHintController({
@@ -3135,7 +3121,7 @@ async function runSequential(options) {
3135
3121
  events,
3136
3122
  transcript,
3137
3123
  iteration: transcript.length,
3138
- elapsedMs: elapsedMs$1(startedAtMs)
3124
+ elapsedMs: elapsedMs(startedAtMs)
3139
3125
  })
3140
3126
  };
3141
3127
  const response = await generateModelTurn({
@@ -3270,7 +3256,7 @@ async function runSequential(options) {
3270
3256
  events,
3271
3257
  transcript,
3272
3258
  iteration: transcript.length,
3273
- elapsedMs: elapsedMs$1(startedAtMs)
3259
+ elapsedMs: elapsedMs(startedAtMs)
3274
3260
  }));
3275
3261
  if (!stopRecord) return false;
3276
3262
  stopped = true;
@@ -3286,7 +3272,7 @@ async function runSequential(options) {
3286
3272
  reason: record.budgetReason ?? "cost",
3287
3273
  cost: totalCost,
3288
3274
  iteration: transcript.length,
3289
- elapsedMs: elapsedMs$1(startedAtMs),
3275
+ elapsedMs: elapsedMs(startedAtMs),
3290
3276
  detail: record.detail ?? {}
3291
3277
  };
3292
3278
  emit(event);
@@ -3309,15 +3295,6 @@ function responseCost$1(response) {
3309
3295
  totalTokens: response.usage?.totalTokens ?? 0
3310
3296
  };
3311
3297
  }
3312
- function createRunId$1() {
3313
- return globalThis.crypto?.randomUUID?.() ?? `run-${Date.now().toString(36)}`;
3314
- }
3315
- function nowMs$1() {
3316
- return globalThis.performance?.now() ?? Date.now();
3317
- }
3318
- function elapsedMs$1(startedAtMs) {
3319
- return Math.max(0, nowMs$1() - startedAtMs);
3320
- }
3321
3298
  //#endregion
3322
3299
  //#region src/runtime/shared.ts
3323
3300
  async function runShared(options) {
@@ -3594,18 +3571,6 @@ function responseCost(response) {
3594
3571
  totalTokens: response.usage?.totalTokens ?? 0
3595
3572
  };
3596
3573
  }
3597
- function createRunId() {
3598
- return globalThis.crypto?.randomUUID?.() ?? `run-${Date.now().toString(36)}`;
3599
- }
3600
- function nowMs() {
3601
- return globalThis.performance?.now() ?? Date.now();
3602
- }
3603
- function elapsedMs(startedAtMs) {
3604
- return Math.max(0, nowMs() - startedAtMs);
3605
- }
3606
- function providerCallIdFor(runId, oneBasedIndex) {
3607
- return `${runId}:provider-call:${oneBasedIndex}`;
3608
- }
3609
3574
  //#endregion
3610
3575
  //#region src/runtime/engine.ts
3611
3576
  var defaultHighLevelProtocol = "sequential";
@@ -4515,6 +4480,263 @@ function isJsonValue(value) {
4515
4480
  return false;
4516
4481
  }
4517
4482
  //#endregion
4518
- export { Dogpile, DogpileError, budget, builtInDogpileToolIdentity, builtInDogpileToolInputSchema, builtInDogpileToolPermissions, combineTerminationDecisions, convergence, createCodeExecToolAdapter, createEngine, createOpenAICompatibleProvider, createRuntimeToolExecutor, createWebSearchToolAdapter, evaluateBudget, evaluateConvergence, evaluateFirstOf, evaluateJudge, evaluateTermination, evaluateTerminationStop, firstOf, judge, normalizeBuiltInDogpileTool, normalizeBuiltInDogpileTools, normalizeRuntimeToolAdapterError, replay, replayStream, run, runtimeToolAvailability, runtimeToolManifest, stream, validateBuiltInDogpileToolInput };
4483
+ //#region src/runtime/logger.ts
4484
+ /** Logger that drops every call. The default when no logger is supplied. */
4485
+ var noopLogger = {
4486
+ debug() {},
4487
+ info() {},
4488
+ warn() {},
4489
+ error() {}
4490
+ };
4491
+ /**
4492
+ * Build a console-backed logger respecting a minimum level.
4493
+ *
4494
+ * The output format is JSON-on-one-line so it can be piped straight into log
4495
+ * collectors. Use `loggerFromEvents` to bridge it to a Dogpile stream handle.
4496
+ */
4497
+ function consoleLogger(options = {}) {
4498
+ const minLevel = options.level ?? "info";
4499
+ const allowed = (level) => LEVEL_ORDER[level] >= LEVEL_ORDER[minLevel];
4500
+ const emit = (level, message, fields) => {
4501
+ if (!allowed(level)) return;
4502
+ const payload = {
4503
+ level,
4504
+ message
4505
+ };
4506
+ if (fields !== void 0) payload.fields = fields;
4507
+ (level === "error" ? console.error : level === "warn" ? console.warn : console.log)(JSON.stringify(payload));
4508
+ };
4509
+ return {
4510
+ debug: (message, fields) => emit("debug", message, fields),
4511
+ info: (message, fields) => emit("info", message, fields),
4512
+ warn: (message, fields) => emit("warn", message, fields),
4513
+ error: (message, fields) => emit("error", message, fields)
4514
+ };
4515
+ }
4516
+ var LEVEL_ORDER = {
4517
+ debug: 0,
4518
+ info: 1,
4519
+ warn: 2,
4520
+ error: 3
4521
+ };
4522
+ /**
4523
+ * Bridge a `Logger` to a Dogpile stream handle by returning a
4524
+ * `StreamEventSubscriber`. Pass it to `handle.subscribe(...)`.
4525
+ *
4526
+ * Logger throws are caught and routed to `logger.error` so a misbehaving
4527
+ * logger can never crash an in-flight run.
4528
+ *
4529
+ * @example
4530
+ * ```ts
4531
+ * const handle = Dogpile.stream({ intent, model });
4532
+ * handle.subscribe(loggerFromEvents(consoleLogger({ level: "info" })));
4533
+ * const result = await handle.result;
4534
+ * ```
4535
+ */
4536
+ function loggerFromEvents(logger, options = {}) {
4537
+ const includeSet = options.include ? new Set(options.include) : void 0;
4538
+ return (event) => {
4539
+ const eventType = event.type;
4540
+ if (includeSet && !includeSet.has(eventType)) return;
4541
+ const level = options.levelFor?.(event) ?? defaultLevel(event);
4542
+ const message = describeEvent(event);
4543
+ const fields = summarizeEvent(event);
4544
+ try {
4545
+ logger[level](message, fields);
4546
+ } catch (cause) {
4547
+ try {
4548
+ logger.error("dogpile logger threw while handling event", {
4549
+ eventType,
4550
+ error: cause instanceof Error ? cause.message : String(cause)
4551
+ });
4552
+ } catch {}
4553
+ }
4554
+ };
4555
+ }
4556
+ function defaultLevel(event) {
4557
+ switch (event.type) {
4558
+ case "model-output-chunk": return "debug";
4559
+ case "budget-stop": return "warn";
4560
+ case "error": return "error";
4561
+ case "tool-result": return event.result?.type === "error" ? "warn" : "info";
4562
+ default: return "info";
4563
+ }
4564
+ }
4565
+ function describeEvent(event) {
4566
+ return `dogpile:${event.type}`;
4567
+ }
4568
+ function summarizeEvent(event) {
4569
+ const fields = { eventType: event.type };
4570
+ const at = event.at;
4571
+ if (typeof at === "string") fields.at = at;
4572
+ const runId = event.runId;
4573
+ if (typeof runId === "string") fields.runId = runId;
4574
+ const agentId = event.agentId;
4575
+ if (typeof agentId === "string") fields.agentId = agentId;
4576
+ const role = event.role;
4577
+ if (typeof role === "string") fields.role = role;
4578
+ return fields;
4579
+ }
4580
+ //#endregion
4581
+ //#region src/runtime/retry.ts
4582
+ /**
4583
+ * Default DogpileError codes that `withRetry` retries when no `retryOn`
4584
+ * predicate is supplied. These map to the transient provider failures listed
4585
+ * in `docs/developer-usage.md`.
4586
+ */
4587
+ var DEFAULT_RETRYABLE_DOGPILE_CODES = [
4588
+ "provider-rate-limited",
4589
+ "provider-timeout",
4590
+ "provider-unavailable"
4591
+ ];
4592
+ var DEFAULTS = {
4593
+ maxAttempts: 3,
4594
+ baseDelayMs: 250,
4595
+ maxDelayMs: 4e3,
4596
+ jitter: "full"
4597
+ };
4598
+ /**
4599
+ * Wrap a `ConfiguredModelProvider` with a retry policy. The wrapper:
4600
+ *
4601
+ * - Preserves the provider `id` so traces remain stable.
4602
+ * - Retries `generate()` calls when the policy says the error is retryable.
4603
+ * - Propagates `AbortSignal` cancellation immediately — never retries after
4604
+ * the caller cancels.
4605
+ * - Honors a `Retry-After`-style hint exposed via `error.detail.retryAfterMs`
4606
+ * when present and the policy did not provide its own `delayForError`.
4607
+ * - Forwards `stream()` calls through unchanged — streaming retries cannot be
4608
+ * safely automated because partial output may have already been observed.
4609
+ *
4610
+ * @example
4611
+ * ```ts
4612
+ * const robustProvider = withRetry(rawProvider, {
4613
+ * maxAttempts: 4,
4614
+ * baseDelayMs: 500,
4615
+ * onRetry: ({ attempt, delayMs, error }) => {
4616
+ * logger.warn("provider retry", { attempt, delayMs, error });
4617
+ * }
4618
+ * });
4619
+ * ```
4620
+ */
4621
+ function withRetry(provider, policy = {}) {
4622
+ const settings = {
4623
+ maxAttempts: policy.maxAttempts ?? DEFAULTS.maxAttempts,
4624
+ baseDelayMs: policy.baseDelayMs ?? DEFAULTS.baseDelayMs,
4625
+ maxDelayMs: policy.maxDelayMs ?? DEFAULTS.maxDelayMs,
4626
+ jitter: policy.jitter ?? DEFAULTS.jitter,
4627
+ retryOn: policy.retryOn ?? defaultRetryOn,
4628
+ random: policy.random ?? Math.random,
4629
+ sleep: policy.sleep ?? defaultSleep
4630
+ };
4631
+ if (settings.maxAttempts < 1) throw new DogpileError({
4632
+ code: "invalid-configuration",
4633
+ message: "withRetry: maxAttempts must be >= 1.",
4634
+ detail: { maxAttempts: settings.maxAttempts }
4635
+ });
4636
+ if (settings.baseDelayMs < 0 || settings.maxDelayMs < 0) throw new DogpileError({
4637
+ code: "invalid-configuration",
4638
+ message: "withRetry: delay fields must be non-negative.",
4639
+ detail: {
4640
+ baseDelayMs: settings.baseDelayMs,
4641
+ maxDelayMs: settings.maxDelayMs
4642
+ }
4643
+ });
4644
+ const wrapped = {
4645
+ id: provider.id,
4646
+ async generate(request) {
4647
+ let lastError;
4648
+ for (let attempt = 1; attempt <= settings.maxAttempts; attempt++) {
4649
+ if (request.signal?.aborted) throw abortReason(request.signal);
4650
+ try {
4651
+ return await provider.generate(request);
4652
+ } catch (error) {
4653
+ lastError = error;
4654
+ if (isAbortError(error) || request.signal?.aborted) throw error;
4655
+ if (attempt >= settings.maxAttempts || !settings.retryOn(error)) throw error;
4656
+ const delayMs = chooseDelay({
4657
+ attempt,
4658
+ error,
4659
+ settings,
4660
+ policy
4661
+ });
4662
+ policy.onRetry?.({
4663
+ attempt,
4664
+ maxAttempts: settings.maxAttempts,
4665
+ delayMs,
4666
+ error,
4667
+ providerId: provider.id
4668
+ });
4669
+ await settings.sleep(delayMs, request.signal);
4670
+ }
4671
+ }
4672
+ throw lastError ?? new DogpileError({
4673
+ code: "unknown",
4674
+ message: "withRetry: exhausted attempts without throwing or returning."
4675
+ });
4676
+ }
4677
+ };
4678
+ if (typeof provider.stream === "function") {
4679
+ const upstreamStream = provider.stream.bind(provider);
4680
+ wrapped.stream = (request) => upstreamStream(request);
4681
+ }
4682
+ return wrapped;
4683
+ }
4684
+ function chooseDelay(args) {
4685
+ const override = args.policy.delayForError?.(args.error) ?? retryAfterFromError(args.error);
4686
+ if (override !== void 0 && Number.isFinite(override) && override >= 0) return Math.min(args.settings.maxDelayMs, override);
4687
+ const exponential = args.settings.baseDelayMs * 2 ** (args.attempt - 1);
4688
+ const capped = Math.min(args.settings.maxDelayMs, exponential);
4689
+ if (args.settings.jitter === "none") return capped;
4690
+ return Math.floor(capped * args.settings.random());
4691
+ }
4692
+ function defaultRetryOn(error) {
4693
+ if (isAbortError(error)) return false;
4694
+ if (DogpileError.isInstance(error)) {
4695
+ if (error.code === "aborted" || error.code === "invalid-configuration") return false;
4696
+ return DEFAULT_RETRYABLE_DOGPILE_CODES.includes(error.code);
4697
+ }
4698
+ if (error instanceof TypeError) return true;
4699
+ return false;
4700
+ }
4701
+ function isAbortError(error) {
4702
+ if (DogpileError.isInstance(error) && error.code === "aborted") return true;
4703
+ if (typeof error === "object" && error !== null) {
4704
+ if (error.name === "AbortError") return true;
4705
+ }
4706
+ return false;
4707
+ }
4708
+ function abortReason(signal) {
4709
+ return signal.reason ?? new DogpileError({
4710
+ code: "aborted",
4711
+ message: "Request aborted."
4712
+ });
4713
+ }
4714
+ function retryAfterFromError(error) {
4715
+ if (!DogpileError.isInstance(error)) return void 0;
4716
+ const detail = error.detail;
4717
+ if (!detail || typeof detail !== "object") return void 0;
4718
+ const candidate = detail.retryAfterMs;
4719
+ if (typeof candidate === "number" && Number.isFinite(candidate) && candidate >= 0) return candidate;
4720
+ }
4721
+ function defaultSleep(ms, signal) {
4722
+ if (ms <= 0) return Promise.resolve();
4723
+ return new Promise((resolve, reject) => {
4724
+ if (signal?.aborted) {
4725
+ reject(abortReason(signal));
4726
+ return;
4727
+ }
4728
+ const timer = setTimeout(() => {
4729
+ signal?.removeEventListener("abort", onAbort);
4730
+ resolve();
4731
+ }, ms);
4732
+ const onAbort = () => {
4733
+ clearTimeout(timer);
4734
+ reject(abortReason(signal));
4735
+ };
4736
+ signal?.addEventListener("abort", onAbort, { once: true });
4737
+ });
4738
+ }
4739
+ //#endregion
4740
+ export { DEFAULT_RETRYABLE_DOGPILE_CODES, Dogpile, DogpileError, budget, builtInDogpileToolIdentity, builtInDogpileToolInputSchema, builtInDogpileToolPermissions, combineTerminationDecisions, consoleLogger, convergence, createCodeExecToolAdapter, createEngine, createOpenAICompatibleProvider, createRuntimeToolExecutor, createWebSearchToolAdapter, evaluateBudget, evaluateConvergence, evaluateFirstOf, evaluateJudge, evaluateTermination, evaluateTerminationStop, firstOf, judge, loggerFromEvents, noopLogger, normalizeBuiltInDogpileTool, normalizeBuiltInDogpileTools, normalizeRuntimeToolAdapterError, replay, replayStream, run, runtimeToolAvailability, runtimeToolManifest, stream, validateBuiltInDogpileToolInput, withRetry };
4519
4741
 
4520
4742
  //# sourceMappingURL=index.js.map