{"version":3,"sources":["../src/action.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { JSONSchema7 } from 'json-schema';\nimport * as z from 'zod';\nimport { getAsyncContext } from './async-context.mjs';\nimport { Channel, lazy } from './async.mjs';\nimport { getContext, runWithContext, type ActionContext } from './context.mjs';\nimport type { ActionType, Registry } from './registry.mjs';\nimport { parseSchema } from './schema.mjs';\nimport {\n  type ActionStreamInput,\n  type ActionStreamSubscriber,\n  type StreamManager,\n} from './streaming.mjs';\nimport {\n  SPAN_TYPE_ATTR,\n  runInNewSpan,\n  setCustomMetadataAttributes,\n} from './tracing.mjs';\n\nexport { StatusCodes, StatusSchema, type Status } from './statusTypes.mjs';\nexport { InMemoryStreamManager, StreamNotFoundError } from './streaming.mjs';\nexport type {\n  ActionStreamInput,\n  ActionStreamSubscriber,\n  JSONSchema7,\n  StreamManager,\n};\n\nconst makeNoopAbortSignal = () => new AbortController().signal;\n\n/**\n * Action metadata.\n */\nexport interface ActionMetadata<\n  I extends z.ZodTypeAny = z.ZodTypeAny,\n  O extends z.ZodTypeAny = z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n  /** The type of action (e.g. 'prompt', 'flow'). */\n  actionType?: ActionType;\n  /** Registry key (unique identifier). */\n  key?: string;\n  /** The name of the action. */\n  name: string;\n  /** Description of the action. */\n  description?: string;\n  /** Input Zod schema. */\n  inputSchema?: I;\n  /** Input JSON schema. */\n  inputJsonSchema?: JSONSchema7;\n  /** Output Zod schema. */\n  outputSchema?: O;\n  /** Output JSON schema. */\n  outputJsonSchema?: JSONSchema7;\n  /** Stream Zod schema. */\n  streamSchema?: S;\n  /** Schema of the initialization data. */\n  initSchema?: z.ZodTypeAny;\n  /** JSON schema of the initialization data. */\n  initJsonSchema?: JSONSchema7;\n  /** Metadata for the action. */\n  metadata?: Record<string, any>;\n}\n\n/** Zod schema for {@link ActionMetadata}. */\nexport const ActionMetadataSchema = z.object({\n  key: z.string().optional(),\n  actionType: z.string().optional(),\n  name: z.string(),\n  description: z.string().optional(),\n  inputSchema: z.unknown().optional(),\n  inputJsonSchema: z.object({}).optional(),\n  outputSchema: z.unknown().optional(),\n  outputJsonSchema: z.object({}).optional(),\n  streamSchema: z.unknown().optional(),\n  initSchema: z.unknown().optional(),\n  initJsonSchema: z.object({}).optional(),\n  metadata: z.record(z.string(), z.any()).optional(),\n});\n\n/**\n * Results of an action run. Includes telemetry.\n */\nexport interface ActionResult<O> {\n  result: O;\n  telemetry: {\n    traceId: string;\n    spanId: string;\n  };\n}\n\n/**\n * Options (side channel) data to pass to the model.\n */\nexport interface ActionRunOptions<S, Init = any> {\n  /**\n   * Streaming callback (optional).\n   */\n  onChunk?: StreamingCallback<S>;\n\n  /**\n   * Additional runtime context data (ex. auth context data).\n   */\n  context?: ActionContext;\n\n  /**\n   * Additional span attributes to apply to OT spans.\n   */\n  telemetryLabels?: Record<string, string>;\n\n  /**\n   * Abort signal for the action request.\n   */\n  abortSignal?: AbortSignal;\n\n  /**\n   * Callback that fires immediately when the root span is created for the action,\n   * providing early access to telemetry data (trace ID, span ID).\n   * This is useful for scenarios where telemetry needs to be available before the action completes.\n   * Note: This only fires once for the root action span, not for nested spans.\n   */\n  onTraceStart?: (traceInfo: { traceId: string; spanId: string }) => void;\n\n  /**\n   * Initialization data provided to the action.\n   */\n  init?: Init;\n}\n\n/**\n * Options (side channel) data to pass to the model for bi-directional actions.\n */\nexport interface BidiActionRunOptions<S, I = any, Init = any>\n  extends ActionRunOptions<S, Init> {\n  /**\n   * Streaming input (optional).\n   */\n  inputStream?: AsyncIterable<I>;\n}\n\n/**\n * Options (side channel) data to pass to the model.\n */\nexport interface ActionFnArg<S, I = any, Init = any> {\n  /**\n   * Whether the caller of the action requested streaming.\n   */\n  streamingRequested: boolean;\n\n  /**\n   * Streaming callback (optional).\n   */\n  sendChunk: StreamingCallback<S>;\n\n  /**\n   * Additional runtime context data (ex. auth context data).\n   */\n  context?: ActionContext;\n\n  /**\n   * Trace context containing trace and span IDs.\n   */\n  trace: {\n    traceId: string;\n    spanId: string;\n  };\n\n  /**\n   * Abort signal for the action request.\n   */\n  abortSignal: AbortSignal;\n\n  registry?: Registry;\n\n  /**\n   * Streaming input.\n   *\n   * The action runtime always provides this. For single-input (unary) actions\n   * it is a stream containing just the one input item.\n   */\n  inputStream: AsyncIterable<I>;\n\n  /**\n   * Initialization data provided to the action.\n   */\n  init: Init;\n}\n\n/**\n * Streaming response from an action.\n */\nexport interface StreamingResponse<\n  O extends z.ZodTypeAny = z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n  /** Iterator over the streaming chunks. */\n  stream: AsyncGenerator<z.infer<S>>;\n  /** Final output of the action. */\n  output: Promise<z.infer<O>>;\n}\n\n/**\n * Streaming response from a bi-directional action.\n */\nexport interface BidiStreamingResponse<\n  O extends z.ZodTypeAny = z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n  I extends z.ZodTypeAny = z.ZodTypeAny,\n> extends StreamingResponse<O, S> {\n  /**\n   * Sends a chunk of data to the action (for bi-directional streaming).\n   */\n  send(chunk: z.infer<I>): void;\n  /**\n   * Closes the input stream to the action.\n   */\n  close(): void;\n}\n\n/**\n * Self-describing, validating, observable, locally and remotely callable function.\n */\nexport type Action<\n  I extends z.ZodTypeAny = z.ZodTypeAny,\n  O extends z.ZodTypeAny = z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n  RunOptions extends ActionRunOptions<\n    z.infer<S>,\n    z.infer<Init>\n    // unfortunately we can't use Init generic param to type ActionRunOptions here (using any)\n    // this is somewhat mitigated in BidiAction interface, so anyone interacting with\n    // bidi actions will still get properly typed init option.\n  > = ActionRunOptions<z.infer<S>, any>,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n> = ((input?: z.infer<I>, options?: RunOptions) => Promise<z.infer<O>>) & {\n  /** @hidden */\n  __action: ActionMetadata<I, O, S>;\n  /** @hidden */\n  __registry?: Registry;\n  run(\n    input?: z.infer<I>,\n    options?: RunOptions\n  ): Promise<ActionResult<z.infer<O>>>;\n\n  stream(input?: z.infer<I>, opts?: RunOptions): StreamingResponse<O, S>;\n};\n\nexport interface BidiAction<\n  IS extends z.ZodTypeAny = z.ZodTypeAny,\n  O extends z.ZodTypeAny = z.ZodTypeAny,\n  OS extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n  RunOptions extends BidiActionRunOptions<\n    z.infer<OS>,\n    z.infer<IS>,\n    z.infer<Init>\n  > = BidiActionRunOptions<z.infer<OS>, z.infer<IS>, z.infer<Init>>,\n> extends Action<IS, O, OS, RunOptions, Init> {\n  streamBidi(\n    init?: z.infer<Init>,\n    opts?: RunOptions\n  ): BidiStreamingResponse<O, OS, IS>;\n}\n\n/**\n * Action factory params.\n */\nexport type ActionParams<\n  I extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n> = {\n  /**\n   * Name of the action, or an object with pluginId and actionId.\n   */\n  name:\n    | string\n    | {\n        pluginId: string;\n        actionId: string;\n      };\n  /**\n   * Description of the action.\n   */\n  description?: string;\n  /**\n   * Input Zod schema.\n   */\n  inputSchema?: I;\n  /**\n   * Input JSON schema.\n   */\n  inputJsonSchema?: JSONSchema7;\n  /**\n   * Output Zod schema.\n   */\n  outputSchema?: O;\n  /**\n   * Output JSON schema.\n   */\n  outputJsonSchema?: JSONSchema7;\n  /**\n   * Metadata for the action.\n   */\n  metadata?: Record<string, any>;\n  /**\n   * Middleware to apply to the action.\n   */\n  use?: Middleware<z.infer<I>, z.infer<O>, z.infer<S>>[];\n  /**\n   * Stream Zod schema.\n   */\n  streamSchema?: S;\n  /**\n   * The type of action.\n   */\n  actionType: ActionType;\n  /**\n   * Zod schema for the initialization data.\n   */\n  initSchema?: Init;\n  /**\n   * JSON schema for the initialization data.\n   */\n  initJsonSchema?: JSONSchema7;\n};\n\n/**\n * Configuration for an async action (lazy loaded).\n */\nexport type ActionAsyncParams<\n  I extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n> = ActionParams<I, O, S> & {\n  fn: (\n    input: z.infer<I>,\n    options: ActionFnArg<z.infer<S>, z.infer<I>>\n  ) => Promise<z.infer<O>>;\n};\n\n/**\n * Simple middleware that only modifies request/response.\n */\nexport type SimpleMiddleware<I = any, O = any> = (\n  req: I,\n  next: (req?: I) => Promise<O>\n) => Promise<O>;\n\n/**\n * Middleware that has access to options (including streaming callback).\n */\nexport type MiddlewareWithOptions<I = any, O = any, S = any> = (\n  req: I,\n  options: ActionRunOptions<S, I> | undefined,\n  next: (req?: I, options?: ActionRunOptions<S, I>) => Promise<O>\n) => Promise<O>;\n\n/**\n * Middleware function for actions.\n */\nexport type Middleware<I = any, O = any, S = any> =\n  | SimpleMiddleware<I, O>\n  | MiddlewareWithOptions<I, O, S>;\n\n/**\n * Creates an action with provided middleware.\n */\nexport function actionWithMiddleware<\n  I extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n  action: Action<I, O, S, any, Init>,\n  middleware: Middleware<z.infer<I>, z.infer<O>, z.infer<S>>[]\n): Action<I, O, S, any, Init> {\n  const wrapped = (async (\n    req: z.infer<I>,\n    options?: ActionRunOptions<z.infer<S>, z.infer<Init>>\n  ) => {\n    return (await wrapped.run(req, options)).result;\n  }) as Action<I, O, S, any, Init>;\n  wrapped.__action = action.__action;\n  wrapped.run = async (\n    req: z.infer<I>,\n    options?: ActionRunOptions<z.infer<S>, z.infer<Init>>\n  ): Promise<ActionResult<z.infer<O>>> => {\n    let telemetry;\n    const dispatch = async (\n      index: number,\n      req: z.infer<I>,\n      opts?: ActionRunOptions<z.infer<S>, z.infer<Init>>\n    ) => {\n      if (index === middleware.length) {\n        // end of the chain, call the original model action\n        const result = await action.run(req, opts);\n        telemetry = result.telemetry;\n        return result.result;\n      }\n\n      const currentMiddleware = middleware[index];\n      if (currentMiddleware.length === 3) {\n        return (currentMiddleware as MiddlewareWithOptions<I, O, z.infer<S>>)(\n          req,\n          opts,\n          async (modifiedReq, modifiedOptions) =>\n            dispatch(index + 1, modifiedReq || req, modifiedOptions || opts)\n        );\n      } else if (currentMiddleware.length === 2) {\n        return (currentMiddleware as SimpleMiddleware<I, O>)(\n          req,\n          async (modifiedReq) => dispatch(index + 1, modifiedReq || req, opts)\n        );\n      } else {\n        throw new Error('unspported middleware function shape');\n      }\n    };\n    wrapped.stream = action.stream;\n    if ((action as any as BidiAction).streamBidi) {\n      (wrapped as BidiAction<I, O, S, Init>).streamBidi = (\n        action as BidiAction<I, O, S, Init>\n      ).streamBidi;\n    }\n\n    return { result: await dispatch(0, req, options), telemetry };\n  };\n  return wrapped;\n}\n\n/**\n * Creates an action with the provided config.\n */\nexport function action<\n  I extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n  config: ActionParams<I, O, S, Init>,\n  fn: (\n    input: z.infer<I>,\n    options: ActionFnArg<z.infer<S>, z.infer<Init>>\n  ) => Promise<z.infer<O>>\n): Action<I, O, z.infer<S>, any, Init> {\n  const actionName =\n    typeof config.name === 'string'\n      ? config.name\n      : `${config.name.pluginId}/${config.name.actionId}`;\n  const actionMetadata = {\n    key: `/${config.actionType}/${actionName}`,\n    name: actionName,\n    description: config.description,\n    inputSchema: config.inputSchema,\n    inputJsonSchema: config.inputJsonSchema,\n    outputSchema: config.outputSchema,\n    outputJsonSchema: config.outputJsonSchema,\n    streamSchema: config.streamSchema,\n    initSchema: config.initSchema,\n    initJsonSchema: config.initJsonSchema,\n    metadata: config.metadata,\n    actionType: config.actionType,\n  } as ActionMetadata<I, O, S>;\n\n  const actionFn = (async (\n    input?: I,\n    options?: ActionRunOptions<z.infer<S>, z.infer<Init>>\n  ) => {\n    return (await actionFn.run(input, options)).result;\n  }) as Action<I, O, z.infer<S>, any, Init>;\n  actionFn.__action = { ...actionMetadata };\n\n  actionFn.run = async (\n    input: z.infer<I>,\n    options?: ActionRunOptions<z.infer<S>, z.infer<Init>> & {\n      inputStream?: AsyncIterable<z.infer<I>>;\n    }\n  ): Promise<ActionResult<z.infer<O>>> => {\n    if (config.inputSchema || config.inputJsonSchema) {\n      if (!options?.inputStream) {\n        input = parseSchema(input, {\n          schema: config.inputSchema,\n          jsonSchema: config.inputJsonSchema,\n        });\n      } else {\n        const inputStream = options.inputStream;\n        options = {\n          ...options,\n          inputStream: (async function* () {\n            for await (const item of inputStream) {\n              yield parseSchema(item, {\n                schema: config.inputSchema,\n                jsonSchema: config.inputJsonSchema,\n              });\n            }\n          })(),\n        };\n      }\n    }\n\n    if (config.initSchema || config.initJsonSchema) {\n      const validatedInit = parseSchema(options?.init, {\n        schema: config.initSchema,\n        jsonSchema: config.initJsonSchema,\n      });\n      options = { ...options, init: validatedInit };\n    }\n\n    let traceId;\n    let spanId;\n    const genkitKey = actionFn.__action.key;\n    let output = await runInNewSpan(\n      {\n        metadata: {\n          name: actionName,\n        },\n        labels: {\n          [SPAN_TYPE_ATTR]: 'action',\n          'genkit:metadata:subtype': config.actionType,\n          ...(genkitKey ? { 'genkit:key': genkitKey } : {}),\n          ...options?.telemetryLabels,\n        },\n      },\n      async (metadata, span) => {\n        setCustomMetadataAttributes({\n          subtype: config.actionType,\n        });\n        if (options?.context) {\n          setCustomMetadataAttributes({\n            context: JSON.stringify(options.context),\n          });\n        }\n\n        traceId = span.spanContext().traceId;\n        spanId = span.spanContext().spanId;\n        if (options?.onTraceStart) {\n          options.onTraceStart({ traceId, spanId });\n        }\n        metadata.name = actionName;\n        metadata.input = input;\n        if (options?.init !== undefined) {\n          // Store `init` raw (like `input`) so it is serialized consistently by\n          // the tracing layer. Pre-stringifying here would diverge from `input`\n          // and could throw on non-serializable values, failing the whole run.\n          metadata.init = options.init;\n        }\n\n        try {\n          const actFn = () =>\n            fn(input, {\n              ...options,\n              // Context can either be explicitly set, or inherited from the parent action.\n              context: {\n                ...actionFn.__registry?.context,\n                ...(options?.context ?? getContext()),\n              },\n              streamingRequested:\n                !!options?.onChunk &&\n                options.onChunk !== sentinelNoopStreamingCallback,\n              sendChunk: options?.onChunk ?? sentinelNoopStreamingCallback,\n              inputStream:\n                options?.inputStream ?? asyncIterableFromArray([input]),\n              trace: {\n                traceId,\n                spanId,\n              },\n              registry: actionFn.__registry,\n              abortSignal: options?.abortSignal ?? makeNoopAbortSignal(),\n            } as ActionFnArg<z.infer<S>, z.infer<I>, z.infer<Init>>);\n          // if context is explicitly passed in, we run action with the provided context,\n          // otherwise we let upstream context carry through.\n          const output = await runWithContext(options?.context, actFn);\n\n          metadata.output = JSON.stringify(output);\n          return output;\n        } catch (err) {\n          if (typeof err === 'object') {\n            (err as any).traceId = traceId;\n          }\n          throw err;\n        }\n      }\n    );\n    output = parseSchema(output, {\n      schema: config.outputSchema,\n      jsonSchema: config.outputJsonSchema,\n    });\n    return {\n      result: output,\n      telemetry: {\n        traceId,\n        spanId,\n      },\n    };\n  };\n\n  actionFn.stream = (\n    input?: z.infer<I>,\n    opts?: ActionRunOptions<z.infer<S>, z.infer<Init>> & {\n      inputStream?: AsyncIterable<z.infer<I>>;\n    }\n  ): StreamingResponse<O, S> => {\n    let chunkStreamController: ReadableStreamController<z.infer<S>>;\n    const chunkStream = new ReadableStream<z.infer<S>>({\n      start(controller) {\n        chunkStreamController = controller;\n      },\n      pull() {},\n      cancel() {},\n    });\n\n    const invocationPromise = actionFn\n      .run(\n        !opts?.inputStream && config.inputSchema\n          ? config.inputSchema.parse(input)\n          : input,\n        {\n          onChunk: ((chunk: z.infer<S>) => {\n            chunkStreamController.enqueue(chunk);\n          }) as S extends z.ZodVoid ? undefined : StreamingCallback<z.infer<S>>,\n          context: {\n            ...actionFn.__registry?.context,\n            ...(opts?.context ?? getContext()),\n          },\n          inputStream: opts?.inputStream,\n          abortSignal: opts?.abortSignal,\n          telemetryLabels: opts?.telemetryLabels,\n          init: opts?.init,\n        }\n      )\n      .then((s) => s.result)\n      .finally(() => {\n        try {\n          chunkStreamController.close();\n        } catch (e) {\n          // Ignore if already closed or cancelled\n        }\n      });\n\n    return {\n      output: invocationPromise,\n      stream: (async function* () {\n        const reader = chunkStream.getReader();\n        try {\n          while (true) {\n            const chunk = await reader.read();\n            if (chunk.value) {\n              yield chunk.value;\n            }\n            if (chunk.done) {\n              break;\n            }\n          }\n          return await invocationPromise;\n        } finally {\n          // Catch prevents unhandled promise rejection if the stream was already cleanly finalized\n          reader.cancel().catch(() => {});\n        }\n      })(),\n    };\n  };\n\n  if (config.use) {\n    return actionWithMiddleware(actionFn, config.use);\n  }\n  return actionFn;\n}\n\nexport function isAction(a: unknown): a is Action {\n  return typeof a === 'function' && '__action' in a;\n}\n\n/**\n * Defines an action with the given config and registers it in the registry.\n */\nexport function defineAction<\n  I extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n  registry: Registry,\n  config: ActionParams<I, O, S, Init>,\n  fn: (\n    input: z.infer<I>,\n    options: ActionFnArg<z.infer<S>, z.infer<I>, z.infer<Init>>\n  ) => Promise<z.infer<O>>\n): Action<I, O, S, ActionRunOptions<z.infer<S>, z.infer<I>>, Init> {\n  if (isInRuntimeContext()) {\n    throw new Error(\n      'Cannot define new actions at runtime.\\n' +\n        'See: https://github.com/genkit-ai/genkit/blob/main/docs/errors/no_new_actions_at_runtime.md'\n    );\n  }\n  const act = action(config, async (i: I, options): Promise<z.infer<O>> => {\n    await registry.initializeAllPlugins();\n    return await runInActionRuntimeContext(() => fn(i, options));\n  });\n  act.__action.actionType = config.actionType;\n  registry.registerAction(config.actionType, act);\n  return act;\n}\n\n/**\n * Defines a bi-directional action with the given config and registers it in the registry.\n */\nexport function defineBidiAction<\n  IS extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  OS extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n  registry: Registry,\n  config: ActionParams<IS, O, OS, Init>,\n  fn: (\n    input: ActionFnArg<z.infer<OS>, z.infer<IS>, z.infer<Init>>\n  ) => AsyncGenerator<z.infer<OS>, z.infer<O>, void>\n): BidiAction<IS, O, OS, Init> {\n  const act = bidiAction(config, (input) => {\n    return (async function* () {\n      await registry.initializeAllPlugins();\n      return yield* fn(input);\n    })();\n  });\n  registry.registerAction(config.actionType, act);\n  return act;\n}\n\n/**\n * Creates a bi-directional action with the given config.\n */\nexport function bidiAction<\n  IS extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  OS extends z.ZodTypeAny = z.ZodTypeAny,\n  Init extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n  config: ActionParams<IS, O, OS, Init>,\n  fn: (\n    input: ActionFnArg<z.infer<OS>, z.infer<IS>, z.infer<Init>>\n  ) => AsyncGenerator<z.infer<OS>, z.infer<O>, void>\n): BidiAction<IS, O, OS, Init> {\n  const meta = { ...config.metadata, bidi: true };\n  const act = action({ ...config, metadata: meta }, async (input, options) => {\n    const stream = options.inputStream;\n\n    const outputGen = fn({\n      ...options,\n      inputStream: stream,\n    } as ActionFnArg<z.infer<OS>, z.infer<IS>, z.infer<Init>>);\n\n    const iter = outputGen[Symbol.asyncIterator]();\n    let result: z.infer<O>;\n    try {\n      while (true) {\n        const { value, done } = await iter.next();\n        if (done) {\n          result = value;\n          break;\n        }\n        options.sendChunk(value);\n      }\n    } finally {\n      if (iter.return) {\n        await iter.return(undefined as any);\n      }\n    }\n    return result;\n  }) as unknown as BidiAction<IS, O, OS, Init>;\n\n  act.streamBidi = (init, opts) => {\n    let channel: Channel<z.infer<IS>> | undefined;\n    let stream = opts?.inputStream;\n    if (!stream) {\n      channel = new Channel<z.infer<IS>>();\n      stream = channel;\n    }\n\n    const result = act.stream(undefined, {\n      ...opts,\n      init: init,\n      inputStream: stream,\n    });\n\n    return {\n      ...result,\n      stream: (async function* () {\n        try {\n          for await (const chunk of result.stream) {\n            yield chunk;\n          }\n        } finally {\n          if (channel) {\n            channel.close();\n          }\n        }\n      })(),\n      send: (chunk) => {\n        if (!channel) {\n          throw new Error('Cannot send to a provided stream.');\n        }\n        channel.send(chunk);\n      },\n      close: () => {\n        if (!channel) {\n          throw new Error('Cannot close a provided stream.');\n        }\n        channel.close();\n      },\n    };\n  };\n\n  return act;\n}\n\n/**\n * Defines an action with the given config promise and registers it in the registry.\n */\nexport function defineActionAsync<\n  I extends z.ZodTypeAny,\n  O extends z.ZodTypeAny,\n  S extends z.ZodTypeAny = z.ZodTypeAny,\n>(\n  registry: Registry,\n  actionType: ActionType,\n  name:\n    | string\n    | {\n        pluginId: string;\n        actionId: string;\n      },\n  config: PromiseLike<ActionAsyncParams<I, O, S>>,\n  onInit?: (action: Action<I, O, S>) => void\n): PromiseLike<Action<I, O, S>> {\n  const actionName =\n    typeof name === 'string' ? name : `${name.pluginId}/${name.actionId}`;\n  const actionPromise = lazy(() =>\n    config.then((resolvedConfig) => {\n      const act = action(\n        resolvedConfig,\n        async (i: I, options): Promise<z.infer<O>> => {\n          await registry.initializeAllPlugins();\n          return await runInActionRuntimeContext(() =>\n            resolvedConfig.fn(i, options)\n          );\n        }\n      );\n      act.__action.actionType = actionType;\n      act.__action.key = `/${actionType}/${actionName}`;\n      onInit?.(act);\n      return act;\n    })\n  );\n  registry.registerActionAsync(actionType, actionName, actionPromise);\n  return actionPromise;\n}\n\n/** Callback function invoked with each streaming chunk during action execution. */\nexport type StreamingCallback<T> = (chunk: T) => void;\n\nconst streamingAlsKey = 'core.action.streamingCallback';\nexport const sentinelNoopStreamingCallback = () => null;\n\n/**\n * Executes provided function with streaming callback in async local storage which can be retrieved\n * using {@link getStreamingCallback}.\n */\nexport function runWithStreamingCallback<S, O>(\n  streamingCallback: StreamingCallback<S> | undefined,\n  fn: () => O\n): O {\n  return getAsyncContext().run(\n    streamingAlsKey,\n    streamingCallback || sentinelNoopStreamingCallback,\n    fn\n  );\n}\n\n/**\n * Retrieves the {@link StreamingCallback} previously set by {@link runWithStreamingCallback}\n *\n * @hidden\n */\nexport function getStreamingCallback<S>(): StreamingCallback<S> | undefined {\n  const cb = getAsyncContext().getStore<StreamingCallback<S>>(streamingAlsKey);\n  if (cb === sentinelNoopStreamingCallback) {\n    return undefined;\n  }\n  return cb;\n}\n\nconst runtimeContextAslKey = 'core.action.runtimeContext';\n\n/**\n * Checks whether the caller is currently in the runtime context of an action.\n */\nexport function isInRuntimeContext() {\n  return getAsyncContext().getStore(runtimeContextAslKey) === 'runtime';\n}\n\n/**\n * Execute the provided function in the action runtime context.\n */\nexport function runInActionRuntimeContext<R>(fn: () => R) {\n  return getAsyncContext().run(runtimeContextAslKey, 'runtime', fn);\n}\n\n/**\n * Execute the provided function outside the action runtime context.\n */\nexport function runOutsideActionRuntimeContext<R>(fn: () => R) {\n  return getAsyncContext().run(runtimeContextAslKey, 'outside', fn);\n}\n\nasync function* asyncIterableFromArray<T>(array: T[]): AsyncIterable<T> {\n  for (const item of array) {\n    yield item;\n  }\n}\n"],"mappings":"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","names":["action","req","output"]}