{"version":3,"file":"supervisor.mjs","names":[],"sources":["../../../../../../../ai/src/supervisor/supervisor.ts"],"sourcesContent":["import type { SupervisorEventMap } from \"../contracts/events/event-map.type\";\nimport type { ExecutionReport } from \"../contracts/result/execution-report.type\";\nimport type { SupervisorResult } from \"../contracts/result/supervisor-result.type\";\nimport type { StreamContract } from \"../contracts/stream/stream.contract\";\nimport type { SupervisorIntentValue } from \"../contracts/supervisor/intent-entry.type\";\nimport type {\n  SupervisorConfig,\n  SupervisorEventHandler,\n} from \"../contracts/supervisor/supervisor-config.type\";\nimport type {\n  SupervisorExecuteOptions,\n  SupervisorResumeOptions,\n} from \"../contracts/supervisor/supervisor-execute-options.type\";\nimport type { SupervisorInput } from \"../contracts/supervisor/supervisor-input.type\";\nimport type { SupervisorStreamEvent } from \"../contracts/supervisor/supervisor-stream-event.type\";\nimport type {\n  SupervisorAsToolOptions,\n  SupervisorContract,\n} from \"../contracts/supervisor/supervisor.contract\";\nimport { SupervisorFailedError } from \"../errors\";\nimport { notifyObservers } from \"../observe/resolve-observers\";\nimport type { ToolContract } from \"../tool/tool\";\nimport { asTool } from \"./as-tool\";\nimport { SupervisorEmitter } from \"./emitter\";\nimport { assertRouterDescriptions, resolveIntentEntries } from \"./entries\";\nimport { SupervisorExecution } from \"./execution\";\nimport { computeSignature } from \"./signature\";\nimport { loadSnapshotForResume } from \"./snapshot\";\nimport { createSupervisorStream } from \"./supervisor-stream\";\n\n/**\n * `ai.supervisor(config)` — construct a `SupervisorContract`. Validates\n * the config at author time (throws `SupervisorFailedError` on bad\n * shape), resolves agent entries, computes a stable structural\n * signature, wires the three-tier event emitter, and returns an\n * instance that satisfies `ExecutableContract` so it can compose into\n * tools, outer agents, and (future) orchestrators uniformly.\n *\n * @example\n * const support = ai.supervisor({\n *   name: \"customer-support\",\n *   router: routerAgent,\n *   intents: { triage, orderLookup, billingLookup, resolver },\n *   evaluate: (ctx) => ctx.result.resolver?.output ? { satisfied: true } : undefined,\n *   output: z.object({ response: z.string(), refund: z.boolean() }),\n *   maxIterations: 6,\n * });\n */\nexport function supervisor<\n  TOutput = unknown,\n  TState = TOutput,\n  TIntents extends Record<string, SupervisorIntentValue> = Record<string, SupervisorIntentValue>,\n  TArtifacts = Record<string, unknown>,\n>(config: SupervisorConfig<TOutput, TState, TIntents, TArtifacts>): SupervisorContract<TOutput> {\n  validateFactoryConfig(config as unknown as SupervisorConfig<TOutput>);\n\n  const entries = resolveIntentEntries(config.intents, config.name);\n\n  assertRouterDescriptions(config as SupervisorConfig<unknown>, entries);\n\n  if (config.initialAgent && !entries.has(config.initialAgent)) {\n    throw new SupervisorFailedError(\n      `ai.supervisor(\"${config.name}\"): \\`initialAgent\\` \"${config.initialAgent}\" is not a key in \\`intents\\``,\n      { context: { authoring: true } },\n    );\n  }\n\n  const signature = computeSignature(config as SupervisorConfig<unknown>, entries);\n  const emitter = new SupervisorEmitter(config.on);\n\n  async function execute(\n    input: SupervisorInput,\n    options?: SupervisorExecuteOptions,\n  ): Promise<SupervisorResult<TOutput>> {\n    const runId = options?.runId ?? generateRunId();\n\n    const execution = new SupervisorExecution<TOutput>({\n      config: config as unknown as SupervisorConfig<TOutput>,\n      entries,\n      signature,\n      emitter,\n      input,\n      runId,\n      options,\n    });\n\n    const result = await execution.run();\n\n    // Route the finished report to any resolved observers (F1/F3).\n    // Gated by `config.observe` + the global observe-all flag; observer\n    // errors are swallowed inside `notifyObservers`. `ai.team(...)`\n    // forwards its `observe` into this same config, so a team inherits\n    // observability through here with no extra wiring. Bridge the\n    // pre-existing `SupervisorReport = Omit<BaseReport, \"type\">` drift\n    // (the report carries `type: \"supervisor\"` at runtime) so this call\n    // site adds no new type error beyond the documented baseline.\n    await notifyObservers(config.observe, result.report as unknown as ExecutionReport);\n\n    return result;\n  }\n\n  function stream(\n    input: SupervisorInput,\n    options?: SupervisorExecuteOptions,\n  ): StreamContract<SupervisorResult<TOutput>, SupervisorStreamEvent> {\n    const runId = options?.runId ?? generateRunId();\n    const { controller, stream: contract } = createSupervisorStream<SupervisorResult<TOutput>>();\n\n    const execution = new SupervisorExecution<TOutput>({\n      config: config as unknown as SupervisorConfig<TOutput>,\n      entries,\n      signature,\n      emitter,\n      input,\n      runId,\n      options,\n      streamController: controller,\n    });\n\n    // Route the finished report to resolved observers once the streamed\n    // run settles. Attached to the run promise (not awaited — `stream`\n    // returns synchronously); `notifyObservers` swallows observer errors.\n    void execution\n      .run()\n      .then((result) =>\n        notifyObservers(config.observe, result.report as unknown as ExecutionReport),\n      );\n\n    return contract;\n  }\n\n  async function resume(\n    runId: string,\n    options?: SupervisorResumeOptions,\n  ): Promise<SupervisorResult<TOutput>> {\n    const snapshot = await loadSnapshotForResume({\n      config: config as SupervisorConfig<unknown>,\n      signature,\n      runId,\n      options,\n    });\n\n    const execution = new SupervisorExecution<TOutput>({\n      config: config as unknown as SupervisorConfig<TOutput>,\n      entries,\n      signature,\n      emitter,\n      input: snapshot.input,\n      runId,\n      options,\n      resumeFrom: snapshot,\n    });\n\n    const result = await execution.run();\n\n    await notifyObservers(config.observe, result.report as unknown as ExecutionReport);\n\n    return result;\n  }\n\n  const instance: SupervisorContract<TOutput> = {\n    name: config.name,\n    inputSchema: config.inputSchema,\n    signature,\n    execute,\n    stream,\n    resume,\n    on<K extends keyof SupervisorEventMap>(\n      event: K,\n      handler: SupervisorEventHandler<K>,\n    ): () => void {\n      return emitter.on(event, handler);\n    },\n    off<K extends keyof SupervisorEventMap>(event: K, handler: SupervisorEventHandler<K>): void {\n      emitter.off(event, handler);\n    },\n    asTool<TToolInput = string>(\n      options: SupervisorAsToolOptions<TToolInput>,\n    ): ToolContract<TToolInput, TOutput> {\n      return asTool<TOutput, TToolInput>(instance, options);\n    },\n  };\n\n  return instance;\n}\n\n/**\n * Factory-time validation. Enforces the XOR + pairing rules the design\n * locked in §2 and surfaces any violation as a typed\n * `SupervisorFailedError` tagged `authoring: true`.\n */\nfunction validateFactoryConfig<T>(config: SupervisorConfig<T>): void {\n  if (!config.name || typeof config.name !== \"string\") {\n    throw new SupervisorFailedError(\"ai.supervisor: `name` is required and must be a string\", {\n      context: { authoring: true },\n    });\n  }\n\n  if (!config.intents || typeof config.intents !== \"object\") {\n    throw new SupervisorFailedError(`ai.supervisor(\"${config.name}\"): \\`intents\\` is required`, {\n      context: { authoring: true },\n    });\n  }\n\n  const hasRoute = typeof config.route === \"function\";\n  const hasRouter = !!config.router;\n\n  if (hasRouter) {\n    const router = config.router as { execute?: unknown } | { agent?: { execute?: unknown } };\n    const isBareAgent = typeof (router as { execute?: unknown }).execute === \"function\";\n    const isEntryForm =\n      !isBareAgent &&\n      typeof (router as { agent?: { execute?: unknown } }).agent === \"object\" &&\n      typeof (router as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n\n    if (!isBareAgent && !isEntryForm) {\n      throw new SupervisorFailedError(\n        `ai.supervisor(\"${config.name}\"): \\`router\\` must be an agent contract or a \\`{ agent, placeholders?, input? }\\` entry`,\n        { context: { authoring: true } },\n      );\n    }\n  }\n\n  if (hasRoute && hasRouter) {\n    throw new SupervisorFailedError(\n      `ai.supervisor(\"${config.name}\"): \\`route\\` and \\`router\\` are mutually exclusive — configure exactly one`,\n      { context: { authoring: true } },\n    );\n  }\n\n  // Phase 7 / decisions §37 — `classifier` is the iter-0 prelude;\n  // satisfies the \"must have a dispatch source\" rule on its own.\n  // Composes with router/route (classifier drives iter 0; router/route\n  // takes iter 1+). When configured alone, supervisor terminates after\n  // iter 0's branch settles.\n  const hasClassifier = config.classifier !== undefined;\n\n  if (!hasRoute && !hasRouter && !hasClassifier) {\n    throw new SupervisorFailedError(\n      `ai.supervisor(\"${config.name}\"): one of \\`route\\`, \\`router\\`, or \\`classifier\\` is required`,\n      { context: { authoring: true } },\n    );\n  }\n\n  // Phase 7 — classifier and initialAgent both decide what runs first.\n  // Coexistence is meaningless; throw loudly.\n  if (hasClassifier && config.initialAgent) {\n    throw new SupervisorFailedError(\n      `ai.supervisor(\"${config.name}\"): \\`classifier\\` and \\`initialAgent\\` are mutually exclusive — both decide which intent runs first. Pick one.`,\n      { context: { authoring: true } },\n    );\n  }\n\n  // Phase 3.4 (Q9) — evaluate now pairs with both `route` and\n  // `router`. State-driven termination is useful in either dispatch\n  // mode; the historical router-only restriction was incidental,\n  // not principled.\n\n  if (config.ack !== undefined) {\n    const ack = config.ack;\n    const isCallback = typeof ack === \"function\";\n    const isAgentEntry =\n      typeof ack === \"object\" &&\n      ack !== null &&\n      typeof (ack as { agent?: { execute?: unknown } }).agent?.execute === \"function\";\n    const isRunEntry =\n      typeof ack === \"object\" &&\n      ack !== null &&\n      typeof (ack as { run?: unknown }).run === \"function\";\n\n    if (!isCallback && !isAgentEntry && !isRunEntry) {\n      throw new SupervisorFailedError(\n        `ai.supervisor(\"${config.name}\"): \\`ack\\` must be an \\`{ agent, ... }\\` entry, an \\`{ run, ... }\\` entry, or a bare callback function`,\n        { context: { authoring: true } },\n      );\n    }\n\n    if (isAgentEntry && isRunEntry) {\n      throw new SupervisorFailedError(\n        `ai.supervisor(\"${config.name}\"): \\`ack\\` cannot declare both \\`agent\\` and \\`run\\` — pick one`,\n        { context: { authoring: true } },\n      );\n    }\n  }\n\n  if (config.maxIterations !== undefined && config.maxIterations < 1) {\n    throw new SupervisorFailedError(\n      `ai.supervisor(\"${config.name}\"): \\`maxIterations\\` must be >= 1`,\n      { context: { authoring: true, maxIterations: config.maxIterations } },\n    );\n  }\n\n  // Width bound on parallel dispatch (see `maxFanOut` docs). Same\n  // authoring-error shape as `maxIterations`, but integer-only — a\n  // fractional cap would silently reject legitimate widths.\n  if (\n    config.maxFanOut !== undefined &&\n    (!Number.isInteger(config.maxFanOut) || config.maxFanOut < 1)\n  ) {\n    throw new SupervisorFailedError(\n      `ai.supervisor(\"${config.name}\"): \\`maxFanOut\\` must be an integer >= 1`,\n      { context: { authoring: true, maxFanOut: config.maxFanOut } },\n    );\n  }\n}\n\nfunction generateRunId(): string {\n  return `sup_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n"],"mappings":"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"}