@databricks/appkit 0.61.1 → 0.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CLAUDE.md +1 -0
  2. package/dist/agents/databricks.d.ts.map +1 -1
  3. package/dist/agents/databricks.js.map +1 -1
  4. package/dist/agents/supervisor-api.d.ts.map +1 -1
  5. package/dist/agents/supervisor-api.js.map +1 -1
  6. package/dist/app/index.d.ts.map +1 -1
  7. package/dist/app/index.js.map +1 -1
  8. package/dist/appkit/package.js +1 -1
  9. package/dist/cache/index.d.ts.map +1 -1
  10. package/dist/cache/index.js.map +1 -1
  11. package/dist/cache/storage/memory.js.map +1 -1
  12. package/dist/cache/storage/persistent.js.map +1 -1
  13. package/dist/cli/commands/codemod/index.js.map +1 -1
  14. package/dist/cli/commands/codemod/on-plugins-ready.js.map +1 -1
  15. package/dist/cli/commands/docs.js.map +1 -1
  16. package/dist/cli/commands/doctor/bundle.js.map +1 -1
  17. package/dist/cli/commands/doctor/index.js.map +1 -1
  18. package/dist/cli/commands/doctor/report.js.map +1 -1
  19. package/dist/cli/commands/doctor/resolve-targets.js.map +1 -1
  20. package/dist/cli/commands/doctor/run.js.map +1 -1
  21. package/dist/cli/commands/generate-types.js.map +1 -1
  22. package/dist/cli/commands/lint.js.map +1 -1
  23. package/dist/cli/commands/plugin/add-resource/add-resource.js.map +1 -1
  24. package/dist/cli/commands/plugin/create/create.js.map +1 -1
  25. package/dist/cli/commands/plugin/create/prompt-resource.js.map +1 -1
  26. package/dist/cli/commands/plugin/create/scaffold.js.map +1 -1
  27. package/dist/cli/commands/plugin/index.js.map +1 -1
  28. package/dist/cli/commands/plugin/list/list.js.map +1 -1
  29. package/dist/cli/commands/plugin/promote/promote.js.map +1 -1
  30. package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
  31. package/dist/cli/commands/plugin/validate/validate-manifest.js.map +1 -1
  32. package/dist/cli/commands/plugin/validate/validate.js.map +1 -1
  33. package/dist/cli/commands/registry/add.js.map +1 -1
  34. package/dist/cli/commands/registry/client.js.map +1 -1
  35. package/dist/cli/commands/registry/config-writer.js.map +1 -1
  36. package/dist/cli/commands/registry/env-reconcile.js.map +1 -1
  37. package/dist/cli/commands/registry/env-writer.js.map +1 -1
  38. package/dist/cli/commands/registry/index.js.map +1 -1
  39. package/dist/cli/commands/registry/info.js.map +1 -1
  40. package/dist/cli/commands/registry/list.js.map +1 -1
  41. package/dist/cli/commands/registry/requirements.js.map +1 -1
  42. package/dist/cli/commands/registry/server-register.js.map +1 -1
  43. package/dist/cli/commands/registry/workspace-picker.js.map +1 -1
  44. package/dist/cli/commands/setup.js.map +1 -1
  45. package/dist/cli/index.js.map +1 -1
  46. package/dist/connectors/files/client.js.map +1 -1
  47. package/dist/connectors/lakebase/index.d.ts.map +1 -1
  48. package/dist/connectors/lakebase/index.js.map +1 -1
  49. package/dist/connectors/lakebase/pool-manager.d.ts.map +1 -1
  50. package/dist/connectors/lakebase/pool-manager.js.map +1 -1
  51. package/dist/connectors/lakebase/routing-pool.d.ts.map +1 -1
  52. package/dist/connectors/lakebase/routing-pool.js.map +1 -1
  53. package/dist/connectors/mcp/client.d.ts.map +1 -1
  54. package/dist/connectors/mcp/client.js.map +1 -1
  55. package/dist/connectors/sql-warehouse/client.js.map +1 -1
  56. package/dist/context/client-options.js.map +1 -1
  57. package/dist/context/execution-context.d.ts.map +1 -1
  58. package/dist/context/execution-context.js.map +1 -1
  59. package/dist/context/index.d.ts +1 -1
  60. package/dist/context/service-context.d.ts +55 -3
  61. package/dist/context/service-context.d.ts.map +1 -1
  62. package/dist/context/service-context.js.map +1 -1
  63. package/dist/core/agent/build-toolkit.js.map +1 -1
  64. package/dist/core/agent/load-agents.d.ts.map +1 -1
  65. package/dist/core/agent/load-agents.js.map +1 -1
  66. package/dist/core/agent/run-agent.d.ts.map +1 -1
  67. package/dist/core/agent/run-agent.js.map +1 -1
  68. package/dist/core/agent/toolkit-resolver.js.map +1 -1
  69. package/dist/core/agent/tools/define-tool.d.ts.map +1 -1
  70. package/dist/core/agent/tools/define-tool.js.map +1 -1
  71. package/dist/core/agent/tools/tool.d.ts.map +1 -1
  72. package/dist/core/agent/tools/tool.js.map +1 -1
  73. package/dist/core/agent/types.d.ts.map +1 -1
  74. package/dist/core/agent/types.js.map +1 -1
  75. package/dist/core/appkit.d.ts.map +1 -1
  76. package/dist/core/appkit.js.map +1 -1
  77. package/dist/core/lifecycle-manager.js.map +1 -1
  78. package/dist/core/plugin-context.d.ts +13 -0
  79. package/dist/core/plugin-context.d.ts.map +1 -1
  80. package/dist/core/plugin-context.js +12 -1
  81. package/dist/core/plugin-context.js.map +1 -1
  82. package/dist/errors/configuration.d.ts.map +1 -1
  83. package/dist/errors/configuration.js.map +1 -1
  84. package/dist/logging/logger.js.map +1 -1
  85. package/dist/logging/wide-event-emitter.js.map +1 -1
  86. package/dist/plugin/dev-reader.d.ts.map +1 -1
  87. package/dist/plugin/dev-reader.js.map +1 -1
  88. package/dist/plugin/interceptors/cache.js.map +1 -1
  89. package/dist/plugin/interceptors/retry.js.map +1 -1
  90. package/dist/plugin/interceptors/telemetry.js.map +1 -1
  91. package/dist/plugin/plugin.d.ts +2 -2
  92. package/dist/plugin/plugin.d.ts.map +1 -1
  93. package/dist/plugin/plugin.js.map +1 -1
  94. package/dist/plugins/agents/agents.d.ts.map +1 -1
  95. package/dist/plugins/agents/agents.js.map +1 -1
  96. package/dist/plugins/agents/event-translator.js.map +1 -1
  97. package/dist/plugins/agents/thread-store.js.map +1 -1
  98. package/dist/plugins/ai-search/ai-search.d.ts.map +1 -1
  99. package/dist/plugins/ai-search/ai-search.js.map +1 -1
  100. package/dist/plugins/analytics/analytics.d.ts.map +1 -1
  101. package/dist/plugins/analytics/analytics.js.map +1 -1
  102. package/dist/plugins/analytics/mv/cache.js.map +1 -1
  103. package/dist/plugins/analytics/mv/constants.js.map +1 -1
  104. package/dist/plugins/analytics/mv/formatters.js.map +1 -1
  105. package/dist/plugins/analytics/mv/metadata.js.map +1 -1
  106. package/dist/plugins/analytics/mv/registry.js.map +1 -1
  107. package/dist/plugins/analytics/mv/schemas.js.map +1 -1
  108. package/dist/plugins/analytics/query.js.map +1 -1
  109. package/dist/plugins/analytics/result-delivery.js.map +1 -1
  110. package/dist/plugins/files/helpers.js.map +1 -1
  111. package/dist/plugins/files/plugin.d.ts.map +1 -1
  112. package/dist/plugins/files/plugin.js.map +1 -1
  113. package/dist/plugins/files/types.d.ts.map +1 -1
  114. package/dist/plugins/genie/genie.d.ts.map +1 -1
  115. package/dist/plugins/genie/genie.js.map +1 -1
  116. package/dist/plugins/jobs/plugin.d.ts.map +1 -1
  117. package/dist/plugins/jobs/plugin.js.map +1 -1
  118. package/dist/plugins/jobs/types.d.ts.map +1 -1
  119. package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
  120. package/dist/plugins/lakebase/lakebase.js.map +1 -1
  121. package/dist/plugins/lakebase/types.d.ts.map +1 -1
  122. package/dist/plugins/server/base-server.js.map +1 -1
  123. package/dist/plugins/server/client-config-sanitizer.js.map +1 -1
  124. package/dist/plugins/server/index.d.ts.map +1 -1
  125. package/dist/plugins/server/index.js.map +1 -1
  126. package/dist/plugins/server/react-source-loc-vite-plugin.js.map +1 -1
  127. package/dist/plugins/server/remote-tunnel/remote-tunnel-controller.js.map +1 -1
  128. package/dist/plugins/server/remote-tunnel/remote-tunnel-manager.js.map +1 -1
  129. package/dist/plugins/server/static-server.js.map +1 -1
  130. package/dist/plugins/server/utils.js.map +1 -1
  131. package/dist/plugins/server/vite-dev-server.js.map +1 -1
  132. package/dist/plugins/serving/schema-filter.js.map +1 -1
  133. package/dist/plugins/serving/serving.d.ts.map +1 -1
  134. package/dist/plugins/serving/serving.js.map +1 -1
  135. package/dist/plugins/ui-variants/index.js.map +1 -1
  136. package/dist/registry/manifest-loader.d.ts.map +1 -1
  137. package/dist/registry/manifest-loader.js.map +1 -1
  138. package/dist/registry/resource-registry.d.ts.map +1 -1
  139. package/dist/registry/resource-registry.js.map +1 -1
  140. package/dist/registry/types.d.ts.map +1 -1
  141. package/dist/registry/types.js.map +1 -1
  142. package/dist/schemas/manifest.d.ts.map +1 -1
  143. package/dist/schemas/manifest.js.map +1 -1
  144. package/dist/schemas/metric-fqn.js.map +1 -1
  145. package/dist/shared/src/plugin.d.ts.map +1 -1
  146. package/dist/shared/src/schemas/manifest.d.ts.map +1 -1
  147. package/dist/shared/src/schemas/metric-fqn.js.map +1 -1
  148. package/dist/shared/src/schemas/metric-metadata-bundle.js.map +1 -1
  149. package/dist/shared/src/schemas/metric-source.js.map +1 -1
  150. package/dist/shared/src/sse/analytics.js.map +1 -1
  151. package/dist/shared/src/workspace-client/legacy.js.map +1 -1
  152. package/dist/shared/src/workspace-client/types.d.ts.map +1 -1
  153. package/dist/stream/sse-writer.js.map +1 -1
  154. package/dist/stream/stream-manager.d.ts.map +1 -1
  155. package/dist/stream/stream-manager.js.map +1 -1
  156. package/dist/stream/types.js.map +1 -1
  157. package/dist/telemetry/instrumentations.js.map +1 -1
  158. package/dist/telemetry/telemetry-manager.js.map +1 -1
  159. package/dist/telemetry/telemetry-provider.js.map +1 -1
  160. package/dist/telemetry/trace-sampler.js.map +1 -1
  161. package/dist/testing/expect-stream.d.ts +111 -0
  162. package/dist/testing/expect-stream.d.ts.map +1 -0
  163. package/dist/testing/expect-stream.js +154 -0
  164. package/dist/testing/expect-stream.js.map +1 -0
  165. package/dist/testing/fixtures.d.ts +257 -0
  166. package/dist/testing/fixtures.d.ts.map +1 -0
  167. package/dist/testing/fixtures.js +385 -0
  168. package/dist/testing/fixtures.js.map +1 -0
  169. package/dist/testing/index.d.ts +5 -0
  170. package/dist/testing/index.js +5 -0
  171. package/dist/testing/test-plugin-context.d.ts +158 -0
  172. package/dist/testing/test-plugin-context.d.ts.map +1 -0
  173. package/dist/testing/test-plugin-context.js +139 -0
  174. package/dist/testing/test-plugin-context.js.map +1 -0
  175. package/dist/type-generator/cache.js.map +1 -1
  176. package/dist/type-generator/index.js.map +1 -1
  177. package/dist/type-generator/migration.js.map +1 -1
  178. package/dist/type-generator/mv-registry/config.js.map +1 -1
  179. package/dist/type-generator/query-registry.js.map +1 -1
  180. package/dist/type-generator/serving/cache.js.map +1 -1
  181. package/dist/type-generator/serving/generator.js.map +1 -1
  182. package/dist/type-generator/serving/server-file-extractor.d.ts.map +1 -1
  183. package/dist/type-generator/serving/server-file-extractor.js.map +1 -1
  184. package/dist/type-generator/serving/vite-plugin.d.ts.map +1 -1
  185. package/dist/type-generator/serving/vite-plugin.js.map +1 -1
  186. package/dist/type-generator/vite-plugin.d.ts.map +1 -1
  187. package/dist/type-generator/vite-plugin.js.map +1 -1
  188. package/dist/workspace-client/legacy.js.map +1 -1
  189. package/dist/workspace-client/types.d.ts.map +1 -1
  190. package/docs/plugins/testing.md +245 -0
  191. package/llms.txt +1 -0
  192. package/package.json +15 -2
  193. package/sbom.cdx.json +1 -1
  194. package/skills/appkit-ui-variants/SKILL.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"client-options.js","names":["productVersion","productName"],"sources":["../../src/context/client-options.ts"],"sourcesContent":["import { coerce } from \"semver\";\nimport {\n name as productName,\n version as productVersion,\n} from \"../../package.json\";\nimport type { ClientOptions } from \"../workspace-client\";\n\nconst normalizedVersion = (coerce(productVersion)?.version ??\n productVersion) as ClientOptions[\"productVersion\"];\n\n/**\n * SDK client options that stamp every `apiClient.request()` with an AppKit\n * User-Agent (`@databricks/appkit/<version>`), so outbound Databricks traffic\n * is attributable to AppKit. Use this for every `WorkspaceClient` AppKit\n * constructs at runtime.\n */\nexport function getClientOptions(): ClientOptions {\n const isDev = process.env.NODE_ENV === \"development\";\n\n return {\n product: productName,\n productVersion: normalizedVersion,\n ...(isDev && { userAgentExtra: { mode: \"dev\" } }),\n };\n}\n\n/**\n * Product/version User-Agent string matching the SDK stamp, for raw `fetch`\n * call sites that bypass the SDK's `apiClient` and have no client to derive it\n * from (e.g. the MCP connector).\n */\nexport const APPKIT_USER_AGENT = `${productName}/${normalizedVersion}`;\n"],"mappings":";;;;AAOA,MAAM,oBAAqB,OAAOA,QAAe,EAAE,WACjDA;;;;;;;AAQF,SAAgB,mBAAkC;AAGhD,QAAO;EACL,SAASC;EACT,gBAAgB;EAChB,GALY,QAAQ,IAAI,aAAa,iBAKxB,EAAE,gBAAgB,EAAE,MAAM,OAAO,EAAE;EACjD;;;;;;;AAQH,MAAa,oBAAoB,GAAGA,KAAY,GAAG"}
1
+ {"version":3,"file":"client-options.js","names":["productVersion","productName"],"sources":["../../src/context/client-options.ts"],"sourcesContent":["import { coerce } from \"semver\";\n\nimport {\n name as productName,\n version as productVersion,\n} from \"../../package.json\";\nimport type { ClientOptions } from \"../workspace-client\";\n\nconst normalizedVersion = (coerce(productVersion)?.version ??\n productVersion) as ClientOptions[\"productVersion\"];\n\n/**\n * SDK client options that stamp every `apiClient.request()` with an AppKit\n * User-Agent (`@databricks/appkit/<version>`), so outbound Databricks traffic\n * is attributable to AppKit. Use this for every `WorkspaceClient` AppKit\n * constructs at runtime.\n */\nexport function getClientOptions(): ClientOptions {\n const isDev = process.env.NODE_ENV === \"development\";\n\n return {\n product: productName,\n productVersion: normalizedVersion,\n ...(isDev && { userAgentExtra: { mode: \"dev\" } }),\n };\n}\n\n/**\n * Product/version User-Agent string matching the SDK stamp, for raw `fetch`\n * call sites that bypass the SDK's `apiClient` and have no client to derive it\n * from (e.g. the MCP connector).\n */\nexport const APPKIT_USER_AGENT = `${productName}/${normalizedVersion}`;\n"],"mappings":";;;;AAQA,MAAM,oBAAqB,OAAOA,QAAe,EAAE,WACjDA;;;;;;;AAQF,SAAgB,mBAAkC;AAGhD,QAAO;EACL,SAASC;EACT,gBAAgB;EAChB,GALY,QAAQ,IAAI,aAAa,iBAKxB,EAAE,gBAAgB,EAAE,MAAM,OAAO,EAAE;EACjD;;;;;;;AAQH,MAAa,oBAAoB,GAAGA,KAAY,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.d.ts","names":[],"sources":["../../src/context/execution-context.ts"],"mappings":";;;;;;;;;;;iBAmCgB,mBAAA,CAAA,GAAuB,gBAAA"}
1
+ {"version":3,"file":"execution-context.d.ts","names":[],"sources":["../../src/context/execution-context.ts"],"mappings":";;;;;;;;;;;iBAoCgB,mBAAA,CAAA,GAAuB,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.js","names":[],"sources":["../../src/context/execution-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ConfigurationError } from \"../errors\";\nimport { ServiceContext } from \"./service-context\";\nimport {\n type ExecutionContext,\n isUserContext,\n type UserContext,\n} from \"./user-context\";\n\n/**\n * AsyncLocalStorage for execution context.\n * Used to pass user context through the call stack without explicit parameters.\n */\nconst executionContextStorage = new AsyncLocalStorage<UserContext>();\n\n/**\n * Run a function in the context of a user.\n * All calls within the function will have access to the user context.\n *\n * @param userContext - The user context to use\n * @param fn - The function to run\n * @returns The result of the function\n */\nexport function runInUserContext<T>(userContext: UserContext, fn: () => T): T {\n return executionContextStorage.run(userContext, fn);\n}\n\n/**\n * Get the current execution context.\n *\n * - If running inside a user context (via asUser), returns the user context\n * - Otherwise, returns the service context\n *\n * @throws Error if ServiceContext is not initialized\n */\nexport function getExecutionContext(): ExecutionContext {\n const userContext = executionContextStorage.getStore();\n if (userContext) {\n return userContext;\n }\n return ServiceContext.get();\n}\n\n/**\n * Get the current user ID for cache keying and telemetry.\n *\n * Returns the user ID if in user context, otherwise the service user ID.\n */\nexport function getCurrentUserId(): string {\n const ctx = getExecutionContext();\n if (isUserContext(ctx)) {\n return ctx.userId;\n }\n return ctx.serviceUserId;\n}\n\n/**\n * Get the WorkspaceClient for the current execution context.\n */\nexport function getWorkspaceClient() {\n return getExecutionContext().client;\n}\n\n/**\n * Get the warehouse ID promise.\n */\nexport function getWarehouseId(): Promise<string> {\n const ctx = getExecutionContext();\n if (!ctx.warehouseId) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"No plugin requires a SQL Warehouse. Add a sql_warehouse resource to your plugin manifest, or set DATABRICKS_WAREHOUSE_ID\",\n );\n }\n return ctx.warehouseId;\n}\n\n/**\n * Get the workspace ID promise.\n */\nexport function getWorkspaceId(): Promise<string> {\n return getExecutionContext().workspaceId;\n}\n\n/**\n * Check if currently running in a user context.\n */\nexport function isInUserContext(): boolean {\n const ctx = executionContextStorage.getStore();\n return ctx !== undefined;\n}\n\n/**\n * Get the user context if one is active, otherwise `undefined`.\n * Unlike `getExecutionContext()`, this does not require `ServiceContext`\n * to be initialized and never throws.\n */\nexport function getUserContext(): UserContext | undefined {\n return executionContextStorage.getStore();\n}\n"],"mappings":";;;;;;;;;;;AAaA,MAAM,0BAA0B,IAAI,mBAAgC;;;;;;;;;AAUpE,SAAgB,iBAAoB,aAA0B,IAAgB;AAC5E,QAAO,wBAAwB,IAAI,aAAa,GAAG;;;;;;;;;;AAWrD,SAAgB,sBAAwC;CACtD,MAAM,cAAc,wBAAwB,UAAU;AACtD,KAAI,YACF,QAAO;AAET,QAAO,eAAe,KAAK;;;;;;;AAQ7B,SAAgB,mBAA2B;CACzC,MAAM,MAAM,qBAAqB;AACjC,KAAI,cAAc,IAAI,CACpB,QAAO,IAAI;AAEb,QAAO,IAAI;;;;;AAMb,SAAgB,qBAAqB;AACnC,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,iBAAkC;CAChD,MAAM,MAAM,qBAAqB;AACjC,KAAI,CAAC,IAAI,YACP,OAAM,mBAAmB,iBACvB,gBACA,2HACD;AAEH,QAAO,IAAI;;;;;AAMb,SAAgB,iBAAkC;AAChD,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,kBAA2B;AAEzC,QADY,wBAAwB,UAAU,KAC/B;;;;;;;AAQjB,SAAgB,iBAA0C;AACxD,QAAO,wBAAwB,UAAU"}
1
+ {"version":3,"file":"execution-context.js","names":[],"sources":["../../src/context/execution-context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { ConfigurationError } from \"../errors\";\nimport { ServiceContext } from \"./service-context\";\nimport {\n type ExecutionContext,\n isUserContext,\n type UserContext,\n} from \"./user-context\";\n\n/**\n * AsyncLocalStorage for execution context.\n * Used to pass user context through the call stack without explicit parameters.\n */\nconst executionContextStorage = new AsyncLocalStorage<UserContext>();\n\n/**\n * Run a function in the context of a user.\n * All calls within the function will have access to the user context.\n *\n * @param userContext - The user context to use\n * @param fn - The function to run\n * @returns The result of the function\n */\nexport function runInUserContext<T>(userContext: UserContext, fn: () => T): T {\n return executionContextStorage.run(userContext, fn);\n}\n\n/**\n * Get the current execution context.\n *\n * - If running inside a user context (via asUser), returns the user context\n * - Otherwise, returns the service context\n *\n * @throws Error if ServiceContext is not initialized\n */\nexport function getExecutionContext(): ExecutionContext {\n const userContext = executionContextStorage.getStore();\n if (userContext) {\n return userContext;\n }\n return ServiceContext.get();\n}\n\n/**\n * Get the current user ID for cache keying and telemetry.\n *\n * Returns the user ID if in user context, otherwise the service user ID.\n */\nexport function getCurrentUserId(): string {\n const ctx = getExecutionContext();\n if (isUserContext(ctx)) {\n return ctx.userId;\n }\n return ctx.serviceUserId;\n}\n\n/**\n * Get the WorkspaceClient for the current execution context.\n */\nexport function getWorkspaceClient() {\n return getExecutionContext().client;\n}\n\n/**\n * Get the warehouse ID promise.\n */\nexport function getWarehouseId(): Promise<string> {\n const ctx = getExecutionContext();\n if (!ctx.warehouseId) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"No plugin requires a SQL Warehouse. Add a sql_warehouse resource to your plugin manifest, or set DATABRICKS_WAREHOUSE_ID\",\n );\n }\n return ctx.warehouseId;\n}\n\n/**\n * Get the workspace ID promise.\n */\nexport function getWorkspaceId(): Promise<string> {\n return getExecutionContext().workspaceId;\n}\n\n/**\n * Check if currently running in a user context.\n */\nexport function isInUserContext(): boolean {\n const ctx = executionContextStorage.getStore();\n return ctx !== undefined;\n}\n\n/**\n * Get the user context if one is active, otherwise `undefined`.\n * Unlike `getExecutionContext()`, this does not require `ServiceContext`\n * to be initialized and never throws.\n */\nexport function getUserContext(): UserContext | undefined {\n return executionContextStorage.getStore();\n}\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,0BAA0B,IAAI,mBAAgC;;;;;;;;;AAUpE,SAAgB,iBAAoB,aAA0B,IAAgB;AAC5E,QAAO,wBAAwB,IAAI,aAAa,GAAG;;;;;;;;;;AAWrD,SAAgB,sBAAwC;CACtD,MAAM,cAAc,wBAAwB,UAAU;AACtD,KAAI,YACF,QAAO;AAET,QAAO,eAAe,KAAK;;;;;;;AAQ7B,SAAgB,mBAA2B;CACzC,MAAM,MAAM,qBAAqB;AACjC,KAAI,cAAc,IAAI,CACpB,QAAO,IAAI;AAEb,QAAO,IAAI;;;;;AAMb,SAAgB,qBAAqB;AACnC,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,iBAAkC;CAChD,MAAM,MAAM,qBAAqB;AACjC,KAAI,CAAC,IAAI,YACP,OAAM,mBAAmB,iBACvB,gBACA,2HACD;AAEH,QAAO,IAAI;;;;;AAMb,SAAgB,iBAAkC;AAChD,QAAO,qBAAqB,CAAC;;;;;AAM/B,SAAgB,kBAA2B;AAEzC,QADY,wBAAwB,UAAU,KAC/B;;;;;;;AAQjB,SAAgB,iBAA0C;AACxD,QAAO,wBAAwB,UAAU"}
@@ -1,3 +1,3 @@
1
- import "./service-context.js";
1
+ import { ServiceContext } from "./service-context.js";
2
2
  import { UserContext } from "./user-context.js";
3
3
  import { getExecutionContext } from "./execution-context.js";
@@ -1,5 +1,5 @@
1
- import { WorkspaceClient } from "../workspace-client/index.js";
2
- import "./user-context.js";
1
+ import { ClientOptions, WorkspaceClient } from "../workspace-client/index.js";
2
+ import { UserContext } from "./user-context.js";
3
3
 
4
4
  //#region src/context/service-context.d.ts
5
5
  /**
@@ -16,6 +16,58 @@ interface ServiceContextState {
16
16
  /** Promise that resolves to the workspace ID */
17
17
  workspaceId: Promise<string>;
18
18
  }
