import {z} from 'zod' export type GetApiApiV1AiAgentsAdminReviewSignalsOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const aiAgentSemanticTargetRef = z.union([z.object({modelName: z.string(), type: z.literal("model")}), z.object({exploreName: z.string(), modelName: z.string(), type: z.literal("explore")}), z.object({exploreName: z.string().optional(), joinName: z.string(), modelName: z.string(), type: z.literal("join")}), z.object({dimensionName: z.string(), modelName: z.string(), type: z.literal("dimension")}), z.object({dimensionName: z.string().optional(), metricName: z.string(), modelName: z.string(), type: z.literal("metric")}), z.object({dimensionName: z.string(), parentDimensionName: z.string(), modelName: z.string(), type: z.literal("additional_dimension")}), z.object({fieldName: z.string(), exploreName: z.string(), modelName: z.string(), type: z.literal("required_filter")}), z.object({targetName: z.string(), targetType: z.enum(["model", "dimension", "metric"]), modelName: z.string(), type: z.literal("ai_hint")})]); export const aiAgentConfigurationSetting = z.enum(["instructions", "knowledge_documents", "data_access", "self_improvement", "sql_mode", "mcp_servers", "explore_tags", "space_access", "user_or_group_access", "unknown"]); export const aiAgentTargetRef = z.union([aiAgentSemanticTargetRef, z.object({agentUuid: z.string(), type: z.literal("agent")}), z.object({setting: aiAgentConfigurationSetting, type: z.literal("agent_config")}), z.object({capabilityKey: z.string(), type: z.literal("product_capability")}), z.object({key: z.string(), type: z.literal("runtime")}), z.object({tileUuid: z.string().nullable(), dashboardUuid: z.string().nullable(), chartUuid: z.string().nullable(), type: z.literal("content")})]); export const aiAgentRecommendationAction = z.enum(["update_semantic_yaml", "update_agent_instructions", "add_knowledge_document", "enable_data_access", "enable_sql_mode", "enable_self_improvement", "configure_mcp_server", "adjust_explore_tags", "update_access", "route_to_product_work", "request_more_evidence", "no_action"]); export const aiAgentRecommendation = z.object({targetRefs: z.array(aiAgentTargetRef), rationale: z.string(), title: z.string(), actionType: aiAgentRecommendationAction}); export const aiAgentEvidenceExcerpt = z.object({redacted: z.boolean(), text: z.string(), source: z.enum(["user_prompt", "assistant_answer", "next_user_prompt", "conversation_context", "tool_call", "tool_result", "agent_config"])}); export const aiAgentFixTarget = z.enum(["semantic_yaml_patch", "project_context_rule", "agent_configuration_change", "dbt_modeling_ticket", "semantic_layer_ticket", "product_capability_ticket", "runtime_reliability_ticket", "feedback_needed", "no_action"]); export const aiAgentRootCause = z.enum(["semantic_layer", "project_context", "agent_configuration", "product_capability", "runtime_reliability", "feedback_quality", "not_a_failure", "ambiguous"]); export const aiAgentReviewClassifierEventType = z.enum(["response_saved", "feedback_changed"]); export const recordStringUnknown = z.record(z.string(), z.unknown()); export const aiAgentReviewClassifierRunScope = z.union([z.object({dryRun: z.boolean().optional(), agentUuid: z.string().optional(), projectUuid: z.string().optional(), endedAt: z.string(), startedAt: z.string(), type: z.literal("backfill")}), z.object({agentUuid: z.string(), projectUuid: z.string(), threadUuid: z.string(), promptUuid: z.string(), eventType: aiAgentReviewClassifierEventType, type: z.literal("live_event")}), z.object({filters: recordStringUnknown, requestedByUserUuid: z.string(), type: z.literal("manual")})]); export const aiAgentReviewClassifierConfidence = z.enum(["low", "medium", "high"]); export const aiAgentImplicitSignalSource = z.enum(["next_user_correction", "next_user_dispute", "next_user_retry", "output_shape_correction", "tool_error", "assistant_no_answer", "product_capability_request", "human_intervention"]); export const aiAgentTurnSignal = z.enum(["normal_refinement", "implicit_correction", "explicit_dispute", "retry_after_failure", "output_shape_correction", "new_question", "acceptance_or_continuation", "product_capability_request", "human_intervention", "ambiguous"]); export const aiAgentReviewSignalSummary = z.object({finding: z.object({recommendation: aiAgentRecommendation.nullable(), evidenceExcerpts: z.array(aiAgentEvidenceExcerpt), fixTargets: z.array(aiAgentFixTarget), subcategories: z.array(z.string()), primaryRootCause: aiAgentRootCause, reviewItemUuid: z.string().nullable(), uuid: z.string()}).nullable(), errorMessage: z.string().nullable(), responsePreview: z.string().nullable(), prompt: z.string(), runScope: aiAgentReviewClassifierRunScope, createdAt: z.string(), promotionReason: z.string().nullable(), promotedToFinding: z.boolean(), confidence: aiAgentReviewClassifierConfidence, implicitSignalSources: z.array(aiAgentImplicitSignalSource), signal: aiAgentTurnSignal, agentUuid: z.string(), projectUuid: z.string(), threadUuid: z.string(), promptUuid: z.string(), runUuid: z.string(), uuid: z.string()}); export const apiAiAgentReviewSignalsResponse = z.object({results: z.array(aiAgentReviewSignalSummary), status: z.literal("ok")}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * GET /api/v1/aiAgents/admin/review-signals */ export const getApiApiV1AiAgentsAdminReviewSignals = async (options: GetApiApiV1AiAgentsAdminReviewSignalsOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/api/v1/aiAgents/admin/review-signals${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(apiAiAgentReviewSignalsResponse, await res.json()) };