import type { CapabilityTier, SpendPolicy } from '../types'; export interface TaskTemplate { id: string; slug: string; label: string; requiredCapability: CapabilityTier; primaryModel: string; fallbackModel: string; allowedModels: string[]; caps: SpendPolicy['caps']; systemInstructions: string; } export const TASK_TEMPLATES: Record = { 'risk-review': { id: 'risk-review-v1', slug: 'risk-review', label: 'Risk review agent', requiredCapability: 'read_only', primaryModel: 'openai/gpt-4o-mini', fallbackModel: 'anthropic/claude-haiku-4-5', allowedModels: ['openai/gpt-4o-mini', 'anthropic/claude-haiku-4-5'], caps: [ { amountCents: 50, window: 'per_call', action: 'downgrade', downgradeTo: 'anthropic/claude-haiku-4-5', reason: 'Per-call budget reached, routing to fallback model' }, { amountCents: 2500, window: 'per_day', action: 'block', reason: 'Daily budget reached' }, ], systemInstructions: 'Classify transaction, vendor, and account risk. Return concise findings with evidence pointers only.', }, 'payment-approval': { id: 'payment-approval-v1', slug: 'payment-approval', label: 'Payment approval agent', requiredCapability: 'payment_initiate', primaryModel: 'anthropic/claude-sonnet-4-6', fallbackModel: 'openai/gpt-5-mini', allowedModels: ['anthropic/claude-sonnet-4-6', 'openai/gpt-5-mini'], caps: [ { amountCents: 500, window: 'per_call', action: 'downgrade', downgradeTo: 'openai/gpt-5-mini', reason: 'Per-call budget reached, routing to fallback model' }, { amountCents: 20000, window: 'per_day', action: 'block', reason: 'Daily budget reached' }, ], systemInstructions: 'Review payment intent and policy evidence. Recommend approve, hold, or escalate. Never execute funds movement.', }, 'chargeback-evidence': { id: 'chargeback-evidence-v1', slug: 'chargeback-evidence', label: 'Chargeback evidence agent', requiredCapability: 'read_only', primaryModel: 'openai/gpt-5-mini', fallbackModel: 'openai/gpt-4o-mini', allowedModels: ['openai/gpt-5-mini', 'openai/gpt-4o-mini'], caps: [ { amountCents: 100, window: 'per_call', action: 'downgrade', downgradeTo: 'openai/gpt-4o-mini', reason: 'Per-call budget reached, routing to fallback model' }, { amountCents: 5000, window: 'per_day', action: 'block', reason: 'Daily budget reached' }, ], systemInstructions: 'Assemble claim evidence from provided records. Cite source IDs and keep disputed facts separate from verified records.', }, 'agent-support': { id: 'agent-support-v1', slug: 'agent-support', label: 'Agent support workflow', requiredCapability: 'data_write', primaryModel: 'openai/gpt-4o-mini', fallbackModel: 'google/gemini-3-flash-preview', allowedModels: ['openai/gpt-4o-mini', 'google/gemini-3-flash-preview'], caps: [ { amountCents: 25, window: 'per_call', action: 'downgrade', downgradeTo: 'google/gemini-3-flash-preview', reason: 'Per-call budget reached, routing to fallback model' }, { amountCents: 10000, window: 'per_day', action: 'block', reason: 'Daily budget reached' }, ], systemInstructions: 'Draft support replies and update allowed fields only after policy checks. Escalate billing, payment, and identity changes.', }, 'code-scan': { id: 'code-scan-v1', slug: 'code-scan', label: 'Code scan agent', requiredCapability: 'read_only', primaryModel: 'google/gemini-3-flash-preview', fallbackModel: 'openai/gpt-4o-mini', allowedModels: ['google/gemini-3-flash-preview', 'openai/gpt-4o-mini'], caps: [ { amountCents: 10, window: 'per_call', action: 'downgrade', downgradeTo: 'openai/gpt-4o-mini', reason: 'Per-call budget reached, routing to fallback model' }, { amountCents: 3000, window: 'per_day', action: 'block', reason: 'Daily budget reached' }, ], systemInstructions: 'Scan code for spend, audit, and integration risks. Return findings with file paths and minimal fix guidance.', }, }; export function listTaskTemplates(): TaskTemplate[] { return Object.values(TASK_TEMPLATES); } export function getTaskTemplate(slug: string): TaskTemplate | null { return TASK_TEMPLATES[slug] ?? null; } export function policyFromTemplate(slug: string, tenantId = 'my-tenant'): SpendPolicy | null { const template = getTaskTemplate(slug); if (!template) return null; return { id: template.id, name: template.label, scope: { tenantId }, caps: template.caps.map((cap) => ({ ...cap })), mode: 'enforce', requiredCapability: template.requiredCapability, version: 1, effectiveFrom: new Date().toISOString(), }; }