19
+ /**
20
+ * ServiceContext is a singleton that manages the service principal's
21
+ * WorkspaceClient and shared resources like warehouse/workspace IDs.
22
+ *
23
+ * It's initialized once at app startup and provides the foundation
24
+ * for both service principal and user context execution.
25
+ */
26
+ declare class ServiceContext {
27
+ private static instance;
28
+ private static initPromise;
29
+ /**
30
+ * Initialize the service context. Should be called once at app startup.
31
+ * Safe to call multiple times - will return the same instance.
32
+ *
33
+ * @param options - Which shared resources to resolve (derived from plugin manifests).
34
+ * @param client - Optional pre-configured WorkspaceClient to use instead
35
+ * of creating one from environment credentials.
36
+ */
37
+ static initialize(options?: {
38
+ warehouseId?: boolean;
39
+ }, client?: WorkspaceClient): Promise<ServiceContextState>;
40
+ /**
41
+ * Get the initialized service context.
42
+ * @throws Error if not initialized
43
+ */
44
+ static get(): ServiceContextState;
45
+ /**
46
+ * Check if the service context has been initialized.
47
+ */
48
+ static isInitialized(): boolean;
49
+ /**
50
+ * Create a user context from request headers.
51
+ *
52
+ * @param token - The user's access token from x-forwarded-access-token header
53
+ * @param userId - The user's ID from x-forwarded-user header
54
+ * @param userName - Optional user name
55
+ * @throws Error if token is not provided
56
+ */
57
+ static createUserContext(token: string, userId: string, userName?: string, userEmail?: string): UserContext;
58
+ /**
59
+ * Get the client options for WorkspaceClient.
60
+ * Exposed for testing purposes.
61
+ */
62
+ static getClientOptions(): ClientOptions;
63
+ private static createContext;
64
+ private static getWorkspaceId;
65
+ private static getWarehouseId;
66
+ /**
67
+ * Reset the service context. Only for testing purposes.
68
+ */
69
+ static reset(): void;
70
+ }
19
71
  //#endregion
20
- export { ServiceContextState };
72
+ export { ServiceContext, ServiceContextState };
21
73
  //# sourceMappingURL=service-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-context.d.ts","names":[],"sources":["../../src/context/service-context.ts"],"mappings":";;;;;;AAoBA;;UAAiB,mBAAA;EAEP;EAAR,MAAA,EAAQ,eAAA;EAMK;EAJb,aAAA;EAIoB;EAFpB,WAAA,GAAc,OAAA;EAJN;EAMR,WAAA,EAAa,OAAA;AAAA"}
