///
import * as Data from "effect/Data";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import type { LanguageModel } from "effect/unstable/ai/LanguageModel";
import * as Binding from "../../Binding.ts";
import type { RuntimeContext } from "../../RuntimeContext.ts";
import type { Gateway as GatewayResource } from "./Gateway.ts";
import { type LanguageModelOptions } from "./LanguageModel.ts";
/**
* Binding service that turns a {@link Gateway} resource
* into a typed {@link QueryGatewayClient} for Worker runtime code. Wraps
* the Cloudflare.AI. Gateway runtime binding so each operation returns
* an Effect tagged with {@link GatewayError}, exposes the raw
* Workers AI handle for `ai.run(...)`, and provides a `model(options)`
* factory that produces an `effect/unstable/ai` `LanguageModel`
* `Layer`.
*
* Bind a {@link Gateway} to a Worker and obtain the
* Effect-native AI Gateway client (`run`, `getUrl`, `model`, …).
*
* `QueryGateway` is a single identifier that is simultaneously the binding's
* Context tag, its type, and the callable —
* `yield* Cloudflare.AI.QueryGateway(gateway)`.
*
*
* ### Calling AI Gateway
* **Example:** Run through a gateway
* Bind the gateway during the Worker's init phase, then use `run` or
* `getUrl` from request handlers.
* ```typescript
* const aiGateway = yield* Cloudflare.AI.QueryGateway(gateway);
*
* return {
* fetch: Effect.gen(function* () {
* return yield* aiGateway.run({
* provider: "workers-ai",
* endpoint: "@cf/meta/llama-3.1-8b-instruct",
* headers: { "content-type": "application/json" },
* query: { prompt: "Write a concise status update" },
* });
* }),
* };
* ```
*
* ### Driving Effect AI through the gateway
* **Example:** `aiGateway.model(...)` -> Effect AI `LanguageModel`
* `model(options)` produces a `Layer` that translates `LanguageModel.generateText` /
* `streamText` calls (including tool calls and structured outputs)
* into `ai.run(...)` against the bound Workers AI model, routed
* through the gateway.
* ```typescript
* const aiGateway = yield* Cloudflare.AI.QueryGateway(gateway);
*
* const languageModel = aiGateway.model({
* model: "@cf/meta/llama-3.1-8b-instruct",
* parameters: { temperature: 0.7, maxTokens: 1024 },
* });
*
* const response = yield* LanguageModel.generateText({ prompt }).pipe(
* Effect.provide(languageModel),
* );
* ```
*
* Provide {@link QueryGatewayBinding} in the worker's runtime layer
* to resolve the underlying Cloudflare.AI. binding at request time.
*
* @binding
* @product AI Gateway
* @category AI
*/
export interface QueryGateway extends Binding.Service<
QueryGateway,
"Cloudflare.AI.QueryGateway",
(gateway: GatewayResource) => Effect.Effect
> {}
export const QueryGateway = Binding.Service(
"Cloudflare.AI.QueryGateway",
);
// Error raised by AI Gateway runtime operations.
export class GatewayError extends Data.TaggedError("AiGatewayError")<{
/**
* Human-readable runtime error message.
*/
message: string;
/**
* Original error thrown by the Cloudflare runtime binding.
*/
cause: unknown;
}> {}
/**
* Effect-native client for a Cloudflare.AI. Gateway Worker binding.
*
* Wraps the runtime {@link Gateway} binding so each operation returns an
* Effect tagged with {@link GatewayError}. Use
* `Cloudflare.AI.QueryGateway(gateway)` inside a Worker's init phase.
*/
export interface QueryGatewayClient {
/**
* Effect resolving to the raw Workers AI binding.
*/
raw: Effect.Effect;
/**
* Effect resolving to the raw AI Gateway runtime binding.
*/
gateway: Effect.Effect;
/**
* Effect resolving to the gateway id (the resource attribute, captured at
* bind time). Useful when calling `ai.run(model, inputs, { gateway: { id } })`
* — the in-account path for first-party services like Workers AI.
*/
id: Effect.Effect;
/**
* Update metadata on an existing AI Gateway log entry.
*/
patchLog(
logId: string,
data: Parameters[1],
): Effect.Effect;
/**
* Read an AI Gateway log entry by ID.
*/
getLog(
logId: string,
): Effect.Effect;
/**
* Build a provider URL routed through this gateway.
*/
getUrl(
provider?: Parameters[0],
): Effect.Effect;
/**
* Run an AI Gateway request through the Cloudflare runtime binding.
*/
run(
data: Parameters[0],
options?: Parameters[1],
): Effect.Effect;
model(
options: Omit,
): Layer.Layer;
}