{"version":3,"sources":["../../../src/agent-builder/ee/types.ts","../../../src/agent-builder/ee/errors.ts","../../../src/agent-builder/ee/normalize-candidate.ts","../../../src/agent-builder/ee/allowlist.ts","../../../src/agent-builder/ee/policy.ts","../../../src/agent-builder/ee/picker.ts"],"names":["getRegisteredProviders","parseModelString","isProviderRegistered"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Provider, ModelForProvider } from '../../llm/model';\nimport type { SerializedMemoryConfig } from '../../memory/types';\nimport type { StorageBrowserRef, StorageWorkspaceRef } from '../../storage/types';\n\n/**\n * Allowlist entry for a known provider (one of the generated `Provider` strings).\n * `modelId` narrows to the union of model ids declared for that provider.\n * Omitting `modelId` is the **provider wildcard** — every model under the provider is allowed.\n */\nexport type KnownProviderEntry = {\n  [P in Provider]: { provider: P; modelId?: ModelForProvider<P> };\n}[Provider];\n\n/**\n * Allowlist entry for a custom / gateway provider that isn't in the generated registry.\n *\n * The `kind: 'custom'` discriminant is **required** — without it, an arbitrary string\n * provider would silently bypass the typo protection that `KnownProviderEntry` gives.\n * `modelId` is `string` (with the `& {}` escape hatch keeping autocomplete usable).\n */\nexport type CustomProviderEntry = {\n  kind: 'custom';\n  provider: string;\n  // string & {} preserves IDE autocomplete on call sites that still pass known model\n  // strings, while making the type accept arbitrary gateway model ids.\n  modelId?: string & {};\n};\n\n/**\n * Allowlist entry. Either a typed known-provider entry, or a tagged custom-provider entry.\n */\nexport type ProviderModelEntry = KnownProviderEntry | CustomProviderEntry;\n\n/**\n * Default model entry. Same shape as {@link ProviderModelEntry} but `modelId` is required —\n * a default needs to point at a specific model, not a whole provider.\n */\nexport type DefaultModelEntry =\n  | { [P in Provider]: { provider: P; modelId: ModelForProvider<P> } }[Provider]\n  | { kind: 'custom'; provider: string; modelId: string & {} };\n\n/**\n * Admin-controlled model policy for the Agent Builder.\n * Owned here; re-exported from `@mastra/core/agent-builder/ee` and the SDK.\n *\n * Invariants (enforced in Phase 4):\n * - `active: false` → all other fields ignored.\n * - `active: true` + `pickerVisible: false` (locked) → `default` MUST be set.\n * - When `allowed` is non-empty, `default` (if set) MUST satisfy `isModelAllowed(allowed, default)`.\n */\nexport interface BuilderModelPolicy {\n  active: boolean;\n  pickerVisible?: boolean;\n  allowed?: ProviderModelEntry[];\n  default?: DefaultModelEntry;\n}\n\n/**\n * Default values for agents created via the builder.\n * Used as fallbacks when the user doesn't specify a value.\n */\nexport interface BuilderAgentDefaults extends Record<string, unknown> {\n  /** Default memory configuration for new agents */\n  memory?: SerializedMemoryConfig;\n  /** Default workspace reference for new agents */\n  workspace?: StorageWorkspaceRef;\n  /** Default browser configuration for new agents */\n  browser?: StorageBrowserRef;\n  /**\n   * Admin-controlled model allowlist + default applied to new agents.\n   * `allowed` empty/undefined ⇒ no restriction. `default` (if set) is preselected on create.\n   * See parent RFC for full semantics (wildcards, custom gateways, deny-by-default).\n   */\n  models?: {\n    allowed?: ProviderModelEntry[];\n    default?: DefaultModelEntry;\n  };\n  /**\n   * Admin-controlled allowlist of tool IDs visible in the builder tools picker.\n   *\n   * Semantics:\n   * - omitted (`undefined`) ⇒ unrestricted; show all registered tools.\n   * - `allowed: []` ⇒ empty picker (explicit lockdown).\n   * - `allowed: [...ids]` ⇒ show only the listed tool IDs.\n   *\n   * IDs are `tool.id` (preferred — what you see in the UI, URLs and traces)\n   * but the registration key (the property name under `Mastra({ tools: {…} })`)\n   * is also accepted as an alias. Matched against the registered tools at\n   * request time. Unknown IDs are dropped and surfaced as warnings.\n   */\n  tools?: {\n    allowed?: string[];\n  };\n  /**\n   * Admin-controlled allowlist of agent IDs visible in the builder sub-agents picker.\n   *\n   * Semantics:\n   * - omitted (`undefined`) ⇒ unrestricted; show all registered agents.\n   * - `allowed: []` ⇒ empty picker (explicit lockdown).\n   * - `allowed: [...ids]` ⇒ show only the listed agent IDs.\n   *\n   * IDs are `Agent.id` (preferred — what you see in the UI, URLs and traces)\n   * but the registration key (the property name under `Mastra({ agents: {…} })`)\n   * is also accepted as an alias. Matched against the registered agents at\n   * request time. Unknown IDs are dropped and surfaced as warnings.\n   */\n  agents?: {\n    allowed?: string[];\n  };\n  /**\n   * Admin-controlled allowlist of workflow IDs visible in the builder workflows picker.\n   *\n   * Semantics:\n   * - omitted (`undefined`) ⇒ unrestricted; show all registered workflows.\n   * - `allowed: []` ⇒ empty picker (explicit lockdown).\n   * - `allowed: [...ids]` ⇒ show only the listed workflow IDs.\n   *\n   * IDs are `workflow.id` (preferred — what you see in the UI, URLs and traces)\n   * but the registration key (the property name under `Mastra({ workflows: {…} })`)\n   * is also accepted as an alias. Matched against the registered workflows at\n   * request time. Unknown IDs are dropped and surfaced as warnings.\n   */\n  workflows?: {\n    allowed?: string[];\n  };\n}\n\n/**\n * Feature toggles for the agent editor surface.\n * Each key controls visibility of that section in the builder UI.\n *\n * **Semantic: omitted = true (allowlist model — features default ON)**\n * - omitted or `true` — feature is visible to users\n * - `false` — feature is hidden\n *\n * Admins opt OUT of features by setting them to `false`. The raw\n * `AgentFeatures` shape carries `undefined`/`true`/`false`; the resolved\n * shape produced by {@link resolveAgentFeatures} is fully populated and is\n * what consumers (server handlers, UI hooks) actually read via\n * `IAgentBuilder.getFeatures()`.\n *\n * Consumer code should use strict equality on the resolved shape:\n * ```ts\n * const showTools = builder.getFeatures()?.agent?.tools === true;\n * ```\n *\n * Special case — `browser`: defaults to `true` ONLY when a valid\n * `configuration.agent.browser` (with `config.provider`) is provided.\n * Without a provider, the toggle has no backend, so the resolved value is\n * `false` regardless of the omitted-default. An explicit `browser: true`\n * with missing/invalid config is downgraded to `false` and surfaced as a\n * warning by `EditorAgentBuilder` (admin error feedback).\n */\nexport interface AgentFeatures {\n  tools?: boolean;\n  agents?: boolean;\n  workflows?: boolean;\n  scorers?: boolean;\n  skills?: boolean;\n  memory?: boolean;\n  variables?: boolean;\n  /** Favorite agents and skills with per-user state and aggregate counts. */\n  favorites?: boolean;\n  avatarUpload?: boolean;\n  /**\n   * Allow end-users to enable browser access for their agents.\n   * Defaults to `true` only when a valid browser provider is configured;\n   * otherwise resolves to `false`. See doc above for the full rule.\n   */\n  browser?: boolean;\n  /**\n   * Whether the model picker is visible to end-users in the Agent Builder.\n   * Omitted ⇒ picker visible (default-on). `false` ⇒ picker hidden (locked\n   * mode); admin's `models.default` is applied.\n   * When visible, choices are filtered by `models.allowed` if set.\n   */\n  model?: boolean;\n}\n\n/**\n * Default-on values for {@link AgentFeatures}. `browser` is defaulted\n * dynamically by {@link resolveAgentFeatures} based on configuration; it is\n * intentionally absent here so the shape mirrors what `resolveAgentFeatures`\n * unconditionally fills in.\n */\nexport const BUILDER_FEATURE_DEFAULTS: Required<Omit<AgentFeatures, 'browser'>> = {\n  tools: true,\n  agents: true,\n  workflows: true,\n  scorers: true,\n  skills: true,\n  memory: true,\n  variables: true,\n  favorites: true,\n  avatarUpload: true,\n  model: true,\n};\n\n/**\n * Context required to resolve {@link AgentFeatures} defaults. Lives separately\n * from the raw config so this helper stays pure and synchronous.\n */\nexport interface ResolveAgentFeaturesContext {\n  /**\n   * Whether `configuration.agent.browser` declares a valid provider.\n   * Drives the default-on/off decision for `features.agent.browser`.\n   */\n  hasBrowserConfig: boolean;\n}\n\n/**\n * Pure normalization of the raw {@link AgentFeatures} into a fully-populated\n * shape with default-on semantics applied.\n *\n * Rules:\n * - Explicit `false` always wins (admin opt-out).\n * - Explicit `true` wins for non-`browser` keys.\n * - Omitted keys resolve to `true` (except `browser`, see below).\n * - `browser`:\n *   - explicit `false` ⇒ `false`.\n *   - explicit `true` + `hasBrowserConfig: false` ⇒ `false` (caller is\n *     responsible for emitting a warning; this helper does not throw).\n *   - explicit `true` + `hasBrowserConfig: true` ⇒ `true`.\n *   - omitted ⇒ `hasBrowserConfig` (default-on only when prerequisite met).\n */\nexport function resolveAgentFeatures(\n  raw: AgentFeatures | undefined,\n  ctx: ResolveAgentFeaturesContext,\n): Required<AgentFeatures> {\n  const pick = <K extends keyof typeof BUILDER_FEATURE_DEFAULTS>(key: K): boolean => {\n    const explicit = raw?.[key];\n    return explicit === undefined ? BUILDER_FEATURE_DEFAULTS[key] : explicit;\n  };\n\n  const resolveBrowser = (): boolean => {\n    const explicit = raw?.browser;\n    if (explicit === false) return false;\n    if (explicit === true) return ctx.hasBrowserConfig;\n    return ctx.hasBrowserConfig;\n  };\n\n  return {\n    tools: pick('tools'),\n    agents: pick('agents'),\n    workflows: pick('workflows'),\n    scorers: pick('scorers'),\n    skills: pick('skills'),\n    memory: pick('memory'),\n    variables: pick('variables'),\n    favorites: pick('favorites'),\n    avatarUpload: pick('avatarUpload'),\n    model: pick('model'),\n    browser: resolveBrowser(),\n  };\n}\n\n/**\n * Configuration for the Agent Builder EE feature.\n * Passed to `MastraEditorConfig.builder`.\n *\n * All fields are optional. JSON-safe (no functions, no class instances).\n */\nexport interface AgentBuilderOptions {\n  /**\n   * Whether the builder is enabled. Default: true.\n   * Set to false to disable the builder without removing the config.\n   */\n  enabled?: boolean;\n\n  /**\n   * Deployment-level feature toggles.\n   * Key presence means \"this surface exists for this deployment.\"\n   */\n  features?: {\n    agent?: AgentFeatures;\n  };\n\n  /**\n   * Admin-pinned values applied to every artifact the builder produces.\n   * Not overridable by end-users.\n   *\n   * Known fields are typed explicitly; additional fields allowed for extensibility.\n   */\n  configuration?: {\n    agent?: BuilderAgentDefaults;\n  };\n\n  /**\n   * Skill registries the Agent Builder is allowed to browse and install from.\n   *\n   * Each registry is opt-in. When no registries are enabled, the Builder hides\n   * registry browse UI entirely. When at least one is enabled, the Builder\n   * shows a \"Browse registries\" entry alongside \"Create skill\".\n   */\n  registries?: {\n    /**\n     * The public skills.sh registry (https://skills.sh).\n     * Off by default — admins must explicitly opt in.\n     */\n    skillsSh?: {\n      /** When true, the Builder may browse and install from skills.sh. */\n      enabled: boolean;\n    };\n  };\n}\n\n/**\n * Public interface for the Agent Builder.\n * Implemented by EditorAgentBuilder in @mastra/editor/ee.\n */\nexport interface IAgentBuilder {\n  readonly enabled: boolean;\n  getFeatures(): AgentBuilderOptions['features'];\n  getConfiguration(): AgentBuilderOptions['configuration'];\n  /**\n   * The opt-in skill registries this Builder is allowed to browse and install\n   * from. Returns `undefined` when the admin has not configured any registries.\n   */\n  getRegistries?(): AgentBuilderOptions['registries'];\n  /**\n   * Optional warnings produced during construction-time validation\n   * (e.g. allowlist entries with unknown providers that lack `kind: 'custom'`).\n   * Surfaced via `GET /editor/builder/settings.modelPolicyWarnings` for admin UI display.\n   */\n  getModelPolicyWarnings?(): string[];\n}\n","import type { ModelCandidate } from './normalize-candidate';\nimport type { ProviderModelEntry } from './types';\n\nexport const MODEL_NOT_ALLOWED_CODE = 'MODEL_NOT_ALLOWED' as const;\n\n/**\n * Thrown by `enforceModelAllowlist` call sites when a write attempts to persist\n * a model that the active builder allowlist does not permit.\n *\n * Lives in `@mastra/core` so editor and server layers can both throw it\n * without crossing package boundaries. The server adapter\n * (`packages/server/src/server/handlers/error.ts`) maps this to HTTP 422 with\n * a structured JSON body of the same shape.\n */\nexport class ModelNotAllowedError extends Error {\n  readonly code = MODEL_NOT_ALLOWED_CODE;\n  readonly allowed: ProviderModelEntry[] | undefined;\n  readonly attempted: ModelCandidate;\n  readonly offendingLabel: string;\n\n  constructor(args: {\n    allowed: ProviderModelEntry[] | undefined;\n    attempted: ModelCandidate;\n    offendingLabel: string;\n    message?: string;\n  }) {\n    const message =\n      args.message ??\n      `Model \"${args.attempted.provider}/${args.attempted.modelId}\" (${args.offendingLabel}) is not in the configured allowlist.`;\n    super(message);\n    this.name = 'ModelNotAllowedError';\n    this.allowed = args.allowed;\n    this.attempted = args.attempted;\n    this.offendingLabel = args.offendingLabel;\n  }\n}\n\nexport function isModelNotAllowedError(error: unknown): error is ModelNotAllowedError {\n  return error instanceof Error && (error as { code?: unknown }).code === MODEL_NOT_ALLOWED_CODE;\n}\n","import { getRegisteredProviders, parseModelString } from '../../llm/model/provider-registry.js';\nimport type { MastraModelConfig } from '../../llm/model/shared.types.js';\nimport type { StorageConditionalField, StorageConditionalVariant, StorageModelConfig } from '../../storage/types.js';\n\nexport type ModelCandidateOrigin =\n  | 'static'\n  | 'conditional-variant'\n  | 'conditional-default'\n  | 'runtime'\n  | 'list'\n  | 'sdk-instance'\n  | 'openai-compatible';\n\n/**\n * A single normalized provider/model candidate extracted from one of the many\n * shapes a model can be expressed in across the codebase.\n *\n * `origin` records which dispatch branch produced the candidate, mainly for\n * error messages on conditional variants.\n *\n * `label` is a short human-friendly description (variant index / SDK provider id\n * / etc.) used by `enforceModelAllowlist` when reporting the offending entry.\n */\nexport interface ModelCandidate {\n  provider: string;\n  modelId: string;\n  origin: ModelCandidateOrigin;\n  label?: string;\n}\n\n/**\n * Anything we accept as input to {@link toModelCandidates}. Kept open so call\n * sites can pass arbitrary stored or runtime model values without manual coercion.\n */\nexport type ModelCandidateInput =\n  | string\n  | MastraModelConfig\n  | StorageModelConfig\n  | StorageConditionalField<StorageModelConfig>\n  | StorageConditionalVariant<string>[]\n  | { provider?: unknown; modelId?: unknown; name?: unknown; id?: unknown; providerId?: unknown }\n  | ((...args: unknown[]) => unknown)\n  | null\n  | undefined;\n\n/**\n * Gateway-aware split of a runtime model string. `parseModelString` only splits\n * on the first slash, which fails for gateway provider IDs that themselves\n * contain a slash (e.g. `acme/custom/foo-1`). We try the longest registered\n * provider prefix first and fall back to the first-slash split when no match\n * is found in the registry.\n */\nfunction splitRuntimeModelString(input: string): { provider: string; modelId: string } | undefined {\n  const providers = getRegisteredProviders().sort((a, b) => b.length - a.length);\n  for (const providerId of providers) {\n    const prefix = `${providerId}/`;\n    if (input.startsWith(prefix)) {\n      const modelId = input.slice(prefix.length);\n      if (modelId.length > 0) return { provider: providerId, modelId };\n    }\n  }\n  const parsed = parseModelString(input);\n  if (parsed.provider && parsed.modelId) {\n    return { provider: parsed.provider, modelId: parsed.modelId };\n  }\n  return undefined;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction fromObject(value: Record<string, unknown>, origin: ModelCandidateOrigin, label?: string): ModelCandidate[] {\n  // SDK instance: AI SDK language models expose `provider` + `modelId`.\n  const providerField = value.provider;\n  const modelIdField = value.modelId;\n  const nameField = value.name;\n  const idField = value.id;\n  const providerIdField = value.providerId;\n\n  // OpenAICompatibleConfig `{ id: 'provider/model' }` — must be checked before\n  // `{ provider, modelId }` so AI SDK instances (which also have `provider`)\n  // don't get pre-empted by a stale `id` lookup.\n  if (typeof idField === 'string' && idField.includes('/') && providerField === undefined) {\n    const split = splitRuntimeModelString(idField);\n    if (split) {\n      return [{ ...split, origin: 'openai-compatible', label: label ?? idField }];\n    }\n  }\n\n  // OpenAICompatibleConfig `{ providerId, modelId }`\n  if (typeof providerIdField === 'string' && typeof modelIdField === 'string') {\n    return [\n      {\n        provider: providerIdField,\n        modelId: modelIdField,\n        origin: 'openai-compatible',\n        label: label ?? `${providerIdField}/${modelIdField}`,\n      },\n    ];\n  }\n\n  // AI SDK language model instance: `{ provider, modelId, ... doGenerate }`\n  if (typeof providerField === 'string' && typeof modelIdField === 'string') {\n    const isSdkInstance = typeof (value as { doGenerate?: unknown }).doGenerate === 'function';\n    return [\n      {\n        provider: providerField,\n        modelId: modelIdField,\n        origin: isSdkInstance ? 'sdk-instance' : origin,\n        label: label ?? `${providerField}/${modelIdField}`,\n      },\n    ];\n  }\n\n  // Stored static `{ provider, name }`\n  if (typeof providerField === 'string' && typeof nameField === 'string') {\n    return [\n      {\n        provider: providerField,\n        modelId: nameField,\n        origin,\n        label: label ?? `${providerField}/${nameField}`,\n      },\n    ];\n  }\n\n  return [];\n}\n\n/**\n * Convert any supported model expression into a flat list of `{ provider, modelId }`\n * candidates. Empty array means \"could not statically determine\" — callers\n * should treat that as unenforced at this level (runtime defense in Phase 7\n * picks it up).\n *\n * Dispatch order:\n * 1. `null` / `undefined` / `function` → `[]` (dynamic, defer to runtime)\n * 2. `string` → gateway-aware split\n * 3. Conditional variants array → walk each variant\n * 4. Object → openai-compatible / SDK instance / stored static, see {@link fromObject}\n */\nexport function toModelCandidates(input: ModelCandidateInput): ModelCandidate[] {\n  if (input === null || input === undefined) return [];\n\n  if (typeof input === 'function') return [];\n\n  if (typeof input === 'string') {\n    const split = splitRuntimeModelString(input);\n    if (!split) return [];\n    return [{ ...split, origin: 'runtime', label: input }];\n  }\n\n  if (Array.isArray(input)) {\n    const candidates: ModelCandidate[] = [];\n    input.forEach((variant, index) => {\n      if (!isPlainObject(variant)) return;\n      const value = (variant as { value?: unknown }).value ?? variant;\n      const hasRules = isPlainObject(variant) && 'rules' in variant && (variant as { rules?: unknown }).rules != null;\n      const origin: ModelCandidateOrigin = hasRules ? 'conditional-variant' : 'conditional-default';\n      const label = hasRules ? `variant[${index}]` : `variant[${index}] (default)`;\n      if (typeof value === 'string') {\n        const split = splitRuntimeModelString(value);\n        if (split) {\n          candidates.push({ ...split, origin, label });\n        }\n        return;\n      }\n      if (isPlainObject(value)) {\n        candidates.push(...fromObject(value, origin, label));\n      }\n    });\n    return candidates;\n  }\n\n  if (isPlainObject(input)) {\n    return fromObject(input, 'static');\n  }\n\n  return [];\n}\n","import { isProviderRegistered } from '../../llm/model/provider-registry.js';\nimport { ModelNotAllowedError } from './errors.js';\nimport { toModelCandidates } from './normalize-candidate.js';\nimport type { ModelCandidate, ModelCandidateInput } from './normalize-candidate.js';\nimport type { ProviderModelEntry } from './types.js';\n\n/**\n * Candidate model to check against the allowlist.\n * Caller is responsible for normalizing the source shape via {@link toModelCandidates}\n * (in `./normalize-candidate.ts`) before reaching this matcher.\n */\nexport interface ModelMatchCandidate {\n  provider: string;\n  modelId: string;\n}\n\n/**\n * Single-entry match: provider equality (case-sensitive). When the entry omits\n * `modelId` it matches every model under that provider (provider wildcard).\n *\n * Custom (`kind: 'custom'`) entries match by exact provider string. Known-provider\n * entries match by exact provider string too — the typed surface is purely a\n * compile-time guard.\n */\nexport function matchesProvider(entry: ProviderModelEntry, candidate: ModelMatchCandidate): boolean {\n  if (entry.provider !== candidate.provider) return false;\n  if (!entry.modelId) return true; // wildcard\n  return entry.modelId === candidate.modelId;\n}\n\n/**\n * Returns `true` if the candidate is allowed under the given allowlist.\n *\n * Rules:\n * - `undefined` allowlist ⇒ unrestricted (always `true`).\n * - `[]` empty allowlist ⇒ unrestricted (always `true`).\n * - Non-empty allowlist where **every** entry's provider is unknown to the\n *   runtime registry AND not tagged `kind: 'custom'` ⇒ deny everything. This\n *   prevents typos (e.g. `openaii`) from acting as an unintended deny-all that\n *   silently allows anything else; it is the documented \"deny vs ignore\" rule.\n */\nexport function isModelAllowed(allowed: ProviderModelEntry[] | undefined, candidate: ModelMatchCandidate): boolean {\n  if (allowed === undefined) return true;\n  if (allowed.length === 0) return true;\n\n  const activeEntries = allowed.filter(entry => {\n    if ('kind' in entry && entry.kind === 'custom') return true;\n    return isProviderRegistered(entry.provider);\n  });\n\n  if (activeEntries.length === 0) return false;\n\n  return activeEntries.some(entry => matchesProvider(entry, candidate));\n}\n\n/**\n * Result of an allowlist enforcement check.\n *\n * `attempted` is the candidate (or list of candidates) that triggered the\n * decision; `offendingLabel` (when set) names the specific failing entry so\n * callers can surface it in error messages — particularly useful for\n * conditional model variants.\n */\nexport type EnforceModelAllowlistResult =\n  | { ok: true }\n  | {\n      ok: false;\n      attempted: ModelCandidate;\n      offendingLabel: string;\n    };\n\n/**\n * Apply an allowlist to any supported model expression. Normalizes via\n * `toModelCandidates`, then runs `isModelAllowed` per candidate. Returns the\n * **first** failing candidate so error messages can pinpoint which variant of\n * a conditional / fallback list violated the policy.\n *\n * If `toModelCandidates` returns no candidates (dynamic function, unparsable\n * shape) this passes — runtime defense (Phase 7) handles those cases.\n */\nexport function enforceModelAllowlist(\n  allowed: ProviderModelEntry[] | undefined,\n  input: ModelCandidateInput,\n): EnforceModelAllowlistResult {\n  const candidates = toModelCandidates(input);\n  for (const candidate of candidates) {\n    if (!isModelAllowed(allowed, candidate)) {\n      return {\n        ok: false,\n        attempted: candidate,\n        offendingLabel: candidate.label ?? candidate.origin,\n      };\n    }\n  }\n  return { ok: true };\n}\n\n/**\n * Convenience wrapper around `enforceModelAllowlist` that throws\n * `ModelNotAllowedError` on rejection. Use at write call sites so the server\n * adapter can translate into HTTP 422 + structured body.\n */\nexport function assertModelAllowed(allowed: ProviderModelEntry[] | undefined, input: ModelCandidateInput): void {\n  const result = enforceModelAllowlist(allowed, input);\n  if (result.ok) return;\n  throw new ModelNotAllowedError({\n    allowed,\n    attempted: result.attempted,\n    offendingLabel: result.offendingLabel,\n  });\n}\n","import type { IAgentBuilder, BuilderModelPolicy, DefaultModelEntry, ProviderModelEntry } from './types';\n\n/**\n * Inputs for the shared {@link isBuilderModelPolicyActive} predicate.\n *\n * Lives separately from {@link BuilderModelPolicy} because we need to ask the\n * \"is the model slice active?\" question at config-validation time, *before*\n * a `BuilderModelPolicy` has been built.\n */\nexport interface BuilderModelPolicyInputs {\n  /** `AgentBuilderOptions.enabled` (defaulted: missing = `true`). */\n  enabled: boolean;\n  /** `features.agent.model` — `true` means picker visible. */\n  pickerVisible: boolean;\n  /** `configuration.agent.models.allowed`. */\n  allowed?: ProviderModelEntry[];\n  /** `configuration.agent.models.default`. */\n  default?: DefaultModelEntry;\n}\n\n/**\n * Single source of truth for whether the admin has actually configured a model\n * policy. Reused by:\n * - {@link builderToModelPolicy} (UI / runtime derivation)\n * - `EditorAgentBuilder` config validation (Phase 4)\n * - Server-side enforcement gate (Phase 6)\n *\n * \"Active\" means the admin opted into the model slice in some way:\n * - the picker is visible (open-mode), OR\n * - an allowlist was set, OR\n * - a default model was set.\n *\n * If the builder is `enabled: false`, the slice is never active.\n */\nexport function isBuilderModelPolicyActive(inputs: BuilderModelPolicyInputs): boolean {\n  if (!inputs.enabled) return false;\n  if (inputs.pickerVisible) return true;\n  if (inputs.allowed !== undefined) return true;\n  if (inputs.default !== undefined) return true;\n  return false;\n}\n\n/**\n * Pure derivation of the {@link BuilderModelPolicy} from an `IAgentBuilder`.\n * No `Mastra` / `IEditor` dependency — server and editor wrappers feed it\n * a builder instance through their own resolution paths.\n *\n * Returns `{ active: false }` when:\n * - the builder is missing,\n * - the builder is disabled, or\n * - none of the model-slice signals are present.\n *\n * In every active case, `allowed` and `default` are passed through verbatim\n * so locked-mode UI still has the data it needs to render the chosen model.\n */\nexport function builderToModelPolicy(builder: IAgentBuilder | undefined): BuilderModelPolicy {\n  if (!builder || !builder.enabled) {\n    return { active: false };\n  }\n\n  const features = builder.getFeatures();\n  const configuration = builder.getConfiguration();\n  const pickerVisible = features?.agent?.model === true;\n  const models = configuration?.agent?.models;\n  const allowed = models?.allowed;\n  const defaultModel = models?.default;\n\n  const active = isBuilderModelPolicyActive({\n    enabled: builder.enabled,\n    pickerVisible,\n    allowed,\n    default: defaultModel,\n  });\n\n  if (!active) {\n    return { active: false };\n  }\n\n  return {\n    active: true,\n    pickerVisible,\n    ...(allowed !== undefined ? { allowed } : {}),\n    ...(defaultModel !== undefined ? { default: defaultModel } : {}),\n  };\n}\n","import type { BuilderAgentDefaults } from './types';\n\n/**\n * Resolved picker visibility for the Agent Builder configure panel.\n *\n * One field per kind (tools / agents / workflows).\n * - `null` ⇒ unrestricted (show all registered entries).\n * - `string[]` ⇒ explicit allowlist (may be empty to show none).\n */\nexport interface ResolvedPickerVisibility {\n  visibleTools: string[] | null;\n  visibleAgents: string[] | null;\n  visibleWorkflows: string[] | null;\n  /** Non-fatal warnings (e.g. unknown IDs in any allowlist). */\n  warnings: string[];\n}\n\nexport interface ResolvePickerVisibilityInputs {\n  /** The `agent` slice of `AgentBuilderOptions['configuration']`. */\n  config: BuilderAgentDefaults | undefined;\n  /** All tool IDs currently registered with the Mastra instance. */\n  registeredToolIds: readonly string[];\n  /** All agent IDs currently registered with the Mastra instance. */\n  registeredAgentIds: readonly string[];\n  /** All workflow IDs currently registered with the Mastra instance. */\n  registeredWorkflowIds: readonly string[];\n}\n\ninterface ResolveOneResult {\n  visible: string[] | null;\n  warnings: string[];\n}\n\nfunction resolveOne(\n  allowlist: string[] | undefined,\n  registered: readonly string[],\n  kindLabel: string,\n  configPath: string,\n): ResolveOneResult {\n  if (allowlist === undefined) {\n    return { visible: null, warnings: [] };\n  }\n\n  const known = new Set(registered);\n  const seen = new Set<string>();\n  const visible: string[] = [];\n  const warnings: string[] = [];\n\n  for (const id of allowlist) {\n    if (seen.has(id)) continue;\n    seen.add(id);\n    if (known.has(id)) {\n      visible.push(id);\n    } else {\n      warnings.push(\n        `${configPath} references unknown ${kindLabel} \"${id}\" — no ${kindLabel} with this ID is registered. It will be hidden from the builder picker.`,\n      );\n    }\n  }\n\n  return { visible, warnings };\n}\n\n/**\n * Pure derivation of {@link ResolvedPickerVisibility} from admin config and\n * the registered tool/agent/workflow sets.\n *\n * Per kind:\n * - allowlist undefined ⇒ `null` (unrestricted), no warnings.\n * - allowlist provided ⇒ filter to known IDs; emit one warning per unknown ID.\n *\n * Stable order: each visible list preserves admin-provided order with unknowns\n * dropped. Duplicates are de-duplicated.\n */\nexport function resolvePickerVisibility({\n  config,\n  registeredToolIds,\n  registeredAgentIds,\n  registeredWorkflowIds,\n}: ResolvePickerVisibilityInputs): ResolvedPickerVisibility {\n  const tools = resolveOne(config?.tools?.allowed, registeredToolIds, 'tool', 'configuration.agent.tools.allowed');\n  const agents = resolveOne(config?.agents?.allowed, registeredAgentIds, 'agent', 'configuration.agent.agents.allowed');\n  const workflows = resolveOne(\n    config?.workflows?.allowed,\n    registeredWorkflowIds,\n    'workflow',\n    'configuration.agent.workflows.allowed',\n  );\n\n  return {\n    visibleTools: tools.visible,\n    visibleAgents: agents.visible,\n    visibleWorkflows: workflows.visible,\n    warnings: [...tools.warnings, ...agents.warnings, ...workflows.warnings],\n  };\n}\n"]}