{"version":3,"sources":["../../src/agent-config/field.ts","../../src/agent-config/descriptor.ts","../../src/config.ts"],"sourcesContent":["/**\n * Tiny declarative field schema + reader used by the canonical AgentConfig\n * contract (`src/config.ts`).\n *\n * WHY THIS EXISTS (and why it isn't zod): the config contract is consumed by\n * three repos and, more importantly, by MANY DEPLOYED VERSIONS of this package\n * at once. A field that the dashboard publishes today is read tomorrow by a\n * customer's server that was installed six weeks ago. The one property the\n * validator must therefore have is *forward tolerance*: a document that carries\n * a field this build has never heard of must still load. A hand-rolled engine\n * lets us make that guarantee structural — every validator in the package is\n * derived from ONE descriptor, and the read mode (strict vs tolerant) is a\n * parameter, so \"strict here, tolerant there\" can never drift.\n *\n * Two modes, one descriptor:\n *\n *   • `strict`   — the WRITER contract. Unknown keys and invalid values are\n *                  errors. Used where a document is authored or accepted for\n *                  storage (publish, preview trust boundary). Strictness at the\n *                  writer is what keeps typos and junk out of the store.\n *   • `tolerant` — the READER contract. Unknown keys are DROPPED (recorded, not\n *                  fatal). An OPTIONAL known field whose value this build cannot\n *                  interpret (a new enum member, a changed shape) is DROPPED so\n *                  the schema default applies. Only a missing/invalid REQUIRED\n *                  field is fatal. Used by every runtime consumer: the customer's\n *                  handler, the hosted config fetcher, the browser bootstrap.\n *\n * The invariant this buys: within one `schemaVersion`, an OLDER reader can\n * always load a NEWER document (additive fields are ignored; new enum members\n * fall back to defaults). A change that would break that — removing a field,\n * changing a field's type or meaning, making an optional field required — is a\n * new `schemaVersion`. See docs/config-evolution.md.\n *\n * The reader always returns a NEW value containing only known, valid fields.\n * Callers never observe unknown keys, so downstream code cannot accidentally\n * depend on something the contract does not define.\n */\n\nexport type Primitive = string | number | boolean;\n\nexport type FieldSpec =\n  | { kind: 'boolean' }\n  | { kind: 'string'; nonEmpty?: boolean }\n  | { kind: 'number'; integer?: boolean; min?: number; max?: number }\n  | { kind: 'literal'; value: Primitive }\n  | { kind: 'enum'; values: readonly Primitive[] }\n  | { kind: 'object'; fields: FieldMap }\n  | { kind: 'array'; item: FieldSpec }\n  | { kind: 'union'; options: readonly FieldSpec[] };\n\nexport interface Field {\n  spec: FieldSpec;\n  /**\n   * A required field that is missing or invalid is fatal in BOTH modes. Keep\n   * this list tiny: every required field is a field an old reader cannot\n   * default, i.e. a field that can never be added to an existing object\n   * without a schema-version bump.\n   */\n  required?: boolean;\n  /**\n   * First package version whose canonical schema carried this field. Purely\n   * informational (docs, dashboards showing \"requires widget ≥ x\"), but\n   * mandatory so a field can never be added without recording when.\n   */\n  since: string;\n  /** One-line, human-readable meaning. Surfaces in the schema description. */\n  description: string;\n  /**\n   * Default applied by consumers when the field is absent or dropped. Only\n   * meaningful on leaf fields. Recorded in the schema description so the\n   * dashboard and docs can show it without a second source of truth.\n   */\n  default?: Primitive;\n}\n\nexport type FieldMap = Record<string, Field>;\n\nexport type ReadMode = 'strict' | 'tolerant';\n\nexport type ReadIssueCode = 'unknown_key' | 'invalid_value' | 'missing_required';\n\nexport interface ReadIssue {\n  /** Dotted path from the document root, e.g. `client.features.voiceInput`. */\n  path: string;\n  code: ReadIssueCode;\n  message: string;\n}\n\nexport type ReadResult<T> =\n  | {\n      ok: true;\n      value: T;\n      /**\n       * Fields the reader ignored. Empty in strict mode (anything here would\n       * have been an error). Non-empty in tolerant mode means \"this document\n       * was written by a newer schema than this build knows\" — worth logging\n       * once, never worth failing over.\n       */\n      dropped: ReadIssue[];\n    }\n  | { ok: false; issues: ReadIssue[] };\n\n// ── helpers ──────────────────────────────────────────────────────────────────\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst join = (path: string, key: string | number): string =>\n  path === '' ? String(key) : `${path}.${key}`;\n\n/** Human label for a spec — used in issue messages and the schema description. */\nexport function describeSpec(spec: FieldSpec): string {\n  switch (spec.kind) {\n    case 'boolean':\n      return 'boolean';\n    case 'string':\n      return spec.nonEmpty ? 'non-empty string' : 'string';\n    case 'number': {\n      const base = spec.integer ? 'integer' : 'number';\n      const lo = spec.min !== undefined ? ` ≥ ${spec.min}` : '';\n      const hi = spec.max !== undefined ? ` ≤ ${spec.max}` : '';\n      return `${base}${lo}${hi}`;\n    }\n    case 'literal':\n      return `literal ${JSON.stringify(spec.value)}`;\n    case 'enum':\n      return `one of ${spec.values.map((v) => JSON.stringify(v)).join(' | ')}`;\n    case 'object':\n      return 'object';\n    case 'array':\n      return `array of ${describeSpec(spec.item)}`;\n    case 'union':\n      return spec.options.map(describeSpec).join(' | ');\n  }\n}\n\n// ── reader ───────────────────────────────────────────────────────────────────\n\n/**\n * One issue describing a dropped optional field/item, at ITS path, with the\n * nested causes summarised relative to it (`textColor: required field is\n * missing`). Keeps `dropped` readable in logs: one line per thing that vanished.\n */\nfunction droppedIssue(path: string, causes: readonly ReadIssue[]): ReadIssue {\n  if (causes.length === 1 && causes[0].path === path) {\n    return { path, code: 'invalid_value', message: causes[0].message };\n  }\n  const detail = causes\n    .map((c) => `${c.path.startsWith(`${path}.`) ? c.path.slice(path.length + 1) : c.path}: ${c.message}`)\n    .join('; ');\n  return { path, code: 'invalid_value', message: `dropped (${detail})` };\n}\n\ninterface Ctx {\n  mode: ReadMode;\n  dropped: ReadIssue[];\n}\n\ntype Inner = { ok: true; value: unknown } | { ok: false; issues: ReadIssue[] };\n\nfunction readSpec(value: unknown, spec: FieldSpec, path: string, ctx: Ctx): Inner {\n  const invalid = (message: string): Inner => ({\n    ok: false,\n    issues: [{ path, code: 'invalid_value', message }],\n  });\n\n  switch (spec.kind) {\n    case 'boolean':\n      return typeof value === 'boolean' ? { ok: true, value } : invalid('expected a boolean');\n\n    case 'string':\n      if (typeof value !== 'string') return invalid('expected a string');\n      if (spec.nonEmpty && value.trim().length === 0) return invalid('expected a non-empty string');\n      return { ok: true, value };\n\n    case 'number': {\n      if (typeof value !== 'number' || !Number.isFinite(value)) return invalid('expected a finite number');\n      if (spec.integer && !Number.isSafeInteger(value)) return invalid('expected an integer');\n      if (spec.min !== undefined && value < spec.min) return invalid(`expected a value ≥ ${spec.min}`);\n      if (spec.max !== undefined && value > spec.max) return invalid(`expected a value ≤ ${spec.max}`);\n      return { ok: true, value };\n    }\n\n    case 'literal':\n      return value === spec.value\n        ? { ok: true, value }\n        : invalid(`expected ${JSON.stringify(spec.value)}`);\n\n    case 'enum':\n      return (spec.values as readonly unknown[]).includes(value)\n        ? { ok: true, value }\n        : invalid(`expected ${describeSpec(spec)}`);\n\n    case 'object':\n      return readFields(value, spec.fields, path, ctx);\n\n    case 'array': {\n      if (!Array.isArray(value)) return invalid('expected an array');\n      const out: unknown[] = [];\n      const issues: ReadIssue[] = [];\n      value.forEach((item, index) => {\n        const read = readSpec(item, spec.item, join(path, index), ctx);\n        if (read.ok) {\n          out.push(read.value);\n        } else if (ctx.mode === 'tolerant') {\n          // A single unreadable item must not take the whole list down: an\n          // older widget still renders the starter prompts it understands.\n          ctx.dropped.push(droppedIssue(join(path, index), read.issues));\n        } else {\n          issues.push(...read.issues);\n        }\n      });\n      return issues.length > 0 ? { ok: false, issues } : { ok: true, value: out };\n    }\n\n    case 'union': {\n      // First option that reads cleanly wins. In tolerant mode an object option\n      // may itself drop unknown keys — that is still a clean read.\n      for (const option of spec.options) {\n        const before = ctx.dropped.length;\n        const read = readSpec(value, option, path, ctx);\n        if (read.ok) return read;\n        // Roll back drops recorded by an option that ultimately failed.\n        ctx.dropped.length = before;\n      }\n      return invalid(`expected ${describeSpec(spec)}`);\n    }\n  }\n}\n\nfunction readFields(value: unknown, fields: FieldMap, path: string, ctx: Ctx): Inner {\n  if (!isRecord(value)) {\n    return { ok: false, issues: [{ path, code: 'invalid_value', message: 'expected an object' }] };\n  }\n\n  const out: Record<string, unknown> = {};\n  const issues: ReadIssue[] = [];\n\n  // Unknown keys: fatal for a writer, ignorable for a reader.\n  for (const key of Object.keys(value)) {\n    if (key in fields) continue;\n    const issue: ReadIssue = {\n      path: join(path, key),\n      code: 'unknown_key',\n      message: 'not part of this schema version',\n    };\n    if (ctx.mode === 'strict') issues.push(issue);\n    else ctx.dropped.push(issue);\n  }\n\n  for (const [key, field] of Object.entries(fields)) {\n    const fieldPath = join(path, key);\n    const present = key in value && value[key] !== undefined;\n\n    if (!present) {\n      if (field.required) {\n        issues.push({ path: fieldPath, code: 'missing_required', message: 'required field is missing' });\n      }\n      continue;\n    }\n\n    const read = readSpec(value[key], field.spec, fieldPath, ctx);\n    if (read.ok) {\n      out[key] = read.value;\n      continue;\n    }\n\n    // Invalid value. Required → always fatal. Optional → fatal for a writer,\n    // dropped (default applies) for a reader. The drop is reported at the\n    // FIELD's path (that is what disappeared), with the nested causes folded\n    // into the message.\n    if (field.required || ctx.mode === 'strict') {\n      issues.push(...read.issues);\n    } else {\n      ctx.dropped.push(droppedIssue(fieldPath, read.issues));\n    }\n  }\n\n  return issues.length > 0 ? { ok: false, issues } : { ok: true, value: out };\n}\n\n/**\n * Read `value` against `fields`. See the module doc for the two modes.\n *\n * `T` is the caller's promise about the shape `fields` describes; the engine\n * cannot prove it (that is what the `satisfies Record<keyof T, Field>` gate in\n * the descriptor is for).\n */\nexport function readObject<T>(value: unknown, fields: FieldMap, mode: ReadMode): ReadResult<T> {\n  const ctx: Ctx = { mode, dropped: [] };\n  const read = readFields(value, fields, '', ctx);\n  if (!read.ok) return { ok: false, issues: read.issues };\n  return { ok: true, value: read.value as T, dropped: ctx.dropped };\n}\n\n// ── schema description (for snapshots, docs, dashboards) ─────────────────────\n\nexport interface FieldDescription {\n  path: string;\n  kind: string;\n  required: boolean;\n  since: string;\n  description: string;\n  default?: Primitive;\n  enum?: Primitive[];\n  min?: number;\n  max?: number;\n  integer?: boolean;\n  literal?: Primitive;\n}\n\n/**\n * Flatten a field map into a sorted list of leaf-and-branch descriptions. This\n * is the machine-readable form of the contract: the compatibility gate diffs\n * it against the last released baseline, and dashboards/docs can render it.\n */\nexport function describeFields(fields: FieldMap, prefix = ''): FieldDescription[] {\n  const out: FieldDescription[] = [];\n  for (const [key, field] of Object.entries(fields)) {\n    const path = join(prefix, key);\n    describeInto(out, path, field.spec, field);\n  }\n  return out.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n}\n\nfunction describeInto(out: FieldDescription[], path: string, spec: FieldSpec, field: Field): void {\n  const base: FieldDescription = {\n    path,\n    kind: spec.kind === 'union' ? spec.options.map((o) => o.kind).join('|') : spec.kind,\n    required: field.required === true,\n    since: field.since,\n    description: field.description,\n  };\n  if (field.default !== undefined) base.default = field.default;\n  if (spec.kind === 'enum') base.enum = [...spec.values];\n  if (spec.kind === 'literal') base.literal = spec.value;\n  if (spec.kind === 'number') {\n    if (spec.integer) base.integer = true;\n    if (spec.min !== undefined) base.min = spec.min;\n    if (spec.max !== undefined) base.max = spec.max;\n  }\n  out.push(base);\n\n  const children = (s: FieldSpec): void => {\n    if (s.kind === 'object') out.push(...describeFields(s.fields, path));\n    else if (s.kind === 'array') children(s.item);\n    else if (s.kind === 'union') s.options.forEach(children);\n  };\n  children(spec);\n}\n","/**\n * THE schema descriptor for the canonical AgentConfig contract (schema v1).\n *\n * Everything that validates, describes, or defaults an agent configuration in\n * this package is derived from the field maps below — `isAgentConfig` (strict\n * writer), `readAgentConfig` / `readAgentBootstrap` (tolerant readers),\n * `resolveFeatures` (defaults), `describeAgentConfigSchema()` (the\n * machine-readable contract the compatibility gate snapshots). There is no\n * second list of keys anywhere. Adding a field is ONE entry here plus the\n * matching optional property on the TypeScript interface.\n *\n * GATES (they fail the build / the test suite, on purpose):\n *\n *   1. Every field map is declared `satisfies Record<keyof <Interface>, Field>`.\n *      Add a property to `FeatureConfig` without a descriptor entry → type\n *      error. Add a descriptor entry without the property → type error. The\n *      type and the contract cannot drift.\n *   2. `test/config-evolution.test.ts` snapshots `describeAgentConfigSchema()`\n *      and diffs it against the baseline of the LAST RELEASE. Removing a field,\n *      changing its kind, tightening a range, dropping an enum member, or\n *      making an optional field required fails the suite — those are\n *      schema-major changes and need a new `schemaVersion`, not a PR.\n *\n * RULES OF THE ROAD (full text in docs/config-evolution.md):\n *\n *   • New fields are OPTIONAL and carry `since` + a `default` where one exists.\n *   • A field's meaning never changes. Need different semantics? New field.\n *   • Enum members may be ADDED (old readers drop the unknown value and apply\n *     the default) but never removed or renamed.\n *   • `required: true` is reserved for the envelope — fields no reader can\n *     default. New required fields cannot be added to an existing object.\n */\n\nimport type { DisplayConfig, FeatureConfig, ThemeConfig } from '../types';\nimport type {\n  AgentBootstrap,\n  AgentClientConfig,\n  AgentConfig,\n  AgentRuntimeConfig,\n  SerializableFollowUpConfig,\n  SerializableMemoryConfig,\n  SerializableSandboxConfig,\n  SerializableStarterPrompt,\n  SerializableTitleConfig,\n} from '../config';\nimport type { Field, FieldMap } from './field';\n\n/** Schema major. Bumps only for breaking changes (see module doc). */\nexport const AGENT_CONFIG_SCHEMA_VERSION = 1 as const;\n\n/** The release that introduced the canonical schema — `since` for every v1 field. */\nconst V1 = '0.15.0';\n/** 0.20.0 — composer voice dictation. */\nconst V0_20 = '0.20.0';\n\n// ── runtime ──────────────────────────────────────────────────────────────────\n\nconst FOLLOW_UP_FIELDS = {\n  enabled: { spec: { kind: 'boolean' }, since: V1, description: 'Generate follow-up suggestions after each reply.' },\n  max: { spec: { kind: 'number', integer: true, min: 1, max: 5 }, since: V1, description: 'Maximum follow-up suggestions per reply.' },\n  timeoutMs: { spec: { kind: 'number', integer: true, min: 1 }, since: V1, description: 'Time budget for follow-up generation.' },\n} satisfies Record<keyof SerializableFollowUpConfig, Field>;\n\nconst TITLE_FIELDS = {\n  enabled: { spec: { kind: 'boolean' }, since: V1, description: 'Name conversations with a lightweight model call after the first exchange.' },\n  timeoutMs: { spec: { kind: 'number', integer: true, min: 1 }, since: V1, description: 'Time budget for title generation.' },\n} satisfies Record<keyof SerializableTitleConfig, Field>;\n\nconst MEMORY_FIELDS = {\n  enabled: { spec: { kind: 'boolean' }, required: true, since: V1, description: 'Long-term memory on/off.' },\n  inject: { spec: { kind: 'boolean' }, required: true, since: V1, description: 'Inject recalled memories before generation.' },\n  extract: { spec: { kind: 'boolean' }, required: true, since: V1, description: 'Extract and store memories after a completed turn.' },\n  limit: { spec: { kind: 'number', integer: true, min: 1, max: 20 }, required: true, since: V1, description: 'Maximum memories injected per turn.' },\n} satisfies Record<keyof SerializableMemoryConfig, Field>;\n\nconst SANDBOX_FIELDS = {\n  enabled: { spec: { kind: 'boolean' }, required: true, since: '0.25.0', default: false, description: 'Enable Mordn-managed sandboxes for verified users; subject to published config and operator policy.' },\n} satisfies Record<keyof SerializableSandboxConfig, Field>;\n\nexport const RUNTIME_FIELDS = {\n  model: { spec: { kind: 'string', nonEmpty: true }, required: true, since: V1, description: 'Gateway model identifier the handler runs.' },\n  systemPrompt: { spec: { kind: 'string' }, since: V1, description: 'System prompt.' },\n  temperature: { spec: { kind: 'number', min: 0, max: 2 }, since: V1, description: 'Sampling temperature.' },\n  maxOutputTokens: { spec: { kind: 'number', integer: true, min: 1 }, since: V1, description: 'Output token cap per turn.' },\n  followUps: {\n    spec: { kind: 'union', options: [{ kind: 'boolean' }, { kind: 'object', fields: FOLLOW_UP_FIELDS }] },\n    since: V1,\n    description: 'Follow-up suggestions: boolean shorthand or detailed settings.',\n  },\n  titles: {\n    spec: { kind: 'union', options: [{ kind: 'boolean' }, { kind: 'object', fields: TITLE_FIELDS }] },\n    since: V1,\n    description: 'Smart thread titles: boolean shorthand or detailed settings.',\n  },\n  memory: { spec: { kind: 'object', fields: MEMORY_FIELDS }, since: V1, description: 'Long-term memory settings.' },\n  sandbox: { spec: { kind: 'object', fields: SANDBOX_FIELDS }, since: '0.25.0', description: 'Managed workspace per verified user within this tenant and agent, shared across conversations. Absent means off.' },\n} satisfies Record<keyof AgentRuntimeConfig, Field>;\n\n// ── client ───────────────────────────────────────────────────────────────────\n\nconst THEME_FIELDS = {\n  backgroundColor: { spec: { kind: 'string' }, required: true, since: V1, description: 'Chat background color (hex).' },\n  textColor: { spec: { kind: 'string' }, required: true, since: V1, description: 'Body text color (hex).' },\n  primaryColor: { spec: { kind: 'string' }, required: true, since: V1, description: 'Primary accent color (hex).' },\n} satisfies Record<keyof ThemeConfig, Field>;\n\nexport const FEATURE_FIELDS = {\n  fileUpload: { spec: { kind: 'boolean' }, since: V1, default: false, description: 'Show the attach button and accept file uploads.' },\n  fileUploadAccept: { spec: { kind: 'string' }, since: V1, default: 'image/*', description: 'HTML `accept` filter for the file picker.' },\n  fileUploadMaxBytes: { spec: { kind: 'number', integer: true, min: 1 }, since: V1, description: 'Client-side per-file size cap in bytes.' },\n  webSearch: { spec: { kind: 'boolean' }, since: V1, default: false, description: 'Enable web search.' },\n  voiceInput: { spec: { kind: 'boolean' }, since: V0_20, default: true, description: 'Show the microphone button for browser speech-to-text dictation into the composer (rendered only where the browser supports it; never auto-sends).' },\n  voiceInputLanguage: { spec: { kind: 'string' }, since: V0_20, description: 'BCP-47 language for dictation. Defaults to the page language, then the browser language.' },\n} satisfies Record<keyof FeatureConfig, Field>;\n\nconst TOGGLE_POSITION_FIELDS = {\n  bottom: { spec: { kind: 'string' }, since: V1, description: 'CSS offset from the bottom edge.' },\n  right: { spec: { kind: 'string' }, since: V1, description: 'CSS offset from the right edge.' },\n} satisfies Record<keyof NonNullable<DisplayConfig['toggleButtonPosition']>, Field>;\n\nexport const DISPLAY_FIELDS = {\n  layout: { spec: { kind: 'enum', values: ['popup', 'inline', 'page'] }, since: V1, default: 'popup', description: 'Layout shape the widget renders in.' },\n  size: { spec: { kind: 'enum', values: ['compact', 'default', 'large', 'full'] }, since: V1, default: 'default', description: 'Width preset (popup layout).' },\n  width: { spec: { kind: 'string' }, since: V1, description: 'Custom CSS width override.' },\n  resizable: { spec: { kind: 'boolean' }, since: V1, default: true, description: 'Drag-to-resize.' },\n  defaultOpen: { spec: { kind: 'boolean' }, since: V1, default: false, description: 'Start open.' },\n  starterPromptsLayout: { spec: { kind: 'enum', values: ['list', 'grid'] }, since: V1, default: 'list', description: 'Empty-state starter prompt layout.' },\n  showToggleButton: { spec: { kind: 'boolean' }, since: V1, default: true, description: 'Render the floating toggle button.' },\n  toggleButtonPosition: { spec: { kind: 'object', fields: TOGGLE_POSITION_FIELDS }, since: V1, description: 'Toggle button offsets.' },\n  keyboardShortcut: {\n    spec: { kind: 'union', options: [{ kind: 'string' }, { kind: 'literal', value: false }] },\n    since: V1,\n    description: 'Keyboard combo that toggles the widget, or `false` for none.',\n  },\n} satisfies Record<keyof DisplayConfig, Field>;\n\nconst STARTER_PROMPT_FIELDS = {\n  title: { spec: { kind: 'string' }, required: true, since: V1, description: 'Prompt text (sent as the message when clicked).' },\n  subtitle: { spec: { kind: 'string' }, since: V1, description: 'Secondary line.' },\n} satisfies Record<keyof SerializableStarterPrompt, Field>;\n\nexport const CLIENT_FIELDS = {\n  greeting: { spec: { kind: 'string' }, since: V1, description: 'Empty-state headline.' },\n  subGreeting: { spec: { kind: 'string' }, since: V1, description: 'Faint line under the greeting.' },\n  assistantName: { spec: { kind: 'string' }, since: V1, description: \"The assistant's display name.\" },\n  theme: { spec: { kind: 'object', fields: THEME_FIELDS }, since: V1, description: 'Color theme (all-or-nothing).' },\n  features: { spec: { kind: 'object', fields: FEATURE_FIELDS }, since: V1, description: 'Feature flags.' },\n  display: { spec: { kind: 'object', fields: DISPLAY_FIELDS }, since: V1, description: 'Layout and chrome.' },\n  starterPrompts: { spec: { kind: 'array', item: { kind: 'object', fields: STARTER_PROMPT_FIELDS } }, since: V1, description: 'Empty-state starter prompts.' },\n  capabilitiesPrompt: { spec: { kind: 'string' }, since: V1, description: 'Client-visible capabilities blurb.' },\n  feedback: { spec: { kind: 'boolean' }, since: V1, default: false, description: 'Show per-message feedback controls.' },\n  streamingThrottleMs: { spec: { kind: 'number', integer: true, min: 0 }, since: V1, description: 'Render throttle for streamed text.' },\n  persistState: { spec: { kind: 'boolean' }, since: V1, description: 'Persist open/closed state per user.' },\n  allowAutoReopen: { spec: { kind: 'boolean' }, since: V1, description: 'Allow the widget to reopen itself after an explicit dismiss.' },\n} satisfies Record<keyof AgentClientConfig, Field>;\n\n// ── envelopes ────────────────────────────────────────────────────────────────\n\nexport const AGENT_CONFIG_FIELDS = {\n  schemaVersion: { spec: { kind: 'literal', value: AGENT_CONFIG_SCHEMA_VERSION }, required: true, since: V1, description: 'Schema major.' },\n  runtime: { spec: { kind: 'object', fields: RUNTIME_FIELDS }, required: true, since: V1, description: 'Server-side runtime settings.' },\n  client: { spec: { kind: 'object', fields: CLIENT_FIELDS }, required: true, since: V1, description: 'Browser-safe client projection.' },\n} satisfies Record<keyof AgentConfig, Field>;\n\n/** Independent of `schemaVersion`: transport shape and config schema evolve separately. */\nexport const BOOTSTRAP_PROTOCOL_VERSION = 1 as const;\n\nexport const BOOTSTRAP_FIELDS = {\n  protocolVersion: { spec: { kind: 'literal', value: BOOTSTRAP_PROTOCOL_VERSION }, required: true, since: V1, description: 'Bootstrap envelope version.' },\n  agent: { spec: { kind: 'string', nonEmpty: true }, required: true, since: V1, description: 'Resolved agent identifier.' },\n  revision: { spec: { kind: 'string', nonEmpty: true }, required: true, since: V1, description: 'Published revision identifier.' },\n  client: { spec: { kind: 'object', fields: CLIENT_FIELDS }, required: true, since: V1, description: 'Browser-safe client projection.' },\n  storageScope: { spec: { kind: 'string', nonEmpty: true }, required: true, since: V1, description: 'Opaque browser storage namespace.' },\n} satisfies Record<keyof AgentBootstrap, Field>;\n\n// ── defaults ─────────────────────────────────────────────────────────────────\n\n/** Collect the `default`s declared on a field map — the one place defaults live. */\nexport function defaultsOf<T extends FieldMap>(fields: T): Partial<Record<keyof T, unknown>> {\n  const out: Partial<Record<keyof T, unknown>> = {};\n  for (const key of Object.keys(fields) as Array<keyof T>) {\n    const d = fields[key].default;\n    if (d !== undefined) out[key] = d;\n  }\n  return out;\n}\n","/**\n * Canonical, JSON-serializable agent configuration shared by the control plane,\n * server handler, bootstrap response, and browser preview transport.\n *\n * Validation lives in two flavours, both derived from ONE descriptor\n * (`src/agent-config/descriptor.ts`) so they cannot drift:\n *\n *   • `isAgentConfig` / `isAgentBootstrap` — STRICT. The writer contract.\n *     Unknown keys are errors. Use where a document is authored or accepted\n *     for storage (publish, preview trust boundary).\n *   • `readAgentConfig` / `readAgentBootstrap` — TOLERANT. The reader\n *     contract. Unknown keys and uninterpretable optional values are dropped\n *     (and reported), never fatal. Use in every runtime consumer, so a\n *     document published by a NEWER dashboard/schema loads on an OLDER\n *     deployed widget. See docs/config-evolution.md.\n */\nimport type { DisplayConfig, FeatureConfig, ThemeConfig } from './types';\nimport { describeFields, readObject, type ReadIssue, type ReadResult } from './agent-config/field';\nimport {\n  AGENT_CONFIG_FIELDS,\n  AGENT_CONFIG_SCHEMA_VERSION,\n  BOOTSTRAP_FIELDS,\n  BOOTSTRAP_PROTOCOL_VERSION,\n  FEATURE_FIELDS,\n  defaultsOf,\n} from './agent-config/descriptor';\n\nexport { AGENT_CONFIG_SCHEMA_VERSION, BOOTSTRAP_PROTOCOL_VERSION };\nexport type { ReadIssue as ConfigReadIssue, ReadResult as ConfigReadResult };\nexport type { FieldDescription as ConfigFieldDescription } from './agent-config/field';\n\nexport interface SerializableStarterPrompt {\n  title: string;\n  subtitle?: string;\n}\n\nexport interface SerializableFollowUpConfig {\n  enabled?: boolean;\n  max?: number;\n  timeoutMs?: number;\n}\n\nexport interface SerializableTitleConfig {\n  enabled?: boolean;\n  timeoutMs?: number;\n}\n\nexport interface SerializableMemoryConfig {\n  enabled: boolean;\n  /** Inject recalled memories before generation. */\n  inject: boolean;\n  /** Extract and store memories after a completed turn. */\n  extract: boolean;\n  /** Maximum memories injected per turn. */\n  limit: number;\n}\n\n/** Managed workspace per verified user within an agent/tenant; absent means off. */\nexport interface SerializableSandboxConfig {\n  enabled: boolean;\n}\n\nexport interface AgentRuntimeConfig {\n  model: string;\n  systemPrompt?: string;\n  temperature?: number;\n  maxOutputTokens?: number;\n  followUps?: boolean | SerializableFollowUpConfig;\n  /**\n   * Smart thread titles: a lightweight post-response model call names the\n   * conversation after its first exchange. Default ON — pass `false` to keep\n   * the first-message-prefix placeholder titles.\n   */\n  titles?: boolean | SerializableTitleConfig;\n  memory?: SerializableMemoryConfig;\n  /** Enable sandboxes: Mordn-managed, shared across this user's conversations. */\n  sandbox?: SerializableSandboxConfig;\n}\n\nexport interface AgentClientConfig {\n  greeting?: string;\n  /** Faint line under the greeting headline (free display text). */\n  subGreeting?: string;\n  /** The assistant's name (identity, not the greeting sub line). */\n  assistantName?: string;\n  theme?: ThemeConfig;\n  features?: FeatureConfig;\n  display?: DisplayConfig;\n  starterPrompts?: SerializableStarterPrompt[];\n  capabilitiesPrompt?: string;\n  feedback?: boolean;\n  streamingThrottleMs?: number;\n  persistState?: boolean;\n  allowAutoReopen?: boolean;\n}\n\nexport interface AgentConfig {\n  schemaVersion: typeof AGENT_CONFIG_SCHEMA_VERSION;\n  runtime: AgentRuntimeConfig;\n  client: AgentClientConfig;\n}\n\n/** Hosted control-plane record consumed by the handler. */\nexport interface PublishedAgentConfig {\n  agent: string;\n  revision: string;\n  config: AgentConfig;\n}\n\n/** Browser-safe projection returned from GET /bootstrap. */\nexport interface AgentBootstrap {\n  protocolVersion: typeof BOOTSTRAP_PROTOCOL_VERSION;\n  agent: string;\n  revision: string;\n  client: AgentClientConfig;\n  storageScope: string;\n}\n\nexport function mergeAgentClientConfig(\n  published: AgentClientConfig | undefined,\n  explicit: AgentClientConfig | undefined,\n): AgentClientConfig {\n  if (!published) return explicit ?? {};\n  if (!explicit) return published;\n  return {\n    ...published,\n    ...explicit,\n    theme: explicit.theme ?? published.theme,\n    features:\n      published.features || explicit.features\n        ? { ...published.features, ...explicit.features }\n        : undefined,\n    display:\n      published.display || explicit.display\n        ? {\n            ...published.display,\n            ...explicit.display,\n            toggleButtonPosition:\n              published.display?.toggleButtonPosition || explicit.display?.toggleButtonPosition\n                ? {\n                    ...published.display?.toggleButtonPosition,\n                    ...explicit.display?.toggleButtonPosition,\n                  }\n                : undefined,\n          }\n        : undefined,\n  };\n}\n\n// ── Readers (tolerant) ───────────────────────────────────────────────────────\n\n/**\n * Read a complete schema-v1 config the way a RUNTIME must: fields this build\n * doesn't know are dropped and reported in `dropped`, never fatal. Fails only\n * on a wrong `schemaVersion` or a missing/invalid required field. Use in the\n * handler, the hosted config fetcher, and any other consumer of a published\n * document. The returned `value` contains only known, valid fields.\n */\nexport function readAgentConfig(value: unknown): ReadResult<AgentConfig> {\n  return readObject<AgentConfig>(value, AGENT_CONFIG_FIELDS, 'tolerant');\n}\n\n/** Tolerant reader for the browser-safe bootstrap envelope (see `readAgentConfig`). */\nexport function readAgentBootstrap(value: unknown): ReadResult<AgentBootstrap> {\n  return readObject<AgentBootstrap>(value, BOOTSTRAP_FIELDS, 'tolerant');\n}\n\n// ── Validators (strict) ──────────────────────────────────────────────────────\n\n/**\n * Validate the complete, strict schema-v1 config before it is authored,\n * stored, or trusted as a preview. Unknown keys are rejected — this is what\n * keeps typos and junk out of published revisions. Runtime consumers must use\n * `readAgentConfig` instead, or a newer dashboard will break older deployments.\n */\nexport function isAgentConfig(value: unknown): value is AgentConfig {\n  return readObject<AgentConfig>(value, AGENT_CONFIG_FIELDS, 'strict').ok;\n}\n\n/** Strict validator for the bootstrap envelope. Browsers should prefer `readAgentBootstrap`. */\nexport function isAgentBootstrap(value: unknown): value is AgentBootstrap {\n  return readObject<AgentBootstrap>(value, BOOTSTRAP_FIELDS, 'strict').ok;\n}\n\n// ── Defaults ─────────────────────────────────────────────────────────────────\n\n/** `FeatureConfig` with every defaulted flag resolved. */\nexport interface ResolvedFeatureConfig {\n  fileUpload: boolean;\n  fileUploadAccept: string;\n  fileUploadMaxBytes?: number;\n  webSearch: boolean;\n  voiceInput: boolean;\n  voiceInputLanguage?: string;\n}\n\n/** Feature defaults, sourced from the descriptor — the single place they live. */\nexport const DEFAULT_FEATURES: ResolvedFeatureConfig = defaultsOf(FEATURE_FIELDS) as ResolvedFeatureConfig;\n\n/**\n * Apply schema defaults to a (possibly partial or absent) `features` object.\n * Consumers read flags from the result instead of sprinkling `=== true` /\n * `?? 'image/*'` fallbacks through UI code, so a default changes in one place.\n */\nexport function resolveFeatures(features?: FeatureConfig | null): ResolvedFeatureConfig {\n  const resolved: ResolvedFeatureConfig = { ...DEFAULT_FEATURES };\n  if (!features) return resolved;\n  for (const [key, value] of Object.entries(features)) {\n    if (value !== undefined) (resolved as unknown as Record<string, unknown>)[key] = value;\n  }\n  return resolved;\n}\n\n// ── Schema description ───────────────────────────────────────────────────────\n\n/**\n * Machine-readable description of the whole contract: every path with its\n * kind, requiredness, `since`, default and constraints. The compatibility gate\n * (`test/config-evolution.test.ts`) snapshots this and diffs it against the\n * last release; dashboards and docs can render it directly.\n */\nexport function describeAgentConfigSchema() {\n  return {\n    schemaVersion: AGENT_CONFIG_SCHEMA_VERSION,\n    bootstrapProtocolVersion: BOOTSTRAP_PROTOCOL_VERSION,\n    config: describeFields(AGENT_CONFIG_FIELDS),\n    bootstrap: describeFields(BOOTSTRAP_FIELDS),\n  };\n}\n\n/** One-line summary of read issues for error messages and logs. */\nexport function formatConfigIssues(issues: readonly ReadIssue[]): string {\n  return issues.map((issue) => `${issue.path || '<root>'}: ${issue.message}`).join('; ');\n}\n"],"mappings":"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","names":[]}