@mastra/server 1.57.0-alpha.1 → 1.57.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 (171) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/_types/@internal_core/dist/storage/index.d.ts +2 -0
  3. package/dist/_types/@internal_voice/dist/_types/@internal_core/dist/request-context/index.d.ts +4 -1
  4. package/dist/_types/@mastra_schema-compat/dist/_types/@internal_ai-sdk-v5/dist/index.d.ts +16 -217
  5. package/dist/_types/@mastra_schema-compat/dist/_types/@internal_ai-v6/dist/index.d.ts +31 -378
  6. package/dist/{a2a-CE7HKP5V.cjs → a2a-DKnwIgiw.cjs} +2 -2
  7. package/dist/{a2a-CE7HKP5V.cjs.map → a2a-DKnwIgiw.cjs.map} +1 -1
  8. package/dist/{a2a-_3LYIc9y.js → a2a-uPi5sPwb.js} +2 -2
  9. package/dist/{a2a-_3LYIc9y.js.map → a2a-uPi5sPwb.js.map} +1 -1
  10. package/dist/{agent-versions-DC1Rp5EP.js → agent-versions-Bsrpa_zb.js} +2 -2
  11. package/dist/{agent-versions-DC1Rp5EP.js.map → agent-versions-Bsrpa_zb.js.map} +1 -1
  12. package/dist/{agent-versions-DhkWMz0z.cjs → agent-versions-CdQGF-3e.cjs} +2 -2
  13. package/dist/{agent-versions-DhkWMz0z.cjs.map → agent-versions-CdQGF-3e.cjs.map} +1 -1
  14. package/dist/{agents-DD4PJgsF.js → agents-CYvun9iI.js} +12 -7
  15. package/dist/agents-CYvun9iI.js.map +1 -0
  16. package/dist/{agents-B9ofSVSn.cjs → agents-Dk2qoJi_.cjs} +12 -7
  17. package/dist/agents-Dk2qoJi_.cjs.map +1 -0
  18. package/dist/{api-schema-manifest-Ba-Ssw4H.cjs → api-schema-manifest-7-NC9Dyc.cjs} +2 -2
  19. package/dist/{api-schema-manifest-Ba-Ssw4H.cjs.map → api-schema-manifest-7-NC9Dyc.cjs.map} +1 -1
  20. package/dist/{api-schema-manifest-DbTP-DpV.js → api-schema-manifest-C5hpdIE_.js} +2 -2
  21. package/dist/{api-schema-manifest-DbTP-DpV.js.map → api-schema-manifest-C5hpdIE_.js.map} +1 -1
  22. package/dist/{builder-registry-C_PysvMI.cjs → builder-registry-BoaXBdm_.cjs} +2 -2
  23. package/dist/{builder-registry-C_PysvMI.cjs.map → builder-registry-BoaXBdm_.cjs.map} +1 -1
  24. package/dist/{builder-registry-DaPvPspl.js → builder-registry-DE5w7bNk.js} +2 -2
  25. package/dist/{builder-registry-DaPvPspl.js.map → builder-registry-DE5w7bNk.js.map} +1 -1
  26. package/dist/{dist-DhFw0bEW.cjs → dist-COHIL6fR.cjs} +156 -46
  27. package/dist/dist-COHIL6fR.cjs.map +1 -0
  28. package/dist/{dist-DRyzA92e.js → dist-DGqlUp0b.js} +156 -46
  29. package/dist/dist-DGqlUp0b.js.map +1 -0
  30. package/dist/docs/SKILL.md +1 -1
  31. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  32. package/dist/docs/references/reference-server-routes.md +13 -0
  33. package/dist/{editor-builder-ByNr3nc9.cjs → editor-builder-BW4nlDcX.cjs} +2 -2
  34. package/dist/{editor-builder-ByNr3nc9.cjs.map → editor-builder-BW4nlDcX.cjs.map} +1 -1
  35. package/dist/{editor-builder-DZRQf2UD.cjs → editor-builder-CWTGCtNu.cjs} +2 -2
  36. package/dist/{editor-builder-DZRQf2UD.cjs.map → editor-builder-CWTGCtNu.cjs.map} +1 -1
  37. package/dist/{editor-builder-CW9Tcqg1.js → editor-builder-Ct2nIbum.js} +2 -2
  38. package/dist/{editor-builder-CW9Tcqg1.js.map → editor-builder-Ct2nIbum.js.map} +1 -1
  39. package/dist/{editor-builder-XFcH8gX0.js → editor-builder-fKbRRlK_.js} +2 -2
  40. package/dist/{editor-builder-XFcH8gX0.js.map → editor-builder-fKbRRlK_.js.map} +1 -1
  41. package/dist/{observability-new-endpoints-DFBDedGH.cjs → observability-new-endpoints-Dk3oatL8.cjs} +3 -1
  42. package/dist/observability-new-endpoints-Dk3oatL8.cjs.map +1 -0
  43. package/dist/{observability-new-endpoints-CCyqX1Ra.js → observability-new-endpoints-YK2DjZto.js} +3 -1
  44. package/dist/observability-new-endpoints-YK2DjZto.js.map +1 -0
  45. package/dist/{processor-providers-BmOA_jeU.js → processor-providers-DBhZC6-4.js} +3 -2
  46. package/dist/processor-providers-DBhZC6-4.js.map +1 -0
  47. package/dist/{processor-providers-DGBNerTY.cjs → processor-providers-DHvTA9AL.cjs} +3 -2
  48. package/dist/processor-providers-DHvTA9AL.cjs.map +1 -0
  49. package/dist/{processors-05Z4P9eW.js → processors-88oJ_4J-.js} +7 -4
  50. package/dist/processors-88oJ_4J-.js.map +1 -0
  51. package/dist/{processors-BirBp7z3.cjs → processors-D6lRjS0e.cjs} +7 -4
  52. package/dist/processors-D6lRjS0e.cjs.map +1 -0
  53. package/dist/route-builder-CIk5k35M.js.map +1 -1
  54. package/dist/route-builder-CgLVYL1c.cjs.map +1 -1
  55. package/dist/{routes-CN8wYsyr.js → routes-CRoTKPvQ.js} +5 -5
  56. package/dist/{routes-CN8wYsyr.js.map → routes-CRoTKPvQ.js.map} +1 -1
  57. package/dist/{routes-2WgTU1wN.cjs → routes-hSY4wTeS.cjs} +5 -5
  58. package/dist/{routes-2WgTU1wN.cjs.map → routes-hSY4wTeS.cjs.map} +1 -1
  59. package/dist/{scorer-versions-BoAERQxp.js → scorer-versions-BA8N488c.js} +2 -2
  60. package/dist/{scorer-versions-BoAERQxp.js.map → scorer-versions-BA8N488c.js.map} +1 -1
  61. package/dist/{scorer-versions-DX81YG5X.cjs → scorer-versions-DpmAJKsY.cjs} +2 -2
  62. package/dist/{scorer-versions-DX81YG5X.cjs.map → scorer-versions-DpmAJKsY.cjs.map} +1 -1
  63. package/dist/server/handlers/a2a.cjs +1 -1
  64. package/dist/server/handlers/a2a.js +1 -1
  65. package/dist/server/handlers/agent-builder.cjs +3 -3
  66. package/dist/server/handlers/agent-builder.js +3 -3
  67. package/dist/server/handlers/agent-versions.cjs +2 -2
  68. package/dist/server/handlers/agent-versions.d.ts +224 -112
  69. package/dist/server/handlers/agent-versions.d.ts.map +1 -1
  70. package/dist/server/handlers/agent-versions.js +2 -2
  71. package/dist/server/handlers/agents.cjs +3 -3
  72. package/dist/server/handlers/agents.d.ts +56 -28
  73. package/dist/server/handlers/agents.d.ts.map +1 -1
  74. package/dist/server/handlers/agents.js +3 -3
  75. package/dist/server/handlers/builder-registry.cjs +1 -1
  76. package/dist/server/handlers/builder-registry.js +1 -1
  77. package/dist/server/handlers/editor-builder.cjs +1 -1
  78. package/dist/server/handlers/editor-builder.js +1 -1
  79. package/dist/server/handlers/favorites-enrichment.cjs +1 -1
  80. package/dist/server/handlers/favorites-enrichment.js +1 -1
  81. package/dist/server/handlers/mcp-client-versions.cjs +1 -1
  82. package/dist/server/handlers/mcp-client-versions.js +1 -1
  83. package/dist/server/handlers/observability-new-endpoints.cjs +1 -1
  84. package/dist/server/handlers/observability-new-endpoints.js +1 -1
  85. package/dist/server/handlers/observability.cjs +1 -1
  86. package/dist/server/handlers/observability.js +1 -1
  87. package/dist/server/handlers/processor-providers.cjs +1 -1
  88. package/dist/server/handlers/processor-providers.d.ts +4 -2
  89. package/dist/server/handlers/processor-providers.d.ts.map +1 -1
  90. package/dist/server/handlers/processor-providers.js +1 -1
  91. package/dist/server/handlers/processors.cjs +17 -2
  92. package/dist/server/handlers/processors.cjs.map +1 -1
  93. package/dist/server/handlers/processors.d.ts +6 -2
  94. package/dist/server/handlers/processors.d.ts.map +1 -1
  95. package/dist/server/handlers/processors.js +17 -2
  96. package/dist/server/handlers/processors.js.map +1 -1
  97. package/dist/server/handlers/prompt-block-versions.cjs +1 -1
  98. package/dist/server/handlers/prompt-block-versions.js +1 -1
  99. package/dist/server/handlers/schedules.d.ts +16 -16
  100. package/dist/server/handlers/scorer-versions.cjs +2 -2
  101. package/dist/server/handlers/scorer-versions.js +2 -2
  102. package/dist/server/handlers/stored-agent-favorites.cjs +3 -3
  103. package/dist/server/handlers/stored-agent-favorites.js +3 -3
  104. package/dist/server/handlers/stored-agents.cjs +3 -3
  105. package/dist/server/handlers/stored-agents.d.ts +224 -56
  106. package/dist/server/handlers/stored-agents.d.ts.map +1 -1
  107. package/dist/server/handlers/stored-agents.js +3 -3
  108. package/dist/server/handlers/stored-mcp-clients.cjs +1 -1
  109. package/dist/server/handlers/stored-mcp-clients.js +1 -1
  110. package/dist/server/handlers/stored-prompt-blocks.cjs +1 -1
  111. package/dist/server/handlers/stored-prompt-blocks.js +1 -1
  112. package/dist/server/handlers/stored-scorers.cjs +2 -2
  113. package/dist/server/handlers/stored-scorers.js +2 -2
  114. package/dist/server/handlers/stored-skill-favorites.cjs +2 -2
  115. package/dist/server/handlers/stored-skill-favorites.js +2 -2
  116. package/dist/server/handlers/stored-skills.cjs +2 -2
  117. package/dist/server/handlers/stored-skills.js +2 -2
  118. package/dist/server/handlers/stored-workspaces.cjs +1 -1
  119. package/dist/server/handlers/stored-workspaces.js +1 -1
  120. package/dist/server/handlers/system.cjs +1 -1
  121. package/dist/server/handlers/system.js +1 -1
  122. package/dist/server/handlers/tools.cjs +2 -2
  123. package/dist/server/handlers/tools.js +2 -2
  124. package/dist/server/handlers/workflows.cjs +2 -2
  125. package/dist/server/handlers/workflows.js +2 -2
  126. package/dist/server/handlers.cjs +1 -1
  127. package/dist/server/handlers.js +1 -1
  128. package/dist/server/schemas/agent-versions.d.ts +140 -0
  129. package/dist/server/schemas/agent-versions.d.ts.map +1 -1
  130. package/dist/server/schemas/agents.d.ts +60 -20
  131. package/dist/server/schemas/agents.d.ts.map +1 -1
  132. package/dist/server/schemas/index.cjs +8 -8
  133. package/dist/server/schemas/index.js +8 -8
  134. package/dist/server/schemas/processor-providers.d.ts +2 -0
  135. package/dist/server/schemas/processor-providers.d.ts.map +1 -1
  136. package/dist/server/schemas/processors.d.ts +4 -0
  137. package/dist/server/schemas/processors.d.ts.map +1 -1
  138. package/dist/server/schemas/schedules.d.ts +5 -5
  139. package/dist/server/schemas/stored-agents.d.ts +296 -0
  140. package/dist/server/schemas/stored-agents.d.ts.map +1 -1
  141. package/dist/server/server-adapter/index.cjs +2 -2
  142. package/dist/server/server-adapter/index.js +2 -2
  143. package/dist/server/server-adapter/routes/processor-providers.d.ts +4 -2
  144. package/dist/server/server-adapter/routes/processor-providers.d.ts.map +1 -1
  145. package/dist/server/server-adapter/routes/processors.d.ts +6 -2
  146. package/dist/server/server-adapter/routes/processors.d.ts.map +1 -1
  147. package/dist/{stored-agents-GBSl2bkv.js → stored-agents-D8ar1Pn7.js} +3 -2
  148. package/dist/stored-agents-D8ar1Pn7.js.map +1 -0
  149. package/dist/{stored-agents-DR_L2wPJ.cjs → stored-agents-DKd89v5z.cjs} +3 -2
  150. package/dist/stored-agents-DKd89v5z.cjs.map +1 -0
  151. package/dist/{stored-scorers-0eeoiKkg.js → stored-scorers-BIKumDRO.js} +2 -2
  152. package/dist/{stored-scorers-0eeoiKkg.js.map → stored-scorers-BIKumDRO.js.map} +1 -1
  153. package/dist/{stored-scorers-CMHNFquG.cjs → stored-scorers-_dqFdh-G.cjs} +2 -2
  154. package/dist/{stored-scorers-CMHNFquG.cjs.map → stored-scorers-_dqFdh-G.cjs.map} +1 -1
  155. package/dist/{utils-qxLrCsRx.js → utils-BUK03Frl.js} +3 -2
  156. package/dist/{utils-qxLrCsRx.js.map → utils-BUK03Frl.js.map} +1 -1
  157. package/dist/{utils-xsPNtHk8.cjs → utils-wESuBh27.cjs} +3 -2
  158. package/dist/{utils-xsPNtHk8.cjs.map → utils-wESuBh27.cjs.map} +1 -1
  159. package/package.json +10 -10
  160. package/dist/agents-B9ofSVSn.cjs.map +0 -1
  161. package/dist/agents-DD4PJgsF.js.map +0 -1
  162. package/dist/dist-DRyzA92e.js.map +0 -1
  163. package/dist/dist-DhFw0bEW.cjs.map +0 -1
  164. package/dist/observability-new-endpoints-CCyqX1Ra.js.map +0 -1
  165. package/dist/observability-new-endpoints-DFBDedGH.cjs.map +0 -1
  166. package/dist/processor-providers-BmOA_jeU.js.map +0 -1
  167. package/dist/processor-providers-DGBNerTY.cjs.map +0 -1
  168. package/dist/processors-05Z4P9eW.js.map +0 -1
  169. package/dist/processors-BirBp7z3.cjs.map +0 -1
  170. package/dist/stored-agents-DR_L2wPJ.cjs.map +0 -1
  171. package/dist/stored-agents-GBSl2bkv.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"builder-registry-DaPvPspl.js","names":[],"sources":["../src/server/schemas/builder-registry.ts","../src/server/handlers/builder-registry.ts"],"sourcesContent":["/**\n * Builder Registry Schemas\n *\n * Schemas for the Agent Builder skill registry routes. These are distinct from\n * the workspace skills.sh proxy schemas because:\n * - Builder routes are not scoped to a workspace.\n * - Builder install does not accept a `mount` field.\n * - Builder install body carries visibility + the resolved registry id.\n * - Builder install response returns the created stored skill id.\n *\n * The upstream skills.sh proxy response shapes are reused via the shared\n * `skillsShSearchResponseSchema`, `skillsShListResponseSchema`, and\n * `skillsShPreviewResponseSchema` since the wire shape from skills.sh is\n * registry-independent.\n */\n\nimport { z } from 'zod/v4';\n\n// =============================================================================\n// Registry list\n// =============================================================================\n\n/** Single entry in the registries list. */\nexport const builderRegistryEntrySchema = z.object({\n id: z.literal('skills-sh').describe('Stable registry identifier'),\n enabled: z.boolean().describe('Whether this registry is enabled in the running deployment'),\n label: z.string().describe('Human-readable registry name'),\n});\n\n/** Response for `GET /editor/builder/registries`. */\nexport const builderRegistriesResponseSchema = z.object({\n registries: z.array(builderRegistryEntrySchema),\n});\n\n// =============================================================================\n// Search / popular / preview\n// =============================================================================\n\n/** Path params used by every per-registry route. */\nexport const builderRegistryPathParams = z.object({\n registryId: z.string().describe('Registry identifier (e.g. \"skills-sh\")'),\n});\n\nexport const builderRegistrySearchQuerySchema = z.object({\n q: z.string().describe('Search query'),\n limit: z.coerce.number().int().min(1).max(100).optional().default(10).describe('Maximum number of results (1-100)'),\n});\n\nexport const builderRegistryPopularQuerySchema = z\n .object({\n limit: z.coerce.number().int().min(1).max(100).optional().default(10).describe('Maximum number of results (1-100)'),\n offset: z.coerce\n .number()\n .int()\n .min(0)\n .optional()\n .default(0)\n .describe('Offset for pagination (must be a multiple of `limit`)'),\n })\n .refine(args => args.offset % args.limit === 0, {\n message: 'offset must be a multiple of limit (the upstream registry pages by `limit`)',\n path: ['offset'],\n });\n\nexport const builderRegistryPreviewQuerySchema = z.object({\n owner: z.string().describe('GitHub repository owner'),\n repo: z.string().describe('GitHub repository name'),\n path: z.string().describe('Skill name within repo'),\n});\n\n// =============================================================================\n// Install\n// =============================================================================\n\n/**\n * Body for `POST /editor/builder/registries/:registryId/install`.\n *\n * Visibility behaves like the standard stored-skill create flow: optional,\n * defaults to private when the caller is authenticated.\n */\nexport const builderRegistryInstallBodySchema = z.object({\n owner: z.string().describe('GitHub repository owner'),\n repo: z.string().describe('GitHub repository name'),\n skillName: z.string().describe('Skill name from the registry'),\n visibility: z.enum(['private', 'public']).optional().describe('Visibility for the new stored skill'),\n});\n\n/** Response for the install route. Mirrors stored-skill identity fields. */\nexport const builderRegistryInstallResponseSchema = z.object({\n storedSkillId: z.string().describe('Id of the newly created stored skill'),\n name: z.string().describe('Resolved skill name'),\n filesWritten: z.number().describe('Number of files materialized into the skill version snapshot'),\n});\n\nexport type BuilderRegistryEntry = z.infer<typeof builderRegistryEntrySchema>;\nexport type BuilderRegistriesResponse = z.infer<typeof builderRegistriesResponseSchema>;\nexport type BuilderRegistryInstallBody = z.infer<typeof builderRegistryInstallBodySchema>;\nexport type BuilderRegistryInstallResponse = z.infer<typeof builderRegistryInstallResponseSchema>;\n","/**\n * Builder Registry Handlers\n *\n * Routes that let admins browse and install skills from configured external\n * registries (currently just skills.sh) directly into the Builder's stored\n * skills DB. Distinct from the workspace skills.sh routes, which write to a\n * workspace filesystem and never touch storage.\n *\n * Registry availability is driven by `AgentBuilderOptions.registries`. When\n * the requested registry is disabled (or the builder is missing entirely),\n * the routes 404 instead of leaking the surface.\n */\n\nimport type { Mastra } from '@mastra/core';\nimport type { StorageSkillFileNode } from '@mastra/core/storage';\n\nimport { HTTPException } from '../http-exception';\nimport {\n builderRegistriesResponseSchema,\n builderRegistryInstallBodySchema,\n builderRegistryInstallResponseSchema,\n builderRegistryPathParams,\n builderRegistryPopularQuerySchema,\n builderRegistryPreviewQuerySchema,\n builderRegistrySearchQuerySchema,\n} from '../schemas/builder-registry';\nimport {\n skillsShListResponseSchema,\n skillsShPreviewResponseSchema,\n skillsShSearchResponseSchema,\n} from '../schemas/workspace';\nimport { createRoute } from '../server-adapter/routes/route-builder';\nimport { toSlug } from '../utils';\nimport { getCallerAuthorId } from './authorship';\nimport { handleError } from './error';\nimport {\n assertSafeFilePath,\n assertSafeSkillName,\n fetchSkillFiles,\n getPopularSkillsSh,\n previewSkillsSh,\n searchSkillsSh,\n} from './skills-sh-shared';\n\n// =============================================================================\n// Registry resolution\n// =============================================================================\n\n/** Stable identifiers + display labels for every supported registry. */\nconst REGISTRY_LABELS: Record<string, string> = {\n 'skills-sh': 'skills.sh',\n};\n\ninterface RegistryStatus {\n id: 'skills-sh';\n enabled: boolean;\n label: string;\n}\n\n/**\n * Resolve which registries are enabled for the running deployment by reading\n * the builder's `registries` config. Returns a list with all known registries\n * (so the frontend can render an empty/disabled state) plus their enabled\n * flag.\n */\nasync function resolveRegistries(mastra: Mastra): Promise<RegistryStatus[]> {\n const editor = mastra.getEditor();\n if (!editor || typeof editor.resolveBuilder !== 'function') {\n return [{ id: 'skills-sh', enabled: false, label: REGISTRY_LABELS['skills-sh']! }];\n }\n const builder = await editor.resolveBuilder();\n const registries = builder?.getRegistries?.();\n return [\n {\n id: 'skills-sh',\n enabled: registries?.skillsSh?.enabled === true,\n label: REGISTRY_LABELS['skills-sh']!,\n },\n ];\n}\n\n/**\n * Hard-gate: throws 404 when the requested registry is unknown or disabled.\n * Mirrors `requireBuilderFeature` semantics — no surface leak for OFF registries.\n */\nasync function requireEnabledRegistry(mastra: Mastra, registryId: string): Promise<void> {\n const list = await resolveRegistries(mastra);\n const match = list.find(r => r.id === registryId);\n if (!match || !match.enabled) {\n throw new HTTPException(404, { message: 'Registry not found' });\n }\n}\n\n// =============================================================================\n// File-tree helpers\n// =============================================================================\n\n/**\n * Convert a flat list of `{ path, content, encoding }` entries into the\n * `StorageSkillFileNode` tree shape expected by the stored-skills create path.\n *\n * Each path is validated via `assertSafeFilePath` to prevent traversal from\n * upstream-controlled responses. Folder nodes are created on demand.\n */\nfunction buildFileTree(\n files: Array<{ path: string; content: string; encoding: 'utf-8' | 'base64' }>,\n): StorageSkillFileNode[] {\n const root: StorageSkillFileNode[] = [];\n\n for (const file of files) {\n const safePath = assertSafeFilePath(file.path);\n const segments = safePath.split('/').filter(Boolean);\n if (segments.length === 0) continue;\n\n let cursor = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n let folder = cursor.find(node => node.type === 'folder' && node.name === segment);\n if (!folder) {\n folder = { name: segment, type: 'folder', children: [] };\n cursor.push(folder);\n }\n if (!folder.children) folder.children = [];\n cursor = folder.children;\n }\n\n const fileName = segments[segments.length - 1]!;\n const content = file.encoding === 'base64' ? Buffer.from(file.content, 'base64').toString('utf-8') : file.content;\n cursor.push({ name: fileName, type: 'file', content });\n }\n\n return root;\n}\n\n/**\n * Locally-bound SKILL.md frontmatter parser.\n *\n * Mirrors `parseSkillSnapshotFromFiles` from `@mastra/core/workspace`, but\n * inlined here because the server package's `@mastra/core` peer floor\n * (>=1.32.0) predates that helper. Once the floor is bumped to a release\n * containing the helper, this can be replaced by the shared core import.\n *\n * Only SKILL.md is consulted — frontmatter is split from the body using a\n * minimal YAML key:value reader sufficient for the fields registries\n * actually use (name, description). The body is everything after the\n * second `---` line, trimmed.\n */\ntype ParsedSkillSnapshot = {\n name?: string;\n description?: string;\n instructions: string;\n};\n\nfunction parseSkillSnapshot(\n files: Array<{ path: string; content: string; encoding: 'utf-8' | 'base64' }>,\n): ParsedSkillSnapshot | null {\n const skillMd = files.find(f => f.path === 'SKILL.md');\n if (!skillMd) return null;\n\n const raw =\n skillMd.encoding === 'base64' ? Buffer.from(skillMd.content, 'base64').toString('utf-8') : skillMd.content;\n\n const fmMatch = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!fmMatch) {\n return { instructions: raw.trim() };\n }\n\n const fmBlock = fmMatch[1] ?? '';\n const body = fmMatch[2] ?? '';\n const frontmatter: Record<string, string> = {};\n for (const line of fmBlock.split(/\\r?\\n/)) {\n const m = line.match(/^([A-Za-z0-9_-]+)\\s*:\\s*(.*)$/);\n if (!m) continue;\n const key = m[1];\n const value = m[2] ?? '';\n if (!key) continue;\n // Strip surrounding quotes, leave the rest as-is. Registry SKILL.md\n // frontmatter is consistently flat string fields in practice.\n frontmatter[key] = value.trim().replace(/^[\"'](.*)[\"']$/, '$1');\n }\n\n return {\n name: frontmatter.name,\n description: frontmatter.description,\n instructions: body.trim(),\n };\n}\n\n// =============================================================================\n// Routes\n// =============================================================================\n\n/**\n * GET /editor/builder/registries\n *\n * Lists every known registry and whether it's enabled in this deployment.\n * Used by the Builder UI to decide whether to show the \"Browse registry\"\n * entry point at all.\n */\nexport const LIST_BUILDER_REGISTRIES_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries',\n responseType: 'json',\n responseSchema: builderRegistriesResponseSchema,\n summary: 'List available skill registries',\n description: 'Returns the configured external skill registries and their enabled state.',\n tags: ['Editor'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra }) => {\n try {\n const registries = await resolveRegistries(mastra);\n return { registries };\n } catch (error) {\n return handleError(error, 'Error listing builder registries');\n }\n },\n});\n\n/**\n * GET /editor/builder/registries/:registryId/search\n *\n * Proxies a search query to the underlying registry. Currently only\n * registryId=\"skills-sh\" is supported.\n */\nexport const BUILDER_REGISTRY_SEARCH_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries/:registryId/search',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n queryParamSchema: builderRegistrySearchQuerySchema,\n responseSchema: skillsShSearchResponseSchema,\n summary: 'Search skills in a registry',\n description: 'Proxies a search request to the configured registry to avoid CORS issues.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra, registryId, q, limit }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n return await searchSkillsSh({ q, limit });\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error searching registry');\n }\n },\n});\n\n/**\n * GET /editor/builder/registries/:registryId/popular\n *\n * Returns the most popular skills in a registry.\n */\nexport const BUILDER_REGISTRY_POPULAR_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries/:registryId/popular',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n queryParamSchema: builderRegistryPopularQuerySchema,\n responseSchema: skillsShListResponseSchema,\n summary: 'Get popular skills from a registry',\n description: 'Proxies a popular-skills request to the configured registry to avoid CORS issues.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra, registryId, limit, offset }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n return await getPopularSkillsSh({ limit, offset });\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error fetching popular skills');\n }\n },\n});\n\n/**\n * GET /editor/builder/registries/:registryId/preview\n *\n * Returns the rendered SKILL.md content for a single skill in the registry.\n */\nexport const BUILDER_REGISTRY_PREVIEW_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries/:registryId/preview',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n queryParamSchema: builderRegistryPreviewQuerySchema,\n responseSchema: skillsShPreviewResponseSchema,\n summary: 'Preview a skill from a registry',\n description: 'Fetches the SKILL.md content for a single skill in the configured registry.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra, registryId, owner, repo, path: skillName }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n return await previewSkillsSh({ owner, repo, skillName });\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error fetching skill preview');\n }\n },\n});\n\n/**\n * POST /editor/builder/registries/:registryId/install\n *\n * Fetches the full file tree for a skill from the registry, parses the\n * SKILL.md frontmatter for name/description, and persists everything as a\n * new stored skill. The registry origin is recorded under `metadata.origin`\n * so the UI can surface \"imported from skills.sh\" badges and re-resolve the\n * source later.\n *\n * Collisions (a stored skill with the derived id already exists) return 409\n * so the UI can offer an \"Open existing\" link instead of silently\n * overwriting.\n */\nexport const BUILDER_REGISTRY_INSTALL_ROUTE = createRoute({\n method: 'POST',\n path: '/editor/builder/registries/:registryId/install',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n bodySchema: builderRegistryInstallBodySchema,\n responseSchema: builderRegistryInstallResponseSchema,\n summary: 'Install a registry skill into stored skills',\n description: 'Fetches a skill from the configured registry and persists it as a new stored skill.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:write',\n handler: async ({ mastra, requestContext, registryId, owner, repo, skillName, visibility: bodyVisibility }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n\n const storage = mastra.getStorage();\n if (!storage) {\n throw new HTTPException(500, { message: 'Storage is not configured' });\n }\n const skillStore = await storage.getStore('skills');\n if (!skillStore) {\n throw new HTTPException(500, { message: 'Skills storage domain is not available' });\n }\n\n // Pull files from the registry\n const result = await fetchSkillFiles(owner, repo, skillName);\n if (!result || result.files.length === 0) {\n throw new HTTPException(404, {\n message: `Could not find skill \"${skillName}\" in ${owner}/${repo}.`,\n });\n }\n\n const safeSkillId = assertSafeSkillName(result.skillId);\n const files = buildFileTree(result.files);\n\n // Parse SKILL.md frontmatter into structured fields. Splitting\n // frontmatter (name/description) from the markdown body keeps the\n // body as the agent-facing `instructions` instead of polluting it\n // with raw YAML metadata. SKILL.md missing or unparseable simply\n // yields a null snapshot — registry-provided values then fill in.\n const snapshot = parseSkillSnapshot(result.files);\n\n const resolvedName = snapshot?.name ?? safeSkillId;\n const description = snapshot?.description ?? `Imported from ${owner}/${repo}`;\n const id = toSlug(resolvedName) || safeSkillId;\n\n if (!id) {\n throw new HTTPException(400, {\n message: 'Could not derive skill ID from registry skill metadata.',\n });\n }\n\n // Reject collisions instead of silently overwriting; UI offers \"Open existing\".\n const existing = await skillStore.getById(id);\n if (existing) {\n throw new HTTPException(409, {\n message: `Skill with id \"${id}\" already exists.`,\n // Surface the existing id so the client can deep-link.\n cause: { storedSkillId: id },\n });\n }\n\n // Match the standard create flow: no caller = always public, otherwise default private.\n const authorId = getCallerAuthorId(requestContext) ?? undefined;\n const visibility: 'private' | 'public' = authorId ? (bodyVisibility ?? 'private') : 'public';\n\n // Use the SKILL.md body (post-frontmatter) as instructions. Frontmatter\n // values are already lifted into structured columns above, so re-storing\n // them in `instructions` would both duplicate metadata and feed YAML\n // into the agent's prompt. Fall back to description when no usable body\n // exists so `resolved.snapshot.instructions` stays non-empty.\n const instructions = snapshot?.instructions?.trim() ? snapshot.instructions : description;\n\n await skillStore.create({\n skill: {\n id,\n authorId,\n visibility,\n name: resolvedName,\n description,\n instructions,\n files,\n metadata: {\n origin: {\n type: 'skills-sh',\n owner,\n repo,\n skillName,\n },\n },\n },\n });\n\n return {\n storedSkillId: id,\n name: resolvedName,\n filesWritten: result.files.length,\n };\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error installing registry skill');\n }\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"builder-registry-DE5w7bNk.js","names":[],"sources":["../src/server/schemas/builder-registry.ts","../src/server/handlers/builder-registry.ts"],"sourcesContent":["/**\n * Builder Registry Schemas\n *\n * Schemas for the Agent Builder skill registry routes. These are distinct from\n * the workspace skills.sh proxy schemas because:\n * - Builder routes are not scoped to a workspace.\n * - Builder install does not accept a `mount` field.\n * - Builder install body carries visibility + the resolved registry id.\n * - Builder install response returns the created stored skill id.\n *\n * The upstream skills.sh proxy response shapes are reused via the shared\n * `skillsShSearchResponseSchema`, `skillsShListResponseSchema`, and\n * `skillsShPreviewResponseSchema` since the wire shape from skills.sh is\n * registry-independent.\n */\n\nimport { z } from 'zod/v4';\n\n// =============================================================================\n// Registry list\n// =============================================================================\n\n/** Single entry in the registries list. */\nexport const builderRegistryEntrySchema = z.object({\n id: z.literal('skills-sh').describe('Stable registry identifier'),\n enabled: z.boolean().describe('Whether this registry is enabled in the running deployment'),\n label: z.string().describe('Human-readable registry name'),\n});\n\n/** Response for `GET /editor/builder/registries`. */\nexport const builderRegistriesResponseSchema = z.object({\n registries: z.array(builderRegistryEntrySchema),\n});\n\n// =============================================================================\n// Search / popular / preview\n// =============================================================================\n\n/** Path params used by every per-registry route. */\nexport const builderRegistryPathParams = z.object({\n registryId: z.string().describe('Registry identifier (e.g. \"skills-sh\")'),\n});\n\nexport const builderRegistrySearchQuerySchema = z.object({\n q: z.string().describe('Search query'),\n limit: z.coerce.number().int().min(1).max(100).optional().default(10).describe('Maximum number of results (1-100)'),\n});\n\nexport const builderRegistryPopularQuerySchema = z\n .object({\n limit: z.coerce.number().int().min(1).max(100).optional().default(10).describe('Maximum number of results (1-100)'),\n offset: z.coerce\n .number()\n .int()\n .min(0)\n .optional()\n .default(0)\n .describe('Offset for pagination (must be a multiple of `limit`)'),\n })\n .refine(args => args.offset % args.limit === 0, {\n message: 'offset must be a multiple of limit (the upstream registry pages by `limit`)',\n path: ['offset'],\n });\n\nexport const builderRegistryPreviewQuerySchema = z.object({\n owner: z.string().describe('GitHub repository owner'),\n repo: z.string().describe('GitHub repository name'),\n path: z.string().describe('Skill name within repo'),\n});\n\n// =============================================================================\n// Install\n// =============================================================================\n\n/**\n * Body for `POST /editor/builder/registries/:registryId/install`.\n *\n * Visibility behaves like the standard stored-skill create flow: optional,\n * defaults to private when the caller is authenticated.\n */\nexport const builderRegistryInstallBodySchema = z.object({\n owner: z.string().describe('GitHub repository owner'),\n repo: z.string().describe('GitHub repository name'),\n skillName: z.string().describe('Skill name from the registry'),\n visibility: z.enum(['private', 'public']).optional().describe('Visibility for the new stored skill'),\n});\n\n/** Response for the install route. Mirrors stored-skill identity fields. */\nexport const builderRegistryInstallResponseSchema = z.object({\n storedSkillId: z.string().describe('Id of the newly created stored skill'),\n name: z.string().describe('Resolved skill name'),\n filesWritten: z.number().describe('Number of files materialized into the skill version snapshot'),\n});\n\nexport type BuilderRegistryEntry = z.infer<typeof builderRegistryEntrySchema>;\nexport type BuilderRegistriesResponse = z.infer<typeof builderRegistriesResponseSchema>;\nexport type BuilderRegistryInstallBody = z.infer<typeof builderRegistryInstallBodySchema>;\nexport type BuilderRegistryInstallResponse = z.infer<typeof builderRegistryInstallResponseSchema>;\n","/**\n * Builder Registry Handlers\n *\n * Routes that let admins browse and install skills from configured external\n * registries (currently just skills.sh) directly into the Builder's stored\n * skills DB. Distinct from the workspace skills.sh routes, which write to a\n * workspace filesystem and never touch storage.\n *\n * Registry availability is driven by `AgentBuilderOptions.registries`. When\n * the requested registry is disabled (or the builder is missing entirely),\n * the routes 404 instead of leaking the surface.\n */\n\nimport type { Mastra } from '@mastra/core';\nimport type { StorageSkillFileNode } from '@mastra/core/storage';\n\nimport { HTTPException } from '../http-exception';\nimport {\n builderRegistriesResponseSchema,\n builderRegistryInstallBodySchema,\n builderRegistryInstallResponseSchema,\n builderRegistryPathParams,\n builderRegistryPopularQuerySchema,\n builderRegistryPreviewQuerySchema,\n builderRegistrySearchQuerySchema,\n} from '../schemas/builder-registry';\nimport {\n skillsShListResponseSchema,\n skillsShPreviewResponseSchema,\n skillsShSearchResponseSchema,\n} from '../schemas/workspace';\nimport { createRoute } from '../server-adapter/routes/route-builder';\nimport { toSlug } from '../utils';\nimport { getCallerAuthorId } from './authorship';\nimport { handleError } from './error';\nimport {\n assertSafeFilePath,\n assertSafeSkillName,\n fetchSkillFiles,\n getPopularSkillsSh,\n previewSkillsSh,\n searchSkillsSh,\n} from './skills-sh-shared';\n\n// =============================================================================\n// Registry resolution\n// =============================================================================\n\n/** Stable identifiers + display labels for every supported registry. */\nconst REGISTRY_LABELS: Record<string, string> = {\n 'skills-sh': 'skills.sh',\n};\n\ninterface RegistryStatus {\n id: 'skills-sh';\n enabled: boolean;\n label: string;\n}\n\n/**\n * Resolve which registries are enabled for the running deployment by reading\n * the builder's `registries` config. Returns a list with all known registries\n * (so the frontend can render an empty/disabled state) plus their enabled\n * flag.\n */\nasync function resolveRegistries(mastra: Mastra): Promise<RegistryStatus[]> {\n const editor = mastra.getEditor();\n if (!editor || typeof editor.resolveBuilder !== 'function') {\n return [{ id: 'skills-sh', enabled: false, label: REGISTRY_LABELS['skills-sh']! }];\n }\n const builder = await editor.resolveBuilder();\n const registries = builder?.getRegistries?.();\n return [\n {\n id: 'skills-sh',\n enabled: registries?.skillsSh?.enabled === true,\n label: REGISTRY_LABELS['skills-sh']!,\n },\n ];\n}\n\n/**\n * Hard-gate: throws 404 when the requested registry is unknown or disabled.\n * Mirrors `requireBuilderFeature` semantics — no surface leak for OFF registries.\n */\nasync function requireEnabledRegistry(mastra: Mastra, registryId: string): Promise<void> {\n const list = await resolveRegistries(mastra);\n const match = list.find(r => r.id === registryId);\n if (!match || !match.enabled) {\n throw new HTTPException(404, { message: 'Registry not found' });\n }\n}\n\n// =============================================================================\n// File-tree helpers\n// =============================================================================\n\n/**\n * Convert a flat list of `{ path, content, encoding }` entries into the\n * `StorageSkillFileNode` tree shape expected by the stored-skills create path.\n *\n * Each path is validated via `assertSafeFilePath` to prevent traversal from\n * upstream-controlled responses. Folder nodes are created on demand.\n */\nfunction buildFileTree(\n files: Array<{ path: string; content: string; encoding: 'utf-8' | 'base64' }>,\n): StorageSkillFileNode[] {\n const root: StorageSkillFileNode[] = [];\n\n for (const file of files) {\n const safePath = assertSafeFilePath(file.path);\n const segments = safePath.split('/').filter(Boolean);\n if (segments.length === 0) continue;\n\n let cursor = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i]!;\n let folder = cursor.find(node => node.type === 'folder' && node.name === segment);\n if (!folder) {\n folder = { name: segment, type: 'folder', children: [] };\n cursor.push(folder);\n }\n if (!folder.children) folder.children = [];\n cursor = folder.children;\n }\n\n const fileName = segments[segments.length - 1]!;\n const content = file.encoding === 'base64' ? Buffer.from(file.content, 'base64').toString('utf-8') : file.content;\n cursor.push({ name: fileName, type: 'file', content });\n }\n\n return root;\n}\n\n/**\n * Locally-bound SKILL.md frontmatter parser.\n *\n * Mirrors `parseSkillSnapshotFromFiles` from `@mastra/core/workspace`, but\n * inlined here because the server package's `@mastra/core` peer floor\n * (>=1.32.0) predates that helper. Once the floor is bumped to a release\n * containing the helper, this can be replaced by the shared core import.\n *\n * Only SKILL.md is consulted — frontmatter is split from the body using a\n * minimal YAML key:value reader sufficient for the fields registries\n * actually use (name, description). The body is everything after the\n * second `---` line, trimmed.\n */\ntype ParsedSkillSnapshot = {\n name?: string;\n description?: string;\n instructions: string;\n};\n\nfunction parseSkillSnapshot(\n files: Array<{ path: string; content: string; encoding: 'utf-8' | 'base64' }>,\n): ParsedSkillSnapshot | null {\n const skillMd = files.find(f => f.path === 'SKILL.md');\n if (!skillMd) return null;\n\n const raw =\n skillMd.encoding === 'base64' ? Buffer.from(skillMd.content, 'base64').toString('utf-8') : skillMd.content;\n\n const fmMatch = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/);\n if (!fmMatch) {\n return { instructions: raw.trim() };\n }\n\n const fmBlock = fmMatch[1] ?? '';\n const body = fmMatch[2] ?? '';\n const frontmatter: Record<string, string> = {};\n for (const line of fmBlock.split(/\\r?\\n/)) {\n const m = line.match(/^([A-Za-z0-9_-]+)\\s*:\\s*(.*)$/);\n if (!m) continue;\n const key = m[1];\n const value = m[2] ?? '';\n if (!key) continue;\n // Strip surrounding quotes, leave the rest as-is. Registry SKILL.md\n // frontmatter is consistently flat string fields in practice.\n frontmatter[key] = value.trim().replace(/^[\"'](.*)[\"']$/, '$1');\n }\n\n return {\n name: frontmatter.name,\n description: frontmatter.description,\n instructions: body.trim(),\n };\n}\n\n// =============================================================================\n// Routes\n// =============================================================================\n\n/**\n * GET /editor/builder/registries\n *\n * Lists every known registry and whether it's enabled in this deployment.\n * Used by the Builder UI to decide whether to show the \"Browse registry\"\n * entry point at all.\n */\nexport const LIST_BUILDER_REGISTRIES_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries',\n responseType: 'json',\n responseSchema: builderRegistriesResponseSchema,\n summary: 'List available skill registries',\n description: 'Returns the configured external skill registries and their enabled state.',\n tags: ['Editor'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra }) => {\n try {\n const registries = await resolveRegistries(mastra);\n return { registries };\n } catch (error) {\n return handleError(error, 'Error listing builder registries');\n }\n },\n});\n\n/**\n * GET /editor/builder/registries/:registryId/search\n *\n * Proxies a search query to the underlying registry. Currently only\n * registryId=\"skills-sh\" is supported.\n */\nexport const BUILDER_REGISTRY_SEARCH_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries/:registryId/search',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n queryParamSchema: builderRegistrySearchQuerySchema,\n responseSchema: skillsShSearchResponseSchema,\n summary: 'Search skills in a registry',\n description: 'Proxies a search request to the configured registry to avoid CORS issues.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra, registryId, q, limit }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n return await searchSkillsSh({ q, limit });\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error searching registry');\n }\n },\n});\n\n/**\n * GET /editor/builder/registries/:registryId/popular\n *\n * Returns the most popular skills in a registry.\n */\nexport const BUILDER_REGISTRY_POPULAR_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries/:registryId/popular',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n queryParamSchema: builderRegistryPopularQuerySchema,\n responseSchema: skillsShListResponseSchema,\n summary: 'Get popular skills from a registry',\n description: 'Proxies a popular-skills request to the configured registry to avoid CORS issues.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra, registryId, limit, offset }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n return await getPopularSkillsSh({ limit, offset });\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error fetching popular skills');\n }\n },\n});\n\n/**\n * GET /editor/builder/registries/:registryId/preview\n *\n * Returns the rendered SKILL.md content for a single skill in the registry.\n */\nexport const BUILDER_REGISTRY_PREVIEW_ROUTE = createRoute({\n method: 'GET',\n path: '/editor/builder/registries/:registryId/preview',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n queryParamSchema: builderRegistryPreviewQuerySchema,\n responseSchema: skillsShPreviewResponseSchema,\n summary: 'Preview a skill from a registry',\n description: 'Fetches the SKILL.md content for a single skill in the configured registry.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:read',\n handler: async ({ mastra, registryId, owner, repo, path: skillName }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n return await previewSkillsSh({ owner, repo, skillName });\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error fetching skill preview');\n }\n },\n});\n\n/**\n * POST /editor/builder/registries/:registryId/install\n *\n * Fetches the full file tree for a skill from the registry, parses the\n * SKILL.md frontmatter for name/description, and persists everything as a\n * new stored skill. The registry origin is recorded under `metadata.origin`\n * so the UI can surface \"imported from skills.sh\" badges and re-resolve the\n * source later.\n *\n * Collisions (a stored skill with the derived id already exists) return 409\n * so the UI can offer an \"Open existing\" link instead of silently\n * overwriting.\n */\nexport const BUILDER_REGISTRY_INSTALL_ROUTE = createRoute({\n method: 'POST',\n path: '/editor/builder/registries/:registryId/install',\n responseType: 'json',\n pathParamSchema: builderRegistryPathParams,\n bodySchema: builderRegistryInstallBodySchema,\n responseSchema: builderRegistryInstallResponseSchema,\n summary: 'Install a registry skill into stored skills',\n description: 'Fetches a skill from the configured registry and persists it as a new stored skill.',\n tags: ['Editor', 'Skills'],\n requiresAuth: true,\n requiresPermission: 'stored-skills:write',\n handler: async ({ mastra, requestContext, registryId, owner, repo, skillName, visibility: bodyVisibility }) => {\n try {\n await requireEnabledRegistry(mastra, registryId);\n\n const storage = mastra.getStorage();\n if (!storage) {\n throw new HTTPException(500, { message: 'Storage is not configured' });\n }\n const skillStore = await storage.getStore('skills');\n if (!skillStore) {\n throw new HTTPException(500, { message: 'Skills storage domain is not available' });\n }\n\n // Pull files from the registry\n const result = await fetchSkillFiles(owner, repo, skillName);\n if (!result || result.files.length === 0) {\n throw new HTTPException(404, {\n message: `Could not find skill \"${skillName}\" in ${owner}/${repo}.`,\n });\n }\n\n const safeSkillId = assertSafeSkillName(result.skillId);\n const files = buildFileTree(result.files);\n\n // Parse SKILL.md frontmatter into structured fields. Splitting\n // frontmatter (name/description) from the markdown body keeps the\n // body as the agent-facing `instructions` instead of polluting it\n // with raw YAML metadata. SKILL.md missing or unparseable simply\n // yields a null snapshot — registry-provided values then fill in.\n const snapshot = parseSkillSnapshot(result.files);\n\n const resolvedName = snapshot?.name ?? safeSkillId;\n const description = snapshot?.description ?? `Imported from ${owner}/${repo}`;\n const id = toSlug(resolvedName) || safeSkillId;\n\n if (!id) {\n throw new HTTPException(400, {\n message: 'Could not derive skill ID from registry skill metadata.',\n });\n }\n\n // Reject collisions instead of silently overwriting; UI offers \"Open existing\".\n const existing = await skillStore.getById(id);\n if (existing) {\n throw new HTTPException(409, {\n message: `Skill with id \"${id}\" already exists.`,\n // Surface the existing id so the client can deep-link.\n cause: { storedSkillId: id },\n });\n }\n\n // Match the standard create flow: no caller = always public, otherwise default private.\n const authorId = getCallerAuthorId(requestContext) ?? undefined;\n const visibility: 'private' | 'public' = authorId ? (bodyVisibility ?? 'private') : 'public';\n\n // Use the SKILL.md body (post-frontmatter) as instructions. Frontmatter\n // values are already lifted into structured columns above, so re-storing\n // them in `instructions` would both duplicate metadata and feed YAML\n // into the agent's prompt. Fall back to description when no usable body\n // exists so `resolved.snapshot.instructions` stays non-empty.\n const instructions = snapshot?.instructions?.trim() ? snapshot.instructions : description;\n\n await skillStore.create({\n skill: {\n id,\n authorId,\n visibility,\n name: resolvedName,\n description,\n instructions,\n files,\n metadata: {\n origin: {\n type: 'skills-sh',\n owner,\n repo,\n skillName,\n },\n },\n },\n });\n\n return {\n storedSkillId: id,\n name: resolvedName,\n filesWritten: result.files.length,\n };\n } catch (error) {\n if (error instanceof HTTPException) throw error;\n return handleError(error, 'Error installing registry skill');\n }\n },\n});\n"],"mappings":"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"}
@@ -5962,15 +5962,15 @@ function splitLines(text) {
5962
5962
  return result;
5963
5963
  }
5964
5964
  //#endregion
5965
- //#region ../memory/dist/src-DvQWV6nH.js
5966
- var __defProp$4 = Object.defineProperty;
5965
+ //#region ../memory/dist/src-Cwt9gefz.js
5966
+ var __defProp$3 = Object.defineProperty;
5967
5967
  var __exportAll = (all, no_symbols) => {
5968
5968
  let target = {};
5969
- for (var name in all) __defProp$4(target, name, {
5969
+ for (var name in all) __defProp$3(target, name, {
5970
5970
  get: all[name],
5971
5971
  enumerable: true
5972
5972
  });
5973
- if (!no_symbols) __defProp$4(target, Symbol.toStringTag, { value: "Module" });
5973
+ if (!no_symbols) __defProp$3(target, Symbol.toStringTag, { value: "Module" });
5974
5974
  return target;
5975
5975
  };
5976
5976
  var marker$6 = "vercel.ai.error";
@@ -6114,7 +6114,7 @@ Error message: ${getErrorMessage$4(cause)}`,
6114
6114
  _a13$5 = symbol13$5;
6115
6115
  var TypeValidationError$2 = _TypeValidationError;
6116
6116
  var __create = Object.create;
6117
- var __defProp$3 = Object.defineProperty;
6117
+ var __defProp$1$1 = Object.defineProperty;
6118
6118
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6119
6119
  var __getOwnPropNames = Object.getOwnPropertyNames;
6120
6120
  var __getProtoOf = Object.getPrototypeOf;
@@ -6123,14 +6123,14 @@ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).expor
6123
6123
  var __copyProps = (to, from, except, desc) => {
6124
6124
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
6125
6125
  key = keys[i];
6126
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp$3(to, key, {
6126
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp$1$1(to, key, {
6127
6127
  get: ((k) => from[k]).bind(null, key),
6128
6128
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
6129
6129
  });
6130
6130
  }
6131
6131
  return to;
6132
6132
  };
6133
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$3(target, "default", {
6133
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1$1(target, "default", {
6134
6134
  value: mod,
6135
6135
  enumerable: true
6136
6136
  }) : target, mod));
@@ -10193,6 +10193,12 @@ async function cancelResponseBody$1(response) {
10193
10193
  await ((_a2 = response.body) == null ? void 0 : _a2.cancel());
10194
10194
  } catch (e) {}
10195
10195
  }
10196
+ var initialGlobalFetch$1 = globalThis.fetch;
10197
+ isNodeDefaultFetch$1(initialGlobalFetch$1);
10198
+ function isNodeDefaultFetch$1(fetch) {
10199
+ const source = Function.prototype.toString.call(fetch);
10200
+ return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
10201
+ }
10196
10202
  var DEFAULT_MAX_DOWNLOAD_SIZE$1 = 2 * 1024 * 1024 * 1024;
10197
10203
  async function readResponseWithSizeLimit$1({ response, url, maxBytes = DEFAULT_MAX_DOWNLOAD_SIZE$1 }) {
10198
10204
  const contentLength = response.headers.get("content-length");
@@ -10302,11 +10308,11 @@ function withUserAgentSuffix$1(headers, ...userAgentSuffixParts) {
10302
10308
  normalizedHeaders.set("user-agent", [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(" "));
10303
10309
  return Object.fromEntries(normalizedHeaders.entries());
10304
10310
  }
10305
- var VERSION$4 = "3.0.30";
10311
+ var VERSION$4 = "3.0.31";
10306
10312
  var getOriginalFetch$1 = () => globalThis.fetch;
10307
- var getFromApi$1 = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch2 = getOriginalFetch$1() }) => {
10313
+ var getFromApi$1 = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch$1() }) => {
10308
10314
  try {
10309
- const response = await fetch2(url, {
10315
+ const response = await fetch(url, {
10310
10316
  method: "GET",
10311
10317
  headers: withUserAgentSuffix$1(headers, `ai-sdk/provider-utils/${VERSION$4}`, getRuntimeEnvironmentUserAgent$1()),
10312
10318
  signal: abortSignal
@@ -10532,7 +10538,7 @@ function parseJsonEventStream$1({ stream, schema }) {
10532
10538
  } }));
10533
10539
  }
10534
10540
  var getOriginalFetch2$1 = () => globalThis.fetch;
10535
- var postJsonToApi$1 = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch: fetch2 }) => postToApi$1({
10541
+ var postJsonToApi$1 = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }) => postToApi$1({
10536
10542
  url,
10537
10543
  headers: {
10538
10544
  "Content-Type": "application/json",
@@ -10545,11 +10551,11 @@ var postJsonToApi$1 = async ({ url, headers, body, failedResponseHandler, succes
10545
10551
  failedResponseHandler,
10546
10552
  successfulResponseHandler,
10547
10553
  abortSignal,
10548
- fetch: fetch2
10554
+ fetch
10549
10555
  });
10550
- var postToApi$1 = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch2 = getOriginalFetch2$1() }) => {
10556
+ var postToApi$1 = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch2$1() }) => {
10551
10557
  try {
10552
- const response = await fetch2(url, {
10558
+ const response = await fetch(url, {
10553
10559
  method: "POST",
10554
10560
  headers: withUserAgentSuffix$1(headers, `ai-sdk/provider-utils/${VERSION$4}`, getRuntimeEnvironmentUserAgent$1()),
10555
10561
  body: body.content,
@@ -12609,7 +12615,7 @@ async function getVercelRequestId$1() {
12609
12615
  var _a10;
12610
12616
  return (_a10 = getContext$1().headers) == null ? void 0 : _a10["x-vercel-id"];
12611
12617
  }
12612
- var VERSION$2$2 = "2.0.115";
12618
+ var VERSION$2$2 = "2.0.125";
12613
12619
  var AI_GATEWAY_PROTOCOL_VERSION$1 = "0.0.1";
12614
12620
  function createGatewayProvider$1(options = {}) {
12615
12621
  var _a10, _b10;
@@ -13643,7 +13649,7 @@ function getGlobalProvider$1() {
13643
13649
  var _a16;
13644
13650
  return (_a16 = globalThis.AI_SDK_DEFAULT_PROVIDER) != null ? _a16 : gateway$1;
13645
13651
  }
13646
- var VERSION$5 = "5.0.216";
13652
+ var VERSION$5 = "5.0.226";
13647
13653
  var dataContentSchema$1 = zod_v4.z.union([
13648
13654
  zod_v4.z.string(),
13649
13655
  zod_v4.z.instanceof(Uint8Array),
@@ -15078,6 +15084,12 @@ var DownloadError$2 = class extends (_b$2$1 = AISDKError$3, _a$2$1 = symbol$2$1,
15078
15084
  return AISDKError$3.hasMarker(error, marker$2$1);
15079
15085
  }
15080
15086
  };
15087
+ var initialGlobalFetch$2 = globalThis.fetch;
15088
+ isNodeDefaultFetch$2(initialGlobalFetch$2);
15089
+ function isNodeDefaultFetch$2(fetch) {
15090
+ const source = Function.prototype.toString.call(fetch);
15091
+ return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
15092
+ }
15081
15093
  var DEFAULT_MAX_DOWNLOAD_SIZE$2 = 2 * 1024 * 1024 * 1024;
15082
15094
  async function readResponseWithSizeLimit$2({ response, url, maxBytes = DEFAULT_MAX_DOWNLOAD_SIZE$2 }) {
15083
15095
  const contentLength = response.headers.get("content-length");
@@ -15209,11 +15221,11 @@ function withUserAgentSuffix$2(headers, ...userAgentSuffixParts) {
15209
15221
  normalizedHeaders.set("user-agent", [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(" "));
15210
15222
  return Object.fromEntries(normalizedHeaders.entries());
15211
15223
  }
15212
- var VERSION$3$1 = "4.0.40";
15224
+ var VERSION$3$1 = "4.0.41";
15213
15225
  var getOriginalFetch$2 = () => globalThis.fetch;
15214
- var getFromApi$2 = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch2 = getOriginalFetch$2() }) => {
15226
+ var getFromApi$2 = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch$2() }) => {
15215
15227
  try {
15216
- const response = await fetch2(url, {
15228
+ const response = await fetch(url, {
15217
15229
  method: "GET",
15218
15230
  headers: withUserAgentSuffix$2(headers, `ai-sdk/provider-utils/${VERSION$3$1}`, getRuntimeEnvironmentUserAgent$2()),
15219
15231
  signal: abortSignal
@@ -16400,7 +16412,7 @@ function parseJsonEventStream$2({ stream, schema }) {
16400
16412
  } }));
16401
16413
  }
16402
16414
  var getOriginalFetch2$2 = () => globalThis.fetch;
16403
- var postJsonToApi$2 = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch: fetch2 }) => postToApi$2({
16415
+ var postJsonToApi$2 = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }) => postToApi$2({
16404
16416
  url,
16405
16417
  headers: {
16406
16418
  "Content-Type": "application/json",
@@ -16413,11 +16425,11 @@ var postJsonToApi$2 = async ({ url, headers, body, failedResponseHandler, succes
16413
16425
  failedResponseHandler,
16414
16426
  successfulResponseHandler,
16415
16427
  abortSignal,
16416
- fetch: fetch2
16428
+ fetch
16417
16429
  });
16418
- var postToApi$2 = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch2 = getOriginalFetch2$2() }) => {
16430
+ var postToApi$2 = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch2$2() }) => {
16419
16431
  try {
16420
- const response = await fetch2(url, {
16432
+ const response = await fetch(url, {
16421
16433
  method: "POST",
16422
16434
  headers: withUserAgentSuffix$2(headers, `ai-sdk/provider-utils/${VERSION$3$1}`, getRuntimeEnvironmentUserAgent$2()),
16423
16435
  body: body.content,
@@ -18196,7 +18208,7 @@ async function getVercelRequestId$2() {
18196
18208
  var _a11;
18197
18209
  return (_a11 = getContext$2().headers) == null ? void 0 : _a11["x-vercel-id"];
18198
18210
  }
18199
- var VERSION$2$1 = "3.0.153";
18211
+ var VERSION$2$1 = "3.0.163";
18200
18212
  var AI_GATEWAY_PROTOCOL_VERSION$2 = "0.0.1";
18201
18213
  function createGatewayProvider$2(options = {}) {
18202
18214
  var _a11, _b11;
@@ -19192,9 +19204,9 @@ const trace = class TraceAPI {
19192
19204
  this._proxyTracerProvider = new ProxyTracerProvider$3();
19193
19205
  }
19194
19206
  }.getInstance();
19195
- var __defProp$5 = Object.defineProperty;
19207
+ var __defProp$4 = Object.defineProperty;
19196
19208
  var __export$3 = (target, all) => {
19197
- for (var name22 in all) __defProp$5(target, name22, {
19209
+ for (var name22 in all) __defProp$4(target, name22, {
19198
19210
  get: all[name22],
19199
19211
  enumerable: true
19200
19212
  });
@@ -19353,7 +19365,7 @@ function getTotalTimeoutMs(timeout) {
19353
19365
  if (typeof timeout === "number") return timeout;
19354
19366
  return timeout.totalMs;
19355
19367
  }
19356
- var VERSION = "6.0.230";
19368
+ var VERSION = "6.0.241";
19357
19369
  var dataContentSchema$3 = zod_v4.z.union([
19358
19370
  zod_v4.z.string(),
19359
19371
  zod_v4.z.instanceof(Uint8Array),
@@ -26303,6 +26315,68 @@ function isMessageAtOrBeforeCursor(msg, cursor) {
26303
26315
  return false;
26304
26316
  }
26305
26317
  /**
26318
+ * Return the toolCallId of a tool-invocation part in the given state, or undefined.
26319
+ */
26320
+ function getToolInvocationId(part, state) {
26321
+ if (part?.type !== "tool-invocation") return void 0;
26322
+ if (part.toolInvocation.state !== state) return void 0;
26323
+ return part.toolInvocation.toolCallId || void 0;
26324
+ }
26325
+ function collectPendingToolResultIds(allMessages, observedIds) {
26326
+ const pendingToolResultIds = /* @__PURE__ */ new Set();
26327
+ for (const msg of allMessages) {
26328
+ if (!msg?.id) continue;
26329
+ if (observedIds?.has(msg.id)) continue;
26330
+ const parts = msg.content?.parts;
26331
+ if (!parts || !Array.isArray(parts)) continue;
26332
+ for (const part of parts) {
26333
+ const id = getToolInvocationId(part, "result");
26334
+ if (id) pendingToolResultIds.add(id);
26335
+ }
26336
+ }
26337
+ return pendingToolResultIds;
26338
+ }
26339
+ function hasPendingToolResultPair(message, pendingToolResultIds) {
26340
+ if (pendingToolResultIds.size === 0) return false;
26341
+ const parts = message.content?.parts;
26342
+ if (!parts || !Array.isArray(parts)) return false;
26343
+ return parts.some((part) => {
26344
+ const id = getToolInvocationId(part, "call");
26345
+ return id !== void 0 && pendingToolResultIds.has(id);
26346
+ });
26347
+ }
26348
+ function collectPendingToolResultIdsAfterMarker(allMessages, markerMessageIndex, markerMessage) {
26349
+ const pendingToolResultIds = /* @__PURE__ */ new Set();
26350
+ const unobservedMarkerParts = getUnobservedParts(markerMessage);
26351
+ if (unobservedMarkerParts.length > 0) collectPendingToolResultIds([{
26352
+ ...markerMessage,
26353
+ content: {
26354
+ ...markerMessage.content,
26355
+ parts: unobservedMarkerParts
26356
+ }
26357
+ }], void 0).forEach((id) => pendingToolResultIds.add(id));
26358
+ collectPendingToolResultIds(allMessages.slice(markerMessageIndex + 1), void 0).forEach((id) => pendingToolResultIds.add(id));
26359
+ return pendingToolResultIds;
26360
+ }
26361
+ function getUnobservedPartsPreservingToolCallPairs(message) {
26362
+ const parts = message.content?.parts;
26363
+ if (!parts || !Array.isArray(parts)) return [];
26364
+ const endMarkerIndex = findLastCompletedObservationBoundary(message);
26365
+ if (endMarkerIndex === -1) return getUnobservedParts(message);
26366
+ const unobservedParts = getUnobservedParts(message);
26367
+ const unobservedResultIds = /* @__PURE__ */ new Set();
26368
+ for (const part of unobservedParts) {
26369
+ const id = getToolInvocationId(part, "result");
26370
+ if (id) unobservedResultIds.add(id);
26371
+ }
26372
+ if (unobservedResultIds.size === 0) return unobservedParts;
26373
+ const preservedCalls = parts.slice(0, endMarkerIndex).filter((part) => {
26374
+ const id = getToolInvocationId(part, "call");
26375
+ return id !== void 0 && unobservedResultIds.has(id);
26376
+ });
26377
+ return preservedCalls.length > 0 ? [...preservedCalls, ...unobservedParts] : unobservedParts;
26378
+ }
26379
+ /**
26306
26380
  * Safely extract buffered observation chunks from a record.
26307
26381
  * Handles both array and JSON-string formats, returning empty array if malformed.
26308
26382
  */
@@ -26318,6 +26392,7 @@ function filterObservedMessages(opts) {
26318
26392
  const allMessages = messageList.get.all.db();
26319
26393
  const useMarkerBoundaryPruning = opts.useMarkerBoundaryPruning ?? true;
26320
26394
  const preserveMessageIds = opts.preserveMessageIds ?? /* @__PURE__ */ new Set();
26395
+ const observedIds = new Set(Array.isArray(record?.observedMessageIds) ? record.observedMessageIds : []);
26321
26396
  let markerMessageIndex = -1;
26322
26397
  let markerMessage = null;
26323
26398
  for (let i = allMessages.length - 1; i >= 0; i--) {
@@ -26330,33 +26405,40 @@ function filterObservedMessages(opts) {
26330
26405
  }
26331
26406
  }
26332
26407
  if (useMarkerBoundaryPruning && markerMessage && markerMessageIndex !== -1) {
26408
+ const pendingToolResultIds = collectPendingToolResultIdsAfterMarker(allMessages, markerMessageIndex, markerMessage);
26333
26409
  const messagesToRemove = [];
26334
26410
  for (let i = 0; i < markerMessageIndex; i++) {
26335
26411
  const msg = allMessages[i];
26336
- if (msg?.id && msg.id !== "om-continuation" && !preserveMessageIds.has(msg.id)) messagesToRemove.push(msg.id);
26412
+ if (msg?.id && msg.id !== "om-continuation" && !preserveMessageIds.has(msg.id) && !hasPendingToolResultPair(msg, pendingToolResultIds)) messagesToRemove.push(msg.id);
26337
26413
  }
26338
26414
  if (messagesToRemove.length > 0) messageList.removeByIds(messagesToRemove);
26339
- const unobserved = getUnobservedParts(markerMessage);
26415
+ const unobserved = getUnobservedPartsPreservingToolCallPairs(markerMessage);
26340
26416
  if (unobserved.length === 0) {
26341
26417
  if (markerMessage.id) messageList.removeByIds([markerMessage.id]);
26342
26418
  } else if (unobserved.length < (markerMessage.content?.parts?.length ?? 0)) markerMessage.content.parts = unobserved;
26343
26419
  } else if (record) {
26344
- const observedIds = new Set(Array.isArray(record.observedMessageIds) ? record.observedMessageIds : []);
26420
+ const pendingToolResultIds = collectPendingToolResultIds(allMessages, observedIds);
26345
26421
  const derivedCursor = opts.fallbackCursor ?? getLastObservedMessageCursor(allMessages.filter((msg) => !!msg?.id && observedIds.has(msg.id) && !!msg.createdAt));
26346
26422
  const lastObservedAt = record.lastObservedAt;
26347
26423
  const messagesToRemove = [];
26348
26424
  for (const msg of allMessages) {
26349
26425
  if (!msg?.id || msg.id === "om-continuation" || preserveMessageIds.has(msg.id)) continue;
26426
+ const hasPendingPair = hasPendingToolResultPair(msg, pendingToolResultIds);
26350
26427
  if (observedIds.has(msg.id)) {
26428
+ if (hasPendingPair) continue;
26351
26429
  messagesToRemove.push(msg.id);
26352
26430
  continue;
26353
26431
  }
26354
26432
  if (derivedCursor && isMessageAtOrBeforeCursor(msg, derivedCursor)) {
26433
+ if (hasPendingPair) continue;
26355
26434
  messagesToRemove.push(msg.id);
26356
26435
  continue;
26357
26436
  }
26358
26437
  if (lastObservedAt && msg.createdAt) {
26359
- if (new Date(msg.createdAt) <= lastObservedAt) messagesToRemove.push(msg.id);
26438
+ if (new Date(msg.createdAt) <= lastObservedAt) {
26439
+ if (hasPendingPair) continue;
26440
+ messagesToRemove.push(msg.id);
26441
+ }
26360
26442
  }
26361
26443
  }
26362
26444
  if (messagesToRemove.length > 0) messageList.removeByIds(messagesToRemove);
@@ -29634,6 +29716,14 @@ var ObservationalMemory = class ObservationalMemory {
29634
29716
  */
29635
29717
  locks = /* @__PURE__ */ new Map();
29636
29718
  /**
29719
+ * Initial record lookup/creation promises keyed by the effective storage scope.
29720
+ * Concurrent callers share the full read-or-create operation so a stale read
29721
+ * cannot create another generation-zero record after the first insert finishes.
29722
+ * Entries are removed after both success and failure so later calls always
29723
+ * re-read storage and transient failures can be retried.
29724
+ */
29725
+ recordInitializations = /* @__PURE__ */ new Map();
29726
+ /**
29637
29727
  * Acquire a lock for the given key, execute the callback, then release.
29638
29728
  * If a lock is already held, waits for it to be released before acquiring.
29639
29729
  */
@@ -29994,10 +30084,14 @@ var ObservationalMemory = class ObservationalMemory {
29994
30084
  */
29995
30085
  async getOrCreateRecord(threadId, resourceId) {
29996
30086
  const ids = this.getStorageIds(threadId, resourceId);
29997
- let record = await this.storage.getObservationalMemory(ids.threadId, ids.resourceId);
29998
- if (!record) {
30087
+ const initializationKey = ids.threadId === null ? `resource:${ids.resourceId}` : `thread:${ids.threadId}`;
30088
+ const pendingInitialization = this.recordInitializations.get(initializationKey);
30089
+ if (pendingInitialization) return pendingInitialization;
30090
+ const initialization = Promise.resolve().then(async () => {
30091
+ const record = await this.storage.getObservationalMemory(ids.threadId, ids.resourceId);
30092
+ if (record) return record;
29999
30093
  const observedTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
30000
- record = await this.storage.initializeObservationalMemory({
30094
+ return this.storage.initializeObservationalMemory({
30001
30095
  threadId: ids.threadId,
30002
30096
  resourceId: ids.resourceId,
30003
30097
  scope: this.scope,
@@ -30008,8 +30102,13 @@ var ObservationalMemory = class ObservationalMemory {
30008
30102
  },
30009
30103
  observedTimezone
30010
30104
  });
30105
+ });
30106
+ this.recordInitializations.set(initializationKey, initialization);
30107
+ try {
30108
+ return await initialization;
30109
+ } finally {
30110
+ if (this.recordInitializations.get(initializationKey) === initialization) this.recordInitializations.delete(initializationKey);
30011
30111
  }
30012
- return record;
30013
30112
  }
30014
30113
  /**
30015
30114
  * Get current config snapshot for observation markers.
@@ -32350,6 +32449,11 @@ function filterSystemReminderMessages(messages, includeSystemReminders) {
32350
32449
  if (includeSystemReminders) return messages;
32351
32450
  return messages.filter((message) => !isSystemReminderMessage(message));
32352
32451
  }
32452
+ function isTransientSignalMessage(message) {
32453
+ if (message.role !== "signal" || !isRecord(message.content)) return false;
32454
+ const metadata = message.content.metadata;
32455
+ return isRecord(metadata) && isRecord(metadata.signal) && !Array.isArray(metadata.signal) && metadata.signal.transient === true;
32456
+ }
32353
32457
  function normalizeObservationalMemoryConfig(config) {
32354
32458
  if (config === true) return { model: "google/gemini-2.5-flash" };
32355
32459
  if (config === false || config === void 0) return void 0;
@@ -32883,7 +32987,7 @@ ${workingMemory}`;
32883
32987
  async saveMessages({ messages, memoryConfig, observabilityContext }) {
32884
32988
  const span = this.createMemorySpan("save", observabilityContext, void 0, { messageCount: messages.length });
32885
32989
  try {
32886
- const updatedMessages = messages.filter((m) => m.role !== "system").map((m) => {
32990
+ const updatedMessages = messages.filter((m) => m.role !== "system" && !isTransientSignalMessage(m)).map((m) => {
32887
32991
  return this.updateMessageToHideWorkingMemoryV2(m);
32888
32992
  }).filter((m) => Boolean(m));
32889
32993
  const config = this.getMergedThreadConfig(memoryConfig);
@@ -33175,7 +33279,7 @@ ${workingMemory}`;
33175
33279
  */
33176
33280
  async persistMessages(messages) {
33177
33281
  if (messages.length === 0) return;
33178
- const persistableMessages = messages.filter((m) => m.role !== "system");
33282
+ const persistableMessages = messages.filter((m) => m.role !== "system" && !isTransientSignalMessage(m));
33179
33283
  if (persistableMessages.length === 0) return;
33180
33284
  await (await this.getMemoryStore()).saveMessages({ messages: persistableMessages });
33181
33285
  }
@@ -39375,6 +39479,12 @@ async function cancelResponseBody(response) {
39375
39479
  await ((_a2 = response.body) == null ? void 0 : _a2.cancel());
39376
39480
  } catch (e) {}
39377
39481
  }
39482
+ var initialGlobalFetch = globalThis.fetch;
39483
+ isNodeDefaultFetch(initialGlobalFetch);
39484
+ function isNodeDefaultFetch(fetch) {
39485
+ const source = Function.prototype.toString.call(fetch);
39486
+ return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
39487
+ }
39378
39488
  var DEFAULT_MAX_DOWNLOAD_SIZE = 2 * 1024 * 1024 * 1024;
39379
39489
  async function readResponseWithSizeLimit({ response, url, maxBytes = DEFAULT_MAX_DOWNLOAD_SIZE }) {
39380
39490
  const contentLength = response.headers.get("content-length");
@@ -39478,11 +39588,11 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
39478
39588
  normalizedHeaders.set("user-agent", [currentUserAgentHeader, ...userAgentSuffixParts].filter(Boolean).join(" "));
39479
39589
  return Object.fromEntries(normalizedHeaders.entries());
39480
39590
  }
39481
- var VERSION$3 = "3.0.30";
39591
+ var VERSION$3 = "3.0.31";
39482
39592
  var getOriginalFetch = () => globalThis.fetch;
39483
- var getFromApi = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch2 = getOriginalFetch() }) => {
39593
+ var getFromApi = async ({ url, headers = {}, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch() }) => {
39484
39594
  try {
39485
- const response = await fetch2(url, {
39595
+ const response = await fetch(url, {
39486
39596
  method: "GET",
39487
39597
  headers: withUserAgentSuffix(headers, `ai-sdk/provider-utils/${VERSION$3}`, getRuntimeEnvironmentUserAgent()),
39488
39598
  signal: abortSignal
@@ -39708,7 +39818,7 @@ function parseJsonEventStream({ stream, schema }) {
39708
39818
  } }));
39709
39819
  }
39710
39820
  var getOriginalFetch2 = () => globalThis.fetch;
39711
- var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch: fetch2 }) => postToApi({
39821
+ var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch }) => postToApi({
39712
39822
  url,
39713
39823
  headers: {
39714
39824
  "Content-Type": "application/json",
@@ -39721,11 +39831,11 @@ var postJsonToApi = async ({ url, headers, body, failedResponseHandler, successf
39721
39831
  failedResponseHandler,
39722
39832
  successfulResponseHandler,
39723
39833
  abortSignal,
39724
- fetch: fetch2
39834
+ fetch
39725
39835
  });
39726
- var postToApi = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch: fetch2 = getOriginalFetch2() }) => {
39836
+ var postToApi = async ({ url, headers = {}, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch = getOriginalFetch2() }) => {
39727
39837
  try {
39728
- const response = await fetch2(url, {
39838
+ const response = await fetch(url, {
39729
39839
  method: "POST",
39730
39840
  headers: withUserAgentSuffix(headers, `ai-sdk/provider-utils/${VERSION$3}`, getRuntimeEnvironmentUserAgent()),
39731
39841
  body: body.content,
@@ -41785,7 +41895,7 @@ async function getVercelRequestId() {
41785
41895
  var _a10;
41786
41896
  return (_a10 = getContext().headers) == null ? void 0 : _a10["x-vercel-id"];
41787
41897
  }
41788
- var VERSION$2 = "2.0.115";
41898
+ var VERSION$2 = "2.0.125";
41789
41899
  var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
41790
41900
  function createGatewayProvider(options = {}) {
41791
41901
  var _a10, _b10;
@@ -44498,4 +44608,4 @@ const agentBuilderWorkflows = {
44498
44608
  //#endregion
44499
44609
  exports.agentBuilderWorkflows = agentBuilderWorkflows;
44500
44610
 
44501
- //# sourceMappingURL=dist-DhFw0bEW.cjs.map
44611
+ //# sourceMappingURL=dist-COHIL6fR.cjs.map