{"version":3,"file":"agent-stream.mjs","names":[],"sources":["../../../../../../../ai/src/agent/agent-stream.ts"],"sourcesContent":["import type { StreamContract, StreamEvent } from \"../contracts\";\n\n/**\n * Internal async-queue `StreamContract` used by `agent().stream()`.\n *\n * **Role.** The bridge between a streaming `Execution` (which runs in the\n * background, pushing events as they happen) and a consumer that reads\n * those events with `for await` or an `on(...)` handler map.\n *\n * **Responsibility.**\n * - Owns: the event queue, the pending-read promise chain, the terminal\n *   `result` promise, and any user-registered event handlers.\n * - Does NOT own: any knowledge of agents, models, or tool calls — it is a\n *   generic producer/consumer pipe parameterized by `TResult`. The streaming\n *   execution writes via `push()` / `end()` / `fail()`; the consumer reads\n *   via the AsyncIterable surface.\n *\n * Events are coalesced into a queue so that a consumer that starts\n * iterating late still sees every event in order — nothing is dropped. The\n * `on()` handlers fire the moment an event is pushed, independent of\n * whether anyone is iterating.\n *\n * @example\n * // Inside agent.stream():\n * const { controller, stream } = createAgentStream<AgentResult<TOutput>>();\n * new Execution(config, input, options, controller).run();\n * return stream;\n *\n * // Consumer:\n * for await (const event of stream) {\n *   if (event.type === \"streaming\") process.stdout.write(event.delta);\n * }\n * const result = await stream.result;\n */\nexport type StreamController<TResult> = {\n  push(event: StreamEvent): void;\n  end(result: TResult): void;\n  fail(error: Error): void;\n};\n\ntype PendingRead = {\n  resolve(value: IteratorResult<StreamEvent>): void;\n  reject(error: Error): void;\n};\n\nexport function createAgentStream<TResult>(): {\n  controller: StreamController<TResult>;\n  stream: StreamContract<TResult>;\n} {\n  const queue: StreamEvent[] = [];\n  const pending: PendingRead[] = [];\n  const handlers = new Map<StreamEvent[\"type\"], (event: StreamEvent) => void>();\n\n  let closed = false;\n  let failure: Error | undefined;\n  let resolveResult!: (value: TResult) => void;\n  let rejectResult!: (error: Error) => void;\n\n  const result = new Promise<TResult>((resolve, reject) => {\n    resolveResult = resolve;\n    rejectResult = reject;\n  });\n\n  const controller: StreamController<TResult> = {\n    push(event) {\n      const handler = handlers.get(event.type);\n\n      if (handler) {\n        try {\n          handler(event);\n        } catch {\n          // User-provided stream handlers must never crash the agent.\n          // Swallow — structured logging attaches here in Phase 0.5.\n        }\n      }\n\n      const reader = pending.shift();\n\n      if (reader) {\n        reader.resolve({ value: event, done: false });\n        return;\n      }\n\n      queue.push(event);\n    },\n\n    end(finalResult) {\n      closed = true;\n      resolveResult(finalResult);\n\n      while (pending.length > 0) {\n        const reader = pending.shift();\n\n        reader?.resolve({ value: undefined, done: true });\n      }\n    },\n\n    fail(error) {\n      closed = true;\n      failure = error;\n      rejectResult(error);\n\n      while (pending.length > 0) {\n        const reader = pending.shift();\n\n        reader?.reject(error);\n      }\n    },\n  };\n\n  const iterator: AsyncIterator<StreamEvent> = {\n    next() {\n      if (queue.length > 0) {\n        return Promise.resolve({ value: queue.shift()!, done: false });\n      }\n\n      if (closed) {\n        if (failure) {\n          return Promise.reject(failure);\n        }\n\n        return Promise.resolve({ value: undefined, done: true });\n      }\n\n      return new Promise<IteratorResult<StreamEvent>>((resolve, reject) => {\n        pending.push({ resolve, reject });\n      });\n    },\n  };\n\n  const stream: StreamContract<TResult> = {\n    result,\n    on(handlerMap) {\n      for (const [key, handler] of Object.entries(handlerMap)) {\n        if (handler) {\n          handlers.set(\n            key as StreamEvent[\"type\"],\n            handler as (event: StreamEvent) => void,\n          );\n        }\n      }\n\n      return stream;\n    },\n    [Symbol.asyncIterator]() {\n      return iterator;\n    },\n  };\n\n  return { controller, stream };\n}\n"],"mappings":";AA6CA,SAAgB,oBAGd;CACA,MAAM,QAAuB,CAAC;CAC9B,MAAM,UAAyB,CAAC;CAChC,MAAM,2BAAW,IAAI,IAAuD;CAE5E,IAAI,SAAS;CACb,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,SAAS,IAAI,SAAkB,SAAS,WAAW;EACvD,gBAAgB;EAChB,eAAe;CACjB,CAAC;CAED,MAAM,aAAwC;EAC5C,KAAK,OAAO;GACV,MAAM,UAAU,SAAS,IAAI,MAAM,IAAI;GAEvC,IAAI,SACF,IAAI;IACF,QAAQ,KAAK;GACf,QAAQ,CAGR;GAGF,MAAM,SAAS,QAAQ,MAAM;GAE7B,IAAI,QAAQ;IACV,OAAO,QAAQ;KAAE,OAAO;KAAO,MAAM;IAAM,CAAC;IAC5C;GACF;GAEA,MAAM,KAAK,KAAK;EAClB;EAEA,IAAI,aAAa;GACf,SAAS;GACT,cAAc,WAAW;GAEzB,OAAO,QAAQ,SAAS,GAGtB,AAFe,QAAQ,MAElB,CAAC,EAAE,QAAQ;IAAE,OAAO;IAAW,MAAM;GAAK,CAAC;EAEpD;EAEA,KAAK,OAAO;GACV,SAAS;GACT,UAAU;GACV,aAAa,KAAK;GAElB,OAAO,QAAQ,SAAS,GAGtB,AAFe,QAAQ,MAElB,CAAC,EAAE,OAAO,KAAK;EAExB;CACF;CAEA,MAAM,WAAuC,EAC3C,OAAO;EACL,IAAI,MAAM,SAAS,GACjB,OAAO,QAAQ,QAAQ;GAAE,OAAO,MAAM,MAAM;GAAI,MAAM;EAAM,CAAC;EAG/D,IAAI,QAAQ;GACV,IAAI,SACF,OAAO,QAAQ,OAAO,OAAO;GAG/B,OAAO,QAAQ,QAAQ;IAAE,OAAO;IAAW,MAAM;GAAK,CAAC;EACzD;EAEA,OAAO,IAAI,SAAsC,SAAS,WAAW;GACnE,QAAQ,KAAK;IAAE;IAAS;GAAO,CAAC;EAClC,CAAC;CACH,EACF;CAEA,MAAM,SAAkC;EACtC;EACA,GAAG,YAAY;GACb,KAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,UAAU,GACpD,IAAI,SACF,SAAS,IACP,KACA,OACF;GAIJ,OAAO;EACT;EACA,CAAC,OAAO,iBAAiB;GACvB,OAAO;EACT;CACF;CAEA,OAAO;EAAE;EAAY;CAAO;AAC9B"}