1
+ {"version":3,"file":"service-context.d.ts","names":[],"sources":["../../src/context/service-context.ts"],"mappings":";;;;;;AAqBA;;UAAiB,mBAAA;EAEP;EAAR,MAAA,EAAQ,eAAA;EAMK;EAJb,aAAA;EAIoB;EAFpB,WAAA,GAAc,OAAA;EAJN;EAMR,WAAA,EAAa,OAAA;AAAA;;;;;;AAUf;;cAAa,cAAA;EAAA,eACI,QAAA;EAAA,eACA,WAAA;EAaZ;;;;;;;;EAAA,OAHU,UAAA,CACX,OAAA;IAAY,WAAA;EAAA,GACZ,MAAA,GAAS,eAAA,GACR,OAAA,CAAQ,mBAAA;EADA;;;;EAAA,OAmBJ,GAAA,CAAA,GAAO,mBAAA;EAAA;;;EAAA,OAaP,aAAA,CAAA;EAcL;;;;;;;;EAAA,OAFK,iBAAA,CACL,KAAA,UACA,MAAA,UACA,QAAA,WACA,SAAA,YACC,WAAA;EAqLI;;;;EAAA,OA1IA,gBAAA,CAAA,GAAoB,aAAA;EAAA,eAIN,aAAA;EAAA,eA2CA,cAAA;EAAA,eAuBA,cAAA;;;;SAoEd,KAAA,CAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"service-context.js","names":[],"sources":["../../src/context/service-context.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n AuthenticationError,\n ConfigurationError,\n InitializationError,\n} from \"../errors\";\nimport {\n type ClientOptions,\n ConfigError,\n createWorkspaceClient,\n type sql,\n type WorkspaceClient,\n} from \"../workspace-client\";\nimport { getClientOptions } from \"./client-options\";\nimport type { UserContext } from \"./user-context\";\n\n/**\n * Service context holds the service principal client and shared resources.\n * This is initialized once at app startup and shared across all requests.\n */\nexport interface ServiceContextState {\n /** WorkspaceClient authenticated as the service principal */\n client: WorkspaceClient;\n /** The service principal's user ID */\n serviceUserId: string;\n /** Promise that resolves to the warehouse ID (only present when a plugin requires `SQL_WAREHOUSE` resource) */\n warehouseId?: Promise<string>;\n /** Promise that resolves to the workspace ID */\n workspaceId: Promise<string>;\n}\n\n/**\n * ServiceContext is a singleton that manages the service principal's\n * WorkspaceClient and shared resources like warehouse/workspace IDs.\n *\n * It's initialized once at app startup and provides the foundation\n * for both service principal and user context execution.\n */\nexport class ServiceContext {\n private static instance: ServiceContextState | null = null;\n private static initPromise: Promise<ServiceContextState> | null = null;\n\n /**\n * Initialize the service context. Should be called once at app startup.\n * Safe to call multiple times - will return the same instance.\n *\n * @param options - Which shared resources to resolve (derived from plugin manifests).\n * @param client - Optional pre-configured WorkspaceClient to use instead\n * of creating one from environment credentials.\n */\n static async initialize(\n options?: { warehouseId?: boolean },\n client?: WorkspaceClient,\n ): Promise<ServiceContextState> {\n if (ServiceContext.instance) {\n return ServiceContext.instance;\n }\n\n if (ServiceContext.initPromise) {\n return ServiceContext.initPromise;\n }\n\n ServiceContext.initPromise = ServiceContext.createContext(options, client);\n ServiceContext.instance = await ServiceContext.initPromise;\n return ServiceContext.instance;\n }\n\n /**\n * Get the initialized service context.\n * @throws Error if not initialized\n */\n static get(): ServiceContextState {\n if (!ServiceContext.instance) {\n throw InitializationError.notInitialized(\n \"ServiceContext\",\n \"Call ServiceContext.initialize() first\",\n );\n }\n return ServiceContext.instance;\n }\n\n /**\n * Check if the service context has been initialized.\n */\n static isInitialized(): boolean {\n return ServiceContext.instance !== null;\n }\n\n /**\n * Create a user context from request headers.\n *\n * @param token - The user's access token from x-forwarded-access-token header\n * @param userId - The user's ID from x-forwarded-user header\n * @param userName - Optional user name\n * @throws Error if token is not provided\n */\n static createUserContext(\n token: string,\n userId: string,\n userName?: string,\n userEmail?: string,\n ): UserContext {\n if (!token) {\n throw AuthenticationError.missingToken(\"user token\");\n }\n\n const host = process.env.DATABRICKS_HOST;\n if (!host) {\n throw ConfigurationError.missingEnvVar(\"DATABRICKS_HOST\");\n }\n\n const serviceCtx = ServiceContext.get();\n\n // Create user client with the OAuth token from Databricks Apps\n // Note: We use authType: \"pat\" because the token is passed as a Bearer token\n // just like a PAT, even though it's technically an OAuth token\n const userClient = createWorkspaceClient({\n token,\n host,\n authType: \"pat\",\n clientOptions: getClientOptions(),\n });\n\n const tokenFingerprint = createHash(\"sha256\")\n .update(token)\n .digest(\"hex\")\n .slice(0, 16);\n\n return {\n client: userClient,\n userId,\n userName,\n userEmail,\n tokenFingerprint,\n warehouseId: serviceCtx.warehouseId,\n workspaceId: serviceCtx.workspaceId,\n isUserContext: true,\n };\n }\n\n /**\n * Get the client options for WorkspaceClient.\n * Exposed for testing purposes.\n */\n static getClientOptions(): ClientOptions {\n return getClientOptions();\n }\n\n private static async createContext(\n options?: { warehouseId?: boolean },\n client?: WorkspaceClient,\n ): Promise<ServiceContextState> {\n try {\n const wsClient =\n client ?? createWorkspaceClient({ clientOptions: getClientOptions() });\n\n const [resolvedWorkspaceId, currentUser, resolvedWarehouseId] =\n await Promise.all([\n ServiceContext.getWorkspaceId(wsClient),\n wsClient.currentUser.me(),\n options?.warehouseId\n ? ServiceContext.getWarehouseId(wsClient)\n : Promise.resolve(undefined as string | undefined),\n ]);\n\n if (!currentUser.id) {\n throw ConfigurationError.resourceNotFound(\"Service user ID\");\n }\n\n const warehouseId =\n options?.warehouseId && resolvedWarehouseId !== undefined\n ? Promise.resolve(resolvedWarehouseId)\n : undefined;\n\n return {\n client: wsClient,\n serviceUserId: currentUser.id,\n warehouseId,\n workspaceId: Promise.resolve(resolvedWorkspaceId),\n };\n } catch (e) {\n if (e instanceof ConfigError) {\n throw ConfigurationError.databricksAuthenticationSetupFailed(\n e.baseMessage,\n { cause: e },\n );\n }\n throw e;\n }\n }\n\n private static async getWorkspaceId(\n client: WorkspaceClient,\n ): Promise<string> {\n if (process.env.DATABRICKS_WORKSPACE_ID) {\n return process.env.DATABRICKS_WORKSPACE_ID;\n }\n\n const response = (await client.apiClient.request({\n path: \"/api/2.0/preview/scim/v2/Me\",\n method: \"GET\",\n headers: new Headers(),\n raw: false,\n query: {},\n responseHeaders: [\"x-databricks-org-id\"],\n })) as { \"x-databricks-org-id\": string };\n\n if (!response[\"x-databricks-org-id\"]) {\n throw ConfigurationError.resourceNotFound(\"Workspace ID\");\n }\n\n return response[\"x-databricks-org-id\"];\n }\n\n private static async getWarehouseId(\n client: WorkspaceClient,\n ): Promise<string> {\n if (process.env.DATABRICKS_WAREHOUSE_ID) {\n return process.env.DATABRICKS_WAREHOUSE_ID;\n }\n\n const agenticMode =\n process.env.DATABRICKS_APPS_AGENTIC_MODE === \"true\" ||\n process.env.DATABRICKS_APPS_AGENTIC_MODE === \"1\";\n\n if (process.env.NODE_ENV === \"development\" && !agenticMode) {\n const response = (await client.apiClient.request({\n path: \"/api/2.0/sql/warehouses\",\n method: \"GET\",\n headers: new Headers(),\n raw: false,\n query: {\n skip_cannot_use: \"true\",\n },\n })) as { warehouses: sql.EndpointInfo[] };\n\n const priorities: Record<sql.State, number> = {\n RUNNING: 0,\n STOPPED: 1,\n STARTING: 2,\n STOPPING: 3,\n DELETED: 99,\n DELETING: 99,\n };\n\n const warehouses = (response.warehouses || []).sort((a, b) => {\n return (\n priorities[a.state as sql.State] - priorities[b.state as sql.State]\n );\n });\n\n if (response.warehouses.length === 0) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"Please configure the DATABRICKS_WAREHOUSE_ID environment variable\",\n );\n }\n\n const firstWarehouse = warehouses[0];\n if (\n firstWarehouse.state === \"DELETED\" ||\n firstWarehouse.state === \"DELETING\" ||\n !firstWarehouse.id\n ) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"Please configure the DATABRICKS_WAREHOUSE_ID environment variable\",\n );\n }\n\n return firstWarehouse.id;\n }\n\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"Please configure the DATABRICKS_WAREHOUSE_ID environment variable\",\n );\n }\n\n /**\n * Reset the service context. Only for testing purposes.\n */\n static reset(): void {\n ServiceContext.instance = null;\n ServiceContext.initPromise = null;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service-context.js","names":[],"sources":["../../src/context/service-context.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport {\n AuthenticationError,\n ConfigurationError,\n InitializationError,\n} from \"../errors\";\nimport {\n type ClientOptions,\n ConfigError,\n createWorkspaceClient,\n type sql,\n type WorkspaceClient,\n} from \"../workspace-client\";\nimport { getClientOptions } from \"./client-options\";\nimport type { UserContext } from \"./user-context\";\n\n/**\n * Service context holds the service principal client and shared resources.\n * This is initialized once at app startup and shared across all requests.\n */\nexport interface ServiceContextState {\n /** WorkspaceClient authenticated as the service principal */\n client: WorkspaceClient;\n /** The service principal's user ID */\n serviceUserId: string;\n /** Promise that resolves to the warehouse ID (only present when a plugin requires `SQL_WAREHOUSE` resource) */\n warehouseId?: Promise<string>;\n /** Promise that resolves to the workspace ID */\n workspaceId: Promise<string>;\n}\n\n/**\n * ServiceContext is a singleton that manages the service principal's\n * WorkspaceClient and shared resources like warehouse/workspace IDs.\n *\n * It's initialized once at app startup and provides the foundation\n * for both service principal and user context execution.\n */\nexport class ServiceContext {\n private static instance: ServiceContextState | null = null;\n private static initPromise: Promise<ServiceContextState> | null = null;\n\n /**\n * Initialize the service context. Should be called once at app startup.\n * Safe to call multiple times - will return the same instance.\n *\n * @param options - Which shared resources to resolve (derived from plugin manifests).\n * @param client - Optional pre-configured WorkspaceClient to use instead\n * of creating one from environment credentials.\n */\n static async initialize(\n options?: { warehouseId?: boolean },\n client?: WorkspaceClient,\n ): Promise<ServiceContextState> {\n if (ServiceContext.instance) {\n return ServiceContext.instance;\n }\n\n if (ServiceContext.initPromise) {\n return ServiceContext.initPromise;\n }\n\n ServiceContext.initPromise = ServiceContext.createContext(options, client);\n ServiceContext.instance = await ServiceContext.initPromise;\n return ServiceContext.instance;\n }\n\n /**\n * Get the initialized service context.\n * @throws Error if not initialized\n */\n static get(): ServiceContextState {\n if (!ServiceContext.instance) {\n throw InitializationError.notInitialized(\n \"ServiceContext\",\n \"Call ServiceContext.initialize() first\",\n );\n }\n return ServiceContext.instance;\n }\n\n /**\n * Check if the service context has been initialized.\n */\n static isInitialized(): boolean {\n return ServiceContext.instance !== null;\n }\n\n /**\n * Create a user context from request headers.\n *\n * @param token - The user's access token from x-forwarded-access-token header\n * @param userId - The user's ID from x-forwarded-user header\n * @param userName - Optional user name\n * @throws Error if token is not provided\n */\n static createUserContext(\n token: string,\n userId: string,\n userName?: string,\n userEmail?: string,\n ): UserContext {\n if (!token) {\n throw AuthenticationError.missingToken(\"user token\");\n }\n\n const host = process.env.DATABRICKS_HOST;\n if (!host) {\n throw ConfigurationError.missingEnvVar(\"DATABRICKS_HOST\");\n }\n\n const serviceCtx = ServiceContext.get();\n\n // Create user client with the OAuth token from Databricks Apps\n // Note: We use authType: \"pat\" because the token is passed as a Bearer token\n // just like a PAT, even though it's technically an OAuth token\n const userClient = createWorkspaceClient({\n token,\n host,\n authType: \"pat\",\n clientOptions: getClientOptions(),\n });\n\n const tokenFingerprint = createHash(\"sha256\")\n .update(token)\n .digest(\"hex\")\n .slice(0, 16);\n\n return {\n client: userClient,\n userId,\n userName,\n userEmail,\n tokenFingerprint,\n warehouseId: serviceCtx.warehouseId,\n workspaceId: serviceCtx.workspaceId,\n isUserContext: true,\n };\n }\n\n /**\n * Get the client options for WorkspaceClient.\n * Exposed for testing purposes.\n */\n static getClientOptions(): ClientOptions {\n return getClientOptions();\n }\n\n private static async createContext(\n options?: { warehouseId?: boolean },\n client?: WorkspaceClient,\n ): Promise<ServiceContextState> {\n try {\n const wsClient =\n client ?? createWorkspaceClient({ clientOptions: getClientOptions() });\n\n const [resolvedWorkspaceId, currentUser, resolvedWarehouseId] =\n await Promise.all([\n ServiceContext.getWorkspaceId(wsClient),\n wsClient.currentUser.me(),\n options?.warehouseId\n ? ServiceContext.getWarehouseId(wsClient)\n : Promise.resolve(undefined as string | undefined),\n ]);\n\n if (!currentUser.id) {\n throw ConfigurationError.resourceNotFound(\"Service user ID\");\n }\n\n const warehouseId =\n options?.warehouseId && resolvedWarehouseId !== undefined\n ? Promise.resolve(resolvedWarehouseId)\n : undefined;\n\n return {\n client: wsClient,\n serviceUserId: currentUser.id,\n warehouseId,\n workspaceId: Promise.resolve(resolvedWorkspaceId),\n };\n } catch (e) {\n if (e instanceof ConfigError) {\n throw ConfigurationError.databricksAuthenticationSetupFailed(\n e.baseMessage,\n { cause: e },\n );\n }\n throw e;\n }\n }\n\n private static async getWorkspaceId(\n client: WorkspaceClient,\n ): Promise<string> {\n if (process.env.DATABRICKS_WORKSPACE_ID) {\n return process.env.DATABRICKS_WORKSPACE_ID;\n }\n\n const response = (await client.apiClient.request({\n path: \"/api/2.0/preview/scim/v2/Me\",\n method: \"GET\",\n headers: new Headers(),\n raw: false,\n query: {},\n responseHeaders: [\"x-databricks-org-id\"],\n })) as { \"x-databricks-org-id\": string };\n\n if (!response[\"x-databricks-org-id\"]) {\n throw ConfigurationError.resourceNotFound(\"Workspace ID\");\n }\n\n return response[\"x-databricks-org-id\"];\n }\n\n private static async getWarehouseId(\n client: WorkspaceClient,\n ): Promise<string> {\n if (process.env.DATABRICKS_WAREHOUSE_ID) {\n return process.env.DATABRICKS_WAREHOUSE_ID;\n }\n\n const agenticMode =\n process.env.DATABRICKS_APPS_AGENTIC_MODE === \"true\" ||\n process.env.DATABRICKS_APPS_AGENTIC_MODE === \"1\";\n\n if (process.env.NODE_ENV === \"development\" && !agenticMode) {\n const response = (await client.apiClient.request({\n path: \"/api/2.0/sql/warehouses\",\n method: \"GET\",\n headers: new Headers(),\n raw: false,\n query: {\n skip_cannot_use: \"true\",\n },\n })) as { warehouses: sql.EndpointInfo[] };\n\n const priorities: Record<sql.State, number> = {\n RUNNING: 0,\n STOPPED: 1,\n STARTING: 2,\n STOPPING: 3,\n DELETED: 99,\n DELETING: 99,\n };\n\n const warehouses = (response.warehouses || []).sort((a, b) => {\n return (\n priorities[a.state as sql.State] - priorities[b.state as sql.State]\n );\n });\n\n if (response.warehouses.length === 0) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"Please configure the DATABRICKS_WAREHOUSE_ID environment variable\",\n );\n }\n\n const firstWarehouse = warehouses[0];\n if (\n firstWarehouse.state === \"DELETED\" ||\n firstWarehouse.state === \"DELETING\" ||\n !firstWarehouse.id\n ) {\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"Please configure the DATABRICKS_WAREHOUSE_ID environment variable\",\n );\n }\n\n return firstWarehouse.id;\n }\n\n throw ConfigurationError.resourceNotFound(\n \"Warehouse ID\",\n \"Please configure the DATABRICKS_WAREHOUSE_ID environment variable\",\n );\n }\n\n /**\n * Reset the service context. Only for testing purposes.\n */\n static reset(): void {\n ServiceContext.instance = null;\n ServiceContext.initPromise = null;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"build-toolkit.js","names":[],"sources":["../../../src/core/agent/build-toolkit.ts"],"sourcesContent":["import type { AgentToolDefinition } from \"shared\";\nimport { applyToolkitOptions } from \"./toolkit-options\";\nimport type { ToolRegistry } from \"./tools/define-tool\";\nimport { toToolJSONSchema } from \"./tools/json-schema\";\nimport type { ToolkitEntry, ToolkitOptions } from \"./types\";\n\n/**\n * Converts a plugin's internal `ToolRegistry` into a keyed record of\n * `ToolkitEntry` markers suitable for spreading into an `AgentDefinition.tools`\n * record.\n *\n * The `opts` record controls shape and filtering:\n * - `prefix` — overrides the default `${pluginName}.` prefix; `\"\"` drops it.\n * - `only` — allowlist of local tool names to include (post-prefix).\n * - `except` — denylist of local names.\n * - `rename` — per-tool key remapping (applied after prefix/filter).\n *\n * Each entry carries `pluginName` + `localName` so the agents plugin can\n * dispatch back through `PluginContext.executeTool` for OBO + telemetry.\n */\nexport function buildToolkitEntries(\n pluginName: string,\n registry: ToolRegistry,\n opts: ToolkitOptions = {},\n): Record<string, ToolkitEntry> {\n const out: Record<string, ToolkitEntry> = {};\n\n for (const [localName, entry] of Object.entries(registry)) {\n const key = applyToolkitOptions(localName, pluginName, opts);\n if (key === null) continue;\n\n const parameters = toToolJSONSchema(\n entry.schema,\n ) as unknown as AgentToolDefinition[\"parameters\"];\n\n const def: AgentToolDefinition = {\n name: key,\n description: entry.description,\n parameters,\n };\n if (entry.annotations) {\n def.annotations = entry.annotations;\n }\n\n out[key] = {\n __toolkitRef: true,\n pluginName,\n localName,\n def,\n annotations: entry.annotations,\n autoInheritable: entry.autoInheritable,\n };\n }\n\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,SAAgB,oBACd,YACA,UACA,OAAuB,EAAE,EACK;CAC9B,MAAM,MAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,SAAS,EAAE;EACzD,MAAM,MAAM,oBAAoB,WAAW,YAAY,KAAK;AAC5D,MAAI,QAAQ,KAAM;EAElB,MAAM,aAAa,iBACjB,MAAM,OACP;EAED,MAAM,MAA2B;GAC/B,MAAM;GACN,aAAa,MAAM;GACnB;GACD;AACD,MAAI,MAAM,YACR,KAAI,cAAc,MAAM;AAG1B,MAAI,OAAO;GACT,cAAc;GACd;GACA;GACA;GACA,aAAa,MAAM;GACnB,iBAAiB,MAAM;GACxB;;AAGH,QAAO"}
1
+ {"version":3,"file":"build-toolkit.js","names":[],"sources":["../../../src/core/agent/build-toolkit.ts"],"sourcesContent":["import type { AgentToolDefinition } from \"shared\";\n\nimport { applyToolkitOptions } from \"./toolkit-options\";\nimport type { ToolRegistry } from \"./tools/define-tool\";\nimport { toToolJSONSchema } from \"./tools/json-schema\";\nimport type { ToolkitEntry, ToolkitOptions } from \"./types\";\n\n/**\n * Converts a plugin's internal `ToolRegistry` into a keyed record of\n * `ToolkitEntry` markers suitable for spreading into an `AgentDefinition.tools`\n * record.\n *\n * The `opts` record controls shape and filtering:\n * - `prefix` — overrides the default `${pluginName}.` prefix; `\"\"` drops it.\n * - `only` — allowlist of local tool names to include (post-prefix).\n * - `except` — denylist of local names.\n * - `rename` — per-tool key remapping (applied after prefix/filter).\n *\n * Each entry carries `pluginName` + `localName` so the agents plugin can\n * dispatch back through `PluginContext.executeTool` for OBO + telemetry.\n */\nexport function buildToolkitEntries(\n pluginName: string,\n registry: ToolRegistry,\n opts: ToolkitOptions = {},\n): Record<string, ToolkitEntry> {\n const out: Record<string, ToolkitEntry> = {};\n\n for (const [localName, entry] of Object.entries(registry)) {\n const key = applyToolkitOptions(localName, pluginName, opts);\n if (key === null) continue;\n\n const parameters = toToolJSONSchema(\n entry.schema,\n ) as unknown as AgentToolDefinition[\"parameters\"];\n\n const def: AgentToolDefinition = {\n name: key,\n description: entry.description,\n parameters,\n };\n if (entry.annotations) {\n def.annotations = entry.annotations;\n }\n\n out[key] = {\n __toolkitRef: true,\n pluginName,\n localName,\n def,\n annotations: entry.annotations,\n autoInheritable: entry.autoInheritable,\n };\n }\n\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,SAAgB,oBACd,YACA,UACA,OAAuB,EAAE,EACK;CAC9B,MAAM,MAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,SAAS,EAAE;EACzD,MAAM,MAAM,oBAAoB,WAAW,YAAY,KAAK;AAC5D,MAAI,QAAQ,KAAM;EAElB,MAAM,aAAa,iBACjB,MAAM,OACP;EAED,MAAM,MAA2B;GAC/B,MAAM;GACN,aAAa,MAAM;GACnB;GACD;AACD,MAAI,MAAM,YACR,KAAI,cAAc,MAAM;AAG1B,MAAI,OAAO;GACT,cAAc;GACd;GACA;GACA;GACA,aAAa,MAAM;GACnB,iBAAiB,MAAM;GACxB;;AAGH,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"load-agents.d.ts","names":[],"sources":["../../../src/core/agent/load-agents.ts"],"mappings":";;;;;UAkBU,eAAA;EACR,OAAA,GAAU,IAAA,GAAO,cAAA,KAAmB,MAAA;AAAA;AAAA,UAGrB,WAAA;EAJQ;EAMvB,YAAA,GAAe,YAAA,GAAe,OAAA,CAAQ,YAAA;EALI;EAO1C,cAAA,GAAiB,MAAA,SAAe,SAAA;EAPf;;;;;AAGnB;EAWE,OAAA,GAAU,GAAA,SAAY,eAAA;;;;;;;;EAQtB,UAAA,GAAa,MAAA,SAAe,eAAA;AAAA;AAAA,UAGb,UAAA;EAHI;EAKnB,IAAA,EAAM,MAAA,SAAe,eAAA;EAtBrB;EAwBA,YAAA;AAAA;;;;;;iBAgEc,uBAAA,CAAwB,QAAA;;;;;;;;;iBA+BlB,iBAAA,CACpB,QAAA,UACA,GAAA,EAAK,WAAA,GACJ,OAAA,CAAQ,eAAA;;;;;;;;;;;;;;;;;;;iBAgCW,iBAAA,CACpB,GAAA,UACA,GAAA,EAAK,WAAA,GACJ,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"load-agents.d.ts","names":[],"sources":["../../../src/core/agent/load-agents.ts"],"mappings":";;;;;UAoBU,eAAA;EACR,OAAA,GAAU,IAAA,GAAO,cAAA,KAAmB,MAAA;AAAA;AAAA,UAGrB,WAAA;EAJQ;EAMvB,YAAA,GAAe,YAAA,GAAe,OAAA,CAAQ,YAAA;EALI;EAO1C,cAAA,GAAiB,MAAA,SAAe,SAAA;EAPf;;;;;AAGnB;EAWE,OAAA,GAAU,GAAA,SAAY,eAAA;;;;;;;;EAQtB,UAAA,GAAa,MAAA,SAAe,eAAA;AAAA;AAAA,UAGb,UAAA;EAHI;EAKnB,IAAA,EAAM,MAAA,SAAe,eAAA;EAtBrB;EAwBA,YAAA;AAAA;;;;;;iBAgEc,uBAAA,CAAwB,QAAA;;;;;;;;;iBA+BlB,iBAAA,CACpB,QAAA,UACA,GAAA,EAAK,WAAA,GACJ,OAAA,CAAQ,eAAA;;;;;;;;;;;;;;;;;;;iBAgCW,iBAAA,CACpB,GAAA,UACA,GAAA,EAAK,WAAA,GACJ,OAAA,CAAQ,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"load-agents.js","names":[],"sources":["../../../src/core/agent/load-agents.ts"],"sourcesContent":["import type { Dirent } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport yaml from \"js-yaml\";\nimport type { AgentAdapter } from \"shared\";\nimport type { GenerationParams } from \"../../agents/databricks\";\nimport type {\n AgentDefinition,\n AgentTool,\n BaseSystemPromptOption,\n ToolkitEntry,\n ToolkitOptions,\n} from \"../../core/agent/types\";\nimport { isToolkitEntry } from \"../../core/agent/types\";\nimport { createLogger } from \"../../logging/logger\";\n\nconst logger = createLogger(\"agents:loader\");\n\ninterface ToolkitProvider {\n toolkit: (opts?: ToolkitOptions) => Record<string, unknown>;\n}\n\nexport interface LoadContext {\n /** Default model when frontmatter has no `endpoint` and the def has no `model`. */\n defaultModel?: AgentAdapter | Promise<AgentAdapter> | string;\n /** Ambient tool library referenced by frontmatter `tools: [key1, key2]`. */\n availableTools?: Record<string, AgentTool>;\n /**\n * Registered plugin toolkits referenced by `plugin:NAME` entries in the\n * unified `tools:` frontmatter list. Keyed by plugin name; each value\n * exposes the same `toolkit(opts?)` surface as the `plugins` argument to\n * `tools(plugins) => Record<...>` in the code form.\n */\n plugins?: Map<string, ToolkitProvider>;\n /**\n * Code-defined agents contributed by `agents({ agents: { ... } })`. The\n * directory loader resolves `agents:` frontmatter references against\n * these alongside sibling markdown files, so a markdown parent can\n * delegate to a code-defined child. Code-defined names win on collision\n * with markdown names, matching the plugin's top-level merge precedence.\n */\n codeAgents?: Record<string, AgentDefinition>;\n}\n\nexport interface LoadResult {\n /** Agent definitions keyed by agent id (directory name under `dir`). */\n defs: Record<string, AgentDefinition>;\n /** First agent with `default: true` frontmatter (sorted id order), or `null`. */\n defaultAgent: string | null;\n}\n\ninterface Frontmatter {\n endpoint?: string;\n model?: string;\n /**\n * Unified tool list. Each entry is one of:\n *\n * - **`plugin:<name>`** (string) — pull every tool from the named plugin.\n * - **`plugin:<name>: [tool1, tool2]`** — pull only the listed tools\n * (shorthand for `{ only: [...] }`).\n * - **`plugin:<name>: { ...ToolkitOptions }`** — pass full\n * `prefix` / `only` / `except` / `rename` options.\n * - **`<key>`** (string, no `plugin:` prefix) — ambient tool name\n * resolved against the `agents({ tools: { ... } })` config.\n *\n * Mirrors the TS function form `tools(plugins) { ... }` where plugin\n * tools and inline tools live in the same record.\n */\n tools?: FrontmatterToolEntry[];\n /**\n * Other agent ids to expose as sub-agents. Each becomes an `agent-<id>`\n * tool at runtime. Resolution happens at directory-load time in\n * {@link loadAgentsFromDir}; the single-file {@link loadAgentFromFile} path\n * rejects non-empty values since there are no siblings to resolve against.\n */\n agents?: string[];\n maxSteps?: number;\n maxTokens?: number;\n /**\n * Optional OpenAI-compatible generation params forwarded to the serving\n * request body (`temperature`, `top_p`, `stop`, `frequency_penalty`,\n * `presence_penalty`). Parsed defensively in {@link buildDefinition}.\n */\n generationParams?: Record<string, unknown>;\n default?: boolean;\n baseSystemPrompt?: false | string;\n ephemeral?: boolean;\n}\n\n/**\n * Each item in {@link Frontmatter.tools}. Strings are either ambient tool\n * names (no prefix) or bare plugin references (`plugin:NAME`). Objects are\n * single-key mappings whose key is `plugin:NAME` and whose value is either\n * an array of local tool names (sugar for `{ only: [...] }`) or a full\n * `ToolkitOptions` record.\n *\n * Named `FrontmatterToolEntry` to avoid colliding with the exported\n * `ToolEntry` from `tools/define-tool.ts` — that is the plugin-author API\n * surface (`defineTool({ ... }) : ToolEntry`); this is the frontmatter\n * parse type. They are unrelated and live in different layers.\n */\ntype FrontmatterToolEntry =\n | string\n | { [key: string]: ToolkitOptions | string[] };\n\nconst PLUGIN_PREFIX = \"plugin:\";\n\n/**\n * Derives the logical agent id from a markdown path. When the file is named\n * `agent.md`, the id is the parent directory name (folder-based layout);\n * otherwise the id is the file stem (e.g. legacy single-file paths).\n */\nexport function agentIdFromMarkdownPath(filePath: string): string {\n const normalized = path.normalize(filePath);\n const base = path.basename(normalized);\n const parent = path.basename(path.dirname(normalized));\n if (base === \"agent.md\" && parent && parent !== \".\" && parent !== \"..\") {\n return parent;\n }\n return path.basename(normalized, \".md\");\n}\n\nconst ALLOWED_KEYS = new Set([\n \"endpoint\",\n \"model\",\n \"tools\",\n \"agents\",\n \"maxSteps\",\n \"maxTokens\",\n \"generationParams\",\n \"default\",\n \"baseSystemPrompt\",\n \"ephemeral\",\n]);\n\n/**\n * Loads a single markdown agent file and resolves its frontmatter against\n * registered plugin toolkits + ambient tool library.\n *\n * Rejects non-empty `agents:` frontmatter because single-file loads have\n * no siblings to resolve sub-agent references against — callers must use\n * {@link loadAgentsFromDir} when markdown agents delegate to one another.\n */\nexport async function loadAgentFromFile(\n filePath: string,\n ctx: LoadContext,\n): Promise<AgentDefinition> {\n const raw = await fs.readFile(filePath, \"utf-8\");\n const name = agentIdFromMarkdownPath(filePath);\n const { data } = parseFrontmatter(raw, filePath);\n if (Array.isArray(data?.agents) && data.agents.length > 0) {\n throw new Error(\n `Agent '${name}' (${filePath}) declares 'agents:' in frontmatter, ` +\n `which requires loadAgentsFromDir to resolve sibling references. ` +\n `Use loadAgentsFromDir, or wire sub-agents in code via createAgent({ agents: { ... } }).`,\n );\n }\n return buildDefinition(name, raw, filePath, ctx);\n}\n\n/**\n * Scans a directory for one subdirectory per agent, each containing\n * `agent.md` (frontmatter + body). Produces an `AgentDefinition` record keyed\n * by agent id (folder name). Throws on frontmatter errors or unresolved\n * references. Returns an empty map if the directory does not exist.\n *\n * Legacy top-level `*.md` files are rejected with an error — migrate each to\n * `<id>/agent.md` under a sibling folder named for the agent id.\n *\n * Runs in two passes so sub-agent references in frontmatter (`agents: [...]`)\n * can be resolved regardless of directory iteration order:\n *\n * 1. Build every agent's definition from its own `agent.md`.\n * 2. Walk `agents:` references and wire `def.agents = { child: childDef }`\n * by looking them up in the complete map. Dangling names and\n * self-references fail loudly; mutual delegation is allowed and bounded\n * at runtime by `limits.maxSubAgentDepth`.\n */\nexport async function loadAgentsFromDir(\n dir: string,\n ctx: LoadContext,\n): Promise<LoadResult> {\n let entries: Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { defs: {}, defaultAgent: null };\n }\n throw err;\n }\n const orphanMd = entries\n .filter((e) => e.isFile() && e.name.endsWith(\".md\"))\n .map((e) => e.name)\n .sort();\n\n if (orphanMd.length > 0) {\n const hint = orphanMd\n .map((f) => `${path.basename(f, \".md\")}/agent.md`)\n .join(\", \");\n throw new Error(\n `Agents directory contains unsupported top-level markdown file(s): ${orphanMd.join(\", \")}. ` +\n `Use one folder per agent with a fixed entry file, e.g. ${hint}.`,\n );\n }\n\n /** Reserved folder name until per-agent skills land; not an agent package. */\n const RESERVED_DIRS = new Set([\"skills\"]);\n\n const agentIds = entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .filter((name) => !RESERVED_DIRS.has(name))\n .sort();\n\n const defs: Record<string, AgentDefinition> = {};\n const subAgentRefs: Record<string, string[]> = {};\n let defaultAgent: string | null = null;\n\n // Pass 1: build every agent's definition; collect sub-agent refs.\n for (const id of agentIds) {\n const agentPath = path.join(dir, id, \"agent.md\");\n let raw: string;\n try {\n raw = await fs.readFile(agentPath, \"utf-8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new Error(\n `Agents subdirectory '${path.join(dir, id)}' must contain agent.md.`,\n );\n }\n throw err;\n }\n defs[id] = buildDefinition(id, raw, agentPath, ctx);\n const { data } = parseFrontmatter(raw, agentPath);\n if (data?.agents !== undefined) {\n subAgentRefs[id] = normalizeAgentsFrontmatter(data.agents, id, agentPath);\n }\n if (data?.default === true && !defaultAgent) {\n defaultAgent = id;\n }\n }\n\n // Pass 2: resolve sub-agent references against the complete defs map.\n // Code-defined agents (ctx.codeAgents) take precedence over markdown ones\n // with the same name, matching the plugin's top-level merge behaviour.\n for (const [name, refs] of Object.entries(subAgentRefs)) {\n if (refs.length === 0) continue;\n const children: Record<string, AgentDefinition> = {};\n const missing: string[] = [];\n for (const ref of refs) {\n if (ref === name) {\n throw new Error(\n `Agent '${name}' (${path.join(dir, name, \"agent.md\")}) cannot reference itself in 'agents:'.`,\n );\n }\n const sibling = ctx.codeAgents?.[ref] ?? defs[ref];\n if (!sibling) {\n missing.push(ref);\n continue;\n }\n children[ref] = sibling;\n }\n if (missing.length > 0) {\n const available =\n [...Object.keys(ctx.codeAgents ?? {}), ...Object.keys(defs)]\n .sort()\n .join(\", \") || \"<none>\";\n throw new Error(\n `Agent '${name}' references sub-agent(s) '${missing.join(\", \")}' in 'agents:', ` +\n `but no markdown or code agent(s) with those names exist. ` +\n `Available: ${available}.`,\n );\n }\n defs[name].agents = children;\n }\n\n return { defs, defaultAgent };\n}\n\n/**\n * Validates that `agents:` frontmatter is an array of non-empty strings and\n * returns it with duplicates removed. Throws with a clear per-file message\n * on malformed input rather than silently ignoring.\n */\nfunction normalizeAgentsFrontmatter(\n value: unknown,\n agentName: string,\n filePath: string,\n): string[] {\n if (!Array.isArray(value)) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has invalid 'agents:' frontmatter: ` +\n `expected an array of sibling agent ids, got ${typeof value}.`,\n );\n }\n const out: string[] = [];\n const seen = new Set<string>();\n for (const item of value) {\n if (typeof item !== \"string\" || item.trim() === \"\") {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has invalid 'agents:' entry: ` +\n `expected non-empty string, got ${JSON.stringify(item)}.`,\n );\n }\n if (seen.has(item)) continue;\n seen.add(item);\n out.push(item);\n }\n return out;\n}\n\n/** Exposed for tests. Parses `--- yaml ---\\nbody` and validates frontmatter keys. */\nexport function parseFrontmatter(\n raw: string,\n sourcePath?: string,\n): { data: Frontmatter | null; content: string } {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!match) {\n return { data: null, content: raw.trim() };\n }\n let parsed: unknown;\n try {\n parsed = yaml.load(match[1]);\n } catch (err) {\n const src = sourcePath ? ` (${sourcePath})` : \"\";\n throw new Error(\n `Invalid YAML frontmatter${src}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (parsed === null || parsed === undefined) {\n return { data: {}, content: match[2].trim() };\n }\n if (typeof parsed !== \"object\" || Array.isArray(parsed)) {\n const src = sourcePath ? ` (${sourcePath})` : \"\";\n throw new Error(`Frontmatter must be a YAML object${src}`);\n }\n const data = parsed as Record<string, unknown>;\n for (const key of Object.keys(data)) {\n if (!ALLOWED_KEYS.has(key)) {\n logger.warn(\n \"Ignoring unknown frontmatter key '%s' in %s\",\n key,\n sourcePath ?? \"<inline>\",\n );\n }\n }\n return { data: data as Frontmatter, content: match[2].trim() };\n}\n\nconst isNumber = (v: unknown): v is number => typeof v === \"number\";\n\n/**\n * Per-key validators for {@link GenerationParams} frontmatter. Keyed by wire\n * name and typed as `Record<keyof GenerationParams, ...>`, so a new param on\n * the interface is a compile error until it gets an entry here — parsing,\n * unknown-key detection, and warnings all derive from this one table.\n */\nconst GENERATION_PARAM_SPECS: Record<\n keyof GenerationParams,\n { label: string; valid: (v: unknown) => boolean }\n> = {\n temperature: { label: \"number\", valid: isNumber },\n top_p: { label: \"number\", valid: isNumber },\n frequency_penalty: { label: \"number\", valid: isNumber },\n presence_penalty: { label: \"number\", valid: isNumber },\n stop: {\n label: \"string or string[]\",\n valid: (v) =>\n typeof v === \"string\" ||\n (Array.isArray(v) && v.every((s) => typeof s === \"string\")),\n },\n};\n\n/**\n * Defensively maps a frontmatter `generationParams` map to {@link GenerationParams}.\n * Picks only known keys with the expected wire types. A key present with the\n * wrong type (e.g. `temperature: \"0.5\"`) or an unknown key (e.g. `top-p`) is\n * dropped and logged at warn level, so a silently-ignored param is visible\n * rather than mistaken for \"applied\". Returns `undefined` when no valid key is\n * present.\n */\nfunction parseGenerationParams(\n value: unknown,\n sourcePath?: string,\n): GenerationParams | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return undefined;\n }\n const raw = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n const where = sourcePath ?? \"<inline>\";\n\n for (const [key, v] of Object.entries(raw)) {\n const spec = GENERATION_PARAM_SPECS[key as keyof GenerationParams];\n if (!spec) {\n logger.warn(\n \"Ignoring unknown generationParams key '%s' in %s\",\n key,\n where,\n );\n } else if (spec.valid(v)) {\n out[key] = v;\n } else {\n logger.warn(\n \"Ignoring generationParams.%s in %s: expected %s, got %s\",\n key,\n where,\n spec.label,\n typeof v,\n );\n }\n }\n\n return Object.keys(out).length > 0 ? (out as GenerationParams) : undefined;\n}\n\nfunction buildDefinition(\n name: string,\n raw: string,\n filePath: string,\n ctx: LoadContext,\n): AgentDefinition {\n const { data, content } = parseFrontmatter(raw, filePath);\n const fm: Frontmatter = data ?? {};\n\n const tools = resolveFrontmatterTools(name, fm, filePath, ctx);\n const model = fm.model ?? fm.endpoint ?? ctx.defaultModel;\n\n let baseSystemPrompt: BaseSystemPromptOption | undefined;\n if (fm.baseSystemPrompt === false) baseSystemPrompt = false;\n else if (typeof fm.baseSystemPrompt === \"string\")\n baseSystemPrompt = fm.baseSystemPrompt;\n\n return {\n name,\n instructions: content,\n model,\n tools: Object.keys(tools).length > 0 ? tools : undefined,\n maxSteps: typeof fm.maxSteps === \"number\" ? fm.maxSteps : undefined,\n maxTokens: typeof fm.maxTokens === \"number\" ? fm.maxTokens : undefined,\n generationParams: parseGenerationParams(fm.generationParams, filePath),\n baseSystemPrompt,\n ephemeral: typeof fm.ephemeral === \"boolean\" ? fm.ephemeral : undefined,\n };\n}\n\nfunction resolveFrontmatterTools(\n agentName: string,\n fm: Frontmatter,\n filePath: string,\n ctx: LoadContext,\n): Record<string, AgentTool> {\n const out: Record<string, AgentTool> = {};\n const pluginIdx = ctx.plugins ?? new Map<string, ToolkitProvider>();\n\n for (const entry of fm.tools ?? []) {\n const parsed = parseToolEntry(entry, filePath, agentName);\n if (parsed.kind === \"plugin\") {\n const provider = pluginIdx.get(parsed.pluginName);\n if (!provider) {\n const available =\n pluginIdx.size > 0\n ? Array.from(pluginIdx.keys()).join(\", \")\n : \"<none>\";\n throw new Error(\n `Agent '${agentName}' (${filePath}) references 'plugin:${parsed.pluginName}', but plugin '${parsed.pluginName}' is not registered. Available: ${available}`,\n );\n }\n const entries = provider.toolkit(parsed.opts) as Record<string, unknown>;\n for (const [key, value] of Object.entries(entries)) {\n if (!isToolkitEntry(value)) {\n throw new Error(\n `Plugin '${parsed.pluginName}'.toolkit() returned a value at key '${key}' that is not a ToolkitEntry`,\n );\n }\n out[key] = value as ToolkitEntry;\n }\n } else {\n const tool = ctx.availableTools?.[parsed.toolName];\n if (!tool) {\n const available = ctx.availableTools\n ? Object.keys(ctx.availableTools).join(\", \")\n : \"<none>\";\n throw new Error(\n `Agent '${agentName}' (${filePath}) references ambient tool '${parsed.toolName}', which is not in the agents() plugin's tools field. Available: ${available}. ` +\n \"If you meant to reference a plugin, use the 'plugin:NAME' prefix.\",\n );\n }\n out[parsed.toolName] = tool;\n }\n }\n\n return out;\n}\n\ntype ParsedToolEntry =\n | { kind: \"plugin\"; pluginName: string; opts: ToolkitOptions | undefined }\n | { kind: \"ambient\"; toolName: string };\n\n/**\n * Classify one item in the `tools:` frontmatter list into either a plugin\n * reference (with optional ToolkitOptions) or an ambient tool lookup.\n *\n * Strings starting with `plugin:` are bare plugin references. Strings\n * without the prefix are ambient tool names. Object entries are\n * single-key mappings keyed by `plugin:NAME`; the value is either an\n * array (sugar for `{ only: [...] }`) or a full `ToolkitOptions` record.\n */\nfunction parseToolEntry(\n entry: FrontmatterToolEntry,\n filePath: string,\n agentName: string,\n): ParsedToolEntry {\n if (typeof entry === \"string\") {\n if (entry.startsWith(PLUGIN_PREFIX)) {\n const pluginName = entry.slice(PLUGIN_PREFIX.length);\n if (pluginName.length === 0) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty plugin name in 'plugin:'.`,\n );\n }\n return { kind: \"plugin\", pluginName, opts: undefined };\n }\n if (entry.length === 0) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty string in 'tools:'.`,\n );\n }\n return { kind: \"ambient\", toolName: entry };\n }\n if (typeof entry !== \"object\" || entry === null) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has invalid 'tools:' entry: ${JSON.stringify(entry)}`,\n );\n }\n const keys = Object.keys(entry);\n if (keys.length !== 1) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) 'tools:' object entry must have exactly one key, got: ${keys.join(\", \")}`,\n );\n }\n const key = keys[0];\n // Bare `- plugin:` (no name after the colon) parses as a mapping with the\n // key `\"plugin\"`. Catch that as a friendly error rather than dumping it\n // through the generic \"expected key 'plugin:NAME'\" branch.\n if (key === \"plugin\") {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty plugin name in 'plugin:'.`,\n );\n }\n if (!key.startsWith(PLUGIN_PREFIX)) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) 'tools:' object entries are reserved for plugin references; expected key 'plugin:NAME', got '${key}'. ` +\n \"Use a bare string for ambient tools (e.g. `- get_weather`).\",\n );\n }\n const pluginName = key.slice(PLUGIN_PREFIX.length);\n if (pluginName.length === 0) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty plugin name in 'plugin:'.`,\n );\n }\n const value = entry[key];\n if (Array.isArray(value)) {\n return { kind: \"plugin\", pluginName, opts: { only: value } };\n }\n if (typeof value === \"object\" && value !== null) {\n return {\n kind: \"plugin\",\n pluginName,\n opts: value as ToolkitOptions,\n };\n }\n throw new Error(\n `Agent '${agentName}' (${filePath}) 'plugin:${pluginName}' options must be an array of tool names or a ToolkitOptions object.`,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"load-agents.js","names":[],"sources":["../../../src/core/agent/load-agents.ts"],"sourcesContent":["import type { Dirent } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport yaml from \"js-yaml\";\nimport type { AgentAdapter } from \"shared\";\n\nimport type { GenerationParams } from \"../../agents/databricks\";\nimport type {\n AgentDefinition,\n AgentTool,\n BaseSystemPromptOption,\n ToolkitEntry,\n ToolkitOptions,\n} from \"../../core/agent/types\";\nimport { isToolkitEntry } from \"../../core/agent/types\";\nimport { createLogger } from \"../../logging/logger\";\n\nconst logger = createLogger(\"agents:loader\");\n\ninterface ToolkitProvider {\n toolkit: (opts?: ToolkitOptions) => Record<string, unknown>;\n}\n\nexport interface LoadContext {\n /** Default model when frontmatter has no `endpoint` and the def has no `model`. */\n defaultModel?: AgentAdapter | Promise<AgentAdapter> | string;\n /** Ambient tool library referenced by frontmatter `tools: [key1, key2]`. */\n availableTools?: Record<string, AgentTool>;\n /**\n * Registered plugin toolkits referenced by `plugin:NAME` entries in the\n * unified `tools:` frontmatter list. Keyed by plugin name; each value\n * exposes the same `toolkit(opts?)` surface as the `plugins` argument to\n * `tools(plugins) => Record<...>` in the code form.\n */\n plugins?: Map<string, ToolkitProvider>;\n /**\n * Code-defined agents contributed by `agents({ agents: { ... } })`. The\n * directory loader resolves `agents:` frontmatter references against\n * these alongside sibling markdown files, so a markdown parent can\n * delegate to a code-defined child. Code-defined names win on collision\n * with markdown names, matching the plugin's top-level merge precedence.\n */\n codeAgents?: Record<string, AgentDefinition>;\n}\n\nexport interface LoadResult {\n /** Agent definitions keyed by agent id (directory name under `dir`). */\n defs: Record<string, AgentDefinition>;\n /** First agent with `default: true` frontmatter (sorted id order), or `null`. */\n defaultAgent: string | null;\n}\n\ninterface Frontmatter {\n endpoint?: string;\n model?: string;\n /**\n * Unified tool list. Each entry is one of:\n *\n * - **`plugin:<name>`** (string) — pull every tool from the named plugin.\n * - **`plugin:<name>: [tool1, tool2]`** — pull only the listed tools\n * (shorthand for `{ only: [...] }`).\n * - **`plugin:<name>: { ...ToolkitOptions }`** — pass full\n * `prefix` / `only` / `except` / `rename` options.\n * - **`<key>`** (string, no `plugin:` prefix) — ambient tool name\n * resolved against the `agents({ tools: { ... } })` config.\n *\n * Mirrors the TS function form `tools(plugins) { ... }` where plugin\n * tools and inline tools live in the same record.\n */\n tools?: FrontmatterToolEntry[];\n /**\n * Other agent ids to expose as sub-agents. Each becomes an `agent-<id>`\n * tool at runtime. Resolution happens at directory-load time in\n * {@link loadAgentsFromDir}; the single-file {@link loadAgentFromFile} path\n * rejects non-empty values since there are no siblings to resolve against.\n */\n agents?: string[];\n maxSteps?: number;\n maxTokens?: number;\n /**\n * Optional OpenAI-compatible generation params forwarded to the serving\n * request body (`temperature`, `top_p`, `stop`, `frequency_penalty`,\n * `presence_penalty`). Parsed defensively in {@link buildDefinition}.\n */\n generationParams?: Record<string, unknown>;\n default?: boolean;\n baseSystemPrompt?: false | string;\n ephemeral?: boolean;\n}\n\n/**\n * Each item in {@link Frontmatter.tools}. Strings are either ambient tool\n * names (no prefix) or bare plugin references (`plugin:NAME`). Objects are\n * single-key mappings whose key is `plugin:NAME` and whose value is either\n * an array of local tool names (sugar for `{ only: [...] }`) or a full\n * `ToolkitOptions` record.\n *\n * Named `FrontmatterToolEntry` to avoid colliding with the exported\n * `ToolEntry` from `tools/define-tool.ts` — that is the plugin-author API\n * surface (`defineTool({ ... }) : ToolEntry`); this is the frontmatter\n * parse type. They are unrelated and live in different layers.\n */\ntype FrontmatterToolEntry =\n | string\n | { [key: string]: ToolkitOptions | string[] };\n\nconst PLUGIN_PREFIX = \"plugin:\";\n\n/**\n * Derives the logical agent id from a markdown path. When the file is named\n * `agent.md`, the id is the parent directory name (folder-based layout);\n * otherwise the id is the file stem (e.g. legacy single-file paths).\n */\nexport function agentIdFromMarkdownPath(filePath: string): string {\n const normalized = path.normalize(filePath);\n const base = path.basename(normalized);\n const parent = path.basename(path.dirname(normalized));\n if (base === \"agent.md\" && parent && parent !== \".\" && parent !== \"..\") {\n return parent;\n }\n return path.basename(normalized, \".md\");\n}\n\nconst ALLOWED_KEYS = new Set([\n \"endpoint\",\n \"model\",\n \"tools\",\n \"agents\",\n \"maxSteps\",\n \"maxTokens\",\n \"generationParams\",\n \"default\",\n \"baseSystemPrompt\",\n \"ephemeral\",\n]);\n\n/**\n * Loads a single markdown agent file and resolves its frontmatter against\n * registered plugin toolkits + ambient tool library.\n *\n * Rejects non-empty `agents:` frontmatter because single-file loads have\n * no siblings to resolve sub-agent references against — callers must use\n * {@link loadAgentsFromDir} when markdown agents delegate to one another.\n */\nexport async function loadAgentFromFile(\n filePath: string,\n ctx: LoadContext,\n): Promise<AgentDefinition> {\n const raw = await fs.readFile(filePath, \"utf-8\");\n const name = agentIdFromMarkdownPath(filePath);\n const { data } = parseFrontmatter(raw, filePath);\n if (Array.isArray(data?.agents) && data.agents.length > 0) {\n throw new Error(\n `Agent '${name}' (${filePath}) declares 'agents:' in frontmatter, ` +\n `which requires loadAgentsFromDir to resolve sibling references. ` +\n `Use loadAgentsFromDir, or wire sub-agents in code via createAgent({ agents: { ... } }).`,\n );\n }\n return buildDefinition(name, raw, filePath, ctx);\n}\n\n/**\n * Scans a directory for one subdirectory per agent, each containing\n * `agent.md` (frontmatter + body). Produces an `AgentDefinition` record keyed\n * by agent id (folder name). Throws on frontmatter errors or unresolved\n * references. Returns an empty map if the directory does not exist.\n *\n * Legacy top-level `*.md` files are rejected with an error — migrate each to\n * `<id>/agent.md` under a sibling folder named for the agent id.\n *\n * Runs in two passes so sub-agent references in frontmatter (`agents: [...]`)\n * can be resolved regardless of directory iteration order:\n *\n * 1. Build every agent's definition from its own `agent.md`.\n * 2. Walk `agents:` references and wire `def.agents = { child: childDef }`\n * by looking them up in the complete map. Dangling names and\n * self-references fail loudly; mutual delegation is allowed and bounded\n * at runtime by `limits.maxSubAgentDepth`.\n */\nexport async function loadAgentsFromDir(\n dir: string,\n ctx: LoadContext,\n): Promise<LoadResult> {\n let entries: Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { defs: {}, defaultAgent: null };\n }\n throw err;\n }\n const orphanMd = entries\n .filter((e) => e.isFile() && e.name.endsWith(\".md\"))\n .map((e) => e.name)\n .sort();\n\n if (orphanMd.length > 0) {\n const hint = orphanMd\n .map((f) => `${path.basename(f, \".md\")}/agent.md`)\n .join(\", \");\n throw new Error(\n `Agents directory contains unsupported top-level markdown file(s): ${orphanMd.join(\", \")}. ` +\n `Use one folder per agent with a fixed entry file, e.g. ${hint}.`,\n );\n }\n\n /** Reserved folder name until per-agent skills land; not an agent package. */\n const RESERVED_DIRS = new Set([\"skills\"]);\n\n const agentIds = entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .filter((name) => !RESERVED_DIRS.has(name))\n .sort();\n\n const defs: Record<string, AgentDefinition> = {};\n const subAgentRefs: Record<string, string[]> = {};\n let defaultAgent: string | null = null;\n\n // Pass 1: build every agent's definition; collect sub-agent refs.\n for (const id of agentIds) {\n const agentPath = path.join(dir, id, \"agent.md\");\n let raw: string;\n try {\n raw = await fs.readFile(agentPath, \"utf-8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n throw new Error(\n `Agents subdirectory '${path.join(dir, id)}' must contain agent.md.`,\n );\n }\n throw err;\n }\n defs[id] = buildDefinition(id, raw, agentPath, ctx);\n const { data } = parseFrontmatter(raw, agentPath);\n if (data?.agents !== undefined) {\n subAgentRefs[id] = normalizeAgentsFrontmatter(data.agents, id, agentPath);\n }\n if (data?.default === true && !defaultAgent) {\n defaultAgent = id;\n }\n }\n\n // Pass 2: resolve sub-agent references against the complete defs map.\n // Code-defined agents (ctx.codeAgents) take precedence over markdown ones\n // with the same name, matching the plugin's top-level merge behaviour.\n for (const [name, refs] of Object.entries(subAgentRefs)) {\n if (refs.length === 0) continue;\n const children: Record<string, AgentDefinition> = {};\n const missing: string[] = [];\n for (const ref of refs) {\n if (ref === name) {\n throw new Error(\n `Agent '${name}' (${path.join(dir, name, \"agent.md\")}) cannot reference itself in 'agents:'.`,\n );\n }\n const sibling = ctx.codeAgents?.[ref] ?? defs[ref];\n if (!sibling) {\n missing.push(ref);\n continue;\n }\n children[ref] = sibling;\n }\n if (missing.length > 0) {\n const available =\n [...Object.keys(ctx.codeAgents ?? {}), ...Object.keys(defs)]\n .sort()\n .join(\", \") || \"<none>\";\n throw new Error(\n `Agent '${name}' references sub-agent(s) '${missing.join(\", \")}' in 'agents:', ` +\n `but no markdown or code agent(s) with those names exist. ` +\n `Available: ${available}.`,\n );\n }\n defs[name].agents = children;\n }\n\n return { defs, defaultAgent };\n}\n\n/**\n * Validates that `agents:` frontmatter is an array of non-empty strings and\n * returns it with duplicates removed. Throws with a clear per-file message\n * on malformed input rather than silently ignoring.\n */\nfunction normalizeAgentsFrontmatter(\n value: unknown,\n agentName: string,\n filePath: string,\n): string[] {\n if (!Array.isArray(value)) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has invalid 'agents:' frontmatter: ` +\n `expected an array of sibling agent ids, got ${typeof value}.`,\n );\n }\n const out: string[] = [];\n const seen = new Set<string>();\n for (const item of value) {\n if (typeof item !== \"string\" || item.trim() === \"\") {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has invalid 'agents:' entry: ` +\n `expected non-empty string, got ${JSON.stringify(item)}.`,\n );\n }\n if (seen.has(item)) continue;\n seen.add(item);\n out.push(item);\n }\n return out;\n}\n\n/** Exposed for tests. Parses `--- yaml ---\\nbody` and validates frontmatter keys. */\nexport function parseFrontmatter(\n raw: string,\n sourcePath?: string,\n): { data: Frontmatter | null; content: string } {\n const match = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!match) {\n return { data: null, content: raw.trim() };\n }\n let parsed: unknown;\n try {\n parsed = yaml.load(match[1]);\n } catch (err) {\n const src = sourcePath ? ` (${sourcePath})` : \"\";\n throw new Error(\n `Invalid YAML frontmatter${src}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (parsed === null || parsed === undefined) {\n return { data: {}, content: match[2].trim() };\n }\n if (typeof parsed !== \"object\" || Array.isArray(parsed)) {\n const src = sourcePath ? ` (${sourcePath})` : \"\";\n throw new Error(`Frontmatter must be a YAML object${src}`);\n }\n const data = parsed as Record<string, unknown>;\n for (const key of Object.keys(data)) {\n if (!ALLOWED_KEYS.has(key)) {\n logger.warn(\n \"Ignoring unknown frontmatter key '%s' in %s\",\n key,\n sourcePath ?? \"<inline>\",\n );\n }\n }\n return { data: data as Frontmatter, content: match[2].trim() };\n}\n\nconst isNumber = (v: unknown): v is number => typeof v === \"number\";\n\n/**\n * Per-key validators for {@link GenerationParams} frontmatter. Keyed by wire\n * name and typed as `Record<keyof GenerationParams, ...>`, so a new param on\n * the interface is a compile error until it gets an entry here — parsing,\n * unknown-key detection, and warnings all derive from this one table.\n */\nconst GENERATION_PARAM_SPECS: Record<\n keyof GenerationParams,\n { label: string; valid: (v: unknown) => boolean }\n> = {\n temperature: { label: \"number\", valid: isNumber },\n top_p: { label: \"number\", valid: isNumber },\n frequency_penalty: { label: \"number\", valid: isNumber },\n presence_penalty: { label: \"number\", valid: isNumber },\n stop: {\n label: \"string or string[]\",\n valid: (v) =>\n typeof v === \"string\" ||\n (Array.isArray(v) && v.every((s) => typeof s === \"string\")),\n },\n};\n\n/**\n * Defensively maps a frontmatter `generationParams` map to {@link GenerationParams}.\n * Picks only known keys with the expected wire types. A key present with the\n * wrong type (e.g. `temperature: \"0.5\"`) or an unknown key (e.g. `top-p`) is\n * dropped and logged at warn level, so a silently-ignored param is visible\n * rather than mistaken for \"applied\". Returns `undefined` when no valid key is\n * present.\n */\nfunction parseGenerationParams(\n value: unknown,\n sourcePath?: string,\n): GenerationParams | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return undefined;\n }\n const raw = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n const where = sourcePath ?? \"<inline>\";\n\n for (const [key, v] of Object.entries(raw)) {\n const spec = GENERATION_PARAM_SPECS[key as keyof GenerationParams];\n if (!spec) {\n logger.warn(\n \"Ignoring unknown generationParams key '%s' in %s\",\n key,\n where,\n );\n } else if (spec.valid(v)) {\n out[key] = v;\n } else {\n logger.warn(\n \"Ignoring generationParams.%s in %s: expected %s, got %s\",\n key,\n where,\n spec.label,\n typeof v,\n );\n }\n }\n\n return Object.keys(out).length > 0 ? (out as GenerationParams) : undefined;\n}\n\nfunction buildDefinition(\n name: string,\n raw: string,\n filePath: string,\n ctx: LoadContext,\n): AgentDefinition {\n const { data, content } = parseFrontmatter(raw, filePath);\n const fm: Frontmatter = data ?? {};\n\n const tools = resolveFrontmatterTools(name, fm, filePath, ctx);\n const model = fm.model ?? fm.endpoint ?? ctx.defaultModel;\n\n let baseSystemPrompt: BaseSystemPromptOption | undefined;\n if (fm.baseSystemPrompt === false) baseSystemPrompt = false;\n else if (typeof fm.baseSystemPrompt === \"string\")\n baseSystemPrompt = fm.baseSystemPrompt;\n\n return {\n name,\n instructions: content,\n model,\n tools: Object.keys(tools).length > 0 ? tools : undefined,\n maxSteps: typeof fm.maxSteps === \"number\" ? fm.maxSteps : undefined,\n maxTokens: typeof fm.maxTokens === \"number\" ? fm.maxTokens : undefined,\n generationParams: parseGenerationParams(fm.generationParams, filePath),\n baseSystemPrompt,\n ephemeral: typeof fm.ephemeral === \"boolean\" ? fm.ephemeral : undefined,\n };\n}\n\nfunction resolveFrontmatterTools(\n agentName: string,\n fm: Frontmatter,\n filePath: string,\n ctx: LoadContext,\n): Record<string, AgentTool> {\n const out: Record<string, AgentTool> = {};\n const pluginIdx = ctx.plugins ?? new Map<string, ToolkitProvider>();\n\n for (const entry of fm.tools ?? []) {\n const parsed = parseToolEntry(entry, filePath, agentName);\n if (parsed.kind === \"plugin\") {\n const provider = pluginIdx.get(parsed.pluginName);\n if (!provider) {\n const available =\n pluginIdx.size > 0\n ? Array.from(pluginIdx.keys()).join(\", \")\n : \"<none>\";\n throw new Error(\n `Agent '${agentName}' (${filePath}) references 'plugin:${parsed.pluginName}', but plugin '${parsed.pluginName}' is not registered. Available: ${available}`,\n );\n }\n const entries = provider.toolkit(parsed.opts) as Record<string, unknown>;\n for (const [key, value] of Object.entries(entries)) {\n if (!isToolkitEntry(value)) {\n throw new Error(\n `Plugin '${parsed.pluginName}'.toolkit() returned a value at key '${key}' that is not a ToolkitEntry`,\n );\n }\n out[key] = value as ToolkitEntry;\n }\n } else {\n const tool = ctx.availableTools?.[parsed.toolName];\n if (!tool) {\n const available = ctx.availableTools\n ? Object.keys(ctx.availableTools).join(\", \")\n : \"<none>\";\n throw new Error(\n `Agent '${agentName}' (${filePath}) references ambient tool '${parsed.toolName}', which is not in the agents() plugin's tools field. Available: ${available}. ` +\n \"If you meant to reference a plugin, use the 'plugin:NAME' prefix.\",\n );\n }\n out[parsed.toolName] = tool;\n }\n }\n\n return out;\n}\n\ntype ParsedToolEntry =\n | { kind: \"plugin\"; pluginName: string; opts: ToolkitOptions | undefined }\n | { kind: \"ambient\"; toolName: string };\n\n/**\n * Classify one item in the `tools:` frontmatter list into either a plugin\n * reference (with optional ToolkitOptions) or an ambient tool lookup.\n *\n * Strings starting with `plugin:` are bare plugin references. Strings\n * without the prefix are ambient tool names. Object entries are\n * single-key mappings keyed by `plugin:NAME`; the value is either an\n * array (sugar for `{ only: [...] }`) or a full `ToolkitOptions` record.\n */\nfunction parseToolEntry(\n entry: FrontmatterToolEntry,\n filePath: string,\n agentName: string,\n): ParsedToolEntry {\n if (typeof entry === \"string\") {\n if (entry.startsWith(PLUGIN_PREFIX)) {\n const pluginName = entry.slice(PLUGIN_PREFIX.length);\n if (pluginName.length === 0) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty plugin name in 'plugin:'.`,\n );\n }\n return { kind: \"plugin\", pluginName, opts: undefined };\n }\n if (entry.length === 0) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty string in 'tools:'.`,\n );\n }\n return { kind: \"ambient\", toolName: entry };\n }\n if (typeof entry !== \"object\" || entry === null) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has invalid 'tools:' entry: ${JSON.stringify(entry)}`,\n );\n }\n const keys = Object.keys(entry);\n if (keys.length !== 1) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) 'tools:' object entry must have exactly one key, got: ${keys.join(\", \")}`,\n );\n }\n const key = keys[0];\n // Bare `- plugin:` (no name after the colon) parses as a mapping with the\n // key `\"plugin\"`. Catch that as a friendly error rather than dumping it\n // through the generic \"expected key 'plugin:NAME'\" branch.\n if (key === \"plugin\") {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty plugin name in 'plugin:'.`,\n );\n }\n if (!key.startsWith(PLUGIN_PREFIX)) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) 'tools:' object entries are reserved for plugin references; expected key 'plugin:NAME', got '${key}'. ` +\n \"Use a bare string for ambient tools (e.g. `- get_weather`).\",\n );\n }\n const pluginName = key.slice(PLUGIN_PREFIX.length);\n if (pluginName.length === 0) {\n throw new Error(\n `Agent '${agentName}' (${filePath}) has an empty plugin name in 'plugin:'.`,\n );\n }\n const value = entry[key];\n if (Array.isArray(value)) {\n return { kind: \"plugin\", pluginName, opts: { only: value } };\n }\n if (typeof value === \"object\" && value !== null) {\n return {\n kind: \"plugin\",\n pluginName,\n opts: value as ToolkitOptions,\n };\n }\n throw new Error(\n `Agent '${agentName}' (${filePath}) 'plugin:${pluginName}' options must be an array of tool names or a ToolkitOptions object.`,\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-agent.d.ts","names":[],"sources":["../../../src/core/agent/run-agent.ts"],"mappings":";;;;;;UAoCiB,aAAA;;EAEf,QAAA,WAAmB,OAAA;;EAEnB,MAAA,GAAS,WAAA;EAJmB;;;;;;;EAY5B,OAAA,GAAU,UAAA,CAAW,iBAAA;AAAA;AAAA,UAGN,cAAA;EAXf;EAaA,IAAA;EALA;EAOA,MAAA,EAAQ,UAAA;AAAA;;;AAJV;;;;;;;;;AAmCA;;;;;;;;;;;;;;;;;iBAAsB,QAAA,CACpB,GAAA,EAAK,eAAA,EACL,KAAA,EAAO,aAAA,GACN,OAAA,CAAQ,cAAA"}
1
+ {"version":3,"file":"run-agent.d.ts","names":[],"sources":["../../../src/core/agent/run-agent.ts"],"mappings":";;;;;;UAsCiB,aAAA;;EAEf,QAAA,WAAmB,OAAA;;EAEnB,MAAA,GAAS,WAAA;EAJmB;;;;;;;EAY5B,OAAA,GAAU,UAAA,CAAW,iBAAA;AAAA;AAAA,UAGN,cAAA;EAXf;EAaA,IAAA;EALA;EAOA,MAAA,EAAQ,UAAA;AAAA;;;AAJV;;;;;;;;;AAmCA;;;;;;;;;;;;;;;;;iBAAsB,QAAA,CACpB,GAAA,EAAK,eAAA,EACL,KAAA,EAAO,aAAA,GACN,OAAA,CAAQ,cAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-agent.js","names":[],"sources":["../../../src/core/agent/run-agent.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type {\n AgentAdapter,\n AgentEvent,\n AgentToolDefinition,\n Message,\n PluginConstructor,\n PluginData,\n ToolProvider,\n} from \"shared\";\nimport {\n isSupervisorTool,\n SUPERVISOR_EXTENSION_KEY,\n type SupervisorTool,\n} from \"../../agents/supervisor-api\";\nimport { createLogger } from \"../../logging/logger\";\nimport { consumeAdapterStream } from \"./consume-adapter-stream\";\nimport { createPluginsProxy } from \"./plugins-map\";\nimport { resolveToolkitFromProvider } from \"./toolkit-resolver\";\nimport {\n type FunctionTool,\n functionToolToDefinition,\n isFunctionTool,\n} from \"./tools/function-tool\";\nimport { isHostedTool } from \"./tools/hosted-tools\";\nimport type {\n AgentDefinition,\n AgentTool,\n AgentTools,\n Plugins,\n PluginToolkitProvider,\n} from \"./types\";\nimport { isToolkitEntry } from \"./types\";\n\nconst logger = createLogger(\"agent:run-agent\");\n\nexport interface RunAgentInput {\n /** Seed messages for the run. Either a single user string or a full message list. */\n messages: string | Message[];\n /** Abort signal for cancellation. */\n signal?: AbortSignal;\n /**\n * Optional plugin list. Required when `def.tools` is the function form\n * `(plugins) => Record<string, AgentTool>` and the function dereferences\n * any plugins. `runAgent` constructs a fresh instance per plugin and\n * dispatches tool calls against it as the service principal (no OBO —\n * there is no HTTP request in standalone mode).\n */\n plugins?: PluginData<PluginConstructor, unknown, string>[];\n}\n\nexport interface RunAgentResult {\n /** Aggregated text output from all `message_delta` events. */\n text: string;\n /** Every event the adapter yielded, in order. Useful for inspection/tests. */\n events: AgentEvent[];\n}\n\n/**\n * Standalone agent execution without `createApp`. Resolves the adapter, binds\n * inline tools, and drives the adapter's `run()` loop to completion.\n *\n * Limitations vs. running through the agents() plugin:\n * - **No OBO and no approval gate** — there is no HTTP request, so plugin\n * tools run as the service principal. The agents-plugin approval gate\n * that prompts for human confirmation on `effect: \"write\" | \"update\" |\n * \"destructive\"` tools is also absent. LLM-controlled tool arguments\n * flow straight through to the SP. Treat standalone runAgent as a\n * trusted-prompt environment (CI, batch eval, internal scripts) — not\n * as an exposed user-facing surface.\n * - **Hosted tools (MCP) are not supported** — they require a live MCP\n * client that only exists inside the agents plugin's lifecycle.\n * `runAgent` rejects them at index-build time with a clear error.\n * - **Sub-agents** (`agents: { ... }` on the def) are executed as nested\n * `runAgent` calls with no shared thread state. Plugin instances ARE\n * shared across the recursion (same cache as the parent).\n * - **Plugin tools** (used inside the function form via\n * `plugins.<name>.toolkit(...)`) require passing `plugins: [...]` via\n * `RunAgentInput`. Each plugin in that array is constructed once,\n * `attachContext({})` and `await setup()` are called eagerly, and the\n * resulting instance is shared across the top-level run and all\n * sub-agent recursions. Plugins whose `setup()` requires runtime that\n * only `createApp` provides (e.g. `WorkspaceClient`, `ServiceContext`,\n * `PluginContext`) throw at standalone-init time with a clear \"use\n * createApp instead\" message — not mid-stream.\n */\nexport async function runAgent(\n def: AgentDefinition,\n input: RunAgentInput,\n): Promise<RunAgentResult> {\n // Single shared cache for the whole call graph: parent + every nested\n // sub-agent dispatch share constructed plugin instances. Without this,\n // each nested `runAgent` would build its own cache, re-instantiate every\n // plugin, and silently diverge in-instance state between parent and child\n // (e.g. query result caches, connection pools).\n const providerCache = new Map<string, ToolProvider>();\n await initStandalonePlugins(input.plugins ?? [], providerCache);\n return runAgentInternal(def, input, providerCache);\n}\n\nasync function runAgentInternal(\n def: AgentDefinition,\n input: RunAgentInput,\n providerCache: Map<string, ToolProvider>,\n): Promise<RunAgentResult> {\n const adapter = await resolveAdapter(def);\n const messages = normalizeMessages(input.messages, def.instructions);\n const toolIndex = buildStandaloneToolIndex(\n def,\n input.plugins ?? [],\n providerCache,\n );\n // Hosted-supervisor entries are routed via `extensions`, not as callable\n // tools — exclude their placeholder `def` from the wire `tools` array.\n const tools = Array.from(toolIndex.values())\n .filter((e) => e.kind !== \"hosted-supervisor\")\n .map((e) => e.def);\n\n warnOnCapabilityMismatch(def.name ?? \"<anonymous>\", adapter, toolIndex);\n\n const signal = input.signal;\n\n const executeTool = async (name: string, args: unknown): Promise<unknown> => {\n const entry = toolIndex.get(name);\n if (!entry) throw new Error(`Unknown tool: ${name}`);\n if (entry.kind === \"function\") {\n return entry.tool.execute(args as Record<string, unknown>);\n }\n if (entry.kind === \"toolkit\") {\n return entry.provider.executeAgentTool(\n entry.localName,\n args as Record<string, unknown>,\n signal,\n );\n }\n if (entry.kind === \"subagent\") {\n const subInput: RunAgentInput = {\n messages:\n typeof args === \"object\" &&\n args !== null &&\n typeof (args as { input?: unknown }).input === \"string\"\n ? (args as { input: string }).input\n : JSON.stringify(args),\n signal,\n plugins: input.plugins,\n };\n // Reuse the same `providerCache` so sub-agent plugin tools dispatch\n // through the same instances the parent constructed.\n const res = await runAgentInternal(\n entry.agentDef,\n subInput,\n providerCache,\n );\n return res.text;\n }\n if (entry.kind === \"hosted-supervisor\") {\n // Defense-in-depth: should never fire. The placeholder def is\n // filtered out of `tools` above, so the model never sees a callable\n // schema for hosted-supervisor entries. If we ever reach here, the\n // model was somehow handed the def and tried to invoke it directly.\n throw new Error(\n `runAgent: tool \"${name}\" is a hosted-supervisor tool, executed server-side by the Databricks AI Gateway. It must not be invoked from the Node process.`,\n );\n }\n throw new Error(\n `runAgent: tool \"${name}\" is a ${entry.kind} tool. ` +\n \"Hosted/MCP tools are only usable via createApp({ plugins: [..., agents(...)] }).\",\n );\n };\n\n const events: AgentEvent[] = [];\n\n const stream = adapter.run(\n {\n messages,\n tools,\n threadId: randomUUID(),\n signal,\n extensions: buildStandaloneExtensions(toolIndex),\n },\n { executeTool, signal },\n );\n\n // Shared accumulation rule (deltas append, `message` replaces). The\n // `events` array is filled via the `onEvent` side effect so callers that\n // inspect the raw stream still get the full record.\n const text = await consumeAdapterStream(stream, {\n signal,\n onEvent: (event) => {\n events.push(event);\n },\n });\n\n return { text, events };\n}\n\n/**\n * Eagerly construct every plugin in `input.plugins`, run the standard\n * AppKit lifecycle (`attachContext({})` + `await setup()`), and populate\n * `cache`. Failures here surface BEFORE any adapter work — mid-stream\n * `getWorkspaceClient is not initialised`-style errors become a clear\n * startup failure naming the plugin and pointing the user at `createApp`.\n *\n * Plugins that don't need runtime context (no overridden `setup`, or one\n * that doesn't dereference `createApp`-only state) initialise cleanly and\n * standalone runAgent works as documented. Plugins like analytics/files\n * that depend on `WorkspaceClient` will throw the underlying error wrapped\n * with the migration hint.\n */\nasync function initStandalonePlugins(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n cache: Map<string, ToolProvider>,\n): Promise<void> {\n for (const data of plugins) {\n if (cache.has(data.name)) continue;\n const instance = new data.plugin({\n ...(data.config ?? {}),\n name: data.name,\n });\n if (!isStandaloneToolProvider(instance)) {\n throw new Error(\n `runAgent: plugin '${data.name}' is not a ToolProvider ` +\n \"(missing getAgentTools/executeAgentTool). Only ToolProvider plugins \" +\n \"are supported in standalone runAgent.\",\n );\n }\n if (\n typeof (instance as { attachContext?: unknown }).attachContext ===\n \"function\"\n ) {\n try {\n (\n instance as { attachContext: (deps: Record<string, unknown>) => void }\n ).attachContext({});\n } catch (err) {\n throw new Error(\n `runAgent: plugin '${data.name}' attachContext() failed in ` +\n \"standalone mode. This plugin probably depends on createApp's \" +\n \"runtime (WorkspaceClient, ServiceContext, PluginContext). Run \" +\n \"via createApp({ plugins: [..., agents(...)] }) instead. \" +\n `Cause: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err instanceof Error ? err : undefined },\n );\n }\n }\n if (typeof (instance as { setup?: unknown }).setup === \"function\") {\n try {\n await (instance as { setup: () => Promise<void> | void }).setup();\n } catch (err) {\n throw new Error(\n `runAgent: plugin '${data.name}' setup() failed in standalone ` +\n \"mode. This plugin probably depends on createApp's runtime \" +\n \"(WorkspaceClient, ServiceContext, PluginContext). Run via \" +\n \"createApp({ plugins: [..., agents(...)] }) instead. \" +\n `Cause: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err instanceof Error ? err : undefined },\n );\n }\n }\n cache.set(data.name, instance);\n }\n}\n\nasync function resolveAdapter(def: AgentDefinition): Promise<AgentAdapter> {\n const { model } = def;\n if (!model) {\n const { DatabricksAdapter } = await import(\"../../agents/databricks\");\n return DatabricksAdapter.fromModelServing();\n }\n if (typeof model === \"string\") {\n const { DatabricksAdapter } = await import(\"../../agents/databricks\");\n return DatabricksAdapter.fromModelServing(model);\n }\n return await model;\n}\n\nfunction normalizeMessages(\n input: string | Message[],\n instructions: string,\n): Message[] {\n const systemMessage: Message = {\n id: \"system\",\n role: \"system\",\n content: instructions,\n createdAt: new Date(),\n };\n if (typeof input === \"string\") {\n return [\n systemMessage,\n {\n id: randomUUID(),\n role: \"user\",\n content: input,\n createdAt: new Date(),\n },\n ];\n }\n return [systemMessage, ...input];\n}\n\ntype StandaloneEntry =\n | {\n kind: \"function\";\n def: AgentToolDefinition;\n tool: FunctionTool;\n }\n | {\n kind: \"subagent\";\n def: AgentToolDefinition;\n agentDef: AgentDefinition;\n }\n | {\n kind: \"toolkit\";\n def: AgentToolDefinition;\n provider: ToolProvider;\n pluginName: string;\n localName: string;\n }\n | {\n kind: \"hosted\";\n def: AgentToolDefinition;\n }\n | {\n /**\n * Adapter-side hosted tool. Standalone `runAgent` accepts these\n * (unlike MCP hosted tools, which need a live MCP client) because\n * the adapter has everything it needs to execute them server-side:\n * the spec travels via `AgentInput.extensions` and the SA endpoint\n * runs the tool loop. Enables batch-eval / CI use of supervisor\n * agents without `createApp`.\n */\n kind: \"hosted-supervisor\";\n def: AgentToolDefinition;\n spec: SupervisorTool;\n };\n\n/**\n * Resolves `def.tools` (object or function form) and `def.agents`\n * (sub-agents) into a flat dispatch index. The function form is invoked\n * once per call against a {@link Plugins} map drawn from the shared\n * `providerCache` populated by {@link initStandalonePlugins}. Missing\n * references throw a named \"not registered\" error via the proxy.\n */\nfunction buildStandaloneToolIndex(\n def: AgentDefinition,\n plugins: PluginData<PluginConstructor, unknown, string>[],\n providerCache: Map<string, ToolProvider>,\n): Map<string, StandaloneEntry> {\n const index = new Map<string, StandaloneEntry>();\n const tools = resolveDefTools(def, plugins, providerCache);\n\n for (const [key, tool] of Object.entries(tools)) {\n index.set(key, classifyTool(key, tool, providerCache));\n }\n\n for (const [childKey, child] of Object.entries(def.agents ?? {})) {\n const toolName = `agent-${childKey}`;\n index.set(toolName, {\n kind: \"subagent\",\n agentDef: { ...child, name: child.name ?? childKey },\n def: {\n name: toolName,\n description:\n child.instructions.slice(0, 120) ||\n `Delegate to the ${childKey} sub-agent`,\n parameters: {\n type: \"object\",\n properties: {\n input: {\n type: \"string\",\n description: \"Message to send to the sub-agent.\",\n },\n },\n required: [\"input\"],\n },\n },\n });\n }\n\n return index;\n}\n\n/**\n * Resolves `def.tools` to a plain record. The function form is invoked\n * with a typed {@link Plugins} map drawn from the pre-populated\n * `providerCache`; each `plugins.foo.toolkit(opts)` lookup hits the cache\n * directly (no construction at toolkit-call time).\n */\nfunction resolveDefTools(\n def: AgentDefinition,\n plugins: PluginData<PluginConstructor, unknown, string>[],\n providerCache: Map<string, ToolProvider>,\n): AgentTools {\n if (typeof def.tools !== \"function\") {\n return def.tools ?? {};\n }\n const pluginsMap = buildStandalonePluginsMap(plugins, providerCache);\n try {\n return def.tools(pluginsMap);\n } catch (err) {\n const name = def.name ?? \"<anonymous>\";\n throw new Error(\n `runAgent: agent '${name}' tools(plugins) callback threw: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err instanceof Error ? err : undefined },\n );\n }\n}\n\n/**\n * Builds the typed {@link Plugins} map passed to the function form of\n * `def.tools` in standalone mode. Reads pre-constructed instances from\n * `providerCache` (populated eagerly by {@link initStandalonePlugins})\n * and wraps the result in a Proxy so unknown plugin names produce a\n * named \"not registered, Available: ...\" error instead of bubbling up a\n * generic `TypeError: Cannot read properties of undefined`.\n */\nfunction buildStandalonePluginsMap(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n providerCache: Map<string, ToolProvider>,\n): Plugins {\n const out: Record<string, PluginToolkitProvider> = {};\n for (const data of plugins) {\n const provider = providerCache.get(data.name);\n if (!provider) continue; // initStandalonePlugins should have set this\n out[data.name] = {\n toolkit: (opts) => resolveToolkitFromProvider(data.name, provider, opts),\n };\n }\n return createPluginsProxy(out, \"runAgent: tools(plugins)\");\n}\n\nfunction classifyTool(\n key: string,\n tool: AgentTool,\n providerCache: Map<string, ToolProvider>,\n): StandaloneEntry {\n if (isToolkitEntry(tool)) {\n // Toolkit entries inside the function form's returned record carry the\n // provider name they came from, so we can resolve the provider on\n // demand and dispatch through it. The cache is shared with the\n // pluginsMap path so the same instance is reused.\n const provider = providerCacheLookup(tool.pluginName, providerCache);\n return {\n kind: \"toolkit\",\n provider,\n pluginName: tool.pluginName,\n localName: tool.localName,\n def: { ...tool.def, name: key },\n };\n }\n if (isFunctionTool(tool)) {\n return {\n kind: \"function\",\n tool,\n def: { ...functionToolToDefinition(tool), name: key },\n };\n }\n // Supervisor-API hosted tools work in standalone mode: the adapter\n // executes them server-side via `AgentInput.extensions`, no MCP client\n // required. Must come BEFORE the `isHostedTool` MCP rejection — the two\n // predicates classify disjoint values (`isSupervisorTool` matches the\n // `__kind` tag; `isHostedTool` matches the wire-format `type` field),\n // but the placement makes the intent explicit.\n if (isSupervisorTool(tool)) {\n return {\n kind: \"hosted-supervisor\",\n spec: tool.spec,\n def: {\n name: key,\n description: supervisorToolDescription(tool.spec),\n parameters: { type: \"object\", properties: {} },\n },\n };\n }\n if (isHostedTool(tool)) {\n // Hosted tools (e.g. MCP `mcpServer(...)`) need a live MCP client that\n // only exists inside the agents plugin's lifecycle. In standalone\n // `runAgent` they would have errored at dispatch time with a confusing\n // mid-conversation failure; reject them up front so misconfiguration\n // surfaces before the adapter sees the tool list.\n throw new Error(\n `runAgent: tool \"${key}\" is a hosted tool (type=\"${tool.type}\") which is only supported via createApp({ plugins: [..., agents(...)] }). Standalone runAgent has no MCP client.`,\n );\n }\n throw new Error(`runAgent: unrecognized tool shape at key \"${key}\"`);\n}\n\n/** Mirrors `agents.ts`'s `supervisorToolDescription`. */\nfunction supervisorToolDescription(spec: SupervisorTool): string {\n switch (spec.type) {\n case \"genie_space\":\n return spec.genie_space.description;\n case \"uc_function\":\n return spec.uc_function.description;\n case \"knowledge_assistant\":\n return spec.knowledge_assistant.description;\n case \"app\":\n return spec.app.description;\n case \"uc_connection\":\n return spec.uc_connection.description;\n }\n}\n\n/** Mirrors `agents.ts`'s `buildAdapterExtensions`. */\nfunction buildStandaloneExtensions(\n toolIndex: Map<string, StandaloneEntry>,\n): Readonly<Record<string, unknown>> | undefined {\n const supervisorSpecs: SupervisorTool[] = [];\n for (const entry of toolIndex.values()) {\n if (entry.kind === \"hosted-supervisor\") {\n supervisorSpecs.push(entry.spec);\n }\n }\n if (supervisorSpecs.length === 0) return undefined;\n return {\n [SUPERVISOR_EXTENSION_KEY]: { hostedTools: supervisorSpecs },\n };\n}\n\n/**\n * Mirrors the agents-plugin capability warning so standalone `runAgent`\n * produces the same diagnostic when adapter capabilities don't match the\n * tool index. Warn-not-throw: doesn't abort batch evals.\n */\nfunction warnOnCapabilityMismatch(\n agentName: string,\n adapter: AgentAdapter,\n toolIndex: Map<string, StandaloneEntry>,\n): void {\n const accepted = new Set(adapter.acceptsExtensions ?? []);\n\n const hostedSupervisorKeys: string[] = [];\n const inputToolKeys: string[] = [];\n for (const [key, entry] of toolIndex) {\n if (entry.kind === \"hosted-supervisor\") {\n hostedSupervisorKeys.push(key);\n } else {\n inputToolKeys.push(key);\n }\n }\n\n if (\n hostedSupervisorKeys.length > 0 &&\n !accepted.has(SUPERVISOR_EXTENSION_KEY)\n ) {\n logger.warn(\n `Agent '${agentName}' declares hosted-supervisor tools (${hostedSupervisorKeys.join(\", \")}) ` +\n \"but its model adapter does not accept the 'databricks.supervisor' extension. \" +\n \"Pair them with `DatabricksAdapter.fromSupervisorApi(...)`, or remove them.\",\n );\n }\n\n if (adapter.consumesInputTools === false && inputToolKeys.length > 0) {\n logger.warn(\n `Agent '${agentName}' declares function tools / sub-agents (${inputToolKeys.join(\", \")}) ` +\n \"but its model adapter does not consume input.tools. These tools will not be exposed to the model.\",\n );\n }\n}\n\nfunction providerCacheLookup(\n pluginName: string,\n cache: Map<string, ToolProvider>,\n): ToolProvider {\n const cached = cache.get(pluginName);\n if (cached) return cached;\n const available = Array.from(cache.keys()).join(\", \") || \"(none)\";\n throw new Error(\n `runAgent: tool refers to plugin '${pluginName}', but no instance was ` +\n \"initialised for that name. Add it to RunAgentInput.plugins, or — if \" +\n \"this came from a hand-rolled ToolkitEntry — go through \" +\n `plugins[name].toolkit() instead. Available: ${available}.`,\n );\n}\n\n/**\n * Lightweight `ToolProvider` shape check used by standalone `runAgent`.\n *\n * Distinct from `core/plugin-context.isToolProvider` which also requires\n * `asUser` (request-scoped, only meaningful when running inside `createApp`\n * with a live HTTP context). Standalone plugins are constructed without a\n * `WorkspaceClient` and have no request to scope to, so checking only the\n * two `ToolProvider` methods is the right narrowing here.\n */\nfunction isStandaloneToolProvider(value: unknown): value is ToolProvider {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.getAgentTools === \"function\" &&\n typeof obj.executeAgentTool === \"function\"\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-agent.js","names":[],"sources":["../../../src/core/agent/run-agent.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport type {\n AgentAdapter,\n AgentEvent,\n AgentToolDefinition,\n Message,\n PluginConstructor,\n PluginData,\n ToolProvider,\n} from \"shared\";\n\nimport {\n isSupervisorTool,\n SUPERVISOR_EXTENSION_KEY,\n type SupervisorTool,\n} from \"../../agents/supervisor-api\";\nimport { createLogger } from \"../../logging/logger\";\nimport { consumeAdapterStream } from \"./consume-adapter-stream\";\nimport { createPluginsProxy } from \"./plugins-map\";\nimport { resolveToolkitFromProvider } from \"./toolkit-resolver\";\nimport {\n type FunctionTool,\n functionToolToDefinition,\n isFunctionTool,\n} from \"./tools/function-tool\";\nimport { isHostedTool } from \"./tools/hosted-tools\";\nimport type {\n AgentDefinition,\n AgentTool,\n AgentTools,\n Plugins,\n PluginToolkitProvider,\n} from \"./types\";\nimport { isToolkitEntry } from \"./types\";\n\nconst logger = createLogger(\"agent:run-agent\");\n\nexport interface RunAgentInput {\n /** Seed messages for the run. Either a single user string or a full message list. */\n messages: string | Message[];\n /** Abort signal for cancellation. */\n signal?: AbortSignal;\n /**\n * Optional plugin list. Required when `def.tools` is the function form\n * `(plugins) => Record<string, AgentTool>` and the function dereferences\n * any plugins. `runAgent` constructs a fresh instance per plugin and\n * dispatches tool calls against it as the service principal (no OBO —\n * there is no HTTP request in standalone mode).\n */\n plugins?: PluginData<PluginConstructor, unknown, string>[];\n}\n\nexport interface RunAgentResult {\n /** Aggregated text output from all `message_delta` events. */\n text: string;\n /** Every event the adapter yielded, in order. Useful for inspection/tests. */\n events: AgentEvent[];\n}\n\n/**\n * Standalone agent execution without `createApp`. Resolves the adapter, binds\n * inline tools, and drives the adapter's `run()` loop to completion.\n *\n * Limitations vs. running through the agents() plugin:\n * - **No OBO and no approval gate** — there is no HTTP request, so plugin\n * tools run as the service principal. The agents-plugin approval gate\n * that prompts for human confirmation on `effect: \"write\" | \"update\" |\n * \"destructive\"` tools is also absent. LLM-controlled tool arguments\n * flow straight through to the SP. Treat standalone runAgent as a\n * trusted-prompt environment (CI, batch eval, internal scripts) — not\n * as an exposed user-facing surface.\n * - **Hosted tools (MCP) are not supported** — they require a live MCP\n * client that only exists inside the agents plugin's lifecycle.\n * `runAgent` rejects them at index-build time with a clear error.\n * - **Sub-agents** (`agents: { ... }` on the def) are executed as nested\n * `runAgent` calls with no shared thread state. Plugin instances ARE\n * shared across the recursion (same cache as the parent).\n * - **Plugin tools** (used inside the function form via\n * `plugins.<name>.toolkit(...)`) require passing `plugins: [...]` via\n * `RunAgentInput`. Each plugin in that array is constructed once,\n * `attachContext({})` and `await setup()` are called eagerly, and the\n * resulting instance is shared across the top-level run and all\n * sub-agent recursions. Plugins whose `setup()` requires runtime that\n * only `createApp` provides (e.g. `WorkspaceClient`, `ServiceContext`,\n * `PluginContext`) throw at standalone-init time with a clear \"use\n * createApp instead\" message — not mid-stream.\n */\nexport async function runAgent(\n def: AgentDefinition,\n input: RunAgentInput,\n): Promise<RunAgentResult> {\n // Single shared cache for the whole call graph: parent + every nested\n // sub-agent dispatch share constructed plugin instances. Without this,\n // each nested `runAgent` would build its own cache, re-instantiate every\n // plugin, and silently diverge in-instance state between parent and child\n // (e.g. query result caches, connection pools).\n const providerCache = new Map<string, ToolProvider>();\n await initStandalonePlugins(input.plugins ?? [], providerCache);\n return runAgentInternal(def, input, providerCache);\n}\n\nasync function runAgentInternal(\n def: AgentDefinition,\n input: RunAgentInput,\n providerCache: Map<string, ToolProvider>,\n): Promise<RunAgentResult> {\n const adapter = await resolveAdapter(def);\n const messages = normalizeMessages(input.messages, def.instructions);\n const toolIndex = buildStandaloneToolIndex(\n def,\n input.plugins ?? [],\n providerCache,\n );\n // Hosted-supervisor entries are routed via `extensions`, not as callable\n // tools — exclude their placeholder `def` from the wire `tools` array.\n const tools = Array.from(toolIndex.values())\n .filter((e) => e.kind !== \"hosted-supervisor\")\n .map((e) => e.def);\n\n warnOnCapabilityMismatch(def.name ?? \"<anonymous>\", adapter, toolIndex);\n\n const signal = input.signal;\n\n const executeTool = async (name: string, args: unknown): Promise<unknown> => {\n const entry = toolIndex.get(name);\n if (!entry) throw new Error(`Unknown tool: ${name}`);\n if (entry.kind === \"function\") {\n return entry.tool.execute(args as Record<string, unknown>);\n }\n if (entry.kind === \"toolkit\") {\n return entry.provider.executeAgentTool(\n entry.localName,\n args as Record<string, unknown>,\n signal,\n );\n }\n if (entry.kind === \"subagent\") {\n const subInput: RunAgentInput = {\n messages:\n typeof args === \"object\" &&\n args !== null &&\n typeof (args as { input?: unknown }).input === \"string\"\n ? (args as { input: string }).input\n : JSON.stringify(args),\n signal,\n plugins: input.plugins,\n };\n // Reuse the same `providerCache` so sub-agent plugin tools dispatch\n // through the same instances the parent constructed.\n const res = await runAgentInternal(\n entry.agentDef,\n subInput,\n providerCache,\n );\n return res.text;\n }\n if (entry.kind === \"hosted-supervisor\") {\n // Defense-in-depth: should never fire. The placeholder def is\n // filtered out of `tools` above, so the model never sees a callable\n // schema for hosted-supervisor entries. If we ever reach here, the\n // model was somehow handed the def and tried to invoke it directly.\n throw new Error(\n `runAgent: tool \"${name}\" is a hosted-supervisor tool, executed server-side by the Databricks AI Gateway. It must not be invoked from the Node process.`,\n );\n }\n throw new Error(\n `runAgent: tool \"${name}\" is a ${entry.kind} tool. ` +\n \"Hosted/MCP tools are only usable via createApp({ plugins: [..., agents(...)] }).\",\n );\n };\n\n const events: AgentEvent[] = [];\n\n const stream = adapter.run(\n {\n messages,\n tools,\n threadId: randomUUID(),\n signal,\n extensions: buildStandaloneExtensions(toolIndex),\n },\n { executeTool, signal },\n );\n\n // Shared accumulation rule (deltas append, `message` replaces). The\n // `events` array is filled via the `onEvent` side effect so callers that\n // inspect the raw stream still get the full record.\n const text = await consumeAdapterStream(stream, {\n signal,\n onEvent: (event) => {\n events.push(event);\n },\n });\n\n return { text, events };\n}\n\n/**\n * Eagerly construct every plugin in `input.plugins`, run the standard\n * AppKit lifecycle (`attachContext({})` + `await setup()`), and populate\n * `cache`. Failures here surface BEFORE any adapter work — mid-stream\n * `getWorkspaceClient is not initialised`-style errors become a clear\n * startup failure naming the plugin and pointing the user at `createApp`.\n *\n * Plugins that don't need runtime context (no overridden `setup`, or one\n * that doesn't dereference `createApp`-only state) initialise cleanly and\n * standalone runAgent works as documented. Plugins like analytics/files\n * that depend on `WorkspaceClient` will throw the underlying error wrapped\n * with the migration hint.\n */\nasync function initStandalonePlugins(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n cache: Map<string, ToolProvider>,\n): Promise<void> {\n for (const data of plugins) {\n if (cache.has(data.name)) continue;\n const instance = new data.plugin({\n ...(data.config ?? {}),\n name: data.name,\n });\n if (!isStandaloneToolProvider(instance)) {\n throw new Error(\n `runAgent: plugin '${data.name}' is not a ToolProvider ` +\n \"(missing getAgentTools/executeAgentTool). Only ToolProvider plugins \" +\n \"are supported in standalone runAgent.\",\n );\n }\n if (\n typeof (instance as { attachContext?: unknown }).attachContext ===\n \"function\"\n ) {\n try {\n (\n instance as { attachContext: (deps: Record<string, unknown>) => void }\n ).attachContext({});\n } catch (err) {\n throw new Error(\n `runAgent: plugin '${data.name}' attachContext() failed in ` +\n \"standalone mode. This plugin probably depends on createApp's \" +\n \"runtime (WorkspaceClient, ServiceContext, PluginContext). Run \" +\n \"via createApp({ plugins: [..., agents(...)] }) instead. \" +\n `Cause: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err instanceof Error ? err : undefined },\n );\n }\n }\n if (typeof (instance as { setup?: unknown }).setup === \"function\") {\n try {\n await (instance as { setup: () => Promise<void> | void }).setup();\n } catch (err) {\n throw new Error(\n `runAgent: plugin '${data.name}' setup() failed in standalone ` +\n \"mode. This plugin probably depends on createApp's runtime \" +\n \"(WorkspaceClient, ServiceContext, PluginContext). Run via \" +\n \"createApp({ plugins: [..., agents(...)] }) instead. \" +\n `Cause: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err instanceof Error ? err : undefined },\n );\n }\n }\n cache.set(data.name, instance);\n }\n}\n\nasync function resolveAdapter(def: AgentDefinition): Promise<AgentAdapter> {\n const { model } = def;\n if (!model) {\n const { DatabricksAdapter } = await import(\"../../agents/databricks\");\n return DatabricksAdapter.fromModelServing();\n }\n if (typeof model === \"string\") {\n const { DatabricksAdapter } = await import(\"../../agents/databricks\");\n return DatabricksAdapter.fromModelServing(model);\n }\n return await model;\n}\n\nfunction normalizeMessages(\n input: string | Message[],\n instructions: string,\n): Message[] {\n const systemMessage: Message = {\n id: \"system\",\n role: \"system\",\n content: instructions,\n createdAt: new Date(),\n };\n if (typeof input === \"string\") {\n return [\n systemMessage,\n {\n id: randomUUID(),\n role: \"user\",\n content: input,\n createdAt: new Date(),\n },\n ];\n }\n return [systemMessage, ...input];\n}\n\ntype StandaloneEntry =\n | {\n kind: \"function\";\n def: AgentToolDefinition;\n tool: FunctionTool;\n }\n | {\n kind: \"subagent\";\n def: AgentToolDefinition;\n agentDef: AgentDefinition;\n }\n | {\n kind: \"toolkit\";\n def: AgentToolDefinition;\n provider: ToolProvider;\n pluginName: string;\n localName: string;\n }\n | {\n kind: \"hosted\";\n def: AgentToolDefinition;\n }\n | {\n /**\n * Adapter-side hosted tool. Standalone `runAgent` accepts these\n * (unlike MCP hosted tools, which need a live MCP client) because\n * the adapter has everything it needs to execute them server-side:\n * the spec travels via `AgentInput.extensions` and the SA endpoint\n * runs the tool loop. Enables batch-eval / CI use of supervisor\n * agents without `createApp`.\n */\n kind: \"hosted-supervisor\";\n def: AgentToolDefinition;\n spec: SupervisorTool;\n };\n\n/**\n * Resolves `def.tools` (object or function form) and `def.agents`\n * (sub-agents) into a flat dispatch index. The function form is invoked\n * once per call against a {@link Plugins} map drawn from the shared\n * `providerCache` populated by {@link initStandalonePlugins}. Missing\n * references throw a named \"not registered\" error via the proxy.\n */\nfunction buildStandaloneToolIndex(\n def: AgentDefinition,\n plugins: PluginData<PluginConstructor, unknown, string>[],\n providerCache: Map<string, ToolProvider>,\n): Map<string, StandaloneEntry> {\n const index = new Map<string, StandaloneEntry>();\n const tools = resolveDefTools(def, plugins, providerCache);\n\n for (const [key, tool] of Object.entries(tools)) {\n index.set(key, classifyTool(key, tool, providerCache));\n }\n\n for (const [childKey, child] of Object.entries(def.agents ?? {})) {\n const toolName = `agent-${childKey}`;\n index.set(toolName, {\n kind: \"subagent\",\n agentDef: { ...child, name: child.name ?? childKey },\n def: {\n name: toolName,\n description:\n child.instructions.slice(0, 120) ||\n `Delegate to the ${childKey} sub-agent`,\n parameters: {\n type: \"object\",\n properties: {\n input: {\n type: \"string\",\n description: \"Message to send to the sub-agent.\",\n },\n },\n required: [\"input\"],\n },\n },\n });\n }\n\n return index;\n}\n\n/**\n * Resolves `def.tools` to a plain record. The function form is invoked\n * with a typed {@link Plugins} map drawn from the pre-populated\n * `providerCache`; each `plugins.foo.toolkit(opts)` lookup hits the cache\n * directly (no construction at toolkit-call time).\n */\nfunction resolveDefTools(\n def: AgentDefinition,\n plugins: PluginData<PluginConstructor, unknown, string>[],\n providerCache: Map<string, ToolProvider>,\n): AgentTools {\n if (typeof def.tools !== \"function\") {\n return def.tools ?? {};\n }\n const pluginsMap = buildStandalonePluginsMap(plugins, providerCache);\n try {\n return def.tools(pluginsMap);\n } catch (err) {\n const name = def.name ?? \"<anonymous>\";\n throw new Error(\n `runAgent: agent '${name}' tools(plugins) callback threw: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err instanceof Error ? err : undefined },\n );\n }\n}\n\n/**\n * Builds the typed {@link Plugins} map passed to the function form of\n * `def.tools` in standalone mode. Reads pre-constructed instances from\n * `providerCache` (populated eagerly by {@link initStandalonePlugins})\n * and wraps the result in a Proxy so unknown plugin names produce a\n * named \"not registered, Available: ...\" error instead of bubbling up a\n * generic `TypeError: Cannot read properties of undefined`.\n */\nfunction buildStandalonePluginsMap(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n providerCache: Map<string, ToolProvider>,\n): Plugins {\n const out: Record<string, PluginToolkitProvider> = {};\n for (const data of plugins) {\n const provider = providerCache.get(data.name);\n if (!provider) continue; // initStandalonePlugins should have set this\n out[data.name] = {\n toolkit: (opts) => resolveToolkitFromProvider(data.name, provider, opts),\n };\n }\n return createPluginsProxy(out, \"runAgent: tools(plugins)\");\n}\n\nfunction classifyTool(\n key: string,\n tool: AgentTool,\n providerCache: Map<string, ToolProvider>,\n): StandaloneEntry {\n if (isToolkitEntry(tool)) {\n // Toolkit entries inside the function form's returned record carry the\n // provider name they came from, so we can resolve the provider on\n // demand and dispatch through it. The cache is shared with the\n // pluginsMap path so the same instance is reused.\n const provider = providerCacheLookup(tool.pluginName, providerCache);\n return {\n kind: \"toolkit\",\n provider,\n pluginName: tool.pluginName,\n localName: tool.localName,\n def: { ...tool.def, name: key },\n };\n }\n if (isFunctionTool(tool)) {\n return {\n kind: \"function\",\n tool,\n def: { ...functionToolToDefinition(tool), name: key },\n };\n }\n // Supervisor-API hosted tools work in standalone mode: the adapter\n // executes them server-side via `AgentInput.extensions`, no MCP client\n // required. Must come BEFORE the `isHostedTool` MCP rejection — the two\n // predicates classify disjoint values (`isSupervisorTool` matches the\n // `__kind` tag; `isHostedTool` matches the wire-format `type` field),\n // but the placement makes the intent explicit.\n if (isSupervisorTool(tool)) {\n return {\n kind: \"hosted-supervisor\",\n spec: tool.spec,\n def: {\n name: key,\n description: supervisorToolDescription(tool.spec),\n parameters: { type: \"object\", properties: {} },\n },\n };\n }\n if (isHostedTool(tool)) {\n // Hosted tools (e.g. MCP `mcpServer(...)`) need a live MCP client that\n // only exists inside the agents plugin's lifecycle. In standalone\n // `runAgent` they would have errored at dispatch time with a confusing\n // mid-conversation failure; reject them up front so misconfiguration\n // surfaces before the adapter sees the tool list.\n throw new Error(\n `runAgent: tool \"${key}\" is a hosted tool (type=\"${tool.type}\") which is only supported via createApp({ plugins: [..., agents(...)] }). Standalone runAgent has no MCP client.`,\n );\n }\n throw new Error(`runAgent: unrecognized tool shape at key \"${key}\"`);\n}\n\n/** Mirrors `agents.ts`'s `supervisorToolDescription`. */\nfunction supervisorToolDescription(spec: SupervisorTool): string {\n switch (spec.type) {\n case \"genie_space\":\n return spec.genie_space.description;\n case \"uc_function\":\n return spec.uc_function.description;\n case \"knowledge_assistant\":\n return spec.knowledge_assistant.description;\n case \"app\":\n return spec.app.description;\n case \"uc_connection\":\n return spec.uc_connection.description;\n }\n}\n\n/** Mirrors `agents.ts`'s `buildAdapterExtensions`. */\nfunction buildStandaloneExtensions(\n toolIndex: Map<string, StandaloneEntry>,\n): Readonly<Record<string, unknown>> | undefined {\n const supervisorSpecs: SupervisorTool[] = [];\n for (const entry of toolIndex.values()) {\n if (entry.kind === \"hosted-supervisor\") {\n supervisorSpecs.push(entry.spec);\n }\n }\n if (supervisorSpecs.length === 0) return undefined;\n return {\n [SUPERVISOR_EXTENSION_KEY]: { hostedTools: supervisorSpecs },\n };\n}\n\n/**\n * Mirrors the agents-plugin capability warning so standalone `runAgent`\n * produces the same diagnostic when adapter capabilities don't match the\n * tool index. Warn-not-throw: doesn't abort batch evals.\n */\nfunction warnOnCapabilityMismatch(\n agentName: string,\n adapter: AgentAdapter,\n toolIndex: Map<string, StandaloneEntry>,\n): void {\n const accepted = new Set(adapter.acceptsExtensions ?? []);\n\n const hostedSupervisorKeys: string[] = [];\n const inputToolKeys: string[] = [];\n for (const [key, entry] of toolIndex) {\n if (entry.kind === \"hosted-supervisor\") {\n hostedSupervisorKeys.push(key);\n } else {\n inputToolKeys.push(key);\n }\n }\n\n if (\n hostedSupervisorKeys.length > 0 &&\n !accepted.has(SUPERVISOR_EXTENSION_KEY)\n ) {\n logger.warn(\n `Agent '${agentName}' declares hosted-supervisor tools (${hostedSupervisorKeys.join(\", \")}) ` +\n \"but its model adapter does not accept the 'databricks.supervisor' extension. \" +\n \"Pair them with `DatabricksAdapter.fromSupervisorApi(...)`, or remove them.\",\n );\n }\n\n if (adapter.consumesInputTools === false && inputToolKeys.length > 0) {\n logger.warn(\n `Agent '${agentName}' declares function tools / sub-agents (${inputToolKeys.join(\", \")}) ` +\n \"but its model adapter does not consume input.tools. These tools will not be exposed to the model.\",\n );\n }\n}\n\nfunction providerCacheLookup(\n pluginName: string,\n cache: Map<string, ToolProvider>,\n): ToolProvider {\n const cached = cache.get(pluginName);\n if (cached) return cached;\n const available = Array.from(cache.keys()).join(\", \") || \"(none)\";\n throw new Error(\n `runAgent: tool refers to plugin '${pluginName}', but no instance was ` +\n \"initialised for that name. Add it to RunAgentInput.plugins, or — if \" +\n \"this came from a hand-rolled ToolkitEntry — go through \" +\n `plugins[name].toolkit() instead. Available: ${available}.`,\n );\n}\n\n/**\n * Lightweight `ToolProvider` shape check used by standalone `runAgent`.\n *\n * Distinct from `core/plugin-context.isToolProvider` which also requires\n * `asUser` (request-scoped, only meaningful when running inside `createApp`\n * with a live HTTP context). Standalone plugins are constructed without a\n * `WorkspaceClient` and have no request to scope to, so checking only the\n * two `ToolProvider` methods is the right narrowing here.\n */\nfunction isStandaloneToolProvider(value: unknown): value is ToolProvider {\n if (typeof value !== \"object\" || value === null) return false;\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.getAgentTools === \"function\" &&\n typeof obj.executeAgentTool === \"function\"\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"toolkit-resolver.js","names":[],"sources":["../../../src/core/agent/toolkit-resolver.ts"],"sourcesContent":["import type { ToolProvider } from \"shared\";\nimport { applyToolkitOptions } from \"./toolkit-options\";\nimport type { ToolkitEntry, ToolkitOptions } from \"./types\";\n\n/**\n * Internal interface: a `ToolProvider` that optionally exposes a typed\n * `.toolkit(opts)` method. Core plugins (analytics, files, genie, lakebase)\n * implement this; third-party `ToolProvider`s may not.\n */\ntype MaybeToolkitProvider = ToolProvider & {\n toolkit?: (opts?: ToolkitOptions) => Record<string, ToolkitEntry>;\n};\n\n/**\n * Resolve a plugin's tools into a keyed record of {@link ToolkitEntry} markers\n * ready to be merged into an agent's tool index.\n *\n * Preferred path: call the plugin's own `.toolkit(opts)` method, which\n * typically delegates to `buildToolkitEntries` with full `ToolkitOptions`\n * support (prefix, only, except, rename).\n *\n * Fallback path: when the plugin doesn't expose `.toolkit()` (e.g. a\n * third-party `ToolProvider` built with plain `toPlugin`), walk\n * `getAgentTools()` and synthesize namespaced keys (`${pluginName}.${name}`)\n * while still honoring `only` / `except` / `rename` / `prefix`.\n *\n * This helper is the single source of truth for \"turn a provider into a\n * toolkit entry record\" and is used by `AgentsPlugin.buildToolIndex`\n * (the `tools(plugins)` resolution pass and auto-inherit) and by the\n * standalone `runAgent` executor.\n */\nexport function resolveToolkitFromProvider(\n pluginName: string,\n provider: ToolProvider,\n opts?: ToolkitOptions,\n): Record<string, ToolkitEntry> {\n const withToolkit = provider as MaybeToolkitProvider;\n if (typeof withToolkit.toolkit === \"function\") {\n return withToolkit.toolkit(opts);\n }\n\n const out: Record<string, ToolkitEntry> = {};\n for (const tool of provider.getAgentTools()) {\n const key = applyToolkitOptions(tool.name, pluginName, opts);\n if (key === null) continue;\n\n out[key] = {\n __toolkitRef: true,\n pluginName,\n localName: tool.name,\n def: { ...tool, name: key },\n };\n }\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,2BACd,YACA,UACA,MAC8B;CAC9B,MAAM,cAAc;AACpB,KAAI,OAAO,YAAY,YAAY,WACjC,QAAO,YAAY,QAAQ,KAAK;CAGlC,MAAM,MAAoC,EAAE;AAC5C,MAAK,MAAM,QAAQ,SAAS,eAAe,EAAE;EAC3C,MAAM,MAAM,oBAAoB,KAAK,MAAM,YAAY,KAAK;AAC5D,MAAI,QAAQ,KAAM;AAElB,MAAI,OAAO;GACT,cAAc;GACd;GACA,WAAW,KAAK;GAChB,KAAK;IAAE,GAAG;IAAM,MAAM;IAAK;GAC5B;;AAEH,QAAO"}
1
+ {"version":3,"file":"toolkit-resolver.js","names":[],"sources":["../../../src/core/agent/toolkit-resolver.ts"],"sourcesContent":["import type { ToolProvider } from \"shared\";\n\nimport { applyToolkitOptions } from \"./toolkit-options\";\nimport type { ToolkitEntry, ToolkitOptions } from \"./types\";\n\n/**\n * Internal interface: a `ToolProvider` that optionally exposes a typed\n * `.toolkit(opts)` method. Core plugins (analytics, files, genie, lakebase)\n * implement this; third-party `ToolProvider`s may not.\n */\ntype MaybeToolkitProvider = ToolProvider & {\n toolkit?: (opts?: ToolkitOptions) => Record<string, ToolkitEntry>;\n};\n\n/**\n * Resolve a plugin's tools into a keyed record of {@link ToolkitEntry} markers\n * ready to be merged into an agent's tool index.\n *\n * Preferred path: call the plugin's own `.toolkit(opts)` method, which\n * typically delegates to `buildToolkitEntries` with full `ToolkitOptions`\n * support (prefix, only, except, rename).\n *\n * Fallback path: when the plugin doesn't expose `.toolkit()` (e.g. a\n * third-party `ToolProvider` built with plain `toPlugin`), walk\n * `getAgentTools()` and synthesize namespaced keys (`${pluginName}.${name}`)\n * while still honoring `only` / `except` / `rename` / `prefix`.\n *\n * This helper is the single source of truth for \"turn a provider into a\n * toolkit entry record\" and is used by `AgentsPlugin.buildToolIndex`\n * (the `tools(plugins)` resolution pass and auto-inherit) and by the\n * standalone `runAgent` executor.\n */\nexport function resolveToolkitFromProvider(\n pluginName: string,\n provider: ToolProvider,\n opts?: ToolkitOptions,\n): Record<string, ToolkitEntry> {\n const withToolkit = provider as MaybeToolkitProvider;\n if (typeof withToolkit.toolkit === \"function\") {\n return withToolkit.toolkit(opts);\n }\n\n const out: Record<string, ToolkitEntry> = {};\n for (const tool of provider.getAgentTools()) {\n const key = applyToolkitOptions(tool.name, pluginName, opts);\n if (key === null) continue;\n\n out[key] = {\n __toolkitRef: true,\n pluginName,\n localName: tool.name,\n def: { ...tool, name: key },\n };\n }\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,2BACd,YACA,UACA,MAC8B;CAC9B,MAAM,cAAc;AACpB,KAAI,OAAO,YAAY,YAAY,WACjC,QAAO,YAAY,QAAQ,KAAK;CAGlC,MAAM,MAAoC,EAAE;AAC5C,MAAK,MAAM,QAAQ,SAAS,eAAe,EAAE;EAC3C,MAAM,MAAM,oBAAoB,KAAK,MAAM,YAAY,KAAK;AAC5D,MAAI,QAAQ,KAAM;AAElB,MAAI,OAAO;GACT,cAAc;GACd;GACA,WAAW,KAAK;GAChB,KAAK;IAAE,GAAG;IAAM,MAAM;IAAK;GAC5B;;AAEH,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"define-tool.d.ts","names":[],"sources":["../../../../src/core/agent/tools/define-tool.ts"],"mappings":";;;;;;;;AAWA;;;UAAiB,SAAA,WAAoB,CAAA,CAAE,OAAA,GAAU,CAAA,CAAE,OAAA;EACjD,WAAA;EACA,MAAA,EAAQ,CAAA;EACR,WAAA,GAAc,eAAA;EAwBE;;;;;;;;;;;EAZhB,eAAA;EAbA;;;;;;;;;;EAwBA,OAAA,GACE,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAA,GACd,MAAA,GAAS,WAAA,eACI,OAAA;AAAA;AAAA,KAGL,YAAA,GAAe,MAAA,SAAe,SAAA;;;AAA1C;;;;;iBASgB,UAAA,WAAqB,CAAA,CAAE,OAAA,CAAA,CACrC,MAAA,EAAQ,SAAA,CAAU,CAAA,IACjB,SAAA,CAAU,CAAA;;;;;;;iBAUS,mBAAA,CACpB,QAAA,EAAU,YAAA,EACV,IAAA,UACA,IAAA,WACA,MAAA,GAAS,WAAA,GACR,OAAA;;;;;;;;iBAmBa,iBAAA,CACd,QAAA,EAAU,YAAA,GACT,mBAAA"}
1
+ {"version":3,"file":"define-tool.d.ts","names":[],"sources":["../../../../src/core/agent/tools/define-tool.ts"],"mappings":";;;;;;;;AAYA;;;UAAiB,SAAA,WAAoB,CAAA,CAAE,OAAA,GAAU,CAAA,CAAE,OAAA;EACjD,WAAA;EACA,MAAA,EAAQ,CAAA;EACR,WAAA,GAAc,eAAA;EAwBE;;;;;;;;;;;EAZhB,eAAA;EAbA;;;;;;;;;;EAwBA,OAAA,GACE,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAA,GACd,MAAA,GAAS,WAAA,eACI,OAAA;AAAA;AAAA,KAGL,YAAA,GAAe,MAAA,SAAe,SAAA;;;AAA1C;;;;;iBASgB,UAAA,WAAqB,CAAA,CAAE,OAAA,CAAA,CACrC,MAAA,EAAQ,SAAA,CAAU,CAAA,IACjB,SAAA,CAAU,CAAA;;;;;;;iBAUS,mBAAA,CACpB,QAAA,EAAU,YAAA,EACV,IAAA,UACA,IAAA,WACA,MAAA,GAAS,WAAA,GACR,OAAA;;;;;;;;iBAmBa,iBAAA,CACd,QAAA,EAAU,YAAA,GACT,mBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"define-tool.js","names":[],"sources":["../../../../src/core/agent/tools/define-tool.ts"],"sourcesContent":["import type { AgentToolDefinition, ToolAnnotations } from \"shared\";\nimport type { z } from \"zod\";\nimport { toToolJSONSchema } from \"./json-schema\";\nimport { formatZodError } from \"./tool\";\n\n/**\n * Single-tool entry for a plugin's internal tool registry.\n *\n * Plugins collect these into a `Record<string, ToolEntry>` keyed by the tool's\n * public name and dispatch via `executeFromRegistry`.\n */\nexport interface ToolEntry<S extends z.ZodType = z.ZodType> {\n description: string;\n schema: S;\n annotations?: ToolAnnotations;\n /**\n * Whether this tool is eligible for auto-inheritance into markdown or\n * code-defined agents that enable `autoInheritTools`. Defaults to `false`\n * (safe-by-default) — plugin authors must explicitly opt a tool in if they\n * consider it safe enough to appear in every agent's tool record without an\n * explicit `tools:` declaration. Destructive or privilege-sensitive tools\n * should leave this unset so that they only reach agents that wire them\n * explicitly (via `tools:` object/function form, markdown `plugin:NAME`\n * entries in the unified `tools:` list, or\n * `plugins.<name>.toolkit({ only: [...] })`).\n */\n autoInheritable?: boolean;\n /**\n * Callback the agents plugin invokes after Zod validation succeeds.\n *\n * Named `execute` to match the public `tool({ execute })` form — both the\n * agent-author surface and the plugin-author surface now spell their\n * callback the same way. `args` is the inferred Zod output (so `T extends\n * z.ZodType` flows through and `args` is fully typed). `signal` is the\n * per-run AbortSignal: forward it to any awaited I/O so cancellation\n * actually unwinds the call (analytics and lakebase both do this).\n */\n execute: (\n args: z.infer<S>,\n signal?: AbortSignal,\n ) => unknown | Promise<unknown>;\n}\n\nexport type ToolRegistry = Record<string, ToolEntry>;\n\n/**\n * Defines a single tool entry for a plugin's internal registry.\n *\n * The generic `S` flows from `schema` through to the `handler` callback so\n * `args` is fully typed from the Zod schema. Names are assigned by the\n * registry key, so they are not repeated inside the entry.\n */\nexport function defineTool<S extends z.ZodType>(\n config: ToolEntry<S>,\n): ToolEntry<S> {\n return config;\n}\n\n/**\n * Validates tool-call arguments against the entry's schema and invokes its\n * handler. On validation failure, returns an LLM-friendly error string\n * (matching the behavior of `tool()`) rather than throwing, so the model\n * can self-correct on its next turn.\n */\nexport async function executeFromRegistry(\n registry: ToolRegistry,\n name: string,\n args: unknown,\n signal?: AbortSignal,\n): Promise<unknown> {\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Unknown tool: ${name}`);\n }\n const parsed = entry.schema.safeParse(args);\n if (!parsed.success) {\n return formatZodError(parsed.error, name);\n }\n return entry.execute(parsed.data, signal);\n}\n\n/**\n * Produces the `AgentToolDefinition[]` a ToolProvider exposes to the LLM,\n * deriving `parameters` JSON Schema from each entry's Zod schema.\n *\n * Tool names come from registry keys (supports dotted names like\n * `uploads.list` for dynamic plugins).\n */\nexport function toolsFromRegistry(\n registry: ToolRegistry,\n): AgentToolDefinition[] {\n return Object.entries(registry).map(([name, entry]) => {\n const parameters = toToolJSONSchema(\n entry.schema,\n ) as unknown as AgentToolDefinition[\"parameters\"];\n const def: AgentToolDefinition = {\n name,\n description: entry.description,\n parameters,\n };\n if (entry.annotations) {\n def.annotations = entry.annotations;\n }\n return def;\n });\n}\n"],"mappings":";;;;;;;;;;;AAoDA,SAAgB,WACd,QACc;AACd,QAAO;;;;;;;;AAST,eAAsB,oBACpB,UACA,MACA,MACA,QACkB;CAClB,MAAM,QAAQ,SAAS;AACvB,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,iBAAiB,OAAO;CAE1C,MAAM,SAAS,MAAM,OAAO,UAAU,KAAK;AAC3C,KAAI,CAAC,OAAO,QACV,QAAO,eAAe,OAAO,OAAO,KAAK;AAE3C,QAAO,MAAM,QAAQ,OAAO,MAAM,OAAO;;;;;;;;;AAU3C,SAAgB,kBACd,UACuB;AACvB,QAAO,OAAO,QAAQ,SAAS,CAAC,KAAK,CAAC,MAAM,WAAW;EACrD,MAAM,aAAa,iBACjB,MAAM,OACP;EACD,MAAM,MAA2B;GAC/B;GACA,aAAa,MAAM;GACnB;GACD;AACD,MAAI,MAAM,YACR,KAAI,cAAc,MAAM;AAE1B,SAAO;GACP"}
1
+ {"version":3,"file":"define-tool.js","names":[],"sources":["../../../../src/core/agent/tools/define-tool.ts"],"sourcesContent":["import type { AgentToolDefinition, ToolAnnotations } from \"shared\";\nimport type { z } from \"zod\";\n\nimport { toToolJSONSchema } from \"./json-schema\";\nimport { formatZodError } from \"./tool\";\n\n/**\n * Single-tool entry for a plugin's internal tool registry.\n *\n * Plugins collect these into a `Record<string, ToolEntry>` keyed by the tool's\n * public name and dispatch via `executeFromRegistry`.\n */\nexport interface ToolEntry<S extends z.ZodType = z.ZodType> {\n description: string;\n schema: S;\n annotations?: ToolAnnotations;\n /**\n * Whether this tool is eligible for auto-inheritance into markdown or\n * code-defined agents that enable `autoInheritTools`. Defaults to `false`\n * (safe-by-default) — plugin authors must explicitly opt a tool in if they\n * consider it safe enough to appear in every agent's tool record without an\n * explicit `tools:` declaration. Destructive or privilege-sensitive tools\n * should leave this unset so that they only reach agents that wire them\n * explicitly (via `tools:` object/function form, markdown `plugin:NAME`\n * entries in the unified `tools:` list, or\n * `plugins.<name>.toolkit({ only: [...] })`).\n */\n autoInheritable?: boolean;\n /**\n * Callback the agents plugin invokes after Zod validation succeeds.\n *\n * Named `execute` to match the public `tool({ execute })` form — both the\n * agent-author surface and the plugin-author surface now spell their\n * callback the same way. `args` is the inferred Zod output (so `T extends\n * z.ZodType` flows through and `args` is fully typed). `signal` is the\n * per-run AbortSignal: forward it to any awaited I/O so cancellation\n * actually unwinds the call (analytics and lakebase both do this).\n */\n execute: (\n args: z.infer<S>,\n signal?: AbortSignal,\n ) => unknown | Promise<unknown>;\n}\n\nexport type ToolRegistry = Record<string, ToolEntry>;\n\n/**\n * Defines a single tool entry for a plugin's internal registry.\n *\n * The generic `S` flows from `schema` through to the `handler` callback so\n * `args` is fully typed from the Zod schema. Names are assigned by the\n * registry key, so they are not repeated inside the entry.\n */\nexport function defineTool<S extends z.ZodType>(\n config: ToolEntry<S>,\n): ToolEntry<S> {\n return config;\n}\n\n/**\n * Validates tool-call arguments against the entry's schema and invokes its\n * handler. On validation failure, returns an LLM-friendly error string\n * (matching the behavior of `tool()`) rather than throwing, so the model\n * can self-correct on its next turn.\n */\nexport async function executeFromRegistry(\n registry: ToolRegistry,\n name: string,\n args: unknown,\n signal?: AbortSignal,\n): Promise<unknown> {\n const entry = registry[name];\n if (!entry) {\n throw new Error(`Unknown tool: ${name}`);\n }\n const parsed = entry.schema.safeParse(args);\n if (!parsed.success) {\n return formatZodError(parsed.error, name);\n }\n return entry.execute(parsed.data, signal);\n}\n\n/**\n * Produces the `AgentToolDefinition[]` a ToolProvider exposes to the LLM,\n * deriving `parameters` JSON Schema from each entry's Zod schema.\n *\n * Tool names come from registry keys (supports dotted names like\n * `uploads.list` for dynamic plugins).\n */\nexport function toolsFromRegistry(\n registry: ToolRegistry,\n): AgentToolDefinition[] {\n return Object.entries(registry).map(([name, entry]) => {\n const parameters = toToolJSONSchema(\n entry.schema,\n ) as unknown as AgentToolDefinition[\"parameters\"];\n const def: AgentToolDefinition = {\n name,\n description: entry.description,\n parameters,\n };\n if (entry.annotations) {\n def.annotations = entry.annotations;\n }\n return def;\n });\n}\n"],"mappings":";;;;;;;;;;;AAqDA,SAAgB,WACd,QACc;AACd,QAAO;;;;;;;;AAST,eAAsB,oBACpB,UACA,MACA,MACA,QACkB;CAClB,MAAM,QAAQ,SAAS;AACvB,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,iBAAiB,OAAO;CAE1C,MAAM,SAAS,MAAM,OAAO,UAAU,KAAK;AAC3C,KAAI,CAAC,OAAO,QACV,QAAO,eAAe,OAAO,OAAO,KAAK;AAE3C,QAAO,MAAM,QAAQ,OAAO,MAAM,OAAO;;;;;;;;;AAU3C,SAAgB,kBACd,UACuB;AACvB,QAAO,OAAO,QAAQ,SAAS,CAAC,KAAK,CAAC,MAAM,WAAW;EACrD,MAAM,aAAa,iBACjB,MAAM,OACP;EACD,MAAM,MAA2B;GAC/B;GACA,aAAa,MAAM;GACnB;GACD;AACD,MAAI,MAAM,YACR,KAAI,cAAc,MAAM;AAE1B,SAAO;GACP"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.ts","names":[],"sources":["../../../../src/core/agent/tools/tool.ts"],"mappings":";;;;;;UAKiB,UAAA,WAAqB,CAAA,CAAE,OAAA;;;AAAxC;;;;;;EASE,IAAA;EAiCkB;;;;;;;;;;;;;EAnBlB,WAAA;EACA,MAAA,EAAQ,CAAA;EAkBU;;;;;;AAYpB;;EArBE,WAAA,GAAc,eAAA;EAqBiB;;;;;;;;EAZ/B,OAAA,GAAU,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAA,gBAAiB,OAAA;AAAA;;;;;;;;;;iBAY3B,IAAA,WAAe,CAAA,CAAE,OAAA,CAAA,CAAS,MAAA,EAAQ,UAAA,CAAW,CAAA,IAAK,YAAA"}
1
+ {"version":3,"file":"tool.d.ts","names":[],"sources":["../../../../src/core/agent/tools/tool.ts"],"mappings":";;;;;;UAMiB,UAAA,WAAqB,CAAA,CAAE,OAAA;;;AAAxC;;;;;;EASE,IAAA;EAiCkB;;;;;;;;;;;;;EAnBlB,WAAA;EACA,MAAA,EAAQ,CAAA;EAkBU;;;;;;AAYpB;;EArBE,WAAA,GAAc,eAAA;EAqBiB;;;;;;;;EAZ/B,OAAA,GAAU,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAA,gBAAiB,OAAA;AAAA;;;;;;;;;;iBAY3B,IAAA,WAAe,CAAA,CAAE,OAAA,CAAA,CAAS,MAAA,EAAQ,UAAA,CAAW,CAAA,IAAK,YAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool.js","names":[],"sources":["../../../../src/core/agent/tools/tool.ts"],"sourcesContent":["import type { ToolAnnotations } from \"shared\";\nimport type { z } from \"zod\";\nimport type { FunctionTool } from \"./function-tool\";\nimport { toToolJSONSchema } from \"./json-schema\";\n\nexport interface ToolConfig<S extends z.ZodType> {\n /**\n * Optional. When the tool is placed in a keyed record (the standard\n * `tools: { my_tool: tool({...}) }` form, or the function form\n * `tools(plugins) => ({ my_tool: tool({...}) })`), the agents plugin\n * overrides the tool's LLM-visible name with the record key. Set\n * `name` explicitly only if you're constructing a `FunctionTool`\n * outside any keyed-record context — otherwise the record key wins.\n */\n name?: string;\n /**\n * What the tool does, what it expects, and when the LLM should call it.\n * The model reads this verbatim when deciding whether to invoke the tool,\n * so write it for an LLM, not for a human reader of your code: spell out\n * the inputs, the return shape, and any pre-conditions or side effects.\n *\n * Required. Earlier versions silently fell back to the tool's name when\n * omitted, which surfaced cryptic identifiers like `\"get_weather\"` as the\n * description — the model then had no signal about expected use and\n * either skipped the tool or called it speculatively. Making this\n * mandatory at the type level forces a real description at authoring\n * time instead of debugging a confused agent later.\n */\n description: string;\n schema: S;\n /**\n * Behavioural hints forwarded to the resolved tool definition. Prefer\n * `effect` (`\"read\" | \"write\" | \"update\" | \"destructive\"`) — any mutating\n * value forces the agents-plugin approval gate before `execute()` runs\n * and the client's approval card will colour itself accordingly. Legacy\n * `destructive: true` still gates. Dropped silently before the fix that\n * added this field.\n */\n annotations?: ToolAnnotations;\n /**\n * Returning a non-string value is fine: the agent runtime serializes\n * the result via `normalizeToolResult` before handing it to the LLM\n * (strings pass through; `null` becomes `\"null\"`; everything else gets\n * `JSON.stringify`'d; `undefined` becomes `\"\"`). Return whatever shape\n * is most natural for your tool — typically an object — and let the\n * runtime handle the wire format.\n */\n execute: (args: z.infer<S>) => unknown | Promise<unknown>;\n}\n\n/**\n * Factory for defining function tools with Zod schemas.\n *\n * - Generates JSON Schema (for the LLM) from the Zod schema via `z.toJSONSchema()`.\n * - Infers the `execute` argument type from the schema.\n * - Validates tool call arguments at runtime. On validation failure, returns\n * a formatted error string to the LLM instead of throwing, so the model\n * can self-correct on its next turn.\n */\nexport function tool<S extends z.ZodType>(config: ToolConfig<S>): FunctionTool {\n const parameters = toToolJSONSchema(config.schema);\n\n // `name` is only used for the zod-validation error message and the\n // FunctionTool's `name` field; the agents plugin overrides the latter\n // with the record key (`tools: { my_tool: ... }` -> \"my_tool\") at\n // index-build time. Fall back to a generic label so errors are still\n // legible when `name` is omitted.\n const labelForErrors = config.name ?? \"tool\";\n\n return {\n type: \"function\",\n ...(config.name !== undefined ? { name: config.name } : {}),\n description: config.description,\n parameters,\n ...(config.annotations ? { annotations: config.annotations } : {}),\n execute: async (args: Record<string, unknown>) => {\n const parsed = config.schema.safeParse(args);\n if (!parsed.success) {\n return formatZodError(parsed.error, labelForErrors);\n }\n return config.execute(parsed.data as z.infer<S>);\n },\n };\n}\n\n/**\n * Formats a Zod validation error into an LLM-friendly string.\n *\n * Example: `Invalid arguments for get_weather: city: Invalid input: expected string, received undefined`\n */\nexport function formatZodError(error: z.ZodError, toolName: string): string {\n const parts = error.issues.map((issue) => {\n const field = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return `${field}: ${issue.message}`;\n });\n return `Invalid arguments for ${toolName}: ${parts.join(\"; \")}`;\n}\n"],"mappings":";;;;;;;;;;;;AA2DA,SAAgB,KAA0B,QAAqC;CAC7E,MAAM,aAAa,iBAAiB,OAAO,OAAO;CAOlD,MAAM,iBAAiB,OAAO,QAAQ;AAEtC,QAAO;EACL,MAAM;EACN,GAAI,OAAO,SAAS,SAAY,EAAE,MAAM,OAAO,MAAM,GAAG,EAAE;EAC1D,aAAa,OAAO;EACpB;EACA,GAAI,OAAO,cAAc,EAAE,aAAa,OAAO,aAAa,GAAG,EAAE;EACjE,SAAS,OAAO,SAAkC;GAChD,MAAM,SAAS,OAAO,OAAO,UAAU,KAAK;AAC5C,OAAI,CAAC,OAAO,QACV,QAAO,eAAe,OAAO,OAAO,eAAe;AAErD,UAAO,OAAO,QAAQ,OAAO,KAAmB;;EAEnD;;;;;;;AAQH,SAAgB,eAAe,OAAmB,UAA0B;AAK1E,QAAO,yBAAyB,SAAS,IAJ3B,MAAM,OAAO,KAAK,UAAU;AAExC,SAAO,GADO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,SAC7C,IAAI,MAAM;GAC1B,CACiD,KAAK,KAAK"}
1
+ {"version":3,"file":"tool.js","names":[],"sources":["../../../../src/core/agent/tools/tool.ts"],"sourcesContent":["import type { ToolAnnotations } from \"shared\";\nimport type { z } from \"zod\";\n\nimport type { FunctionTool } from \"./function-tool\";\nimport { toToolJSONSchema } from \"./json-schema\";\n\nexport interface ToolConfig<S extends z.ZodType> {\n /**\n * Optional. When the tool is placed in a keyed record (the standard\n * `tools: { my_tool: tool({...}) }` form, or the function form\n * `tools(plugins) => ({ my_tool: tool({...}) })`), the agents plugin\n * overrides the tool's LLM-visible name with the record key. Set\n * `name` explicitly only if you're constructing a `FunctionTool`\n * outside any keyed-record context — otherwise the record key wins.\n */\n name?: string;\n /**\n * What the tool does, what it expects, and when the LLM should call it.\n * The model reads this verbatim when deciding whether to invoke the tool,\n * so write it for an LLM, not for a human reader of your code: spell out\n * the inputs, the return shape, and any pre-conditions or side effects.\n *\n * Required. Earlier versions silently fell back to the tool's name when\n * omitted, which surfaced cryptic identifiers like `\"get_weather\"` as the\n * description — the model then had no signal about expected use and\n * either skipped the tool or called it speculatively. Making this\n * mandatory at the type level forces a real description at authoring\n * time instead of debugging a confused agent later.\n */\n description: string;\n schema: S;\n /**\n * Behavioural hints forwarded to the resolved tool definition. Prefer\n * `effect` (`\"read\" | \"write\" | \"update\" | \"destructive\"`) — any mutating\n * value forces the agents-plugin approval gate before `execute()` runs\n * and the client's approval card will colour itself accordingly. Legacy\n * `destructive: true` still gates. Dropped silently before the fix that\n * added this field.\n */\n annotations?: ToolAnnotations;\n /**\n * Returning a non-string value is fine: the agent runtime serializes\n * the result via `normalizeToolResult` before handing it to the LLM\n * (strings pass through; `null` becomes `\"null\"`; everything else gets\n * `JSON.stringify`'d; `undefined` becomes `\"\"`). Return whatever shape\n * is most natural for your tool — typically an object — and let the\n * runtime handle the wire format.\n */\n execute: (args: z.infer<S>) => unknown | Promise<unknown>;\n}\n\n/**\n * Factory for defining function tools with Zod schemas.\n *\n * - Generates JSON Schema (for the LLM) from the Zod schema via `z.toJSONSchema()`.\n * - Infers the `execute` argument type from the schema.\n * - Validates tool call arguments at runtime. On validation failure, returns\n * a formatted error string to the LLM instead of throwing, so the model\n * can self-correct on its next turn.\n */\nexport function tool<S extends z.ZodType>(config: ToolConfig<S>): FunctionTool {\n const parameters = toToolJSONSchema(config.schema);\n\n // `name` is only used for the zod-validation error message and the\n // FunctionTool's `name` field; the agents plugin overrides the latter\n // with the record key (`tools: { my_tool: ... }` -> \"my_tool\") at\n // index-build time. Fall back to a generic label so errors are still\n // legible when `name` is omitted.\n const labelForErrors = config.name ?? \"tool\";\n\n return {\n type: \"function\",\n ...(config.name !== undefined ? { name: config.name } : {}),\n description: config.description,\n parameters,\n ...(config.annotations ? { annotations: config.annotations } : {}),\n execute: async (args: Record<string, unknown>) => {\n const parsed = config.schema.safeParse(args);\n if (!parsed.success) {\n return formatZodError(parsed.error, labelForErrors);\n }\n return config.execute(parsed.data as z.infer<S>);\n },\n };\n}\n\n/**\n * Formats a Zod validation error into an LLM-friendly string.\n *\n * Example: `Invalid arguments for get_weather: city: Invalid input: expected string, received undefined`\n */\nexport function formatZodError(error: z.ZodError, toolName: string): string {\n const parts = error.issues.map((issue) => {\n const field = issue.path.length > 0 ? issue.path.join(\".\") : \"(root)\";\n return `${field}: ${issue.message}`;\n });\n return `Invalid arguments for ${toolName}: ${parts.join(\"; \")}`;\n}\n"],"mappings":";;;;;;;;;;;;AA4DA,SAAgB,KAA0B,QAAqC;CAC7E,MAAM,aAAa,iBAAiB,OAAO,OAAO;CAOlD,MAAM,iBAAiB,OAAO,QAAQ;AAEtC,QAAO;EACL,MAAM;EACN,GAAI,OAAO,SAAS,SAAY,EAAE,MAAM,OAAO,MAAM,GAAG,EAAE;EAC1D,aAAa,OAAO;EACpB;EACA,GAAI,OAAO,cAAc,EAAE,aAAa,OAAO,aAAa,GAAG,EAAE;EACjE,SAAS,OAAO,SAAkC;GAChD,MAAM,SAAS,OAAO,OAAO,UAAU,KAAK;AAC5C,OAAI,CAAC,OAAO,QACV,QAAO,eAAe,OAAO,OAAO,eAAe;AAErD,UAAO,OAAO,QAAQ,OAAO,KAAmB;;EAEnD;;;;;;;AAQH,SAAgB,eAAe,OAAmB,UAA0B;AAK1E,QAAO,yBAAyB,SAAS,IAJ3B,MAAM,OAAO,KAAK,UAAU;AAExC,SAAO,GADO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,SAC7C,IAAI,MAAM;GAC1B,CACiD,KAAK,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/core/agent/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/core/agent/types.ts"],"mappings":";;;;;;;;;;;;;;;;;UAmBiB,YAAA;EAAA,SACN,YAAA;EACT,UAAA;EACA,SAAA;EACA,GAAA,EAAK,mBAAA;EACL,WAAA,GAAc,eAAA;EAFd;;;;;;EASA,eAAA;AAAA;AASF;;;;;;AAAA,KAAY,SAAA,GACR,YAAA,GACA,UAAA,GACA,YAAA,GAAY,oBAAA;AAAA,UAGC,cAAA;EAF6C;EAI5D,MAAA;EANE;EAQF,IAAA;EAPc;EASd,MAAA;EATc;EAWd,MAAA,GAAS,MAAA;AAAA;;;;;;;;UAUM,qBAAA;EACf,OAAA,CAAQ,IAAA,GAAO,cAAA,GAAiB,MAAA,SAAe,YAAA;AAAA;;;;;;;;;;;;;;;AA2BjD;;;;;AAKA;;;;;KALY,OAAA,GAAU,MAAA,SAAe,qBAAA;;;;UAKpB,aAAA;EACf,SAAA;EACA,WAAA;EACA,SAAA;AAAA;AAAA,KAGU,sBAAA,sBAGN,GAAA,EAAK,aAAA;;;;;KAMC,UAAA,GAAa,MAAA,SAAe,SAAA;;;;;;;;;AAaxC;KAFY,YAAA,IAAgB,OAAA,EAAS,OAAA,KAAY,UAAA;AAAA,UAEhC,eAAA;EA2BP;;;;;;;;;;;;;;;;;;EARR,IAAA;EAoBqB;EAlBrB,YAAA;EAoBS;;;;;EAdT,KAAA,GAAQ,YAAA,GAAe,OAAA,CAAQ,YAAA;EA0B/B;;;;;AAuBF;;;;;AAOA;EA5CE,KAAA,GAAQ,UAAA,GAAa,YAAA;;EAErB,MAAA,GAAS,MAAA,SAAe,eAAA;EA8Cf;EA5CT,gBAAA,GAAmB,sBAAA;EACnB,QAAA;EACA,SAAA;EAgDuB;;;;;;;EAxCvB,gBAAA,GAAmB,gBAAA;EA8BuC;;;;;;;;EArB1D,SAAA;AAAA;;;;;;;;;;;;UAce,sBAAA;EAwCf;EAtCA,IAAA;EA8CE;EA5CF,IAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,gBAAA;EAqExC;EAnEF,GAAA;EAgFmB;EA9EnB,MAAA,GAAS,MAAA,SAAe,eAAA;EAmFd;EAjFV,YAAA;;EAEA,YAAA,GAAe,YAAA,GAAe,OAAA,CAAQ,YAAA;EAwFpB;EAtFlB,KAAA,GAAQ,MAAA,SAAe,SAAA;EA4Fd;EA1FT,gBAAA,aAA6B,sBAAA;EA+FD;EA7F5B,WAAA,GAAc,WAAA;EA4Gc;EA1G5B,gBAAA,GAAmB,sBAAA;EAyEf;;;;;;EAlEJ,GAAA,GAAM,mBAAA;EAyEY;;;;;;;;;EA/DlB,QAAA;IA0ES;;;;;IApEP,qBAAA,YAmF0B;IAjF1B,SAAA;EAAA;EAoF4B;;;;;;;;EA1E9B,MAAA;IA2EA;;;;;IArEE,2BAAA;IAwEqB;;;;;IAlErB,YAAA;IAuEiB;;;;AASrB;IA1EI,gBAAA;IA0EqD;;;;;;;;;;;;IA7DrD,iBAAA;EAAA;AAAA;;KAKQ,iBAAA;EAEN,MAAA;EACA,UAAA;EACA,SAAA;EACA,GAAA,EAAK,mBAAA;AAAA;EAGL,MAAA;EACA,YAAA,EAAc,YAAA;EACd,GAAA,EAAK,mBAAA;AAAA;EAGL,MAAA;EACA,WAAA;EACA,GAAA,EAAK,mBAAA;AAAA;EAGL,MAAA;EACA,SAAA;EACA,GAAA,EAAK,mBAAA;AAAA;;;;;;;;;;;EAaL,MAAA;EACA,IAAA,EAdwB,cAAA;EAexB,GAAA,EAAK,mBAAA;AAAA;AAAA,UAGM,eAAA;EACf,IAAA;EACA,YAAA;EACA,OAAA,EAAS,YAAA;EACT,SAAA,EAAW,GAAA,SAAY,iBAAA;EACvB,gBAAA,GAAmB,sBAAA;EACnB,QAAA;EACA,SAAA;;EAEA,gBAAA,GAAmB,gBAAA;;EAEnB,SAAA;AAAA;;;;;iBAOc,cAAA,CAAe,KAAA,YAAiB,KAAA,IAAS,YAAA"}