/**
 * types.ts
 *
 * Data structures for capturing AI agent behavior during evaluation.
 *
 * When an AI agent runs a task (e.g., "implement a Sanity studio schema"),
 * it may browse documentation, search for APIs, download code samples, etc.
 * These types describe the observed network activity so we can answer:
 *
 *   - What URLs did the agent visit?
 *   - What content did it actually download?
 *   - Did it search sanity.io/docs? What queries?
 *   - How long did it spend fetching vs generating?
 *   - Did it find the *right* documentation pages?
 */
export interface AgentBehaviorLog {
    /** Sanity API calls (non-docs) */
    apiCalls: ApiCall[];
    /** Sanity doc pages the agent visited */
    docPageVisits: DocPageVisit[];
    /** ISO 8601 timestamp when observation ended */
    endedAt: string;
    /** Requests to non-Sanity domains */
    externalRequests: ExternalRequest[];
    /** Time spent waiting on network requests, in ms */
    networkDurationMs: number;
    /** Provider that was observed (e.g., "openai:gpt-4o") */
    provider: string;
    /** Every HTTP request/response observed, in order */
    requests: ObservedRequest[];
    /** Search queries the agent performed */
    searchQueries: SearchQuery[];
    /** Unique identifier for this observation session */
    sessionId: string;
    /** ISO 8601 timestamp when observation started */
    startedAt: string;
    summary: AgentBehaviorSummary;
    /** Task description from the test case */
    taskDescription: string;
    /** Total wall-clock time for the test, in ms */
    totalDurationMs: number;
}
/** Roll-up stats for quick analysis */
export interface AgentBehaviorSummary {
    /** Number of Sanity API calls */
    apiCallCount: number;
    /** Number of sanity.io doc pages visited */
    docPagesVisited: number;
    /** List of unique sanity.io doc slugs visited */
    docSlugsVisited: string[];
    /** List of unique external domains contacted */
    externalDomains: string[];
    /** Number of external (non-Sanity) requests */
    externalRequestCount: number;
    /** Number of search queries performed */
    searchesPerformed: number;
    /** Total bytes downloaded */
    totalBytesDownloaded: number;
    /** Total network time in ms */
    totalNetworkMs: number;
    /** Total number of HTTP requests observed */
    totalRequests: number;
    /** List of unique search queries */
    uniqueSearchQueries: string[];
    /** Number of unique URLs visited */
    uniqueUrls: number;
    /** Whether the agent visited any sanity.io docs at all */
    usedDocs: boolean;
    /** Whether the agent performed any searches */
    usedSearch: boolean;
}
/** An API call to Sanity's API (not docs) */
export interface ApiCall {
    /** API endpoint path */
    endpoint: string;
    /** HTTP method */
    method: string;
    /** Timestamp */
    timestamp: string;
    /** Full URL */
    url: string;
}
/** A page the agent visited on sanity.io/docs */
export interface DocPageVisit {
    /** Response size in bytes */
    contentSize: number;
    /** Slug extracted from the URL, e.g., "groq-introduction" */
    slug: string;
    /** Timestamp of the visit */
    timestamp: string;
    /** Page title if extractable from response */
    title?: string;
    url: string;
}
/** A request to a non-Sanity URL */
export interface ExternalRequest {
    /** Domain extracted from URL */
    domain: string;
    method: string;
    timestamp: string;
    url: string;
}
export interface ObservedRequest {
    /** Request body (for POST searches, etc.), truncated to maxBodyBytes.
     *  Always omitted for `capture: "status-only"` entries. */
    body?: string;
    /**
     * Capture mode discriminator (W0132).
     *
     * - `"full"` — URL matched `includePatterns`; body, headers, contentType,
     *   responseSize, and responsePreview are all captured.
     * - `"status-only"` — URL did not match `includePatterns` but
     *   `statusOnlyForUnmatched` is true. Only url/method/statusCode/
     *   latencyMs/timestamp/seq are recorded; body/headers/contentType/
     *   responsePreview are intentionally omitted to avoid capturing
     *   prompts, completions, or API keys for third-party endpoints.
     *
     * Defaults to `"full"` on legacy records that pre-date W0132.
     */
    capture?: "full" | "status-only";
    /** Content-Type of the response. Always omitted for status-only entries. */
    contentType?: string;
    /** Relevant request headers (e.g., Accept, User-Agent).
     *  Always empty for status-only entries (no header capture at all). */
    headers: Record<string, string>;
    /** Time from request start to response complete, in ms */
    latencyMs: number;
    /** HTTP method */
    method: string;
    /** Response body preview (first N chars), useful for seeing what the agent
     *  actually read. Always omitted for status-only entries. */
    responsePreview?: string;
    /** Response body size in bytes. 0 for status-only entries (we never read
     *  the body). */
    responseSize: number;
    /** Monotonic sequence number within the test run */
    seq: number;
    /** HTTP status code of the response */
    statusCode: number;
    /** ISO 8601 timestamp when the request was initiated */
    timestamp: string;
    /** Full URL requested */
    url: string;
}
/** A search query the agent performed */
export interface SearchQuery {
    /** Extracted query string */
    query: string;
    /** Number of results returned (if detectable) */
    resultCount?: number;
    /** Timestamp */
    timestamp: string;
    /** The search endpoint URL */
    url: string;
}
