/**
 * @sanity/ailf-core — External provider response schemas
 *
 * Zod schemas for HTTP responses from third-party AI providers and search
 * APIs that the agent-observer providers parse. Replaces inline `as`
 * casts on `await response.json()` with parse-don't-validate boundaries.
 *
 * Schemas are intentionally permissive on optional fields (real APIs add
 * fields over time) but strict on shape — a malformed payload surfaces
 * as a clear ZodError at the call site instead of a cryptic
 * `Cannot read properties of undefined` later.
 *
 * @see docs/design-docs/parse-dont-validate.md
 * @see docs/work-items/W0004.json
 */
import { z } from "zod";
// ---------------------------------------------------------------------------
// OpenAI Chat Completions response
//
// Covers both the minimal shape used by the InstrumentedObserverProvider
// (`provider.ts`) and the richer tool-calling shape used by
// `AgenticObserverProvider` (`agentic-provider.ts`).
// ---------------------------------------------------------------------------
const OpenAIToolCallSchema = z.object({
    function: z.object({
        arguments: z.string(),
        name: z.string(),
    }),
    id: z.string(),
    type: z.literal("function"),
});
const OpenAIChatMessageSchema = z.object({
    content: z.union([z.string(), z.null()]),
    role: z.enum(["assistant", "system", "tool", "user"]),
    tool_call_id: z.string().optional(),
    tool_calls: z.array(OpenAIToolCallSchema).optional(),
});
const OpenAIUsageSchema = z.object({
    completion_tokens: z.number().optional(),
    prompt_tokens: z.number().optional(),
    total_tokens: z.number().optional(),
});
const OpenAIErrorSchema = z.object({
    message: z.string().optional(),
});
export const OpenAIChatResponseSchema = z.object({
    choices: z
        .array(z.object({
        finish_reason: z.string().optional(),
        message: OpenAIChatMessageSchema.optional(),
    }))
        .optional(),
    error: OpenAIErrorSchema.optional(),
    usage: OpenAIUsageSchema.optional(),
});
// ---------------------------------------------------------------------------
// OpenAI Responses API response (reasoning models)
// ---------------------------------------------------------------------------
const OpenAIResponsesUsageSchema = z.object({
    input_tokens: z.number().optional(),
    output_tokens: z.number().optional(),
    total_tokens: z.number().optional(),
});
const OpenAIResponsesContentSchema = z.object({
    text: z.string().optional(),
    type: z.string().optional(),
});
const OpenAIResponsesOutputItemSchema = z.object({
    content: z.array(OpenAIResponsesContentSchema).optional(),
    role: z.string().optional(),
    type: z.string().optional(),
});
export const OpenAIResponsesResponseSchema = z.object({
    error: OpenAIErrorSchema.optional(),
    output: z.array(OpenAIResponsesOutputItemSchema).optional(),
    usage: OpenAIResponsesUsageSchema.optional(),
});
// ---------------------------------------------------------------------------
// Anthropic Messages API response
// ---------------------------------------------------------------------------
const AnthropicTextBlockSchema = z.object({
    text: z.string(),
    type: z.literal("text"),
});
const AnthropicToolUseBlockSchema = z.object({
    id: z.string(),
    input: z.record(z.string(), z.unknown()),
    name: z.string(),
    type: z.literal("tool_use"),
});
const AnthropicContentBlockSchema = z.discriminatedUnion("type", [
    AnthropicTextBlockSchema,
    AnthropicToolUseBlockSchema,
]);
const AnthropicUsageSchema = z.object({
    input_tokens: z.number().optional(),
    output_tokens: z.number().optional(),
});
const AnthropicErrorSchema = z.object({
    message: z.string().optional(),
    type: z.string().optional(),
});
export const AnthropicResponseSchema = z.object({
    content: z.array(AnthropicContentBlockSchema).optional(),
    error: AnthropicErrorSchema.optional(),
    model: z.string().optional(),
    stop_reason: z.enum(["end_turn", "max_tokens", "tool_use"]).optional(),
    usage: AnthropicUsageSchema.optional(),
});
// ---------------------------------------------------------------------------
// Google Custom Search API response
// ---------------------------------------------------------------------------
export const GoogleSearchResponseSchema = z.object({
    items: z
        .array(z.object({
        link: z.string(),
        snippet: z.string(),
        title: z.string(),
    }))
        .optional(),
});
// ---------------------------------------------------------------------------
// Agent tool-call arguments
//
// The model emits these as JSON strings via tool-calling; we parse them
// before dispatching. Per-tool schemas keep the contract explicit.
// ---------------------------------------------------------------------------
export const FetchPageToolArgsSchema = z.object({
    url: z.string(),
});
export const ListDocsToolArgsSchema = z.object({
    site: z.string(),
});
export const WebSearchToolArgsSchema = z.object({
    query: z.string(),
});
