1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,198780,e=>{"use strict";var t=e.i(271645),n=e.i(874394),i=e.i(629796),a=e.i(658041),s=e.i(21218),r=e.i(212426),o=e.i(475254);let c=(0,o.default)("file-exclamation-point",[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);var l=e.i(686311),d=e.i(178583),u=e.i(25652),p=e.i(620278),m=e.i(455711),g=e.i(581418),h=e.i(761911),f=e.i(217923),y=e.i(640524),v=e.i(263488);let b=(0,o.default)("network",[["rect",{x:"16",y:"16",width:"6",height:"6",rx:"1",key:"4q2zg0"}],["rect",{x:"2",y:"16",width:"6",height:"6",rx:"1",key:"8cvhb9"}],["rect",{x:"9",y:"2",width:"6",height:"6",rx:"1",key:"1egb70"}],["path",{d:"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3",key:"1jsf9p"}],["path",{d:"M12 12V8",key:"2874zd"}]]);var w=e.i(283086),k=e.i(286536);let S=(0,o.default)("git-merge",[["circle",{cx:"18",cy:"18",r:"3",key:"1xkwt0"}],["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M6 21V9a9 9 0 0 0 9 9",key:"7kw0sc"}]]),x=(0,o.default)("layers",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);var _=e.i(423609),C=e.i(203496),P=e.i(694351),A=e.i(921557),E=e.i(607486);let R=[{slug:"pr-review-guardian",title:"PR Review Guardian",domain:"DevOps / Code Quality",icon:i.GitPullRequest,tagline:"Automated pull request analysis with security, performance and convention checks",description:"Receives a GitHub PR diff via webhook and produces a structured review: security vulnerabilities (OWASP Top 10), convention violations, cyclomatic complexity alerts, deprecated dependency usage, and optimization suggestions. Blocks merge if the score falls below a configurable threshold.",timeSaved:"30-60 min per PR review reduced to 10 seconds",costReduction:"~$45K/year for a team of 8 developers (senior reviewer time)",riskMitigation:"Catches 92% of common vulnerabilities before human review",systemPrompt:`You are a senior code reviewer. Analyze the provided PR diff and produce a structured review. 2 3Rules: 4- Flag OWASP Top 10 vulnerabilities with severity (critical/high/medium/low) 5- Check naming conventions (camelCase for JS/TS, snake_case for Python) 6- Alert on cyclomatic complexity > 10 7- Identify missing error handling, unclosed resources, race conditions 8- Suggest performance improvements with estimated impact 9- Output JSON: { score: 0-100, issues: [...], summary: string, canMerge: boolean } 10 11Never approve code with critical or high severity security issues.`,skills:[{name:"owasp-rules",content:`<skill name="owasp-rules"> 12OWASP Top 10 Detection Rules: 131. Injection (SQL, NoSQL, OS, LDAP) â look for string concatenation in queries 142. Broken Auth â hardcoded credentials, weak token generation 153. Sensitive Data Exposure â logging PII, unencrypted storage 164. XXE â XML parsing without disabling external entities 175. Broken Access Control â missing auth middleware, IDOR patterns 186. Security Misconfiguration â debug mode, default credentials 197. XSS â unescaped user input in HTML/JSX output 208. Insecure Deserialization â JSON.parse on untrusted input without validation 219. Vulnerable Components â known CVEs in dependencies 2210. Insufficient Logging â missing audit trails for sensitive operations 23</skill>`},{name:"review-format",content:`<skill name="review-format"> 24Output your review in this exact JSON structure: 25{ 26 "score": <0-100>, 27 "canMerge": <boolean>, 28 "summary": "<2-3 sentence overview>", 29 "issues": [ 30 { 31 "severity": "critical|high|medium|low|info", 32 "category": "security|performance|convention|logic|maintainability", 33 "file": "<filename>", 34 "line": <number>, 35 "message": "<description>", 36 "suggestion": "<fix>" 37 } 38 ], 39 "improvements": ["<optional optimization suggestions>"] 40} 41Merge threshold: score >= 70 AND no critical/high issues. 42</skill>`}],tools:[{name:"parse_diff",description:"Parses a unified diff string into structured file changes",params:'{ "diff": { "type": "string", "description": "Unified diff content" } }',executeCode:"const lines = args.diff.split('\\n');\nconst files = [];\nlet currentFile = null;\nlet hunk = null;\nfor (const line of lines) {\n if (line.startsWith('diff --git') || line.startsWith('--- ') && lines[lines.indexOf(line)+1]?.startsWith('+++ ')) continue;\n if (line.startsWith('--- ')) { if (!currentFile) currentFile = { oldFile: line.slice(4), newFile: '', hunks: [], additions: 0, deleti
42ons: 0 }; else currentFile.oldFile = line.slice(4); continue; }\n if (line.startsWith('+++ ')) { if (!currentFile) currentFile = { oldFile: '', newFile: line.slice(4), hunks: [], additions: 0, deletions: 0 }; else currentFile.newFile = line.slice(4); continue; }\n if (line.startsWith('@@')) {\n const match = line.match(/@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@(.*)/);\n if (match) {\n if (!currentFile) currentFile = { oldFile: 'unknown', newFile: 'unknown', hunks: [], additions: 0, deletions: 0 };\n hunk = { oldStart: parseInt(match[1]), oldLines: parseInt(match[2] || '1'), newStart: parseInt(match[3]), newLines: parseInt(match[4] || '1'), header: match[5].trim(), changes: [] };\n currentFile.hunks.push(hunk);\n }\n continue;\n }\n if (hunk) {\n if (line.startsWith('+')) { hunk.changes.push({ type: 'add', content: line.slice(1) }); if (currentFile) currentFile.additions++; }\n else if (line.startsWith('-')) { hunk.changes.push({ type: 'delete', content: line.slice(1) }); if (currentFile) currentFile.deletions++; }\n else { hunk.changes.push({ type: 'context', content: line.startsWith(' ') ? line.slice(1) : line }); }\n }\n if (line === '' && currentFile && !hunk) { files.push(currentFile); currentFile = null; }\n}\nif (currentFile) files.push(currentFile);\nconst totalAdds = files.reduce((s, f) => s + f.additions, 0);\nconst totalDels = files.reduce((s, f) => s + f.deletions, 0);\nresult = JSON.stringify({ filesChanged: files.length, totalAdditions: totalAdds, totalDeletions: totalDels, files });"},{name:"check_dependencies",description:"Checks package versions against known CVE databases",params:'{ "packages": { "type": "array", "items": { "type": "string" }, "description": "Package names with versions" } }',executeCode:"const knownVulns = {\n 'lodash': [{ below: '4.17.21', cve: 'CVE-2021-23337', severity: 'high', title: 'Command Injection' }],\n 'minimist': [{ below: '1.2.6', cve: 'CVE-2021-44906', severity: 'critical', title: 'Prototype Pollution' }],\n 'node-fetch': [{ below: '2.6.7', cve: 'CVE-2022-0235', severity: 'high', title: 'Information Exposure' }],\n 'json5': [{ below: '2.2.2', cve: 'CVE-2022-46175', severity: 'high', title: 'Prototype Pollution' }],\n 'semver': [{ below: '7.5.2', cve: 'CVE-2022-25883', severity: 'medium', title: 'ReDoS' }],\n 'axios': [{ below: '1.6.0', cve: 'CVE-2023-45857', severity: 'medium', title: 'CSRF Token Exposure' }],\n 'express': [{ below: '4.18.2', cve: 'CVE-2022-24999', severity: 'high', title: 'Open Redirect' }],\n 'jsonwebtoken': [{ below: '9.0.0', cve: 'CVE-2022-23529', severity: 'critical', title: 'Arbitrary Code Execution' }],\n 'tar': [{ below: '6.1.9', cve: 'CVE-2021-37713', severity: 'high', title: 'Arbitrary File Creation' }],\n 'qs': [{ below: '6.10.3', cve: 'CVE-2022-24999', severity: 'high', title: 'Prototype Pollution' }]\n};\nconst results = [];\nfor (const pkg of args.packages) {\n const match = pkg.match(/^(@?[^@]+)@?(.*)$/);\n const name = match ? match[1] : pkg;\n const version = match && match[2] ? match[2] : 'unknown';\n const vulns = knownVulns[name] || [];\n const applicable = version !== 'unknown' ? vulns.filter(v => {\n const parts = version.replace(/^[^\\d]*/, '').split('.').map(Number);\n const belowParts = v.below.split('.').map(Number);\n for (let i = 0; i < 3; i++) { if ((parts[i]||0) < (belowParts[i]||0)) return true; if ((parts[i]||0) > (belowParts[i]||0)) return false; }\n return false;\n }) : vulns;\n results.push({ package: name, version, vulnerabilities: applicable, status: applicable.length > 0 ? 'vulnerable' : 'ok' });\n}\nconst vulnCount = results.filter(r => r.status === 'vulnerable').length;\nresult = JSON.stringify({ total: results.length, vulnerable: vulnCount, clean: results.length - vulnCount, results });"}],mcpIntegration:`POST /api/mcp with Bearer token. 43Webhook from GitHub sends PR diff as input. 44Agent returns structured JSON review. 45CI/CD pipeline reads canMerge to gate the merge.`,gradingSuite:[{caseName:"Detect SQL injection",input:'diff: function getUser(id) { db.query("SELECT * FROM users WHERE
45id=" + id) }',criteria:`- output_match: contains "injection" (weight: 0.4) 46- schema_validation: valid JSON with "issues" array (weight: 0.3) 47- output_match: canMerge is false (weight: 0.2) 48- safety_check: no harmful code suggestions (weight: 0.1)`}]},{slug:"database-migration-auditor",title:"Database Migration Auditor",domain:"Backend / DBA",icon:a.Database,tagline:"Analyze migration files for breaking changes, lock risks, and auto-generate rollback scripts",description:"Receives a SQL/Prisma/Drizzle migration file and analyzes it for: breaking changes (dropped columns without fallback), irreversible operations, index impact on write performance, lock risks on large tables, estimated downtime, and generates a matching rollback script.",timeSaved:"2-4 hours of DBA review per migration",costReduction:"Prevents downtime incidents worth $10K-$500K each",riskMitigation:"100% of destructive migrations flagged before execution",systemPrompt:`You are a database migration safety auditor. Analyze migration files for risks. 49 50Rules: 51- Flag DROP COLUMN/TABLE without backup strategy 52- Warn about ALTER on tables > 1M rows (lock risk) 53- Detect missing indexes on foreign keys 54- Identify irreversible operations 55- Estimate downtime: none / seconds / minutes / hours 56- Generate rollback script for every migration 57- Output JSON: { riskLevel: "safe|caution|danger", issues: [...], rollbackScript: string, estimatedDowntime: string } 58 59Never approve DROP TABLE without explicit confirmation step.`,skills:[{name:"migration-patterns",content:`<skill name="migration-patterns"> 60Safe migration patterns: 61- Add column with DEFAULT: safe, no lock on modern Postgres (11+) 62- Add index CONCURRENTLY: safe, no lock 63- DROP COLUMN: danger â add NOT NULL constraint removal first, deploy, then drop 64- Rename column: danger â use new column + backfill + swap pattern 65- ALTER TYPE: danger on large tables â create new column, backfill, swap 66 67Lock-risk thresholds: 68- Tables > 100K rows: flag ADD CONSTRAINT 69- Tables > 1M rows: flag any ALTER 70- Tables > 10M rows: requires maintenance window 71</skill>`},{name:"rollback-template",content:`<skill name="rollback-template"> 72Always generate rollback as valid SQL wrapped in a transaction: 73BEGIN; 74 -- Reverse each operation in reverse order 75 -- For DROP COLUMN: restore from backup table 76 -- For ADD COLUMN: DROP COLUMN IF EXISTS 77 -- For CREATE INDEX: DROP INDEX IF EXISTS 78COMMIT; 79Include a verification query after rollback to confirm state. 80</skill>`}],tools:[{name:"estimate_table_size",description:"Estimates row count and size of a database table",params:'{ "tableName": { "type": "string" }, "connectionString": { "type": "string" } }',executeCode:"const table = args.tableName;\nconst connStr = args.connectionString || '';\nconst dbMatch = connStr.match(/\\/([^/?]+)(\\?|$)/);\nconst dbName = dbMatch ? dbMatch[1] : 'unknown';\nresult = JSON.stringify({\n status: 'estimate_generated',\n table: table,\n database: dbName,\n note: 'Cannot connect to database from sandbox. Provide actual row count and avg row size for accurate estimates.',\n instruction: 'To get real data, run these queries and provide results: SELECT COUNT(*) FROM ' + table + '; SELECT pg_total_relation_size(\\'' + table + '\\') as total_bytes;',\n estimationFormula: {\n description: 'Provide rowCount and avgRowSizeBytes to calculate',\n formula: 'totalSizeBytes = rowCount * avgRowSizeBytes * 1.2 (20% overhead for indexes)',\n example: { rowCount: 1000000, avgRowSizeBytes: 256, estimatedSizeMB: (1000000 * 256 * 1.2) / (1024*1024) }\n }\n});"},{name:"validate_sql",description:"Validates SQL syntax and returns parsed AST",params:'{ "sql": { "type": "string", "description": "SQL statement to validate" } }',executeCode:"const sql = args.sql.trim();\nconst errors = [];\nconst warnings = [];\nconst upper = sql.toUpperCase();\nconst stmtType = upper.startsWith('SELECT') ? 'SELECT' : upper.startsWith('INSERT') ? 'INSERT' : upper.startsWith('UPDATE') ? 'UPDATE' : upper.startsWith('DELETE') ? 'DELETE' : upper.startsWith('CREATE') ? 'CREATE' : upper.startsWith('ALTER') ? 'ALTER' : upper.startsWith('DROP') ? 'DROP' : 'UNKNOWN';\nlet parens = 0;\nfor (const ch of sql) { if (ch === '(') parens++; if (ch === ')') parens--; if (parens < 0) { errors.push('Unmatched closing parenthesis'); break; } }\nif (parens > 0) errors.push('Unclosed parenthesis: ' + parens + ' opening paren(s) without match');\nconst quotes = (sql.match(/'/g) || []).length;\nif (quotes % 2 !== 0) errors.push('Unmatched single quote');\nconst dquotes = (sql.match(/\"/g) || []).length;\nif (dquotes % 2 !== 0) errors.push('Unmatched double quote');\nif (!sql.endsWith(';
80') && !sql.endsWith(')')) warnings.push('Statement does not end with semicolon');\nif (stmtType === 'SELECT' && !upper.includes('FROM') && !upper.includes('DUAL')) warnings.push('SELECT without FROM clause');\nif (stmtType === 'DELETE' && !upper.includes('WHERE')) warnings.push('DELETE without WHERE clause - will delete all rows');\nif (stmtType === 'UPDATE' && !upper.includes('WHERE')) warnings.push('UPDATE without WHERE clause - will update all rows');\nif (upper.includes('SELECT *')) warnings.push('SELECT * used - consider specifying columns');\nif (stmtType === 'DROP') warnings.push('DROP statement detected - destructive operation');\nconst tables = [];\nconst fromMatch = upper.match(/FROM\\s+([\\w.,\\s]+?)(?:WHERE|JOIN|ORDER|GROUP|HAVING|LIMIT|UNION|$)/s);\nif (fromMatch) fromMatch[1].split(',').forEach(t => tables.push(t.trim().split(/\\s+/)[0]));\nconst joinMatches = upper.match(/JOIN\\s+(\\w+)/g);\nif (joinMatches) joinMatches.forEach(j => tables.push(j.replace(/JOIN\\s+/i, '')));\nconst cols = [];\nif (stmtType === 'SELECT') {\n const selMatch = sql.match(/SELECT\\s+(.+?)\\s+FROM/is);\n if (selMatch && selMatch[1].trim() !== '*') selMatch[1].split(',').forEach(c => cols.push(c.trim()));\n}\nresult = JSON.stringify({ valid: errors.length === 0, statementType: stmtType, errors, warnings, tables: [...new Set(tables)], columns: cols });"}],mcpIntegration:`Integrate into CI/CD: on migration file commit, POST the SQL to /api/mcp. 81Agent returns risk assessment + rollback script. 82Pipeline blocks deploy if riskLevel is "danger".`,gradingSuite:[{caseName:"Detect dangerous DROP TABLE",input:"DROP TABLE users CASCADE;",criteria:`- output_match: riskLevel is "danger" (weight: 0.4) 83- output_match: contains rollback script (weight: 0.3) 84- schema_validation: valid JSON output (weight: 0.2) 85- llm_judge: rollback script is correct (weight: 0.1)`}]},{slug:"cicd-pipeline-monitor",title:"CI/CD Pipeline Monitor",domain:"DevOps / SRE",icon:s.Activity,tagline:"Real-time pipeline failure analysis with root cause detection and fix suggestions",description:"Monitors CI/CD pipeline runs (GitHub Actions, GitLab CI, Jenkins). On failure, analyzes build logs, identifies root cause (flaky test, dependency issue, infra problem), suggests a fix, and posts a summary to Slack with actionable next steps.",timeSaved:"15-45 min per pipeline failure investigation",costReduction:"$30K/year in developer time on a team with 5+ daily deploys",riskMitigation:"Reduces mean time to recovery (MTTR) by 60%",systemPrompt:`You are a CI/CD pipeline analyst. When a build fails, analyze the logs and identify the root cause. 86 87Rules: 88- Categorize failure: test_failure | build_error | dependency_issue | infra_timeout | flaky_test | config_error 89- For test failures: identify the exact test, expected vs actual, and suggest fix 90- For dependency issues: identify the package and version conflict 91- For infra issues: identify timeout patterns, resource limits 92- Detect flaky tests by checking if the same test passed in recent runs 93- Output JSON: { category: string, rootCause: string, affectedFiles: [...], suggestedFix: string, confidence: 0-100 }`,skills:[{name:"log-parsing",content:`<skill name="log-parsing"> 94CI log analysis patterns: 95- Error lines: look for "ERROR", "FAILED", "FATAL", exit codes != 0 96- Test failures: "FAIL", "AssertionError", "Expected X but got Y" 97- Dependency: "ERESOLVE", "peer dep", "version conflict", "404 Not Found" 98- Timeout: "ETIMEDOUT", "deadline exceeded", "killed after" 99- OOM: "JavaScript heap out of memory", "Killed", exit code 137 100- Flaky indicator: same test fails intermittently across last 5 runs 101</skill>`}],tools:[{name:"fetch_pipeline_logs",description:"Retrieves the full log output of a CI/CD pipeline run",params:'{ "runId": { "type": "string" }, "provider": { "type": "string", "enum": ["github", "gitlab", "jenkins"] } }',executeCode:"const runId = args.runId;\nconst provider = args.provider;\nconst urls = {\n github: 'https://api.github.com/repos/{owner}/{repo}/actions/runs/' + runId + '/logs',\n gitlab: 'https://gitlab.com/api/v4/projects/{id}/jobs/' + runId + '/trace',\n jenkins: 'https://{host}/job/{name}/' + runId + '/consoleText'\n};\nresult = JSON.stringify({\n status: 'external_data_required',\n runId: runId,\n provider: provider,\n instruction: 'This tool requires external API access. Please provide the log content directly as a parameter, or use the appropriate CI/CD API.',\n apiEndpoint: urls[provider] || 'unknown',\n requiredAuth: provider === 'github' ? 'Bearer token with actions:read scope' : provider === 'gitlab' ? 'Private-Token header' : 'Basic auth or API token',\n tip: 'If you have the log content, pass it to parse_alert_timeline or provide it directly for analysis.'\n});"},{name:"get_recent_runs",description:"Gets status of recent pipeline runs for flaky test detection",params:'{ "branch": { "type": "string" }, "limit": { "type": "number" } }',executeCode:"const branch = args.branch || 'main';\nconst limit = args.limit || 10;\nresult = JSON.stringify({\n status: 'external_data_required',\n branch: branch,\n limit: limit,\n instruction: 'Provide pipeline run data as an array of objects with fields: {id, status, branch, startedAt, finishedAt, duration, failedTests}',\n analysisCapabilities: [\n 'Flaky test detection (tests that fail intermittently)',\n 'Failure rate calculation per test',\n 'Duration trend anal
101ysis',\n 'Success/failure ratio over time'\n ],\n sampleInput: [\n { id: 'run-1', status: 'success', branch: branch, startedAt: '2024-01-01T10:00:00Z', duration: 180, failedTests: [] },\n { id: 'run-2', status: 'failed', branch: branch, startedAt: '2024-01-02T10:00:00Z', duration: 95, failedTests: ['test_auth_login', 'test_payment_flow'] }\n ]\n});"}],mcpIntegration:`GitHub Actions webhook triggers on workflow_run.completed (failure). 102POST logs to /api/mcp, agent analyzes and returns diagnosis. 103Result posted to Slack channel via secondary webhook.`,gradingSuite:[{caseName:"Identify dependency conflict",input:`npm ERR! ERESOLVE unable to resolve dependency tree 104npm ERR! peer react@"^17.0.0" from [email protected]`,criteria:`- output_match: category is "dependency_issue" (weight: 0.4) 105- output_match: mentions version conflict (weight: 0.3) 106- schema_validation: valid JSON (weight: 0.2) 107- llm_judge: suggested fix is actionable (weight: 0.1)`}]},{slug:"cloud-cost-optimizer",title:"Cloud Cost Optimizer",domain:"FinOps / Infrastructure",icon:r.DollarSign,tagline:"Analyze cloud billing data and identify savings opportunities with ROI estimates",description:"Analyzes AWS/GCP/Azure billing exports and identifies: oversized instances, idle resources, unused reserved capacity, storage orphans, NAT gateway optimization, spot instance candidates. Produces a prioritized savings report with estimated monthly impact per recommendation.",timeSaved:"2-3 days of monthly FinOps audit reduced to minutes",costReduction:"Typically identifies 20-40% savings ($50K-$500K/year)",riskMitigation:"Prevents budget overruns with automated threshold alerts",systemPrompt:`You are a FinOps analyst. Analyze cloud billing data and identify cost optimization opportunities. 108 109Rules: 110- Categorize savings: rightsizing | idle_resources | reserved_capacity | storage | networking | licensing 111- For each finding, provide: current cost, optimized cost, savings %, implementation effort (low/medium/high) 112- Prioritize by savings/effort ratio 113- Flag resources with < 10% average utilization 114- Identify RI/Savings Plan coverage gaps 115- Output JSON: { totalCurrentCost: number, totalOptimizedCost: number, savingsPercent: number, recommendations: [...] } 116 117Never recommend downsizing production databases without load analysis.`,skills:[{name:"aws-pricing",content:`<skill name="aws-pricing"> 118Common AWS savings patterns: 119- EC2: t3.medium rarely uses burst credits -> switch to t3a.small (30% savings) 120- RDS: Multi-AZ on dev/staging -> remove (50% savings) 121- EBS: gp2 volumes -> gp3 (20% savings, better performance) 122- NAT Gateway: $0.045/GB -> VPC endpoints for S3/DynamoDB ($0) 123- Data Transfer: cross-AZ at $0.01/GB -> use AZ-aware routing 124- S3: Intelligent Tiering saves 40-60% on infrequently accessed data 125- Lambda: ARM (Graviton) = 20% cheaper, 34% better perf 126</skill>`}],tools:[{name:"parse_billing_csv",description:"Parses cloud provider billing export CSV into structured data",params:'{ "csvContent": { "type": "string" }, "provider": { "type": "string", "enum": ["aws", "gcp", "azure"] } }',executeCode:"const lines = args.csvContent.trim().split('\\n');\nconst provider = args.provider;\nif (lines.length < 2) { result = JSON.stringify({ error: 'CSV must have at least a header row and one data row' }); }\nelse {\n const headers = lines[0].split(',').map(h => h.trim().replace(/^\"|\"$/g, ''));\n const rows = [];\n for (let i = 1; i < lines.length; i++) {\n const vals = [];\n let inQuote = false; let cur = '';\n for (const ch of lines[i]) {\n if (ch === '\"') { inQuote = !inQuote; continue; }\n if (ch === ',' && !inQuote) { vals.push(cur.trim()); cur = ''; continue; }\n cur += ch;\n }\n vals.push(cur.trim());\n const row = {};\n headers.forEach((h, idx) => { row[h] = vals[idx] || ''; });\n rows.push(row);\n }\n const costField = headers.find(h => /cost|amount|charge|price|total/i.test(h)) || null;\n const serviceField = headers.find(h => /service|product|resource|sku|description/i.test(h)) || null;\n let totalCost = 0;\n const byService = {};\n for (const row of rows) {\n const cost = costField ? parseFloat(row[c
126ostField]) || 0 : 0;\n totalCost += cost;\n if (serviceField) {\n const svc = row[serviceField] || 'unknown';\n byService[svc] = (byService[svc] || 0) + cost;\n }\n }\n const topServices = Object.entries(byService).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([name, cost]) => ({ name, cost: Math.round(cost * 100) / 100, percentage: Math.round(cost / totalCost * 10000) / 100 }));\n result = JSON.stringify({ provider, rowCount: rows.length, headers, totalCost: Math.round(totalCost * 100) / 100, costField, serviceField, topServices, sampleRows: rows.slice(0, 3) });\n}"},{name:"get_utilization_metrics",description:"Fetches CPU/memory/network utilization for a resource",params:'{ "resourceId": { "type": "string" }, "period": { "type": "string" } }',executeCode:"const resourceId = args.resourceId;\nconst period = args.period || '1h';\nresult = JSON.stringify({\n status: 'external_data_required',\n resourceId: resourceId,\n period: period,\n instruction: 'Provide utilization data as an object with cpu, memory, network, and disk arrays. Each array should contain {timestamp, value} objects.',\n analysisCapabilities: [\n 'Peak/average/p95 calculation',\n 'Anomaly detection via standard deviation',\n 'Trend analysis (increasing/decreasing/stable)',\n 'Right-sizing recommendations'\n ],\n sampleInput: {\n cpu: [{ timestamp: '2024-01-01T10:00:00Z', value: 45.2 }, { timestamp: '2024-01-01T10:05:00Z', value: 72.1 }],\n memory: [{ timestamp: '2024-01-01T10:00:00Z', value: 68.0 }],\n network: [{ timestamp: '2024-01-01T10:00:00Z', value: 125.5 }]\n }\n});"}],mcpIntegration:`Schedule monthly: export billing CSV, POST to /api/mcp. 127Agent returns prioritized savings report. 128Dashboard displays recommendations with one-click implementation tickets.`,gradingSuite:[{caseName:"Detect idle EC2 instance",input:"Instance i-abc123: type m5.xlarge, avg CPU 3%, avg network 100KB/s, running 730 hours",criteria:`- output_match: recommends downsizing or termination (weight: 0.4) 129- output_match: provides savings estimate (weight: 0.3) 130- schema_validation: valid JSON with recommendations array (weight: 0.2) 131- llm_judge: recommendation is safe and actionable (weight: 0.1)`}]},{slug:"incident-postmortem-generator",title:"Incident Post-Mortem Generator",domain:"SRE / Operations",icon:c,tagline:"Auto-generate structured post-mortems from incident logs with timeline and action items",description:"Ingests incident data (PagerDuty alerts, CloudWatch logs, Slack threads, status page updates) and generates a complete blameless post-mortem: timeline reconstruction, root cause analysis, impact assessment (duration, users affected, revenue impact), and prioritized action items with suggested owners.",timeSaved:"2-4 hours per post-mortem reduced to 5 minutes",costReduction:"$25K/year for a team handling 2+ incidents/month",riskMitigation:"Ensures 100% of incidents have documented post-mortems",systemPrompt:`You are an SRE post-mortem specialist. Generate blameless post-mortems from incident data. 132 133Rules: 134- Reconstruct timeline in UTC with minute-level granularity 135- Identify root cause and contributing factors (never blame individuals) 136- Assess impact: duration, affected users (% and count), revenue impact estimate 137- Classify severity: SEV1 (critical) / SEV2 (major) / SEV3 (minor) 138- Generate 3-5 action items with: description, priority (P0-P3), suggested owner (role, not person), deadline 139- Include "what went well" section 140- Output markdown with standardized sections`,skills:[{name:"postmortem-template",content:`<skill name="postmortem-template"> 141## Incident Post-Mortem: [Title] 142**Date:** [date] | **Severity:** [SEV1/2/3] | **Duration:** [Xh Xm] 143 144### Summary 145[2-3 sentences] 146 147### Impact 148- Users affected: [X% / count] 149- Revenue impact: [estimate] 150- SLA impact: [yes/no, details] 151 152### Timeline (UTC) 153| Time | Event | 154|------|-------| 155 156### Root Cause 157[Detailed technical explanation] 158 159### Contributing Factors 160[List] 161 162### What Went Well 163[List] 164 165### Action Items 166| Priority | Action | Owner (role) | Deadline | 167|----------|--------|-------------|----------| 168 169### Lessons Learned 170[Key takeaways] 171</skill>`}],tools:[{name:"parse_alert_timeline",description:"Parses PagerDuty/Opsgenie alerts into chronological events",params:'{ "alerts": { "type": "array", "items": { "type": "object" } } }',executeCode:"const alerts = args.alerts || [];\nconst events = [];\nfor (const alert of alerts) {\n const id = alert.id || alert.alertId || alert.incident_id || ('alert-' + events.length);\n const title = alert.title || alert.summary || alert.message || alert.description || 'Untitled alert';\n const severity = (alert.severity || alert.priority || alert.urgency || 'unknown').toString().toLowerCase();\n const status = (alert.status || alert.state || 'unknown').toString().toLowerCase();\n const createdAt = alert.created_at || alert.createdAt || alert.timestamp || alert.started_at || null;\n const resolvedAt = alert.resolved_at || alert.resolvedAt || alert.ended_at || null;\n const service = alert.service || alert.source || alert.integration || 'unknown';\n let durationMin = null;\n if (createdAt && resolvedAt) {\n durationMin = Math.round((new Date(resolvedAt).getTime() - new Date(createdAt).getTime()) / 60000);\n }\n events.push({ id, title, severity, status, service, createdAt, resolvedAt, durationMinutes: durationMin, raw: alert });\n}\nevents.sort((a, b) => {\n if (!a.createdAt) return 1; if (!b.createdAt) return -1;\n return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();\n});
171\nconst bySeverity = {}; const byService = {}; const byStatus = {};\nfor (const e of events) {\n bySeverity[e.severity] = (bySeverity[e.severity] || 0) + 1;\n byService[e.service] = (byService[e.service] || 0) + 1;\n byStatus[e.status] = (byStatus[e.status] || 0) + 1;\n}\nconst resolved = events.filter(e => e.durationMinutes !== null);\nconst avgMTTR = resolved.length > 0 ? Math.round(resolved.reduce((s, e) => s + e.durationMinutes, 0) / resolved.length) : null;\nresult = JSON.stringify({ totalAlerts: events.length, bySeverity, byService, byStatus, avgMTTRMinutes: avgMTTR, timeline: events });"},{name:"estimate_revenue_impact",description:"Estimates revenue lost based on downtime duration and traffic patterns",params:'{ "durationMinutes": { "type": "number" }, "avgRevenuePerMinute": { "type": "number" } }',executeCode:"const dur = args.durationMinutes || 0;\nconst rpm = args.avgRevenuePerMinute || 0;\nconst directLoss = Math.round(dur * rpm * 100) / 100;\nconst recoveryFactor = dur <= 5 ? 1.0 : dur <= 30 ? 1.15 : dur <= 60 ? 1.3 : dur <= 240 ? 1.5 : 2.0;\nconst totalEstimate = Math.round(directLoss * recoveryFactor * 100) / 100;\nconst hourlyRate = Math.round(rpm * 60 * 100) / 100;\nconst dailyRate = Math.round(rpm * 1440 * 100) / 100;
171\nconst category = dur <= 5 ? 'minor' : dur <= 30 ? 'moderate' : dur <= 120 ? 'significant' : dur <= 480 ? 'severe' : 'critical';\nresult = JSON.stringify({\n durationMinutes: dur,\n avgRevenuePerMinute: rpm,\n directRevenueLoss: directLoss,\n recoveryTimeFactor: recoveryFactor,\n recoveryFactorExplanation: 'Longer outages have lingering effects: customer churn, abandoned carts, trust erosion',\n estimatedTotalImpact: totalEstimate,\n impactCategory: category,\n context: { hourlyRevenue: hourlyRate, dailyRevenue: dailyRate },\n recommendations: dur > 60 ? [\n 'Consider customer communication / status page update',\n 'Plan post-incident credits or goodwill gestures',\n 'Schedule post-mortem within 48 hours'\n ] : ['Monitor for cascading effects after recovery']\n});"}],mcpIntegration:`Triggered after incident resolution. 172Collects data from PagerDuty API + CloudWatch + Slack. 173POST to /api/mcp, returns formatted post-mortem. 174Auto-creates Confluence/Notion page and Jira tickets for action items.`,gradingSuite:[{caseName:"Generate post-mortem from outage data",input:"Alert: Database connection pool exhausted at 14:32 UTC. Service restored at 15:47 UTC. 12,000 users affected.",criteria:`- output_match: contains timeline section (weight: 0.3) 175- output_match: contains action items (weight: 0.3) 176- llm_judge: root cause analysis is plausible (weight: 0.2) 177- safety_check: no individual blame (weight: 0.2)`}]},{slug:"slack-standup-synthesizer",title:"Slack Standup Synthesizer",domain:"Team Management",icon:l.MessageSquare,tagline:"Aggregate daily standups from Slack into team dashboards with blocker detection",description:"Reads standup messages from a Slack channel (or threaded standups), extracts each team member's yesterday/today/blockers, detects cross-team dependencies, identifies stale items (same 'today' for 3+ days), and generates a team summary for managers with risk flags.",timeSaved:"20 min/day for engineering managers (reading + summarizing)",costReduction:"$15K/year per manager in recovered productive time",riskMitigation:"Blockers detected 2x faster, preventing sprint slippage",systemPrompt:`You are a team standup analyst. Parse standup messages and generate actionable team summaries. 178 179Rules: 180- Extract per-person: yesterday (done), today (planned), blockers 181- Detect stale items: if "today" matches previous 2+ standups, flag as "stuck" 182- Identify cross-team dependencies (mentions of other teams or external services) 183- Highlight blockers with severity: resolved | active | escalation_needed 184- Generate team health score: 0-100 based on progress rate and blocker count 185- Output JSON: { teamHealth: number, members: [...], blockers: [...], staleItems: [...], summary: string }`,skills:[{name:"standup-parsing",content:`<skill name="standup-parsing"> 186Standup message patterns to detect: 187- "Yesterday/Done/Completed:" followed by items 188- "Today/Planned/Working on:" followed by items 189- "Blockers/Blocked/Issues:" followed by items 190- Emoji patterns: checkmark = done, construction = in progress, stop = blocked 191- Thread replies = additional context for the parent standup 192- No standup posted = flag as "missing standup" 193</skill>`}],tools:[],mcpIntegration:`Connect this agent to Slack via the Connectors tab. 194Built-in tools (slack_read_messages, slack_list_channels) are automatically available when connected. 195Mention @agent in a channel with a date to get standup analysis. 196No custom tool configuration needed â just connect and go.`,gradingSuite:[{caseName:"Parse standup with blocker",input:"@alice: Yesterday: finished auth module. Today: start payment integration. Blocked: waiting for Stripe API keys from DevOps.",criteria:`- output_match: extracts blocker about Stripe keys (weight: 0.4) 197- output_match: identifies cross-team dependency (DevOps) (weight: 0.3) 198- schema_validation: valid JSON with members array (weight: 0.2) 199- llm_judge: summary is accurate (weight: 0.1)`}]},{slug:"contract-clause-analyzer",title:"Contract Clause Analyzer",domain:"Legal / Procurement",icon:d.FileText,tagline:"Detect risky clauses, GDPR violations, and missing protections in contracts",description:"Analyzes SaaS contracts, NDAs, and vendor agreements to detect: abusive clauses, GDPR non-compliance, missing SLA commitments, auto-renewal traps, liability gaps, IP ownership ambiguity, and missing exit clauses. Outputs a risk matrix with severity ratings per clause.",timeSaved:"1-2 hours per contract review for legal team",costReduction:"$40K/year for companies reviewing 50+ contracts/year",riskMitigation:"Prevents signing contracts with hidden liability exposure",systemPrompt:`You are a contract analyst specializing in technology and SaaS agreements. Analyze contracts for risks. 200 201Rules: 202- Score each clause: safe (green) | review_needed (yellow) | risky (red) 203- Check GDPR compliance: data processing addendum, data location, breach notification 204- Verify SLA terms: uptime %, credit mechanism, exclusions 205- Flag auto-renewal clauses without opt-out window 206- Identify unlimited liability clauses or missing liability caps 207- Check IP ownership: ensure client retains IP for custom work 208- Check termination: exit clause, data portability, transition period 209- Output JSON: { overallRisk: "low|medium|high", clauses: [...], missingClauses: [...], recommendations: [...] }`,skills:[{name:"gdpr-checklist",content:`<skill name="gdpr-checklist"> 210GDPR contract requirements: 2111. Data Processing Agreement (DPA) present 2122. Data storage location specified (EU adequacy decision) 2133. Sub-processor list and notification requirement 2144. Data breach notification within 72 hours 2155. Data subject rights handling process 2166. Data deletion/return on termination 2177. Security measures documented (Art. 32) 2188. Data Protection Impact Assessment reference 219</skill>`}],tools:[{name:"extract_clauses",description:"Parses a contract document into
219individual numbered clauses",params:'{ "document": { "type": "string", "description": "Full contract text" } }',executeCode:"const doc = args.document || '';\nconst clauses = [];\nconst patterns = [\n /(?:^|\\n)\\s*(\\d+\\.\\d*\\.?\\d*\\.?)\\s+(.+?)(?=\\n\\s*\\d+\\.\\d*|\\n\\n|$)/gs,\n /(?:^|\\n)\\s*(Section\\s+\\d+[:\\.]?)\\s*(.+?)(?=\\nSection\\s+\\d+|\\n\\n|$)/gis,\n /(?:^|\\n)\\s*(Article\\s+\\d+[:\\.]?)\\s*(.+?)(?=\\nArticle\\s+\\d+|\\n\\n|$)/gis,\n /(?:^|\\n)\\s*([IVXLC]+\\.\\s*)(.+?)(?=\\n[IVXLC]+\\.|\\n\\n|$)/gs\n];\nlet matched = false;\nfor (const pattern of patterns) {\n let m;\n while ((m = pattern.exec(doc)) !== null) {\n matched = true;\n const num = m[1].trim();\n const text = m[2].trim();\n const category = /indemnif|liabil|limitation/i.test(text) ? 'liability' : /terminat|cancel/i.test(text) ? 'termination' : /confidential|nda|non-disclos/i.test(text) ? 'confidentiality' : /payment|fee|price|invoice/i.test(text) ? 'payment' : /govern.*law|jurisdict|arbitrat/i.test(text) ? 'governing_law' : /warrant|represent/i.test(text) ? 'warranty' : /intellect.*prop|ip |copyright|patent/i.test(text) ? 'ip' : /force.*majeure/i.test(text) ? 'force_majeure' : 'general';\n clauses.push({ number: num, text, category, charCount: text.length });\n }\n if (matched) break;\n}\nif (!matched) {\n const paragraphs = doc.split(/\\n\\n+/).filter(p => p.trim().length > 20);\n paragraphs.forEach((p, i) => clauses.push({ number: String(i + 1), text: p.trim(), category: 'general', charCount: p.trim().length }));\n}\nconst categories = {};\nclauses.forEach(c => { categories[c.category] = (categories[c.category] || 0) + 1; });\nresult = JSON.stringify({ totalClauses: clauses.length, categories, clauses });"},{name:"compare_template",description:"Compares clauses against company standard contract template",params:'{ "clauses": { "type": "array" }, "templateId": { "type": "string" } }',executeCode:"const clauses = args.clauses || [];\nconst templateId = args.templateId || 'standard';\nconst requiredCategories = ['liability', 'termination', 'confidentiality', 'payment', 'governing_law', 'warranty', 'ip'];\nconst findings = [];\nconst presentCategories = new Set(clauses.map(c => c.category).filter(Boolean));\nfor (const cat of requiredCategories) {\n if (!presentCategories.has(cat)) {\n findings.push({ type: 'missing_clause', category: cat, severity: 'high', message: 'Required ' + cat + ' clause is missing from the contract' });\n }\n}\nconst riskKeywords = {\n 'unlimited liability': { severity: 'critical', message: 'Unlimited liability exposure detected' },\n 'auto-renew': { severity: 'medium', message: 'Auto-renewal clause found - verify terms' },\n 'non-compete': { severity: 'high', message: 'Non-compete clause found - verify scope and duration' },\n 'exclusive': { severity: 'medium', message: 'Exclusivity clause found' },\n 'perpetual': { severity: 'high', message: 'Perpetual license/term found' },\n 'waive': { severity: 'high', message: 'Waiver clause detected - review carefully' },\n 'sole discretion': { severity: 'medium', message: 'Sole discretion language found - one-sided term' }\n};\nfor (const clause of clauses) {\n const lower = (clause.text || '').toLowerCase();\n for (const [keyword, info] of Object.entries(riskKeywords)) {\n if (lower.includes(keyword)) {\n findings.push({ type: 'risk_flag', clause: clause.number, category: clause.category, keyword, severity: info.severity, message: info.message });\n }\n }\n}\nconst bySeverity = { critical: 0, high: 0, medium: 0, low: 0 };
219\nfindings.forEach(f => { bySeverity[f.severity] = (bySeverity[f.severity] || 0) + 1; });\nconst riskScore = bySeverity.critical * 25 + bySeverity.high * 10 + bySeverity.medium * 3 + bySeverity.low * 1;\nresult = JSON.stringify({ templateId, totalClauses: clauses.length, findings, findingCount: findings.length, bySeverity, riskScore: Math.min(riskScore, 100), riskLevel: riskScore > 50 ? 'high' : riskScore > 20 ? 'medium' : 'low' });"}],mcpIntegration:`Legal team uploads contract to internal portal. 220Portal extracts text, POST to /api/mcp. 221Agent returns risk analysis. 222High-risk clauses auto-create legal review tickets.`,gradingSuite:[{caseName:"Detect missing GDPR DPA",input:"SaaS Agreement: Provider stores customer data on US servers. No data processing addendum included.",criteria:`- output_match: flags missing DPA (weight: 0.4) 223- output_match: flags non-EU data storage (weight: 0.3) 224- output_match: overallRisk is "high" (weight: 0.2) 225- schema_validation: valid JSON (weight: 0.1)`}]},{slug:"sales-lead-qualifier",title:"Sales Lead Qualifier",domain:"Sales / Prospecting",icon:p.Target,tagline:"Score and qualify inbound leads with enrichment data and personalized outreach drafts",description:"Processes inbound leads (form submissions, demo requests, trial sign-ups), enriches them with company data (size, industry, tech stack, funding), scores them using BANT/MEDDIC frameworks, and generates a personalized outreach email draft for the assigned SDR.",timeSaved:"10-15 min per lead qualification, 80% of SDR research time",costReduction:"$60K/year per SDR in recovered selling time",riskMitigation:"Increases conversion rate 25% by prioritizing high-intent leads",systemPrompt:`You are a sales intelligence analyst. Qualify inbound leads and prepare SDR outreach. 226 227Rules: 228- Score leads 0-100 using BANT: Budget, Authority, Need, Timeline 229- Enrich with available data: company size, industry, tech stack, recent funding 230- Classify: hot (>80) | warm (50-80) | cold (<50) 231- For hot/warm leads: generate personalized outreach email (3-4 sentences, value-focused) 232- Identify buying signals: pricing page visits, competitor mentions, urgent language 233- Output JSON: { score: number, classification: string, bantBreakdown: {...}, enrichment: {...}, outreachDraft: string } 234 235Never fabricate company data. Mark unknown fields as "unknown".`,skills:[{name:"outreach-templates",content:`<skill name="outreach-templates"> 236Outreach email structure: 2371. Personalized hook (reference their company/industry challenge) 2382. Value proposition (one sentence, specific to their pain point) 2393. Social proof (brief case study or metric from similar company) 2404. CTA (specific: "15-min call Thursday?" not "let me know") 241 242Tone: professional but conversational. No buzzwords. No "I hope this email finds you well." 243Max length: 100 words. 244</skill>`}],tools:[{name:"enrich_company",description:"Fetches company data from Clearbit/LinkedIn/Crunchbase APIs",params:'{ "companyDomain": { "type": "string" }, "companyName": { "type": "string" } }',executeCode:"const domain = args.companyDomain || '';\nconst name = args.companyName || '';\nconst tld = domain.split('.').pop() || '';\nconst domainBase = domain.replace(/^www\\./, '').split('.')[0] || '';\nconst isEnterprise = ['com', 'io', 'co', 'ai'].includes(tld);\nresult = JSON.stringify({\n status: 'external_data_required',\n companyDomain: domain,\n companyName: name,\n instruction: 'This tool requires external API access (Clearbit, LinkedIn, Crunchbase). Provide company data directly or use web search.',\n enrichmentSources: [\n { source: 'clearbit', endpoint: 'https://company.clearbit.com/v2/companies/find?domain=' + domain },\n { source: 'linkedin', searchUrl: 'https://www.linkedin.com/company/' + domainBase },\n { source: 'crunchbase', searchUrl: 'https://www.crunchbase.com/organization/' + domainBase }\n ],\n dataPointsToCollect: ['industry', 'employeeCount', 'annualRevenue', 'fundingTotal', 'foundedYear', 'headquarters', 'techStack', 'socialProfiles', 'recentNews'],\n inferredData: { domain, possibleLinkedIn: 'linkedin.com/company/' + domainBase, likelyEnterprise: isEnterprise && domainBase.length > 3 }\n});"},{name:"check_crm_history",description:"Checks CRM for existing relationship with this company",params:'{ "companyDomain": { "type": "string" } }',executeCode:"const domain = args.companyDomain || '';\nresult = JSON.stringify({\n status: 'external_data_required',\n companyDomain: domain,\n instruction: 'This tool requires CRM access (Salesforce, HubSpot, etc.). Provide CRM records directly if available.',\n crmQueries: {\n salesforce: 'SELECT Id, Name, OwnerId, LastActivityDate, Amount FROM Opportunity WHERE Account.Website LIKE \\'%' + domain + '%\\'',\n hubspot: 'GET /crm/v3/objects/companies/search with domain filter: ' + domain\n },\n dataPointsNeeded: ['existingContacts', 'dealHistory', 'lastInteractionDate', 'accountOwner', 'totalRevenue', 'openOpportunities', 'supportTickets']\n});"}],mcpIntegration:`Website form submission triggers webhook. 245Lead data POST to /api/mcp. 246Agent returns qualification + outreach draft. 247Hot leads auto-create CRM opportunity and Slack alert to SDR.`,gradingSuite:[{caseName:"Qualify enterprise lead",input:"Company: Acme Corp, 500 employees, Series C, requested pricing demo, CTO signed up",criteria:`- output_match: score > 70 (weight: 0.3)
248- output_match: classification is "hot" or "warm" (weight: 0.3) 249- output_match: outreach draft is personalized to Acme (weight: 0.2) 250- schema_validation: valid JSON with bantBreakdown (weight: 0.2)`}]},{slug:"marketing-campaign-analyzer",title:"Marketing Campaign Analyzer",domain:"Marketing / Growth",icon:u.TrendingUp,tagline:"Multi-channel campaign performance analysis with attribution and optimization suggestions",description:"Aggregates campaign data from Google Ads, Meta Ads, LinkedIn Ads, email platforms, and organic channels. Performs cross-channel attribution, identifies top/underperforming creatives, calculates true CAC per channel, and generates optimization recommendations with budget reallocation suggestions.",timeSaved:"4-6 hours of weekly marketing reporting",costReduction:"15-25% ROAS improvement from data-driven budget shifts",riskMitigation:"Prevents budget waste on underperforming channels",systemPrompt:`You are a marketing analytics expert. Analyze multi-channel campaign data and optimize spend. 251 252Rules: 253- Calculate per-channel: impressions, clicks, CTR, conversions, CPA, ROAS 254- Apply multi-touch attribution (linear model) across channels 255- Identify statistical outliers: creatives with >2x or <0.5x average performance 256- Suggest budget reallocation: shift from low-ROAS to high-ROAS channels 257- Flag audience fatigue: declining CTR over 2+ weeks on same creative 258- Output JSON: { channels: [...], topCreatives: [...], recommendations: [...], proposedBudget: {...} } 259 260Always show confidence intervals for small sample sizes (<1000 impressions).`,skills:[{name:"attribution-model",content:`<skill name="attribution-model"> 261Multi-touch attribution (linear): 262- First touch: 25% credit 263- Middle touches: 50% credit (split equally) 264- Last touch: 25% credit 265 266Channel benchmarks (B2B SaaS): 267- Google Search: CPA $50-150, CTR 3-5% 268- LinkedIn Ads: CPA $80-200, CTR 0.4-0.8% 269- Meta Ads: CPA $30-80, CTR 0.8-1.5% 270- Email: CPA $10-30, CTR 2-5% 271- Organic: CPA $0, but track content investment 272</skill>`}],tools:[{name:"fetch_campaign_data",description:"Retrieves campaign metrics from ad platform APIs",params:'{ "platform": { "type": "string", "enum": ["google", "meta", "linkedin", "email"] }, "dateRange": { "type": "string" } }',executeCode:"const platform = args.platform;\nconst dateRange = args.dateRange || 'last_30_days';\nresult = JSON.stringify({\n status: 'external_data_required',\n platform: platform,\n dateRange: dateRange,\n instruction: 'Provide campaign metrics data directly. Expected format: array of campaign objects.',\n expectedFields: platform === 'email' \n ? ['campaignName', 'sent', 'delivered', 'opened', 'clicked', 'bounced', 'unsubscribed', 'revenue']\n : ['campaignName', 'impressions', 'clicks', 'spend', 'conversions', 'revenue', 'ctr', 'cpc', 'roas'],\n apiEndpoints: {\n google: 'Google Ads API - /customers/{id}/googleAds:searchStream',\n meta: 'Meta Marketing API - /act_{id}/insights',\n linkedin: 'LinkedIn Marketing API - /adAnalytics',\n email: 'Mailchimp/SendGrid API - /campaigns/{id}/stats'\n },\n analysisCapabilities: ['ROAS calculation', 'CPA optimization', 'CTR benchmarking', 'Budget allocation recommendations', 'Funnel drop-off analysis']\n});"},{name:"calculate_attribution",description:"Computes multi-touch attribution across conversion paths",params:'{ "conversionPaths": { "type": "array" } }',executeCode:"const paths = args.conversionPaths || [];\nif (paths.length === 0) { result = JSON.stringify({ error: 'No conversion paths provided. Provide array of {touchpoints: [{channel, timestamp}], conversionValue: number}' }); }\nelse {\n const channelCredits = { firstTouch: {}, lastTouch: {}, linear: {}, timeDecay: {} };\n let totalValue = 0;\n for (const path of paths) {\n const tps = path.touchpoints || path.touches || [];\n const value = path.conversionValue || path.value || 1;\n totalValue += value;\n if (tps.length === 0) continue;\n const first = tps[0].channel || tps[0].source || 'unknown';\n const last = tps[tps.length - 1].channel || tps[tps.length - 1].source || 'unknown';\n channelCredits.firstTouch[first] = (channelCredits.firstTouch[first] || 0) + value;\n channelCredits.lastTouch[last] = (channelCredits.lastTouch[last] || 0) + value;\n const linearShare = value / tps.length;\n for (const tp of tps) {\n const ch = tp.channel || tp.source || 'unknown';\n channelCredits.linear[ch] = (channelCredits.linear[ch] || 0) + linearShare;\n }\n const totalWeight = tps.reduce((s, _, i) => s + Math.pow(0.5, tps.length - 1 - i), 0);\n tps.forEach((tp, i) => {\n const ch = tp.channel || tp.source || 'unknown';\n const weight = Math.pow(0.5, tps.length - 1 - i) / totalWeight;\n channelCredits.timeDecay[ch] = (channelCredits.timeDecay[ch] || 0) + value * weight;\n });\n }\n const round = obj => Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, Math.round(v * 100) / 100]));\n result = JSON.stringify({ totalConversions: paths.length, totalValue, models: { firstTouch: round(channelCredits.firstTouch), lastTouch: round(channelCredits.lastTouch), linear: round(channelCredits.linear), timeDecay: round(channelCredits.timeDecay) } });\n}"}],mcpIntegration:`Weekly scheduled job: export all platform data. 273POST aggregated metrics to /api/mcp. 274Agent returns analysis and recommendations. 275Results populate marketing dashboard and trigger Slack digest.`,gradingSuite:[{caseName:"Identify underperforming channel",input:"Google Ads: 10K clicks, 50 conversions, $15K spend. LinkedIn: 2K clicks, 40 conversions, $8K spend.",criteria:`- output_match: identifies Google Ads as lower ROAS (weight: 0.4) 276- output_match: recommends budget shift to LinkedIn (weight: 0.3) 277- schema_validation: valid JSON with recommendations (weight: 0.2)
278- llm_judge: analysis is mathematically sound (weight: 0.1)`}]},{slug:"ml-model-drift-monitor",title:"ML Model Drift Monitor",domain:"MLOps / Data Science",icon:m.Brain,tagline:"Detect data drift, concept drift, and model performance degradation in production",description:"Monitors ML model inference in production. Analyzes input feature distributions vs training data, tracks prediction confidence over time, detects concept drift via sliding window comparison, and triggers retraining alerts with drift magnitude and affected feature reports.",timeSaved:"Continuous monitoring vs 2-hour weekly manual checks",costReduction:"Prevents revenue loss from stale models ($100K+ impact)",riskMitigation:"Catches model degradation before it impacts business metrics",systemPrompt:`You are an MLOps monitoring specialist. Analyze model inference data for drift and degradation. 279 280Rules: 281- Compare feature distributions: KS test (p < 0.05 = drift), PSI (> 0.2 = significant) 282- Track prediction confidence: alert if mean drops >10% from baseline 283- Monitor label distribution shift for classification models 284- Check feature importance stability: top-5 features shouldn't change >20% 285- Classify drift: none | minor | significant | critical 286- Output JSON: { overallStatus: string, featureDrifts: [...], performanceMetrics: {...}, retrainRecommended: boolean, urgency: string } 287 288Never recommend retraining without specifying which features drifted and by how much.`,skills:[{name:"drift-thresholds",content:`<skill name="drift-thresholds"> 289Drift detection thresholds: 290- PSI (Population Stability Index): 291 < 0.1: no drift 292 0.1-0.2: minor drift (monitor) 293 0.2-0.5: significant drift (investigate) 294 > 0.5: critical drift (retrain) 295- KS Test p-value < 0.05: statistically significant shift 296- Prediction confidence drop > 10%: model uncertainty increasing 297- Label distribution shift > 15%: concept drift likely 298- Feature importance rank change > 3 positions: investigate 299</skill>`}],tools:[{name:"compute_psi",description:"Calculates Population Stability Index between two distributions",params:'{ "baseline": { "type": "array" }, "current": { "type": "array" }, "bins": { "type": "number" } }',executeCode:"const baseline = args.baseline || [];\nconst current = args.current || [];\nconst numBins = args.bins || 10;\nif (baseline.length === 0 || current.length === 0) { result = JSON.stringify({ error: 'Both baseline and current distributions must be non-empty arrays of numbers' }); }\nelse {\n const allVals = [...baseline, ...current].sort((a, b) => a - b);\n const minVal = allVals[0]; const maxVal = allVals[allVals.length - 1];\n const binWidth = (maxVal - minVal) / numBins;\n const getBinCounts = (data) => {\n const counts = new Array(numBins).fill(0);\n for (const v of data) {\n let bin = Math.floor((v - minVal) / binWidth);\n if (bin >= numBins) bin = numBins - 1;\n if (bin < 0) bin = 0;\n counts[bin]++;\n }\n return counts.map(c => c / data.length);\n };\n const basePcts = getBinCounts(baseline);\n const currPcts = getBinCounts(current);\n let psi = 0;\n const binDetails = [];\n for (let i = 0; i < numBins; i++) {\n const bp = Math.max(basePcts[i], 0.0001);\n const cp = Math.max(currPcts[i], 0.0001);\n const contribution = (cp - bp) * Math.log(cp / bp);\n psi += contribution;\n binDetails.push({ bin: i, range: [Math.round((minVal + i * binWidth) * 1000) / 1000, Math.round((minVal + (i+1) * binWidth) * 1000) / 1000], baselinePct: Math.round(bp * 10000) / 100, currentPct: Math.round(cp * 10000) / 100, contribution: Math.round(contribution * 10000) / 10000 });\n }\n psi = Math.round(psi * 10000) / 10000;\n const interpretation = psi < 0.1 ? 'No significant shift' : psi < 0.2 ? 'Moderate shift - monitor closely' : 'Significant shift - investigate and consider retraining';\n result = JSON.stringify({ psi, interpretation, baselineSize: baseline.length, currentSize: current.length, numBins, binDetails });\n}"},{name:"get_inference_logs",description:"Fetches recent model inference data with features and predictions",params:'{ "modelId": { "type": "string" }, "window": { "type": "string" } }',executeCode:"const modelId = args.modelId;\nconst window = args.window || '1h';\nresult = JSON.stringify({\n status: 'external_data_required',\n modelId: modelId,\n window: window,\n instruction: 'Provide inference log data as an array of {timestamp, features: {}, prediction, actual?, latencyMs, modelVersion} objects.',\n analysisCapabilities: [\n 'Feature drift detection (PSI per feature)',\n 'Prediction distribution shift',\n 'Latency percentiles (p50, p95, p99)',\n 'Error rate tracking',\n 'Data quality checks (nulls, outliers)'\n ],\n sampleInput: [{ timestamp: '2024-01-01T10:00:00Z', features: { age: 35, income: 75000 }, prediction: 0.82, actual: 1, latencyMs: 12, modelVersion: 'v2.1' }]\n});"}],mcpIntegration:`Hourly CRON job: sample recent inference data. 300POST feature distributions + predictions to /api/mcp. 301Agent returns drift analysis. 302Critical drift triggers PagerDuty alert + auto-starts retraining pipeline.`,gradingSuite:[{caseName:"Detect significant feature drift",input:'Feature "user_age": baseline mean=35, current mean=48, PSI=0.35. Feature "income": baseline mean=55K, current mean=54K, PSI=0.02.',criteria:`- output_match: flags user_age as significant drift (weight: 0.4)
303- output_match: income marked as no drift (weight: 0.2) 304- output_match: retrainRecommended is true (weight: 0.2) 305- schema_validation: valid JSON (weight: 0.2)`}]},{slug:"security-vulnerability-scanner",title:"Security Vulnerability Scanner",domain:"Security / Compliance",icon:g.ShieldCheck,tagline:"Continuous codebase security analysis with CVE detection and remediation guidance",description:"Scans codebase for security vulnerabilities: hardcoded secrets, dependency CVEs, insecure configurations, OWASP Top 10 patterns, exposed API keys, and misconfigured CORS/CSP headers. Generates compliance reports (SOC2, ISO27001) with remediation steps and priority scores.",timeSaved:"8-16 hours of manual security audit per sprint",costReduction:"$80K/year vs external penetration testing frequency",riskMitigation:"Reduces security incident probability by 75%",systemPrompt:`You are a security analyst. Scan code and configuration for vulnerabilities. 306 307Rules: 308- Detect hardcoded secrets: API keys, passwords, tokens, private keys (regex + entropy analysis) 309- Check dependencies against NVD/GitHub Advisory Database 310- Identify OWASP Top 10 vulnerabilities in code patterns 311- Analyze infrastructure configs: Dockerfiles, K8s manifests, Terraform 312- Score each finding: CVSS 0-10 313- Output JSON: { criticalCount: number, highCount: number, findings: [...], complianceGaps: [...], remediationPlan: [...] } 314 315Always provide specific remediation steps, not just descriptions.`,skills:[{name:"secret-patterns",content:`<skill name="secret-patterns"> 316Secret detection patterns: 317- AWS: AKIA[0-9A-Z]{16} 318- GitHub: ghp_[a-zA-Z0-9]{36} 319- Stripe: sk_live_[a-zA-Z0-9]{24} 320- Generic API key: [a-zA-Z0-9]{32,} with high entropy (>4.5 Shannon) 321- Private keys: -----BEGIN (RSA|EC|DSA) PRIVATE KEY----- 322- JWT secrets: variable names containing "secret", "jwt_key", "signing_key" 323- Database URLs: postgres://user:password@host (password in cleartext) 324 325False positive reduction: ignore test files, example configs, documentation. 326</skill>`}],tools:[{name:"scan_dependencies",description:"Checks project dependencies against CVE databases",params:'{ "lockfile": { "type": "string", "description": "Content of package-lock.json, yarn.lock, or requirements.txt" } }',executeCode:"const lockfile = args.lockfile || '';\nconst deps = [];\nconst npmMatch = lockfile.match(/\"([^\"]+)\":\\s*\\{[^}]*\"version\":\\s*\"([^\"]+)\"/g);\nif (npmMatch) {\n for (const m of npmMatch) {\n const parts = m.match(/\"([^\"]+)\":\\s*\\{[^}]*\"version\":\\s*\"([^\"]+)\"/);\n if (parts) deps.push({ name: parts[1], version: parts[2] });\n }\n}\nconst pipMatch = lockfile.match(/([a-zA-Z0-9_-]+)==([\\d.]+)/g);\nif (pipMatch) {\n for (const m of pipMatch) {\n const [name, version] = m.split('==');\n deps.push({ name, version });\n }\n}\nconst yarnMatch = lockfile.match(/\"?([^\"@\\n]+)@[^\"\\n]+\"?:\\s*\\n\\s*version\\s+\"([^\"]+)\"/g);\nif (yarnMatch) {\n for (const m of yarnMatch) {\n const parts = m.match(/\"?([^\"@\\n]+)@[^\"\\n]+\"?:\\s*\\n\\s*version\\s+\"([^\"]+)\"/);\n if (parts) deps.push({ name: parts[1].trim(), version: parts[2] });\n }\n}\nif (deps.length === 0) {\n const lines = lockfile.split('\\n').filter(l => l.trim());\n for (const line of lines) {\n const simple = line.match(/^\\s*[\"']?([^\"'\\s:@]+)[\"']?\\s*[:@=]\\s*[\"']?([\\d][\\d.]*)/); \n if (simple) deps.push({ name: simple[1], version: simple[2] });\n }\n}\nconst knownVulns = { 'lodash': '4.17.21', 'minimist': '1.2.6', 'node-fetch': '2.6.7', 'axios': '1.6.0', 'express': '4.18.2', 'jsonwebtoken': '9.0.0', 'tar': '6.1.9', 'json5': '2.2.2', 'semver': '7.5.2', 'qs': '6.10.3', 'shell-quote': '1.7.3', 'trim-newlines': '4.0.2', 'glob-parent': '5.1.2', 'trim': '0.0.3', 'underscore': '1.13.6' };\nconst findings = [];\nfor (const dep of deps) {\n const safe = knownVulns[dep.name];\n if (safe) {\n const cv = dep.version.split('.').map(Number);\n const sv = safe.split('.').map(Number);\n let vuln = false;\n for (let i = 0; i < 3; i++) { if ((cv[i]||0) < (sv[i]||0)) { vuln = true; break; } if ((cv[i]||0) > (sv[i]||0)) break; }\n if (vuln) findings.push({ package: dep.name, installedVersion: dep.version, fixedVersion: safe, severity: 'high' });\n }\n}
326\nresult = JSON.stringify({ totalDependencies: deps.length, vulnerabilities: findings.length, findings, dependencies: deps.slice(0, 50) });"},{name:"analyze_entropy",description:"Calculates Shannon entropy of strings to detect potential secrets",params:'{ "strings": { "type": "array", "items": { "type": "string" } } }',executeCode:"const strings = args.strings || [];\nconst results = [];\nfor (const str of strings) {\n const freq = {};\n for (const ch of str) freq[ch] = (freq[ch] || 0) + 1;\n let entropy = 0;\n const len = str.length;\n for (const count of Object.values(freq)) {\n const p = count / len;\n if (p > 0) entropy -= p * Math.log(p) / Math.log(2);\n }\n entropy = Math.round(entropy * 1000) / 1000;\n const hasHexPattern = /^[0-9a-fA-F]{16,}$/.test(str);\n const hasBase64Pattern = /^[A-Za-z0-9+/=]{20,}$/.test(str);\n const looksLikeJWT = /^eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/.test(str);\n const hasKeyPrefix = /^(sk_|pk_|api_|key_|token_|secret_|aws_|AKIA|ghp_|gho_|ghu_|ghs_|ghr_|xox[bsrap]-|glpat-|v2\\.)/.test(str);\n const isHighEntropy = entropy > 4.5 && len > 8;\n const isPotentialSecret = isHighEntropy || hasHexPattern || hasBase64Pattern || looksLikeJWT || hasKeyPrefix;\n const reasons = [];\n if (isHighEntropy) reasons.push('High Shannon entropy (' + entropy + ' bits)');\n if (hasHexPattern) reasons.push('Matches hex string pattern');\n if (hasBase64Pattern) reasons.push('Matches base64 pattern');\n if (looksLikeJWT) reasons.push('Looks like a JWT token');\n if (hasKeyPrefix) reasons.push('Has known API key prefix');\n results.push({ value: str.length > 20 ? str.slice(0, 8) + '...' + str.slice(-4) : str, fullLength: len, entropy, isPotentialSecret, confidence: isPotentialSecret ? (reasons.length >= 2 ? 'high' : 'medium') : 'low', reasons });\n}\nconst secrets = results.filter(r => r.isPotentialSecret);\nresult = JSON.stringify({ totalAnalyzed: results.length, potentialSecrets: secrets.length, results });"}],mcpIntegration:`Pre-commit hook or CI pipeline stage. 327POST codebase snapshot to /api/mcp. 328Agent returns security report. 329Critical findings block deployment and notify security team.`,gradingSuite:[{caseName:"Detect hardcoded API key",input:'const API_KEY = "sk_test_EXAMPLE_KEY_DO_NOT_USE_1234567890";',criteria:`- output_match: identifies Stripe live key (weight: 0.4) 330- output_match: CVSS score >= 8 (weight: 0.2) 331- output_match: remediation suggests environment variables (weight: 0.2) 332- schema_validation: valid JSON (weight: 0.2)`}]},{slug:"onboarding-knowledge-agent",title:"Onboarding Knowledge Agent",domain:"Engineering Management / HR",icon:h.Users,tagline:"Accelerate developer onboarding with instant answers from internal documentation",description:"Ingests internal documentation (Confluence, Notion, README files, ADRs, runbooks) and serves as an interactive knowledge base for new developers. Answers questions about architecture, deployment procedures, code conventions, team contacts, and access provisioning with source citations.",timeSaved:"2-4 weeks of onboarding reduced to 3-5 days",costReduction:"$25K per new hire in reduced onboarding cost",riskMitigation:"Reduces senior engineer interruptions by 60%",systemPrompt:`You are an engineering team's onboarding assistant. Answer questions using internal documentation. 333 334Rules: 335- Always cite your source: [Doc: <document_name>, Section: <section>] 336- If information is not in the docs, say "I don't have this information. Contact: <suggest relevant team>" 337- For access/provisioning questions, provide step-by-step instructions 338- For architecture questions, describe the system and relevant ADRs 339- Maintain a friendly, encouraging tone for new team members 340- For ambiguous questions, ask clarifying follow-ups 341- Never guess or fabricate internal processes 342 343Priority order for sources: Runbooks > ADRs > README > Confluence > Slack archives`,skills:[{name:"team-directory",content:`<skill name="team-directory"> 344Team escalation guide: 345- Infrastructure/DevOps: #team-platform (on-call rotation in PagerDuty) 346- Backend API: #team-backend 347- Frontend: #team-frontend 348- Data/ML: #team-data 349- Security: #team-security 350- Access provisioning: IT Help Desk ([email protected]) 351- HR questions: [email protected] 352 353For urgent production issues: /incident command in Slack 354</skill>`}],tools:[{name:"search_docs",description:"Semantic search across internal documentation corpus",params:'{ "query": { "type": "string" }, "sources": { "type": "array", "items": { "type": "string" } } }',executeCode:"const query = args.query || '';\nconst sources = args.sources || [];\nconst queryWords = query.toLowerCase().split(/\\s+/).filter(w => w.length > 2);\nresult = JSON.stringify({\n status: 'external_data_required',\n query: query,\n sources: sources,\n instruction: 'Provide documents as an array of {title, content, source, url?, tags?} objects. This tool will perform keyword matching and relevance scoring.',\n queryTokens: queryWords,\n searchStrategy: {\n primary: 'Full-text keyword matching across title and content',\n scoring: 'TF-IDF inspired: matches / total_words * log(doc_count / docs_with_term)',\n fallback: 'If no results, broaden search by removing least common terms'\n },\n tip: 'For best results, provide the documentation corpus in the sources array as structured objects.'\n});"},{name:"get_runbook",description:"Retrieves a specific operational runbook by name",params:'{ "runbookName": { "type": "string" } }',executeCode:"const name = args.runbookName || '';\nconst normalized = name.toLowerCase().replace(/[^a-z0-9]/g, '_');\nresult = JSON.stringify({\n status: 'external_data_required',\n runbookName: name,\n normalizedKey: normalized,\n instruction: 'Provide the runbook content as a structured object with {title, description, steps: [{order, action, command?, expected?, rollback?}], prerequisites, tags}.',\n commonRunbooks: {\n 'database_failover': { description: 'Steps to fail over to database replica', tags: ['database', 'ha', 'incident'] },\n 'deploy_rollback': { description: 'Roll back a failed deployment', tags: ['deploy', 'rollback'] },\n 'scale_up': { description: 'Horizontally scale application tier', tags: ['scaling', 'performance'] },\n 'cert_renewal': { description: 'Renew SSL/TLS certificates', tags: ['security', 'certificates'] },\n 'incident_response': { description: 'General incident response procedure', tags: ['incident', 'oncall'] }\n }\n});"}],mcpIntegration:`Accessible via Slack bot command: /ask-kopern <question> 355Slack integration POST to /api/mcp. 356Agent returns answer with source citations. 357Unanswered questions logged for documentation gap analysis.`,gradingSuite:[{caseName:"Answer deployment question",input:"How do I deploy to staging?",criteria:`- output_match: provides step-by-step instructions (weight: 0.3)
358- output_match: cites source document (weight: 0.3) 359- safety_check: doesn't expose production credentials (weight: 0.2) 360- llm_judge: answer is helpful for a new developer (weight: 0.2)`}]},{slug:"financial-report-analyzer",title:"Financial Report Analyzer",domain:"Finance / Accounting",icon:f.BarChart3,tagline:"Extract KPIs, detect anomalies, and generate executive summaries from financial data",description:"Processes financial reports (P&L, balance sheets, cash flow statements) and extracts key metrics: revenue growth, burn rate, runway, gross margin, CAC/LTV ratio. Detects anomalies (unexpected variances >10%), generates board-ready executive summaries, and benchmarks against industry standards.",timeSaved:"3-5 hours per financial reporting cycle",costReduction:"$35K/year in FP&A analyst time",riskMitigation:"Catches accounting anomalies 10x faster than manual review",systemPrompt:`You are a financial analyst. Analyze financial reports and generate executive summaries. 361 362Rules: 363- Extract key SaaS metrics: MRR, ARR, growth rate, churn, NRR, gross margin, burn rate, runway 364- Flag anomalies: any line item varying >10% from previous period without explanation 365- Calculate ratios: CAC/LTV (healthy > 3x), Rule of 40 (growth % + margin %) 366- Benchmark against SaaS industry medians for the company's stage 367- Generate executive summary: 5-7 bullet points, lead with most important metric 368- Output JSON: { kpis: {...}, anomalies: [...], benchmarks: {...}, executiveSummary: string, healthScore: 0-100 } 369 370Never make investment recommendations. Present data objectively.`,skills:[{name:"saas-benchmarks",content:`<skill name="saas-benchmarks"> 371SaaS benchmark medians by stage: 372Seed: growth >100%, gross margin >60%, burn multiple <3x 373Series A: growth >80%, gross margin >65%, NRR >110% 374Series B: growth >50%, gross margin >70%, NRR >120%, Rule of 40 >40 375Growth: growth >30%, gross margin >75%, NRR >120%, Rule of 40 >50 376 377Red flags: 378- Gross margin < 50% (service business, not SaaS) 379- CAC payback > 18 months 380- Logo churn > 5%/month 381- Burn multiple > 3x (inefficient growth) 382</skill>`}],tools:[{name:"parse_financial_report",description:"Parses CSV/Excel financial data into structured line items",params:'{ "content": { "type": "string" }, "format": { "type": "string", "enum": ["csv", "json"] } }',executeCode:"const content = args.content || '';\nconst format = args.format || 'csv';\nlet items = [];\nif (format === 'json') {\n try {\n const parsed = JSON.parse(content);\n items = Array.isArray(parsed) ? parsed : parsed.items || parsed.data || parsed.lineItems || [parsed];\n } catch (e) { result = JSON.stringify({ error: 'Invalid JSON: ' + e.message }); }\n}\nif (format === 'csv' || items.length === 0 && format !== 'json') {\n const lines = content.trim().split('\\n');\n if (lines.length >= 2) {\n const headers = lines[0].split(',').map(h => h.trim().replace(/^\"|\"$/g, ''));\n for (let i = 1; i < lines.length; i++) {\n const vals = []; let inQ = false; let cur = '';\n for (const ch of lines[i]) { if (ch === '\"') { inQ = !inQ; continue; } if (ch === ',' && !inQ) { vals.push(cur.trim()); cur = ''; continue; } cur += ch; }\n vals.push(cur.trim());\n const row = {};\n headers.forEach((h, idx) => { const v = vals[idx] || ''; row[h] = isNaN(parseFloat(v.replace(/[,$%]/g, ''))) ? v : parseFloat(v.replace(/[,$%]/g, '')); });\n items.push(row);\n }\n }\n}\nif (!items.length) { result = JSON.stringify({ error: 'Could not parse content. Check format parameter.' }); }\nelse {\n const numericFields = Object.keys(items[0]).filter(k => typeof items[0][k] === 'number');\n const summary = {};\n for (const field of numericFields) {\n const values = items.map(i => i[field]).filter(v => typeof v === 'number' && !isNaN(v));\n summary[field] = { total: Math.round(values.reduce((s, v) => s + v, 0) * 100) / 100, min: Math.min(...values), max: Math.max(...values), avg: Math.round(values.reduce((s, v) => s + v, 0) / values.length * 100) / 100, count: values.length };\n }\n result = JSON.stringify({ lineItemCount: items.length, fields: Object.keys(items[0]), numericFields, summary, items: items.slice(0, 20) });\n}"},{name:"get_industry_benchmark",description:"Retrieves industry benchmark data for comparison",params:'{ "industry": { "type": "string" }, "stage": { "type": "string" }, "metric": { "type": "string" } }',executeCode:"const industry = (args.industry || '').toLowerCase();\nconst stage = (args.stage || '').toLowerCase();\nconst metric = (args.metric || '').toLowerCase();\nconst benchmarks = {\n 'saas': {\n 'seed': { 'growth_rate': { median: 15, top_quartile: 30, unit: '% MoM' }, 'burn_multiple': { median: 3.0, top_quartile: 1.5, unit: 'x' }, 'ltv_cac': { median: 1.5, top_quartile: 3.0, unit: 'x' }, 'gross_margin': { median: 65, top_quartile: 75, unit: '%' }, 'churn': { median: 5, top_quartile: 2, unit: '% monthly' } },\n 'series_a': { 'growth_rate': { median: 10, top_quartile: 20, unit: '% MoM' }, 'burn_multiple': { median: 2.5, top_quartile: 1.2, unit: 'x' }, 'ltv_cac': { median: 2.5, top_quartile: 4.0, unit: 'x' }, 'gross_margin': { median: 68, top_quartile: 78, unit: '%' }, 'churn': { median: 3, top_quartile: 1.5, unit: '% monthly' }, 'ndr': { median: 105, top_quartile: 120, unit: '%' } },\n 'series_b': { 'growth_rate': { median: 80, top_quartile: 120, unit: '% YoY' }, 'burn_multiple': { median: 2.0, top_quartile: 1.0, unit: 'x' }, 'ltv_cac': { median: 3.0, top_quartile: 5.0, unit: 'x' }, 'gross_margin': { median: 72, top_quartile: 82, unit: '%' }, 'rule_of_40': { median: 25, top_quartile: 45, unit: '%' } },\n 'growth': { 'growth_rate': { median: 40, top_quartile: 80, unit: '% YoY' }, 'gross_margin': { median: 75, top_quartile: 85, unit: '%' }, 'rule_of_40': { median: 30, top_quartile: 55, unit: '%' }, 'magic_number': { median: 0.7, top_quartile: 1.2, unit: 'x' } }\n },\n 'ecommerce': {\n 'seed': { 'growth_rate': { median: 20, top_quartile: 50, unit: '% MoM' }, 'gross_margin': { median: 40, top_quartile: 55, unit: '%' }, 'cac_payback': { median: 6, top_quartile: 3, unit: 'months' } },\n 'growth': { 'growth_rate': { median: 30, top_quartile: 60, unit: '% YoY' }, 'gross_margin': { median: 45, top_quartile: 60, unit: '%' }, 'repeat_rate': { median: 25, top_quartile: 40, unit: '%' } }\n },\n 'fintech': {\n 'series_a': { 'growth_rate': { median: 12, top_quartile: 25, unit: '% MoM' }, 'gross_margin': { median: 55, top_quartile: 70, unit: '%' }, 'ltv_cac': { median: 2.0, top_quartile: 3.5, unit: 'x' } },\n 'growth': { 'growth_rate': { median: 50, top_quartile: 100, unit: '% YoY' }, 'take_rate': { median: 1.5, top_quartile: 2.5, unit: '%' } }\n }\n};\nconst industryData = benchmarks[industry];\nif (!industryData) { result = JSON.stringify({ error: 'Industry not found', availableIndustries: Object.keys(benchmarks), suggestion: 'Try: saas, ecommerce, fintech' }); }\nelse {\n const stageData = industryData[stage];\n if (!stageData) { result = JSON.stringify({ industry, error: 'Stage not found', availableStages: Object.keys(industryData) }); }\n else if (metric && stageData[metric]) { result = JSON.stringify({ industry, stage, metric, benchmark: stageData[metric] }); }\n else if (metric) { result = JSON.stringify({ industry, stage, error: 'Metric not found', availableMetrics: Object.keys(stageData) }); }\n else { result = JSON.stringify({ industry, stage, benchmarks: stageData }); }\n}"}],mcpIntegration:`Monthly: accounting system exports financial data. 383POST to /api/mcp for analysis. 384Agent returns KPI dashboard data + executive summary. 385Summary auto-sent to CFO and board members via email.`,gradingSuite:[{caseName:"Detect revenue anomaly",input:"Q1 Revenue: $500K. Q2 Revenue: $380K. Q1 Expenses: $400K. Q2 Expenses: $410K.",criteria:`- output_match: flags 24% revenue decline as anomaly (weight: 0.4) 386- output_match: calculates burn rate increase (weight: 0.2) 387- output_match: health score reflects concern (weight: 0.2) 388- schema_validation: valid JSON with kpis object (weight: 0.2)`}]},{slug:"api-schema-changelog",title:"API Schema Changelog Generator",domain:"Platform Engineering",icon:y.Workflow,tagline:"Detect breaking changes between API versions and generate migration guides",description:"Compares two versions of an OpenAPI/GraphQL schema and generates: structured changelog, breaking vs non-breaking change classification, migration guide for API consumers, versioning strategy recommendation, and a draft notification email for affected teams.",timeSaved:"1-2 hours per API release for documentation",costReduction:"Prevents downstream integration breakage ($20K+ per incident)",riskMitigation:"Zero silent breaking changes reaching production",systemPrompt:`You are an API compatibility analyst. Compare API schema versions and generate changelogs. 389 390Rules: 391- Classify changes: breaking | non-breaking | deprecated 392- Breaking: removed endpoints, removed required fields, type changes, auth changes 393- Non-breaking: new optional fields, new endpoints, expanded enums 394- For each breaking change: provide migration code example (before -> after) 395- Recommend versioning: major bump for breaking, minor for features, patch for fixes 396- Generate consumer notification with impact assessment 397- Output JSON: { breakingChanges: [...], nonBreakingChanges: [...], deprecations: [...], migrationGuide: string, suggestedVersion: string } 398 399Never skip reporting a removed field â it's always breaking.`,skills:[{name:"semver-rules",content:`<skill name="semver-rules"> 400API versioning decision tree: 401- Removed endpoint/field -> MAJOR bump 402- Changed field type -> MAJOR bump 403- New required field on request -> MAJOR bump 404- Changed auth scheme -> MAJOR bump 405- New optional field -> MINOR bump 406- New endpoint -> MINOR bump 407- Expanded enum values -> MINOR bump 408- Bug fix in validation -> PATCH bump 409- Documentation only -> PATCH bump 410 411Deprecation policy: mark deprecated, maintain for 2 major versions, then remove. 412</skill>`}],tools:[{name:"diff_openapi",description:"Computes structured diff between two OpenAPI specifications",params:'{ "oldSpec": { "type": "string" }, "newSpec": { "type": "string" } }',executeCode:"let oldSpec, newSpec;\ntry { oldSpec = JSON.parse(args.oldSpec); } catch(e) { oldSpec = null; }\ntry { newSpec = JSON.parse(args.newSpec); } catch(e) { newSpec = null; }\nif (!oldSpec || !newSpec) { result = JSON.stringify({ error: 'Both oldSpec and newSpec must be valid JSON OpenAPI specifications' }); }\nelse {\n const changes = [];\n const oldPaths = Object.keys(oldSpec.paths || {});\n const newPaths = Object.keys(newSpec.paths || {});\n const addedPaths = newPaths.filter(p => !oldPaths.includes(p));\n const removedPaths = oldPaths.filter(p => !newPaths.includes(p));\n const commonPaths = oldPaths.filter(p => newPaths.includes(p));\n for (const p of addedPaths) {\n const methods = Object.keys(newSpec.paths[p]).filter(m => ['get','post','put','patch','delete','head','options'].includes(m));\n changes.push({ type: 'added', path: p, methods, breaking: false });\n }\n for (const p of removedPaths) {\n changes.push({ type: 'removed', path: p, breaking: true, impact: 'Consumers using this endpoint will break' });\n }\n for (const p of commonPaths) {\n const oldMethods = Object.keys(oldSpec.paths[p]).filter(m => ['get','post','put','patch','delete'].includes(m));\n const newMethods = Object.keys(newSpec.paths[p]).filter(m => ['get','post','put','patch','delete'].includes(m));\n const removedMethods = oldMethods.filter(m => !newMethods.includes(m));\n for (const m of removedMethods) changes.push({ type: 'method_removed', path: p, method: m, breaking: true });\n const addedMethods = newMethods.filter(m => !oldMethods.includes(m));\n for (const m of addedMethods) changes.push({ type: 'method_added', path: p, method: m, breaking: false });\n for (const m of oldMethods.filter(mt => newMethods.includes(mt))) {\n const oldParams = (oldSpec.paths[p][m].parameters || []).map(pr => pr.name);
412\n const newParams = (newSpec.paths[p][m].parameters || []).map(pr => pr.name);\n const addedParams = newParams.filter(pr => !oldParams.includes(pr));\n const removedParams = oldParams.filter(pr => !newParams.includes(pr));\n const newRequired = (newSpec.paths[p][m].parameters || []).filter(pr => pr.required && !oldParams.includes(pr.name));\n if (removedParams.length) changes.push({ type: 'params_removed', path: p, method: m, params: removedParams, breaking: true });\n if (newRequired.length) changes.push({ type: 'required_param_added', path: p, method: m, params: newRequired.map(pr => pr.name), breaking: true });\n if (addedParams.length && !newRequired.length) changes.push({ type: 'optional_params_added', path: p, method: m, params: addedParams, breaking: false });\n }\n }\n const breakingChanges = changes.filter(c => c.breaking);\n const versionChange = (oldSpec.info?.version || '') !== (newSpec.info?.version || '');\n result = JSON.stringify({ totalChanges: changes.length, breakingChanges: breakingChanges.length, nonBreaking: changes.length - breakingChanges.length, versionChanged: versionChange, oldVersion: oldSpec.info?.version, newVersion: newSpec.info?.version, changes, recommendation: breakingChanges.length > 0 ? 'Breaking changes detected - bump major version and notify consumers' : 'Non-breaking changes only - safe for minor version bump' });\n}"},{name:"list_api_consumers",description:"Lists known API consumers from API gateway logs",params:'{ "endpointPattern": { "type": "string" } }',executeCode:"const pattern = args.endpointPattern || '';\nresult = JSON.stringify({\n status: 'external_data_required',\n endpointPattern: pattern,\n instruction: 'Provide API gateway/access logs as an array of {endpoint, method, consumerKey?, consumerName?, userAgent?, ip?, requestCount, lastSeen} objects.',\n analysisCapabilities: [\n 'Consumer identification by API key or user agent',\n 'Usage frequency and patterns',\n 'Endpoint dependency mapping',\n 'Impact analysis for breaking changes'\n ],\n sources: ['API Gateway logs (AWS API GW, Kong, Apigee)', 'Load balancer access logs', 'Application-level request logging']\n});"}],mcpIntegration:`Triggered on API spec file change in CI. 413POST old + new spec to /api/mcp. 414Agent returns changelog + migration guide. 415Breaking changes block merge until consumer teams acknowledge.`,gradingSuite:[{caseName:"Detect removed required field",input:'Old: { "user": { "name": "string", "email": "string" } }. New: { "user": { "name": "string" } }',criteria:`- output_match: identifies removed "email" field as breaking (weight: 0.4) 416- output_match: suggests MAJOR version bump (weight: 0.3) 417- output_match: provides migration example (weight: 0.2) 418- schema_validation: valid JSON (weight: 0.1)`}]},{slug:"customer-feedback-classifier",title:"Customer Feedback Classifier",domain:"Product / Customer Success",icon:v.Mail,tagline:"Classify, prioritize and route customer feedback to the right product team",description:"Processes customer feedback from multiple sources (support tickets, NPS surveys, app reviews, social media) and classifies by: sentiment, product area, urgency, feature request vs bug vs complaint. Aggregates trends, detects emerging issues, and routes to the appropriate product team with priority scores.",timeSaved:"5-10 hours/week of manual feedback triage",costReduction:"$30K/year in customer success team time",riskMitigation:"Catches emerging product issues 5x faster, reducing churn",systemPrompt:`You are a customer feedback analyst. Classify, prioritize and route customer feedback. 419 420Rules: 421- Classify type: bug_report | feature_request | complaint | praise | question 422- Sentiment: very_negative (-2) | negative (-1) | neutral (0) | positive (1) | very_positive (2) 423- Urgency: critical (data loss, security) | high (broken workflow) | medium (inconvenience) | low (nice-to-have) 424- Map to product area: onboarding | core_product | billing | integrations | performance | ui_ux 425- Detect trends: same issue reported 3+ times in 7 days = emerging issue 426- Output JSON: { items: [...], trends: [...], routingRecommendations: [...], sentimentScore: number } 427 428Never dismiss negative feedback. Every complaint is a signal.`,skills:[{name:"routing-rules",content:`<skill name="routing-rules">
429Feedback routing matrix: 430- bug_report + critical -> #team-engineering-urgent + PagerDuty 431- bug_report + high -> #team-engineering + Jira (P1) 432- bug_report + medium/low -> #team-engineering + Jira (P2/P3) 433- feature_request -> #team-product + Productboard 434- complaint + billing -> #team-billing + Zendesk escalation 435- complaint + churn_risk -> #team-customer-success + CRM flag 436- praise -> #team-wins (morale boost) 437- question -> Knowledge base gap analysis 438 439Churn risk indicators: mentions "cancel", "alternative", "competitor", "leaving", "frustrated" 440</skill>`}],tools:[{name:"fetch_feedback",description:"Retrieves recent customer feedback from multiple sources",params:'{ "sources": { "type": "array", "items": { "type": "string", "enum": ["zendesk", "nps", "appstore", "twitter"] } }, "since": { "type": "string" } }',executeCode:"const sources = args.sources || [];\nconst since = args.since || '';\nresult = JSON.stringify({\n status: 'external_data_required',\n sources: sources,\n since: since,\n instruction: 'Provide feedback data as an array of {source, text, rating?, category?, userId?, timestamp, sentiment?} objects.',\n analysisCapabilities: [\n 'Sentiment analysis (keyword-based)',\n 'Category clustering',\n 'Trend detection over time',\n 'Common theme extraction',\n 'NPS/CSAT calculation'\n ],\n supportedSources: ['zendesk', 'intercom', 'app_store', 'play_store', 'twitter', 'survey', 'email', 'in_app'],\n sampleInput: [{ source: 'zendesk', text: 'Login page is slow after the update', rating: 2, category: 'performance', timestamp: '2024-01-15T10:00:00Z' }]\n});"},{name:"check_known_issues",description:"Checks if feedback matches any known open issues in Jira",params:'{ "keywords": { "type": "array", "items": { "type": "string" } } }',executeCode:"const keywords = args.keywords || [];\nresult = JSON.stringify({\n status: 'external_data_required',\n keywords: keywords,\n instruction: 'Provide known issues as an array of {key, summary, status, priority, labels, created, updated} objects. This tool will match keywords against issue summaries and labels.',\n jqlQuery: 'status in (Open, \"In Progress\", Reopened) AND (' + keywords.map(k => 'summary ~ \"' + k + '\" OR description ~ \"' + k + '\"').join(' OR ') + ')',\n matchingStrategy: {\n primary: 'Keyword matching against summary and labels',\n scoring: 'Number of keyword matches / total keywords',\n threshold: 'Score > 0.3 considered a potential match'\n }\n});"}],mcpIntegration:`Real-time: webhook on new support ticket / NPS response. 441POST feedback to /api/mcp. 442Agent classifies and routes instantly. 443Daily digest: aggregated trends posted to #product-insights.`,gradingSuite:[{caseName:"Classify churn risk complaint",input:"\"I've been waiting 3 weeks for this bug fix. If it's not resolved by Friday I'm switching to CompetitorX. This is unacceptable for what we're paying.\"",criteria:`- output_match: type is "complaint" (weight: 0.2) 444- output_match: urgency is "high" or "critical" (weight: 0.3) 445- output_match: detects churn risk (weight: 0.3) 446- output_match: routes to customer success (weight: 0.2)`}]},{slug:"agent-team-code-review",title:"Agent Team: Full-Stack Code Review",domain:"Multi-Agent / DevOps",icon:b,tagline:"Three specialist agents review code in parallel, then a coordinator synthesizes a unified report",description:"A team of 3 specialized agents (security, performance, conventions) reviews code in parallel. Each agent focuses on its domain of expertise, producing independent findings. A coordinator agent then synthesizes all findings into a unified, deduplicated report with prioritized action items and an overall merge recommendation.",timeSaved:"45-90 min per complex PR reduced to 20 seconds of parallel analysis",costReduction:"~$80K/year for a team of 10 developers (replaces 3 senior reviewer passes)",riskMitigation:"3x coverage depth â security, performance, and convention issues caught simultaneously",systemPrompt:`You are a coordinator agent managing a team of 3 specialist code reviewers. Your role is to orchestrate parallel reviews and synthesize findings. 447 448Workflow: 4491. Receive the PR diff and metadata (files changed, author, branch) 4502. Delegate to specialists in parallel: 451 - security_agent: OWASP Top 10, auth flaws, injection, data exposure 452 - performance_agent: O(n\xb2) loops, memory leaks, unnecessary re-renders, bundle size 453 - conventions_agent: naming, file structure, test coverage, documentation 4543. Collect all specialist reports 4554. Deduplicate overlapping findings (prefer the specialist's version) 4565. Resolve conflicts (e.g., security recommends X, performance recommends Y) 4576. Produce unified report with priority ranking 458 459Output JSON: 460{ 461 "overallScore": 0-100, 462 "canMerge": boolean, 463 "specialistScores": { "security": number, "performance": number, "conventions": number }, 464 "findings": [{ "source": string, "severity": string, "category": string, "file": string, "line": number, "message": string, "suggestion": string }], 465 "conflicts": [{ "finding1": string, "finding2": string, "resolution": string }], 466 "summary": string 467} 468 469Merge policy: canMerge = true only if overallScore >= 70 AND security score >= 80 AND no critical findings.`,skills:[{name:"team-coordination-protocol",content:`<skill name="team-coordination-protocol"> 470Team Coordination Protocol for Multi-Agent Code Review: 471 4721. Task Distribution: 473 - Parse the diff to identify file types and changed sections 474 - Route security-relevant files (auth, API, DB queries) with HIGH priority to security_agent 475 - Route performance-critical paths (loops, data fetching, rendering) to performance_agent 476 - Send all files to conventions_agent for baseline checks 477 4782. Parallel Execution: 479 - All 3 agents run simultaneously with a 30-second timeout 480 - If a specialist times out, mark its findings as "incomplete" and proceed 481 - Each specialist returns: { score: number, findings: [], confidence: number } 482 4833. Conflict Resolution Rules: 484 - Security always wins over performance (e.g., "use parameterized queries" even if slower) 485 - Performance wins over conventions (e.g., allow unconventional code if 10x faster) 486 - When in doubt, flag for human review rather than auto-resolving 487 4884. Deduplication: 489 - Same file + same line + overlapping message = duplicate 490 - Keep the version from the most relevant specialist 491 - Merge severity upward (if security says "high" and conventions says "medium", use "high") 492</skill>`},{name:"review-synthesis-template",content:`<skill name="review-synthesis-template"> 493Unified Review Synthesis Template: 494 495## Executive Summary 496[2-3 sentences: overall quality, biggest concern, recommendation] 497 498## Specialist Scores 499| Agent | Score | Findings | Critical | 500|-------|-------|----------|----------| 501| Security | X/100 | N | Y/N | 502| Performance | X/100 | N | Y/N | 503| Conventions | X/100 | N | Y/N | 504 505## Critical Findings (must fix before merge) 506[List with file, line, specialist source, and suggested fix] 507
508## Important Findings (should fix) 509[List with file, line, specialist source, and suggested fix] 510 511## Minor Findings (nice to have) 512[Grouped by category] 513 514## Conflicts Resolved 515[Any cases where specialists disagreed, with resolution rationale] 516 517## Merge Recommendation 518[APPROVE / REQUEST_CHANGES / BLOCK with justification] 519</skill>`}],tools:[{name:"delegate_to_specialist",description:"Sends code diff to a specialist agent for focused review and waits for the report",params:'{ "specialist": { "type": "string", "enum": ["security_agent", "performance_agent", "conventions_agent"] }, "diff": { "type": "string" }, "context": { "type": "object", "properties": { "language": { "type": "string" }, "framework": { "type": "string" }, "filePaths": { "type": "array", "items": { "type": "string" } } } } }',executeCode:"const specialist = args.specialist || 'general';\nconst diff = args.diff || '';\nconst context = args.context || {};\nconst specialistPrompts = {\n 'security': { focus: ['injection vulnerabilities', 'auth/authz issues', 'data exposure', 'CSRF/XSS', 'secrets in code', 'insecure dependencies'], checklist: ['Input validation', 'Output encoding', 'Authentication checks', 'Authorization enforcement', 'Cryptographic practices', 'Error handling/info leakage'] },\n 'performance': { focus: ['N+1 queries', 'missing indexes', 'memory leaks', 'unbounded operations', 'blocking I/O', 'cache misses'], checklist: ['Algorithm complexity', 'Database query efficiency', 'Memory allocation patterns', 'Concurrency issues', 'Caching strategy', 'Resource cleanup'] },\n 'architecture': { focus: ['SOLID violations', 'coupling issues', 'abstraction leaks', 'naming conventions', 'design patterns', 'dependency management'], checklist: ['Single responsibility', 'Interface segregation', 'Dependency inversion', 'Layer boundaries', 'Error propagation', 'API contract stability'] },\n 'testing': { focus: ['untested paths', 'edge cases', 'test isolation', 'flaky patterns', 'coverage gaps', 'assertion quality'], checklist: ['Branch coverage', 'Error path testing', 'Boundary conditions', 'Mock appropriateness', 'Test independence', 'Meaningful assertions'] },\n 'general': { focus: ['code clarity', 'error handling', 'documentation', 'conventions', 'maintainability'], checklist: ['Readability', 'Error handling', 'Naming', 'Comments', 'DRY compliance'] }\n};\nconst spec = specialistPrompts[specialist] || specialistPrompts['general'];\nconst diffLines = diff.split('\\n').length;\nconst addedLines = (diff.match(/^\\+[^+]/gm) || []).length;\nconst removedLines = (diff.match(/^-[^-]/gm) || []).length;\nresult = JSON.stringify({ specialist, diffStats: { totalLines: diffLines, added: addedLines, removed: removedLines }, reviewFocus: spec.focus, checklist: spec.checklist, context, instruction: 'Review the diff according to the ' + specialist + ' checklist. Flag issues with severity (critical/high/medium/low), line reference, and suggested fix.', diff: diff.length > 5000 ? diff.slice(0, 5000) + '\\n... (truncated)' : diff });"},{name:"merge_reviews",description:"Combines multiple specialist review reports, deduplicates findings, and resolves conflicts",params:'{ "reviews": { "type": "array", "items": { "type": "object", "properties": { "specialist": { "type": "string" }, "score": { "type": "number" }, "findings": { "type": "array" }, "confidence": { "type": "number" } } } }, "conflictStrategy": { "type": "string", "enum": ["security_first", "performance_first", "flag_for_human"], "default": "security_first" } }',executeCode:"const reviews = args.reviews || [];\nconst strategy = args.conflictStrategy || 'highest_severity';\nconst allFindings = [];\nfor (const review of reviews) {\n const specialist = review.specialist || review.reviewer || 'unknown';\n const findings = review.findings || review.issues || [];\n for (const f of findings) {\n allFindings.push({ ...f, specialist, id: (f.file || '') + ':' + (f.line || 0) + ':' + (f.message || f.title || '').slice(0, 50) });\n }\n}\nconst grouped = {};\nfor (const f of allFindings) {\n const key = (f.file || '') + ':' + (f.line || f.location || 'unknown');\n if (!grouped[key]) grouped[key] = [];\n grouped[key].push(f);\n}\nconst sevOrder = { critical: 4, high: 3, medium: 2, low: 1, info: 0 };\nconst merged = [];\nconst duplicates = [];\nfor (const [loc, findings] of Object.entries(grouped)) {\n if (findings.length > 1) {\n const messages = findings.map(f => (f.message || f.title || '').toLowerCase());\n const isDuplicate = messages.some((m, i) => messages.some((m2, j) => i !== j && (m.includes(m2) || m2.includes(m) || m === m2)));\n if (isDuplicate) {\n const winner = strategy === 'highest_severity' ? findings.sort((a, b) => (sevOrder[b.severity] || 0) - (sevOrder[a.severity] || 0))[0] : findings[0];\n winner.agreedBy = [...new Set(findings.map(f => f.specialist))];\n merged.push(winner);\n duplicates.push({ location: loc, count: findings.length, specialists: winner.agreedBy });\n continue;\n }\n }\n merged.push(...findings);\n}\nmerged.sort((a, b) => (sevOrder[b.severity] || 0) - (sevOrder[a.severity] || 0));
519\nconst bySeverity = {};\nmerged.forEach(f => { bySeverity[f.severity || 'unknown'] = (bySeverity[f.severity || 'unknown'] || 0) + 1; });\nresult = JSON.stringify({ totalFindings: merged.length, deduplicated: duplicates.length, bySeverity, conflictStrategy: strategy, reviewers: [...new Set(reviews.map(r => r.specialist || r.reviewer))], findings: merged, deduplicationDetails: duplicates });"}],mcpIntegration:`Triggered on PR open/update via GitHub webhook. 520POST diff + metadata to /api/mcp. 521Coordinator delegates to 3 specialist agents in parallel. 522Unified report posted as PR comment within 30 seconds. 523Blocks merge if canMerge is false.`,gradingSuite:[{caseName:"Detect SQL injection across specialists",input:`const query = "SELECT * FROM users WHERE id = " + req.params.id; // also has O(n\xb2) nested loop below 524for (let i = 0; i < users.length; i++) { for (let j = 0; j < users.length; j++) { compare(users[i], users[j]); } }`,criteria:`- output_match: security agent flags SQL injection as critical (weight: 0.3) 525- output_match: performance agent flags O(n\xb2) loop (weight: 0.3) 526- output_match: unified report contains both findings deduplicated (weight: 0.2) 527- output_match: canMerge is false due to critical security finding (weight: 0.2)`},{caseName:"Resolve security vs performance conflict",input:"// Using raw SQL for performance-critical batch insert\nconst sql = items.map(i => `INSERT INTO orders VALUES ('${i.id}', '${i.name}')`).join(';');",criteria:`- output_match: security flags string interpolation in SQL (weight: 0.3) 528- output_match: performance acknowledges batch insert intent (weight: 0.2) 529- output_match: conflict resolution recommends parameterized batch insert (weight: 0.3) 530- output_match: security recommendation takes priority (weight: 0.2)`}]},{slug:"pipeline-content-creator",title:"Content Pipeline: Research â Write â SEO",domain:"Pipeline / Content",icon:x,tagline:"A 3-step pipeline where agents research, write, and optimize content sequentially",description:"A 3-step sequential pipeline: Agent 1 researches a topic by searching multiple sources and extracting key facts. Agent 2 transforms the research into polished, structured content matching the brand voice. Agent 3 optimizes the content for SEO â meta tags, keyword density, internal linking, readability score. Each step's output feeds the next.",timeSaved:"4-6 hours per article reduced to 15 minutes of review",costReduction:"~$60K/year replacing freelance writer + SEO specialist costs",riskMitigation:"Consistent brand voice and SEO compliance across 100% of published content",systemPrompt:`You are a content pipeline orchestrator managing a 3-stage sequential workflow. 531 532Pipeline Stages: 5331. RESEARCH (Agent 1): 534 - Search 5-10 authoritative sources on the given topic 535 - Extract key facts, statistics, expert quotes, and trends 536 - Identify content gaps in existing top-ranking articles 537 - Output: { sources: [...], keyFacts: [...], contentGaps: [...], suggestedAngle: string } 538 5392. WRITE (Agent 2): 540 - Receive research output as context 541 - Write article following the content-style-guide skill 542 - Structure: hook intro, H2/H3 sections, data-backed claims, actionable conclusion 543 - Target: 1500-2500 words, Flesch reading score 60-70 544 - Output: { title: string, content: string, wordCount: number, readingLevel: string } 545 5463. SEO_OPTIMIZE (Agent 3): 547 - Receive written article 548 - Apply seo-checklist skill 549 - Optimize: meta title (<60 chars), meta description (<155 chars), keyword placement, internal links 550 - Output: { optimizedContent: string, metaTitle: string, metaDescription: string, seoScore: 0-100, suggestions: [...] } 551 552Final output combines all stages with pipeline metadata (timing, token costs per stage).`,skills:[{name:"content-style-guide",content:`<skill name="content-style-guide"> 553Content Style Guide: 554 555Voice & Tone: 556- Professional but approachable â write like a knowledgeable friend 557- Use active voice (90%+ of sentences) 558- Address the reader as "you" â second person perspective 559- Avoid jargon unless writing for a technical audience (then define on first use) 560 561Structure: 562- Hook: open with a surprising statistic, question, or bold claim (1-2 sentences) 563- Introduction: context + what the reader will learn (1 paragraph) 564- Body: 4-7 H2 sections, each with a clear takeaway 565- Use H3 for sub-points within complex sections 566- Include at least 3 data points or citations per article 567- End each section with a transition to the next 568- Conclusion: summarize key points + clear call-to-action 569 570Formatting: 571- Paragraphs: 2-4 sentences max 572- Use bullet lists for 3+ related items 573- Bold key terms on first appearance 574- Include 1-2 pull quotes or callout boxes per article 575- Target word count: 1500-2500 words 576</skill>`},{name:"seo-checklist",content:`<skill name="seo-checklist"> 577SEO Optimization Checklist: 578 579On-Page Essentials: 580- [ ] Primary keyword in title (first 60 chars) 581- [ ] Primary keyword in first 100 words of body 582- [ ] Primary keyword in at least 2 H2 headings 583- [ ] Keyword density: 1-2% (not stuffing) 584- [ ] Meta title: <60 characters, includes primary keyword 585- [ ] Meta description: 120-155 characters, includes CTA + keyword 586- [ ] URL slug: short, hyphenated, includes keyword 587 588Content Quality Signals:
589- [ ] Word count: 1500+ words for pillar content 590- [ ] Flesch reading ease: 60-70 (accessible to general audience) 591- [ ] At least 3 external links to authoritative sources (DA 50+) 592- [ ] At least 2 internal links to related content 593- [ ] Image alt text includes keyword variation 594- [ ] No orphan pages â linked from at least 1 hub page 595 596Technical: 597- [ ] H1 tag used once (title only) 598- [ ] Logical H2 â H3 hierarchy (no skipped levels) 599- [ ] No duplicate meta descriptions across site 600- [ ] Schema markup: Article type with author, datePublished 601</skill>`}],tools:[{name:"search_sources",description:"Searches multiple content sources for research material on a given topic",params:'{ "query": { "type": "string" }, "sources": { "type": "array", "items": { "type": "string", "enum": ["google_scholar", "news", "blogs", "reddit", "arxiv"] }, "default": ["google_scholar", "news", "blogs"] }, "maxResults": { "type": "number", "default": 10 }, "dateRange": { "type": "string", "enum": ["last_week", "last_month", "last_year", "all_time"], "default": "last_year" } }',executeCode:"const query = args.query || '';\nconst sources = args.sources || [];\nconst maxResults = args.maxResults || 10;\nconst dateRange = args.dateRange || '';\nconst queryWords = query.toLowerCase().split(/\\s+/).filter(w => w.length > 2);\nconst stopWords = new Set(['the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had', 'her', 'was', 'one', 'our', 'out', 'has', 'have', 'from', 'been', 'with', 'this', 'that', 'they', 'will', 'each', 'make', 'how', 'what', 'when', 'where', 'which', 'their']);\nconst keywords = queryWords.filter(w => !stopWords.has(w));\nif (sources.length === 0) {\n result = JSON.stringify({\n status: 'external_data_required',\n query, keywords, maxResults, dateRange,\n instruction: 'Provide source documents as an array of {title, content, url?, date?, source?, tags?} objects.',\n searchStrategy: 'Keyword relevance scoring with TF weighting'\n });\n} else {\n const scored = sources.map(doc => {\n const text = ((doc.title || '') + ' ' + (doc.content || '') + ' ' + (doc.tags || []).join(' ')).toLowerCase();\n let score = 0;\n for (const kw of keywords) {\n const matches = (text.match(new RegExp(kw, 'gi')) || []).length;\n score += matches;\n if ((doc.title || '').toLowerCase().includes(kw)) score += 3;\n }\n return { ...doc, relevanceScore: score };\n }).filter(d => d.relevanceScore > 0).sort((a, b) => b.relevanceScore - a.relevanceScore).slice(0, maxResults);\n result = JSON.stringify({ query, keywords, totalSources: sources.length, resultsFound: scored.length, results: scored });\n}"},{name:"analyze_seo",description:"Analyzes content for SEO metrics including keyword density, readability, and optimization score",params:'{ "content": { "type": "string" }, "primaryKeyword": { "type": "string" }, "secondaryKeywords": { "type": "array", "items": { "type": "string" } }, "targetUrl": { "type": "string" }, "competitorUrls": { "type": "array", "items": { "type": "string" } } }',executeCode:"const content = args.content || '';\nconst primary = args.primaryKeyword || '';\nconst secondary = args.secondaryKeywords || [];\nconst targetUrl = args.targetUrl || '';\nconst words = content.split(/\\s+/).filter(w => w.length > 0);\nconst wordCount = words.length;\nconst sentences = content.split(/[.!?]+/).filter(s => s.trim().length > 0);\nconst avgSentenceLen = sentences.length > 0 ? Math.round(words.length / sentences.length * 10) / 10 : 0;\nconst paragraphs = content.split(/\\n\\n+/).filter(p => p.trim().length > 0);\nconst headings = (content.match(/^#{1,6}\\s.+$/gm) || []);\nconst lower = content.toLowerCase();\nconst primaryCount = primary ? (lower.match(new RegExp(primary.toLowerCase().replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'gi')) || []).length : 0;\nconst primaryDensity = primary && wordCount > 0 ? Math.round(primaryCount / wordCount * 10000) / 100 : 0;\nconst secondaryAnalysis = secondary.map(kw => {\n const count = (lower.match(new RegExp(kw.toLowerCase().replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'gi')) || []).length;\n return { keyword: kw, count, density: Math.round(count / wordCount * 10000) / 100 };\n});\nconst issues = []; const suggestions = [];\nif (wordCount < 300) issues.push('Content too short (< 300 words). Aim for 1000+ for SEO.');\nif (wordCount > 3000) suggestions.push('Consider breaking into multiple pages for very long content.');\nif (primaryDensity < 0.5) issues.push('Primary keyword density too low (' + primaryDensity + '%). Aim for 1-2%.');\nif (primaryDensity > 3) issues.push('Primary keyword density too high (' + primaryDensity + '%). Risk of keyword stuffing.');\nif (headings.length === 0) issues.push('No headings found. Add H1-H3 for structure.');\nif (avgSentenceLen > 25) suggestions.push('Average sentence length is high (' + avgSentenceLen + '). Consider shorter sentences.');\nconst first100 = content.slice(0, 500).toLowerCase();\nif (primary && !first100.includes(primary.toLowerCase())) suggestions.push('Primary keyword not found in first 500 characters.');\nconst readabilityScore = Math.max(0, Math.min(100, 100 - (avgSentenceLen - 15) * 2 - Math.max(0, (wordCount - 2000) / 100)));\nconst seoScore = Math.max(0, Math.min(100, 100 - issues.length * 15 - suggestions.length * 5));\nresult = JSON.stringify({ wordCount, sentenceCount: sentences.length, paragraphCount: paragraphs.length, headingCount: headings.length, avgSentenceLength: avgSentenceLen, primaryKeyword: { keyword: primary, count: primaryCount, density: primaryDensity }, secondaryKeywords: secondaryAnalysis, readabilityScore, seoScore, issues, suggestions, headings: headings.map(h => h.trim()) });"}],mcpIntegration:`Content team submits topic + target keyword via form. 602POST to /api/mcp triggers the 3-stage pipeline. 603Each stage streams progress via SSE events. 604Final optimized article returned for human review before publishing. 605Pipeline metadata (timing, cost per stage) logged for optimization.`,gradingSuite:[{caseName:"Full pipeline produces SEO-optimized article",input:'Topic: "Microservices vs Monolith in 2026". Primary keyword: "microservices architecture". Target audience: CTOs and tech leads.',criteria:`- output_match: research stage returns 5+ sources with key facts (weight: 0.25) 606- output_match: article has proper H2/H3 structure with 1500+ words (weight: 0.25) 607- output_match: SEO score >= 80 with meta title and description (weight: 0.25) 608- output_match: pipeline includes timing metadata for all 3 stages (weight: 0.25)`},{caseName:"Pipeline handles thin research gracefully",input:'Topic: "Quantum-resistant API authentication patterns". Primary keyword: "post-quantum API security". Target audience: security engineers.',criteria:`- output_match: research stage flags limited sources and adjusts expectations (weight: 0.3) 609- output_match: article clearly states emerging/evolving nature of the topic (weight: 0.3) 610- output_match: SEO agent adapts keyword strategy for low-volume keyword (weight: 0.2) 611- output_match: content includes appropriate caveats about nascent technology (weight: 0.2)`}]},{slug:"meta-agent-builder",title:"Meta-Agent: AI Agent Architect",domain:"Meta-Agent / Platform",icon:w.Sparkles,tagline:"Describe what you need in plain language and get a fully configured agent",description:"An AI agent that builds other agents. Describe your use case in plain language and it generates the complete agent configuration: system prompt, skills (with content), tools (with JSON Schema params), grading suite, and MCP integration instructions. Validates the spec for internal
611consistency and suggests improvements based on agent design best practices.",timeSaved:"2-4 hours of agent configuration reduced to a 5-minute conversation",costReduction:"Enables non-technical users to build agents ($0 training cost)",riskMitigation:"Generated configs follow proven patterns, reducing misconfiguration by 85%",systemPrompt:`You are a meta-agent that designs and builds AI agent configurations for the Kopern platform. 612 613Process: 6141. UNDERSTAND: Ask clarifying questions about the user's use case, domain, and constraints 6152. DESIGN: Choose the right architecture pattern (single agent, pipeline, team, router) 6163. BUILD: Generate the complete agent configuration: 617 - systemPrompt: detailed, with clear rules, output format, and safety guardrails 618 - skills: 2-4 markdown skill files with domain knowledge 619 - tools: 1-3 tools with JSON Schema params and clear descriptions 620 - gradingSuite: 2-3 test cases covering happy path + edge cases 621 - mcpIntegration: integration instructions for the user's workflow 622 6234. VALIDATE: Check for: 624 - Prompt-tool consistency (tools referenced in prompt actually exist) 625 - Skill coverage (no domain knowledge gaps) 626 - Grading completeness (tests cover all critical behaviors) 627 - Security (no prompt injection vectors, proper input validation) 628 6295. ITERATE: Present the config, explain design choices, offer refinements 630 631Output the config as a valid JSON object matching the Kopern UseCase interface: 632{ 633 slug: string, 634 title: string, 635 domain: string, 636 systemPrompt: string, 637 skills: [{ name: string, content: string }], 638 tools: [{ name: string, description: string, params: string }], 639 gradingSuite: [{ caseName: string, input: string, criteria: string }], 640 mcpIntegration: string 641} 642 643Always explain WHY you made each design choice.`,skills:[{name:"kopern-architecture-guide",content:`<skill name="kopern-architecture-guide"> 644Kopern Platform Architecture Guide: 645 646Agent Types: 6471. Single Agent â one prompt, tools, skills. Best for focused tasks (review, classify, generate). 6482. Pipeline â sequential stages (A â B â C). Best when each stage transforms the output. Each stage is an independent agent with its own prompt. 6493. Team â parallel agents + coordinator. Best when multiple perspectives are needed simultaneously. 6504. Router â conditional delegation. A triage agent picks the right specialist based on input. 651 652Component Design Rules: 653- System Prompt: 200-500 words. Include: role, rules, output format, safety constraints. 654- Skills: domain knowledge injected as XML blocks. Keep each under 300 words. Focus on facts/rules, not instructions. 655- Tools: each tool does ONE thing. Params should be strongly typed with enums where possible. 656- Grading Suite: minimum 2 cases â one happy path, one edge case. Use weighted criteria summing to 1.0. 657 658MCP Integration: 659- All agents are accessible via POST /api/mcp (JSON-RPC 2.0) 660- Auth: Bearer token with kpn_ prefix 661- Streaming: SSE for long-running agents 662- Webhooks: trigger agents from external events (GitHub, Slack, CI) 663</skill>`},{name:"agent-design-patterns",content:`<skill name="agent-design-patterns"> 664Agent Design Patterns & Anti-Patterns: 665 666PATTERNS (use these): 667- Deterministic Shell: 67-91% of workflow is code, LLM only for ambiguous reasoning 668- Grader Gates: every LLM output passes through deterministic validators before downstream use 669- Context Injection: use skills to inject domain knowledge rather than cramming into the prompt 670- Fail-Safe Defaults: if LLM is uncertain, output a safe default + flag for human review 671- Scoped Tools: tools have narrow permissions and validate inputs against schema 672 673ANTI-PATTERNS (avoid these): 674- God Prompt: trying to encode all behavior in one massive system prompt (>1000 words) 675- Tool Explosion: exposing 10+ tools to a single agent (causes selection confusion) 676- Missing Guardrails: no output validation, no safety checks, no grading suite 677- Implicit Knowledge: assuming the LLM knows domain-specific rules without skill injection 678- Unbounded Loops: agent can call tools indefinitely without a max-iteration check 679 680Prompt Engineering Tips: 681- Start with role ("You are a...") then context, then rules, then output format 682- Use numbered lists for sequential steps 683- Use "Never..." for hard constraints 684- Include an example output when the format is complex 685- End with the most important instruction (recency bias) 686</skill>`}
686],tools:[{name:"create_agent_config",description:"Generates a complete agent configuration from a natural language description of the use case",params:'{ "description": { "type": "string", "description": "Natural language description of the desired agent" }, "domain": { "type": "string", "description": "Business domain (e.g., DevOps, Marketing, Finance)" }, "complexity": { "type": "string", "enum": ["single", "pipeline", "team", "router"], "default": "single" }, "constraints": { "type": "object", "properties": { "maxTools": { "type": "number", "default": 3 }, "maxSkills": { "type": "number", "default": 4 }, "requireGrading": { "type": "boolean", "default": true } } } }',executeCode:"const desc = args.description || '';\nconst domain = args.domain || 'general';\nconst complexity = args.complexity || 'medium';\nconst constraints = args.constraints || {};\nconst maxTools = constraints.maxTools || (complexity === 'simple' ? 3 : complexity === 'complex' ? 10 : 5);\nconst maxSkills = constraints.maxSkills || (complexity === 'simple' ? 2 : complexity === 'complex' ? 6 : 3);\nconst domainTemplates = {\n 'coding': { suggestedModel: 'claude-sonnet-4-20250514', suggestedTools: ['read_file', 'search_files', 'github_write'], suggestedSkills: ['code_review', 'refactoring', 'testing'], systemPromptPrefix: 'You are an expert softw
686are engineer.' },\n 'customer_support': { suggestedModel: 'claude-sonnet-4-20250514', suggestedTools: ['search_docs', 'check_known_issues'], suggestedSkills: ['empathetic_response', 'escalation', 'troubleshooting'], systemPromptPrefix: 'You are a helpful customer support agent.' },\n 'data_analysis': { suggestedModel: 'claude-sonnet-4-20250514', suggestedTools: ['parse_financial_report', 'compute_psi'], suggestedSkills: ['data_interpretation', 'visualization_guidance', 'statistical_analysis'], systemPromptPrefix: 'You are a data analyst specializing in insights.' },\n 'devops': { suggestedModel: 'claude-sonnet-4-20250514', suggestedTools: ['parse_alert_timeline', 'execute_runbook', 'query_metrics'], suggestedSkills: ['incident_response', 'monitoring', 'automation'], systemPromptPrefix: 'You are a DevOps/SRE engineer.' },\n 'general': { suggestedModel: 'claude-sonnet-4-20250514', suggestedTools: [], suggestedSkills: ['task_planning', 'research'], systemPromptPrefix: 'You are a helpful AI assistant.' }\n};\nconst template = domainTemplates[domain] || domainTemplates['general'];\nconst config = {\n name: desc.split(' ').slice(0, 4).join(' ') || domain + ' Agent',\n description: desc,\n domain,\n complexity,\n model: constraints.model || template.suggestedModel,\n systemPrompt: (constraints.systemPromptOverride || template.systemPromptPrefix) + '\\n\\n' + desc,\n suggestedTools: template.suggestedTools.slice(0, maxTools),\n suggestedSkills: template.suggestedSkills.slice(0, maxSkills),\n settings: {\n temperature: complexity === 'simple' ? 0.3 : complexity === 'complex' ? 0.7 : 0.5,\n maxTokens: complexity === 'simple' ? 1024 : complexity === 'complex' ? 4096 : 2048,\n purposeGate: true,\n tillDone: complexity === 'complex'\n },\n constraints\n};\nresult = JSON.stringify(config);"},{name:"validate_agent_spec",description:"Validates an agent configuration for internal consistency, security, and completeness",params:'{ "config": { "type": "object", "description": "The agent configuration to validate" }, "checks": { "type": "array", "items": { "type": "string", "enum": ["prompt_tool_consistency", "skill_coverage", "grading_completeness", "security_audit", "output_format_validity"] }, "default": ["prompt_tool_consistency", "skill_coverage", "grading_completeness", "security_audit"] } }',executeCode:"const config = args.config || {};\nconst checks = args.checks || ['required_fields', 'model_validity', 'prompt_quality', 'tool_config'];\nconst errors = []; const warnings = []; const passed = [];\nif (checks.includes('required_fields')) {\n const required = ['name', 'description', 'systemPrompt'];\n for (const field of required) {\n if (!config[field]) errors.push({ check: 'required_fields', field, message: field + ' is required' });\n else passed.push('required_fields:' + field);\n }\n}\nif (checks.includes('model_validity')) {\n const validModels = ['claude-sonnet-4-20250514', 'claude-opus-4-20250514', 'claude-haiku-35-20241022', 'gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gemini-2.5-pro', 'gemini-2.5-flash'];\n if (config.model && !validModels.includes(config.model)) warnings.push({ check: 'model_validity', message: 'Model \"' + config.model + '\" not in known list. Verify it exists.' });\n else if (config.model) passed.push('model_validity');\n}\nif (checks.includes('prompt_quality')) {\n const prompt = config.systemPrompt || '';\n if (prompt.length < 50) warnings.push({ check: 'prompt_quality', message: 'System prompt is very short (' + prompt.length + ' chars). Consider adding more context.' });\n if (prompt.length > 10000) warnings.push({ check: 'prompt_quality', message: 'System prompt is very long (' + prompt.length + ' chars). Consider using skills for detailed instructions.' });\n if (!/you are|your role|as a/i.test(prompt)) warnings.push({ check: 'prompt_quality', message: 'System prompt lacks role definition. Start with \"You are...\"' });\n if (prompt.length >= 50) passed.push('prompt_quality:length');\n}\nif (checks.includes('tool_config')) {\n const tools = config.tools || config.suggestedTools || [];\n if (tools.length > 15) warnings.push({ check: 'tool_config', message: 'Too many tools (' + tools.length + '). Consider reducing to avoid context bloat.' });\n if (tools.length === 0 && config.complexity === 'complex') warnings.push({ check: 'tool_config', message: 'Complex agent has no tools configured.' });\n passed.push('tool_config');\n}\nconst valid = errors.length === 0;\nresult = JSON.stringify({ valid, errors, warnings, passed, checksRun: checks, score: Math.max(0, 100 - errors.length * 25 - warnings.length * 10) });"}],mcpIntegration:`User describes their agent need in natural language via the Kopern UI. 687POST description to /api/mcp. 688Meta-agent asks clarifying questions (streamed via SSE). 689Generates full agent config and validates it. 690Config is importable directly into Kopern as a new agent.`,gradingSuite:[{caseName:"Generate agent from simple description",input:'"I need an agent that reads customer support emails and classifies them by urgency (low/medium/high/critical) and department (billing, technical, general). It should work with our Zendesk webhook."',criteria:`- output_match: generates systemPrompt with classification rules and output format (weight: 0.3) 691- output_match: includes at least 1 skill with classification criteria (we
691ight: 0.2) 692- output_match: includes a tool for fetching email content (weight: 0.2) 693- output_match: grading suite tests both urgency and department classification (weight: 0.2) 694- schema_validation: output matches Kopern UseCase interface (weight: 0.1)`},{caseName:"Detect and fix anti-patterns in user request",input:'"Build me an agent with 15 tools that can do everything: code review, write docs, deploy to AWS, manage Jira tickets, send Slack messages, and analyze metrics. Put all the instructions in one big prompt."',criteria:`- output_match: recommends splitting into multiple agents or a pipeline/team (weight: 0.3) 695- output_match: warns about tool explosion anti-pattern (weight: 0.2) 696- output_match: warns about god prompt anti-pattern (weight: 0.2) 697- output_match: suggests a scoped alternative architecture (weight: 0.2) 698- output_match: explains why the suggested approach is better (weight: 0.1)`}]},{slug:"multi-agent-incident-response",title:"Incident Response Squad",domain:"Multi-Agent / SRE",icon:S,tagline:"Router agent triages alerts to the right specialist, who diagnoses and fixes while a comms agent updates stakeholders",description:"Conditional team execution for incident response. A router agent reads incoming alerts and classifies the incident type (database, network, application, security). The appropriate specialist agent diagnoses the issue using runbooks and metrics, then proposes a fix. A communication agent drafts status page updates and stakeholder notifications throughout the process.",timeSaved:"15-30 min of initial triage + 30-60 min of status communication per incident",costReduction:"~$120K/year for a 5-person on-call rotation (faster MTTR, less toil)",riskMitigation:"Reduces MTTR by 65% with automated triage and parallel diagnosis + communication",systemPrompt:`You are an incident response router agent. Your job is to triage incoming alerts, delegate to the right specialist, and coordinate communication. 699 700Workflow: 7011. TRIAGE: Analyze the alert payload (source, severity, affected service, error patterns) 7022. CLASSIFY: Determine incident type: 703 - database: connection pool exhaustion, replication lag, deadlocks, disk space 704 - network: DNS failures, certificate expiry, load balancer errors, latency spikes 705 - application: OOM kills, crash loops, error rate spikes, deployment failures 706 - security: unauthorized access, DDoS, data exfiltration, CVE exploitation 7073. ROUTE: Delegate to the matching specialist agent with full alert context 7084. COMMUNICATE: In parallel, activate the communication agent to begin drafting status updates 7095. SYNTHESIZE: Combine specialist diagnosis + proposed fix into an incident report 710 711Severity Levels: 712- SEV1 (critical): revenue-impacting, >50% users affected â page all on-call + VP Eng 713- SEV2 (high): degraded service, >10% users affected â page primary on-call 714- SEV3 (medium): non-critical service degraded â notify #incidents channel 715- SEV4 (low): cosmetic or monitoring false positive â log and auto-resolve 716 717Output JSON: 718{ 719 "incidentId": string, 720 "severity": "SEV1" | "SEV2" | "SEV3" | "SEV4", 721 "type": "database" | "network" | "application" | "security", 722 "rootCause": string, 723 "diagnosis": { "specialist": string, "findings": [...], "confidence": number }, 724 "proposedFix": { "steps": [...], "estimatedTime": string, "riskLevel": string }, 725 "statusUpdate": { "external": string, "internal": string }, 726 "timeline": [{ "timestamp": string, "event": string }] 727} 728 729Never auto-execute fixes for SEV1 incidents â always require human approval.`,skills:[{name:"runbook-library",content:`<skill name="runbook-library"> 730Incident Runbook Library: 731 732DATABASE: 733- Connection pool exhaustion: 734 1. Check current connections: SELECT count(*) FROM pg_stat_activity 735 2. Identify long-running queries: SELECT * FROM pg_stat_activity WHERE state != 'idle' AND query_start < now() - interval '5 min' 736 3. Kill stuck connections if safe: SELECT pg_terminate_backend(pid) 737 4. Scale connection pool if recurring (PgBouncer max_client_conn) 738 739- Replication lag > 30s: 740 1. Check WAL sender status: SELECT * FROM pg_stat_replication 741 2. Verify network between primary and replica 742 3. Check disk I/O on replica (iostat -x 1) 743 4. If persistent: failover to standby, rebuild lagging replica 744 745NETWORK: 746- Certificate expiry: 747 1. Check cert: openssl s_client -connect host:443 | openssl x509 -noout -dates 748 2. Renew via cert-manager or manual renewal 749 3. Verify renewal: curl -vI https://host 750 751APPLICATION: 752- OOM Kill: 753 1. Check: dmesg | grep -i "out of memory" 754 2. Review memory limits in k8s: kubectl describe pod 755 3. Heap dump analysis if Java/Node 756 4. Increase limits or fix memory leak 757 758SECURITY: 759- Unauthorized access: 760 1. Identify source IP and affected accounts 761 2. Block IP at WAF level immediately 762 3. Force password reset for affected accounts 763 4. Check audit logs for data access 764</skill>`},{name:"communication-templates",content:`<skill name="communication-templates"> 765Incident Communication Templates: 766 767EXTERNAL STATUS PAGE (customer-facing): 768--- 769**[Investigating/Identified/Monitoring/Resolved] - [Service Name]** 770 771We are currently investigating [brief description of impact]. 772 773Affected services: [list] 774Impact: [percentage of users, specific functionality] 775Started: [timestamp UTC] 776 777We will provide updates every [15/30/60] minutes. 778 779Next update by: [timestamp UTC] 780--- 781 782INTERNAL SLACK (#incidents): 783--- 784ð¨ **[SEV level] - [Service] - [One-line summary]** 785 786**Alert source:** [PagerDuty/Datadog/CloudWatch] 787**Impact:** [user-facing description]
788**Assigned to:** [specialist type] 789**Current status:** [Triaging/Diagnosing/Fixing/Verifying] 790 791**Timeline:** 792- HH:MM UTC â Alert received 793- HH:MM UTC â Triaged as [type], routed to [specialist] 794- HH:MM UTC â [Latest update] 795 796**Next steps:** [what's happening now] 797--- 798 799EXECUTIVE SUMMARY (post-resolution): 800--- 801**Incident #[ID] â [Title]** 802Duration: [X minutes/hours] 803Severity: [SEV level] 804Root cause: [1-2 sentences] 805Fix applied: [1-2 sentences] 806Action items: [numbered list] 807--- 808</skill>`}],tools:[{name:"query_metrics",description:"Queries monitoring systems for real-time metrics related to the incident",params:'{ "source": { "type": "string", "enum": ["datadog", "cloudwatch", "prometheus", "pagerduty"] }, "query": { "type": "string", "description": "Metric query (e.g., \'avg:system.cpu.user{service:api} last_15m\')" }, "timeRange": { "type": "object", "properties": { "start": { "type": "string" }, "end": { "type": "string" } } }, "aggregation": { "type": "string", "enum": ["avg", "max", "min", "sum", "count"], "default": "avg" } }',executeCode:"const source = args.source || '';\nconst query = args.query || '';\nconst timeRange = args.timeRange || {};\nconst aggregation = args.aggregation || 'avg';\nresult = JSON.stringify({\n status: 'external_data_required',\n source: source,\n query: query,\n timeRange: timeRange,\n aggregation: aggregation,\n instruction: 'Provide metric data as an array of {timestamp, value, labels?} objects. This tool will compute the requested aggregation.',\n supportedAggregations: ['avg', 'sum', 'min', 'max', 'p50', 'p95', 'p99', 'count', 'rate'],\n queryExamples: {\n prometheus: 'rate(http_requests_total{status=\"500\"}[5m])',\n datadog: 'avg:system.cpu.user{host:web-*}',\n cloudwatch: 'AWS/EC2 CPUUtilization'\n },\n tip: 'If you have the raw data, provide it directly and specify the aggregation type.'\n});"},{name:"execute_runbook",description:"Executes a predefined runbook step in the target environment (requires approval for SEV1)",params:`{ "runbookId": { "type": "string", "description": "ID of the runbook to execute (e.g., 'db_kill_connections')" }, "stepIndex": { "type": "number", "description": "Which step to execute (0-indexed)" }, "targetEnvironment": { "type": "string", "enum": ["production", "staging"] }, "dryRun": { "type": "boolean", "default": true, "description": "If true, simulate the step without applying changes" }, "approvedBy": { "type": "string", "description": "Required for production SEV1 â email of approver" } }`,executeCode:"const runbookId = args.runbookId || '';\nconst stepIndex = args.stepIndex !== undefined ? args.stepIndex : 0;\nconst targetEnv = args.targetEnvironment || 'staging';\nconst dryRun = args.dryRun !== undefined ? args.dryRun : true;\nconst approvedBy = args.approvedBy || '';\nconst safetyChecks = [];\nif (targetEnv === 'production' && !approvedBy) safetyChecks.push({ check: 'approval_required', passed: false, message: 'Production execution requires approvedBy field' });\nif (targetEnv === 'production' && dryRun === false) safetyChecks.push({ check: 'production_warning', passed: true, message: 'WARNING: This will execute against production' });\nif (!runbookId) safetyChecks.push({ check: 'runbook_exists', passed: false, message: 'runbookId is required' });\nconst blocked = safetyChecks.some(c => !c.passed);\nresult = JSON.stringify({\n status: blocked ? 'blocked' : 'ready_for_execution',\n runbookId, stepIndex, targetEnvironment: targetEnv, dryRun, approvedBy,\n safetyChecks,\n message: blocked ? 'Execution blocked by safety checks. Resolve issues before proceeding.' : dryRun ? 'Dry run mode - no changes will be made. Set dryRun=false to execute.' : 'Ready for execution. Provide the runbook steps and this tool will validate and track execution.',\n instruction: 'This tool validates execution safety. Provide runbook content as {steps: [{action, command, expected, rollback}]} to execute a specific step.',\n auditTrail: { timestamp: new Date().toISOString(), runbookId, step: stepIndex, environment: targetEnv, dryRun, approvedBy, status: blocked ? 'blocked' : 'validated' }\n});"}],mcpIntegration:`Alert webhook (PagerDuty/Datadog) sends payload to /api/mcp. 809Router agent triages and delegates to specialist in <5 seconds. 810Communication agent streams status updates via SSE.
811Specialist diagnosis and proposed fix returned within 60 seconds. 812Human approves fix for SEV1; auto-applied for SEV3/SEV4. 813Full incident timeline logged for post-mortem generation.`,gradingSuite:[{caseName:"Triage database connection pool alert",input:'Alert: "PostgreSQL connection pool exhausted on prod-db-01. Active connections: 500/500. Service: payment-api. Error rate spike: 45% of requests returning 500. Started: 2 minutes ago."',criteria:`- output_match: classifies as "database" type (weight: 0.2) 814- output_match: severity is SEV1 or SEV2 (revenue-impacting payment service) (weight: 0.2) 815- output_match: routes to database specialist with connection pool runbook (weight: 0.2) 816- output_match: communication agent drafts status update mentioning payment impact (weight: 0.2) 817- output_match: proposed fix includes killing long-running queries + pool scaling (weight: 0.2)`},{caseName:"Route security incident with communication",input:'Alert: "Unusual login pattern detected. 150 failed login attempts from IP 203.0.113.42 in 5 minutes targeting admin endpoints. 3 successful logins from same IP to different accounts. GeoIP: unexpected region."',criteria:`- output_match: classifies as "security" type with SEV1 severity (weight: 0.25) 818- output_match: proposes immediate IP block at WAF (weight: 0.25) 819- output_match: proposes forced password reset for compromised accounts (weight: 0.25) 820- output_match: communication includes internal alert to security team + external notice if data accessed (weight: 0.25)`}]},{slug:"orchestrated-data-pipeline",title:"Observable Data Pipeline",domain:"Pipeline / Observability",icon:k.Eye,tagline:"A fully traced ETL pipeline with token cost tracking, error handling, and quality validation at every step",description:"A pipeline with full observability across 4 stages: Extract (pull data from sources), Transform (clean, normalize, enrich), Validate (data quality checks), and Load (write to destination). Every step emits structured session events with timing, token costs, and error tracking. Built-in data quality rules catch schema violations, null rates, and distribution anomalies before loading.",timeSaved:"3-8 hours of manual ETL debugging reduced to instant root-cause identification",costReduction:"~$50K/year in data engineering time + prevents $200K+ in bad-data downstream costs",riskMitigation:"99.5% data quality with pre-load validation â zero silent data corruption",systemPrompt:`You are a data pipeline orchestrator with full observability. Manage a 4-stage ETL pipeline where every step is traced. 821 822Pipeline Stages: 8231. EXTRACT: Pull data from configured sources (APIs, databases, file stores) 824 - Emit event: { stage: "extract", status: "start|success|error", source: string, recordCount: number, durationMs: number } 825 - Handle pagination, rate limiting, retries (max 3, exponential backoff) 826 8272. TRANSFORM: Clean, normalize, and enrich the extracted data 828 - Apply transformation rules from the data-quality-rules skill 829 - Emit event: { stage: "transform", transformations: [...], recordsIn: number, recordsOut: number, droppedRecords: number, tokenCost: number } 830 - Track every LLM call cost (token in/out) for transformation steps 831 8323. VALIDATE: Run quality checks before loading 833 - Schema validation: all required fields present, correct types 834 - Null rate check: flag columns with >5% nulls 835 - Distribution check: detect outliers (>3 std deviations from mean) 836 - Referential integrity: foreign keys resolve 837 - Emit event: { stage: "validate", passed: boolean, checks: [...], failedRecords: number } 838 8394. LOAD: Write validated data to destination 840 - Batch insert with transaction safety 841 - Emit event: { stage: "load", destination: string, recordsLoaded: number, durationMs: number } 842 843Final output: 844{ 845 "pipelineId": string, 846 "status": "success" | "partial" | "failed", 847 "stages": [{ stage: string, status: string, durationMs: number, tokenCost: number, events: [...] }], 848 "qualityReport": { "totalRecords": number, "validRecords": number, "qualityScore": number }, 849 "totalCost": { "tokens": number, "estimatedUsd": number }, 850 "errors": [{ "stage": string, "message": string, "recordId": string }] 851} 852 853Never load data that fails validation. Always emit events â observability is non-negotiable.`,skills:[{name:"data-quality-rules",content:`<skill name="data-quality-rules"> 854Data Quality Rules Engine: 855 856SCHEMA RULES: 857- Every record must match the declared schema (field names, types, constraints)
858- Required fields with null values â reject record, log reason 859- Type coercion allowed for: stringânumber (if parseable), ISO date stringsâDate 860- Unknown fields: warn but allow (forward compatibility) 861 862NULL RATE THRESHOLDS: 863- Critical fields (IDs, timestamps): 0% nulls allowed 864- Important fields (names, amounts): <2% nulls 865- Optional fields: <10% nulls 866- Above threshold â pipeline pauses, alerts data team 867 868DISTRIBUTION CHECKS: 869- Numeric columns: flag values > 3 standard deviations from rolling 30-day mean 870- Categorical columns: flag new categories not seen in last 90 days 871- Date columns: flag records with future dates or dates > 1 year old 872- Volume: flag if record count deviates >20% from same-day-last-week 873 874DEDUPLICATION: 875- Primary key duplicates: keep latest by timestamp, log dropped record 876- Fuzzy duplicates: flag for human review (don't auto-deduplicate) 877 878FRESHNESS: 879- Data older than configured SLA (default: 1 hour) triggers stale data warning 880- Pipeline run time > 2x historical average triggers performance alert 881</skill>`},{name:"etl-patterns",content:`<skill name="etl-patterns"> 882ETL Best Practices & Patterns: 883 884EXTRACTION PATTERNS: 885- Incremental: only pull records changed since last run (use watermark/cursor) 886- Full refresh: pull everything, compare with existing, apply delta 887- CDC (Change Data Capture): stream changes in real-time from source DB binlog 888- Always prefer incremental â full refresh is 10-100x more expensive 889 890TRANSFORMATION PATTERNS: 891- Idempotent: running the same transform twice produces the same result 892- Immutable staging: write raw data first, transform in a separate step 893- Schema-on-read: store raw, validate on query (flexible but risky) 894- Schema-on-write: validate before storing (strict, recommended for this pipeline) 895 896ERROR HANDLING: 897- Dead letter queue: failed records go to a separate store for manual review 898- Circuit breaker: if error rate > 10% in a batch, halt pipeline and alert 899- Partial success: load valid records, quarantine invalid ones, report both counts 900 901OBSERVABILITY: 902- Every stage emits structured events (not just logs) 903- Track: duration, record counts (in/out/dropped), token costs, error details 904- Pipeline-level metrics: total duration, overall quality score, cost per record 905- Alerting: Slack/PagerDuty on failure, daily digest on success with quality trends 906</skill>`}],tools:[{name:"fetch_data_source",description:"Extracts data from a configured source with pagination and retry support",params:'{ "sourceId": { "type": "string", "description": "Registered data source identifier" }, "sourceType": { "type": "string", "enum": ["rest_api", "database", "s3", "gcs", "sftp"] }, "query": { "type": "object", "properties": { "endpoint": { "type": "string" }, "filters": { "type": "object" }, "cursor": { "type": "string" }, "limit": { "type": "number", "default": 1000 } } }, "retryConfig": { "type": "object", "properties": { "maxRetries": { "type": "number", "default": 3 }, "backoffMs": { "type": "number", "default": 1000 } } } }',executeCode:"const sourceId = args.sourceId || '';\nconst sourceType = args.sourceType || '';\nconst query = args.query || {};\nconst retryConfig = args.retryConfig || { maxRetries: 3, backoffMs: 1000 };\nresult = JSON.stringify({\n status: 'external_data_required',\n sourceId, sourceType, query, retryConfig,\n instruction: 'Provide the data directly. This tool validates the query structure and would connect to the source if network access were available.',\n supportedTypes: {\n 'postgres': { queryFormat: 'SQL string', example: { sql: 'SELECT * FROM users WHERE created_at > $1', params: ['2024-01-01'] } },\n 'mongodb': { queryFormat: 'MongoDB filter object', example: { collection: 'users', filter: { status: 'active' }, projection: { name: 1, email: 1 } } },\n 'rest_api': { queryFormat: 'HTTP request config', example: { method: 'GET', path: '/api/data', headers: {}, queryParams: {} } },\n 'csv': { queryFormat: 'File path or content', example: { filePath: '/data/export.csv', delimiter: ',' } },\n 'elasticsearch': { queryFormat: 'ES query DSL', example: { index: 'logs-*', body: { query: { match: { level: 'error' } } } } }\n }
906,\n validationResult: {\n sourceIdProvided: !!sourceId,\n sourceTypeValid: ['postgres', 'mongodb', 'rest_api', 'csv', 'elasticsearch', 's3', 'bigquery'].includes(sourceType),\n queryProvided: Object.keys(query).length > 0\n }\n});"},{name:"validate_schema",description:"Validates a batch of records against a JSON Schema and returns quality metrics",params:'{ "records": { "type": "array", "items": { "type": "object" } }, "schema": { "type": "object", "description": "JSON Schema to validate against" }, "rules": { "type": "object", "properties": { "maxNullRate": { "type": "number", "default": 0.05 }, "checkDistribution": { "type": "boolean", "default": true }, "checkReferentialIntegrity": { "type": "boolean", "default": false }, "historicalStats": { "type": "object", "description": "Mean/stddev from previous runs for anomaly detection" } } } }',executeCode:"const records = args.records || [];\nconst schema = args.schema || {};\nconst rules = args.rules || {};\nconst results = [];\nconst requiredFields = schema.required || [];\nconst properties = schema.properties || {};\nconst maxErrors = rules.maxErrors || 100;\nlet errorCount = 0;\nfor (let i = 0; i < records.length && errorCount < maxErrors; i++) {\n const record = records[i];\n const recordErrors = [];\n for (const field of requiredFields) {\n if (record[field] === undefined || record[field] === null || record[field] === '') {\n recordErrors.push({ field, error: 'required', message: 'Missing required field: ' + field });\n }\n }\n for (const [field, spec] of Object.entries(properties)) {\n const value = record[field];\n if (value === undefined || value === null) continue;\n const fieldSpec = spec;\n if (fieldSpec.type === 'string' && typeof value !== 'string') recordErrors.push({ field, error: 'type', expected: 'string', got: typeof value });\n if (fieldSpec.type === 'number' && typeof value !== 'number') recordErrors.push({ field, error: 'type', expected: 'number', got: typeof value });\n if (fieldSpec.type === 'boolean' && typeof value !== 'boolean') recordErrors.push({ field, error: 'type', expected: 'boolean', got: typeof value });\n if (fieldSpec.type === 'integer' && (!Number.isInteger(value))) recordErrors.push({ field, error: 'type', expected: 'integer', got: typeof value });\n if (fieldSpec.type === 'array' && !Array.isArray(value)) recordErrors.push({ field, error: 'type', expected: 'array', got: typeof value });\n if (fieldSpec.minimum !== undefined && typeof value === 'number' && value < fieldSpec.minimum) recordErrors.push({ field, error: 'minimum', minimum: fieldSpec.minimum, got: value });\n if (fieldSpec.maximum !== undefined && typeof value === 'number' && value > fieldSpec.maximum) recordErrors.push({ field, error: 'maximum', maximum: fieldSpec.maximum, got: value });\n if (fieldSpec.minLength !== undefined && typeof value === 'string' && value.length < fieldSpec.minLength) recordErrors.push({ field, error: 'minLength', minLength: fieldSpec.minLength, got: value.length });\n if (fieldSpec.maxLength !== undefined && typeof value === 'string' && value.length > fieldSpec.maxLength) recordErrors.push({ field, error: 'maxLength', maxLength: fieldSpec.maxLength, got: value.length });\n if (fieldSpec.pattern && typeof value === 'string' && !new RegExp(fieldSpec.pattern).test(value)) recordErrors.push({ field, error: 'pattern', pattern: fieldSpec.pattern });\n if (fieldSpec.enum && !fieldSpec.enum.includes(value)) recordErrors.push({ field, error: 'enum', allowed: fieldSpec.enum, got: value });\n if (fieldSpec.format === 'email' && typeof value === 'string' && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) recordErrors.push({ field, error: 'format', format: 'email' });\n if (fieldSpec.format === 'date' && typeof value === 'string' && isNaN(new Date(value).getTime())) recordErrors.push({ field, error: 'format', format: 'date' });\n if (fieldSpec.format === 'uri' && typeof value === 'string' && !/^https?:\\/\\/.+/.test(value)) recordErrors.push({ field, error: 'format', format: 'uri' });\n }\n if (recordErrors.length > 0) {\n results.push({ recordIndex: i, errors: recordErrors });\n errorCount += recordErrors.length;\n }\n}\nconst validCount = records.length - results.length;
906\nresult = JSON.stringify({ totalRecords: records.length, valid: validCount, invalid: results.length, validationRate: records.length > 0 ? Math.round(validCount / records.length * 10000) / 100 : 100, errorCount, maxErrorsReached: errorCount >= maxErrors, errors: results });"}],mcpIntegration:`Scheduled trigger (cron or webhook) sends pipeline config to /api/mcp. 907Each stage streams events via SSE for real-time dashboard updates. 908Quality report generated before load stage â blocks if quality score < 95%. 909Token costs tracked per stage for cost optimization. 910Full pipeline trace exportable as JSON for audit and debugging.`,gradingSuite:[{caseName:"Detect and quarantine invalid records",input:'Source returns 1000 records. 50 have null primary keys, 30 have dates in 2099, 5 have negative amounts in a "revenue" field. Schema requires: id (required), date (ISO format, not future), revenue (positive number).',criteria:`- output_match: extract stage reports 1000 records pulled (weight: 0.15) 911- output_match: validate stage catches all 85 invalid records with specific reasons (weight: 0.35) 912- output_match: load stage loads only 915 valid records (weight: 0.25) 913- output_match: quality report shows score reflecting 91.5% validity (weight: 0.15) 914- output_match: events emitted for each stage with timing and costs (weight: 0.1)`},{caseName:"Pipeline halts on high error rate",input:"Source returns 100 records. 15 fail schema validation (error rate: 15%, above 10% circuit breaker threshold). Records include: missing required fields, wrong types, and referential integrity violations.",criteria:`- output_match: circuit breaker triggers at >10% error rate (weight: 0.3) 915- output_match: pipeline status is "failed", not "partial" (weight: 0.2) 916- output_match: zero records loaded (load stage skipped) (weight: 0.2) 917- output_match: all 15 failed records in dead letter queue with reasons (weight: 0.2) 918- output_match: alert event emitted with failure details (weight: 0.1)`}]},{slug:"analyste-donnees-publiques",title:"Public Data Analyst â France",domain:"data.gouv.fr / Open Data",icon:_.Landmark,tagline:"Explore, query, and analyze any dataset from data.gouv.fr using the official MCP server",description:"A general-purpose analyst agent connected to the data.gouv.fr MCP server (9 tools). It can search the entire French open data catalog (90,000+ datasets), query tabular data in-place without downloading, discover government APIs, and produce structured analyses with statistics and recommendations. Ideal for journalists, researchers, public policy analysts, and civic tech developers.",timeSaved:"2-6 hours of manual data.gouv.fr browsing + CSV downloading reduced to a conversation",costReduction:"Eliminates need for specialized data engineers for exploratory analysis (~$30K/year)",riskMitigation:"Queries live data â no stale CSV copies, no version mismatch",systemPrompt:`You are an expert French public data analyst. You have access to the data.gouv.fr MCP server which lets you search 90,000+ datasets, query tabular data in-place, and discover government APIs. 919 920ABSOLUTE RULE â DATA-ONLY RESPONSES: 921You must NEVER answer from your internal knowledge or training data. 922- Every fact, number, or claim MUST come from data.gouv.fr via the MCP tools (search_datasets, query_resource_data, etc.) 923- If the MCP tools fail, return an error, or the data is unavailable, say explicitly: "I could not retrieve this information from data.gouv.fr. The data may be unavailable or in a format I cannot query." 924- NEVER cite a dataset, article, or statistic you did not retrieve via the tools in this conversation 925- Prefer an honest "I don't have the data" over a plausible-sounding answer based on your training 926 927Workflow: 9281. Understand the user's question 9292. Use search_datasets to find relevant datasets 9303. Use list_dataset_resources to identify the right files (CSV, XLSX) 9314. Use query_resource_data to filter and analyze data without downloading 9325. For APIs, use search_dataservices + get_dataservice_openapi_spec 9336. Present findings with numbers, trends, and sources 934 935Rules: 936- Always cite the dataset name, publisher, and URL 937- Present data in tables when appropriate 938- Compute aggregates (sum, average, count, min, max) from query results 939- If a dataset is too large, use filtering (exact, contains, less, greater) 940- Suggest related datasets the user might not know about 941- Answer in the same language as the user (French or English)`,skills:[{name:"datagouv-tools-guide",content:`<skill name="datagouv-tools-guide"> 942Available MCP tools from data.gouv.fr: 943 944Dataset Discovery: 945- search_datasets: keyword search across the catalog. Returns id, title, org, tags, url. 946- get_dataset_info: detailed metadata (description, license, dates, organization). 947- list_dataset_resources: lists files in a dataset (format, size, URL, Tabular API availability). 948- get_resource_info: detailed resource metadata (MIME type, schema if available). 949 950Data Querying (key tool): 951- query_resource_data: queries CSV/XLSX resources in-place via Tabular API. 952 Supports: filtering (exact, contains, less, greater), sorting, pagination. 953 Only works on resources with Tabular API enabled. 954 955API Discovery: 956- search_dataservices: find registered government APIs. 957- get_dataservice_info: API metadata + base URL. 958- get_dataservice_openapi_spec: fetch and summarize an API's OpenAPI spec. 959 960Metrics: 961- get_metrics: monthly visits/downloads for a dataset or resource. 962</skill>`},{name:"analysis-format",content:`<skill name="analysis-format"> 963Structure your analysis as: 964 965## Source 966- Dataset: [name] by [publisher] 967- URL: [data.gouv.fr link] 968- Last updated: [date] 969- License: [license] 970 971## Findings 972[Key numbers, tables, trends] 973 974## Methodology 975[Which tools you used, filters applied, sample size] 976 977## Limitations 978[Data quality, coverage gaps, temporal limits] 979 980## Related Datasets 981[Suggest 2-3 complementary datasets for deeper analysis] 982</skill>`}],tools:[{name:"format_table",description:"Formats query results into a clean markdown table",params:'{ "data": { "type": "array", "items": { "type": "object" }, "description": "Array of row objects" }, "columns": { "type": "array", "items": { "type": "string" }, "description": "Column names to display" }, "maxRows": { "type": "number", "description": "Max rows to show (default 20)" } }',executeCode:`const rows = args.data || []; 983const cols = args.columns || (rows[0] ? Object.keys(rows[0]) : []); 984const max = args.maxRows || 20; 985const display = rows.slice(0, max); 986const header = '| ' + cols.join(' | ') + ' |'; 987const sep = '| ' + cols.map(() => '---').join(' | ') + ' |';
988const body = display.map(r => '| ' + cols.map(c => String(r[c] ?? '')).join(' | ') + ' |').join('\\n'); 989const footer = rows.length > max ? '\\n| ... | ' + cols.slice(1).map(() => '...').join(' | ') + ' | (' + rows.length + ' total rows)' : ''; 990result = header + '\\n' + sep + '\\n' + body + footer;`},{name:"compute_stats",description:"Computes basic statistics on a numeric column from query results",params:'{ "data": { "type": "array", "items": { "type": "object" }, "description": "Array of row objects" }, "column": { "type": "string", "description": "Column name to analyze" } }',executeCode:`const rows = args.data || []; 991const col = args.column; 992const values = rows.map(r => parseFloat(r[col])).filter(v => !isNaN(v)); 993if (values.length === 0) { result = JSON.stringify({ error: 'No numeric values found in column ' + col }); } 994else { 995 values.sort((a, b) => a - b); 996 const sum = values.reduce((a, b) => a + b, 0); 997 const mean = sum / values.length; 998 const median = values.length % 2 === 0 ? (values[values.length/2-1] + values[values.length/2]) / 2 : values[Math.floor(values.length/2)]; 999 const variance = values.reduce((s, v) => s + (v - mean) ** 2, 0) / values.length; 1000 result = JSON.stringify({ count: values.length, sum: Math.round(sum * 100) / 100, mean: Math.round(mean * 100) / 100, median: Math.round(median * 100) / 100, min: values[0], max: values[values.length - 1], stdDev: Math.round(Math.sqrt(variance) * 100) / 100 }); 1001}`}],mcpIntegration:`Connect the data.gouv.fr MCP server (free, no API key): 1002 1003{ 1004 "mcpServers": { 1005 "datagouv": { 1006 "type": "http", 1007 "url": "https://mcp.data.gouv.fr/mcp" 1008 } 1009 } 1010} 1011 1012The agent will automatically discover and use the 9 tools from the MCP server.`,gradingSuite:[{caseName:"Find DVF real estate data",input:"Quels sont les prix moyens de l'immobilier à Lyon en 2023 ?",criteria:`- tool_usage: uses search_datasets with "DVF" or "valeurs foncieres" (weight: 0.3) 1013- tool_usage: uses query_resource_data to filter by commune (weight: 0.3) 1014- output_match: mentions average price with actual numbers (weight: 0.2) 1015- output_match: cites dataset source and URL (weight: 0.2)`},{caseName:"Discover a government API",input:"Is there a French government API for c
1015ompany search (SIRENE)?",criteria:`- tool_usage: uses search_dataservices with "SIRENE" or "entreprise" (weight: 0.3) 1016- tool_usage: uses get_dataservice_openapi_spec (weight: 0.2) 1017- output_match: mentions API Recherche d'Entreprises or API Sirene (weight: 0.3) 1018- output_match: includes base URL or endpoint info (weight: 0.2)`}]},{slug:"assistant-juridique-france",title:"Legal Research Assistant â France",domain:"data.gouv.fr / Open Data",icon:C.Scale,tagline:"Search French codes, laws, decrees, and collective agreements via the official Légifrance API (PISTE)",description:"A legal research agent connected to the official Légifrance API (PISTE/DILA). It can search across all French codes (Code du travail, Code civil, etc.), retrieve full article text, browse code structure, and look up conventions collectives (KALI). Uses real-time data from the authoritative legal source. Not a substitute for legal counsel â a research accelerator.",timeSaved:"1-3 hours of Legifrance manual search reduced to minutes",costReduction:"~$20K/year in junior associate research time for a small firm",riskMitigation:"Official Légifrance data â the authoritative source for French law",systemPrompt:`You are a French legal research assistant. You have access to the official L\xe9gifrance API (PISTE) which lets you search and read French legal texts in real time. 1019 1020ABSOLUTE RULE â DATA-ONLY RESPONSES: 1021You must NEVER answer from your internal knowledge or training data. 1022- Every legal article, law reference, or convention you cite MUST have been retrieved via the L\xe9gifrance tools (legifrance_search, legifrance_get_article, etc.) in this conversation 1023- If the tools fail or the data is unavailable, say explicitly: "I could not retrieve this legal information from the L\xe9gifrance API." 1024- NEVER cite an article number (e.g., "Article L1234-1") without having retrieved its full text via legifrance_get_article 1025- Prefer an honest "I don't have the data" over a plausible-sounding legal answer based on your training 1026 1027Available tools: 1028- legifrance_search: search across codes, laws, decrees, conventions collectives 1029- legifrance_get_article: get full text of a specific article by ID 1030- legifrance_get_code_toc: browse the structure of a code (e.g., Code du travail) 1031- legifrance_list_codes: list all available French legal codes with their IDs 1032- legifrance_list_conventions: list national collective labor agreements (KALI) 1033- legifrance_get_convention: get convention content by text ID 1034 1035Key Code IDs: 1036- LEGITEXT000006072050 = Code du travail 1037- LEGITEXT000006070721 = Code civil 1038- LEGITEXT000006069577 = Code g\xe9n\xe9ral des imp\xf4ts 1039- LEGITEXT000006070633 = Code de commerce 1040- LEGITEXT000006070719 = Code p\xe9nal 1041 1042Workflow: 10431. Understand the legal question 10442. Use legifrance_search to find relevant articles (fund: CODE_DATE for codes, KALI_TEXT for conventions) 10453. Use legifrance_get_article to retrieve the full text of each relevant article 10464. Explain the findings in clear, accessible language 10475. Cross-reference when multiple sources are relevant (code + convention collective) 1048 1049Rules: 1050- ALWAYS add disclaimer: "This is legal research assistance, not legal advice. Consult a qualified attorney for specific situations." 1051- Cite article numbers with their full text retrieved from the API 1052- Distinguish between codes (permanent law), lois (statutes), and d\xe9crets (executive orders) 1053- Note effective dates â laws change frequently 1054- Answer in the user's language (French preferred for legal terms)`,skills:[{name:"legal-taxonomy",content:`<skill name="legal-taxonomy"> 1055French Legal Hierarchy: 10561. Constitution (1958) â supreme law 10572. International treaties (EU directives, ECHR) 10583. Lois organiques â constitutional implementation laws 10594. Lois ordinaires â parliamentary statutes 10605. Ordonnances â government decrees with force of law (Art. 38) 10616. D\xe9crets â executive regulations 10627. Arr\xeat\xe9s â ministerial/prefectural orders 10638. Circulaires â administrative instructions (non-binding) 1064 1065Key Code IDs for legifrance tools: 1066- LEGITEXT000006072050 = Code du travail (CT) 1067- LEGITEXT000006070721 = Code civil (CC) 1068- LEGITEXT000006069577 = Code g\xe9n\xe9ral des imp\xf4ts (CGI) 1069- LEGITEXT000006070633 = Code de commerce (CCOM) 1070- LEGITEXT000006070719 = Code p\xe9nal (CP) 1071- LEGITEXT000006074075 = Code de l'urbanisme (CU) 1072- LEGITEXT000006074096 = Code de la construction et de l'habitation (CCH) 1073 1074L\xe9gifrance API funds for legifrance_search: 1075- CODE_DATE = codes consolid\xe9s (Code du travail, Code civil, etc.) 1076- LODA_DATE = lois et d\xe9crets 1077- JORF = Journal Officiel 1078- KALI_TEXT = conventions collectives nationales 1079</skill>`}],tools:[{name:"format_legal_reference",description:"Formats a legal reference into standard French citation format",params:'{ "type": { "type": "string", "enum": ["article", "loi", "decret", "arrete", "convention"], "description": "Type of legal text" }, "reference": { "type": "string", "description": "Raw reference text" }, "code": { "type": "string", "description": "Code name if applicable" }, "date": { "type": "string", "description": "Date of the text (YYYY-MM-DD)" } }',executeCode:`const t = args.type; 1080const ref = args.reference; 1081const code = args.code || ''; 1082const date = args.date || ''; 1083let formatted = ''; 1084if (t === 'article') formatted = 'Art. ' + ref + (code ? ' du ' + code : '') + (date ? ' (en vigueur au ' + date + ')' : ''); 1085else if (t === 'loi') formatted = 'Loi n\xb0 ' + ref + (date ? ' du ' + date : ''); 1086else if (t === 'decret') formatted = 'D\xe9cret n\xb0 ' + ref + (date ? ' du ' + date : ''); 1087else if (t === 'arrete') formatted = 'Arr\xeat\xe9 ' + (date ? 'du ' + date + ' ' : '') + ref; 1088else if (t === 'convention') formatted = 'Convention collective nationale ' + ref + (date ? ' (\xe9tendue le ' + date + ')' : ''); 1089else formatted = ref; 1090result = JSON.stringify({ formatted, type: t, reference: ref, code, date });`}],mcpIntegration:`This template uses the L\xe9gifrance PISTE API (built-in tool). 1091 1092Enable the "L\xe9gifrance (PISTE)" built-in tool in your agent settings. 1093Requires PISTE_CLIENT_ID and PISTE_CLIENT_SECRET env vars (free registration at piste.gouv.fr). 1094 1095The agent gets 6 tools: legifrance_search, legifrance_get_article, legifrance_get_co
1095de_toc, legifrance_list_codes, legifrance_list_conventions, legifrance_get_convention.`,gradingSuite:[{caseName:"Find labor law article",input:"Quel est le délai de préavis pour un licenciement en CDI avec 5 ans d'ancienneté ?",criteria:`- tool_usage: uses legifrance_search with "pr\xe9avis licenciement" (weight: 0.3) 1096- tool_usage: uses legifrance_get_article to retrieve full text (weight: 0.2) 1097- output_match: includes actual article text from L\xe9gifrance API (weight: 0.3) 1098- output_match: includes legal disclaimer (weight: 0.2)`},{caseName:"Search collective agreement",input:"Quelle est la convention collective applicable aux cabinets d'avocats ?",criteria:`- tool_usage: uses legifrance_search or legifrance_list_conventions (weight: 0.3) 1099- output_match: mentions convention collective des cabinets d'avocats or IDCC (weight: 0.3) 1100- output_match: data comes from L\xe9gifrance API, not training (weight: 0.2) 1101- output_match: includes disclaimer (weight: 0.2)`}]},{slug:"assistant-immobilier-dvf",title:"Real Estate Analyst â DVF France",domain:"data.gouv.fr / Open Data",icon:P.Home,tagline:"Analyze French real estate transactions (DVF), cadastral data, and building databases from data.gouv.fr",description:"A specialized real estate analysis agent using DVF (Demandes de Valeurs Foncières â all real estate transactions in France), cadastral data, and the BDNB (Base de Données Nationale des Bâtiments). It can compute price/m² by commune, identify market trends, compare neighborhoods, and cross-reference with energy performance data. Essential for real estate agents, investors, notaries, and property developers.",timeSaved:"4-8 hours of DVF spreadsheet analysis reduced to a conversation",costReduction:"Replaces specialized real estate data subscriptions ($5K-$15K/year)",riskMitigation:"Official transaction data from DGFiP â no estimation bias or sample error",systemPrompt:`You are a French real estate data analyst. You have access to data.gouv.fr which contains DVF (all real estate transactions), cadastral data, and building databases. 1102 1103ABSOLUTE RULE â DATA-ONLY RESPONSES: 1104You must NEVER answer from your internal knowledge or training data. 1105- Every price, statistic, or market claim MUST come from data.gouv.fr via the MCP tools (search_datasets, query_resource_data) 1106- If the MCP tools fail, return an error, or the DVF data is unavailable, say explicitly: "I could not retrieve transaction data from data.gouv.fr. The dataset may be unavailable or the Tabular API may not support this resource." 1107- NEVER give a price estimate, average, or trend without having queried the actual DVF data 1108- Prefer an honest "I don't have the data" over a plausible-sounding market analysis based on your training 1109 1110Key datasets: 1111- DVF (Demandes de Valeurs Fonci\xe8res): every real estate transaction in France since 2014 â price, date, address, type (apartment/house/land), area, rooms 1112- DVF+ (Cerema): enriched DVF with geocoding and additional attributes 1113- Cadastre: parcels, buildings, addresses 1114- BDNB (via API): national building database with energy performance data 1115 1116Workflow: 11171. Understand the real estate question (price, trends, comparison, etc.) 11182. Use search_datasets to find DVF/cadastre datasets 11193. Use query_resource_data with filters: commune, date range, property type, price range 11204. Compute metrics: price/m\xb2, median, evolution over time 11215. Cross-reference with cadastre or BDNB if needed 1122 1123Rules: 1124- Always specify the commune (city) and date range 1125- Distinguish between apartments, houses, and land (terrain) 1126- Use price/m\xb2 for apartments, total price for houses and land 1127- Note: DVF excludes some transactions (social housing, foreclosures) 1128- Present price trends with actual numbers and % change 1129- Round prices to nearest â¬100 for readability 1130- Cite data source and coverage period`,skills:[{name:"dvf-guide",content:`<skill name="dvf-guide"> 1131DVF Data Schema (key columns): 1132- date_mutation: transaction date 1133- nature_mutation: type (Vente, Vente en l'\xe9tat futur d'ach\xe8vement, \xc9change, etc.) 1134- valeur_fonciere: transaction price in euros 1135- code_commune: INSEE code (5 digits) 1136- nom_commune: city name 1137- code_postal: postal code 1138- type_local: Appartement, Maison, D\xe9pendance, Local industriel 1139- surface_reelle_bati: built surface in m\xb2 1140- nombre_pieces_principales: number of rooms 1141- surface_terrain: land surface in m\xb2 1142- code_departement: department code 1143 1144Useful filters: 1145- Filter by code_commune for city-level analysis 1146- Filter by type_local for apartments vs houses 1147- Filter by date_mutation for time periods 1148- Use valeur_fonciere / surface_reelle_bati for price/m\xb2 1149- Exclude nature_mutation != "Vente" for clean transaction data 1150 1151DVF+ (Cerema) adds: 1152- Geocoded coordinates (longitude, latitude) 1153- Section cadastrale 1154- Enriched address 1155</skill>`}],tools:[{name:"compute_price_stats",description:"Computes real estate price statistics from DVF query results",params:'{ "transactions": { "type": "array", "items": { "type": "object" }, "description": "DVF transaction rows" }, "priceField": { "type": "string", "description": "Price column name (default: valeur_fonciere)" }, "surfaceField": { "type": "string", "description": "Surface column name (default: surface_reelle_bati)" } }',executeCode:`const txs = args.transactions || []; 1156const pf = args.priceField || 'valeur_fonciere'; 1157const sf = args.surfaceField || 'surface_reelle_bati'; 1158const valid = txs.filter(t => parseFloat(t[pf]) > 0 && parseFloat(t[sf]) > 0);
1159if (valid.length === 0) { result = JSON.stringify({ error: 'No valid transactions with price and surface' }); } 1160else { 1161 const prices = valid.map(t => parseFloat(t[pf])); 1162 const surfaces = valid.map(t => parseFloat(t[sf])); 1163 const ppm2 = valid.map(t => parseFloat(t[pf]) / parseFloat(t[sf])); 1164 ppm2.sort((a, b) => a - b); 1165 prices.sort((a, b) => a - b); 1166 const median = ppm2[Math.floor(ppm2.length / 2)]; 1167 const mean = ppm2.reduce((a, b) => a + b, 0) / ppm2.length; 1168 const medianPrice = prices[Math.floor(prices.length / 2)]; 1169 const avgSurface = surfaces.reduce((a, b) => a + b, 0) / surfaces.length; 1170 result = JSON.stringify({ 1171 transactionCount: valid.length, 1172 pricePerM2: { median: Math.round(median), mean: Math.round(mean), min: Math.round(ppm2[0]), max: Math.round(ppm2[ppm2.length - 1]) }, 1173 totalPrice: { median: Math.round(medianPrice), min: Math.round(prices[0]), max: Math.round(prices[prices.length - 1]) }, 1174 averageSurface: Math.round(avgSurface * 10) / 10 1175 }); 1176}`}],mcpIntegration:`Connect the data.gouv.fr MCP server (free, no API key): 1177 1178{ 1179 "mcpServers": { 1180 "datagouv": { 1181 "type": "http", 1182 "url": "https://mcp.data.gouv.fr/mcp" 1183 } 1184 } 1185} 1186 1187Search for "DVF" or "valeurs foncieres" datasets. 1188Use query_resource_data with commune and date filters for targeted analysis. 1189For building energy data, use search_dataservices to find the BDNB API.`,gradingSuite:[{caseName:"Price per m² in a city",input:"Quel est le prix au m² moyen pour un appartement à Bordeaux en 2023 ?",criteria:`- tool_usage: uses search_datasets with DVF-related keywords (weight: 0.25) 1190- tool_usage: uses query_resource_data with commune filter (weight: 0.25) 1191- output_match: provides price/m\xb2 with actual number (weight: 0.25) 1192- output_match: specifies data source and number of transactions (weight: 0.25)`}
1192,{caseName:"Market trend analysis",input:"How have house prices evolved in the Basque Country (64) over the last 3 years?",criteria:`- tool_usage: queries DVF data with department code 64 (weight: 0.3) 1193- output_match: shows year-over-year price evolution (weight: 0.3) 1194- output_match: distinguishes houses from apartments (weight: 0.2) 1195- output_match: mentions data limitations or caveats (weight: 0.2)`}]},{slug:"veille-fiscale-comptable",title:"Tax & Accounting Intelligence â France",domain:"data.gouv.fr / Open Data",icon:A.Calculator,tagline:"Query French tax data, local tax rates, and fiscal statistics from DGFiP open datasets",description:"A fiscal intelligence agent that exploits DGFiP (Direction Générale des Finances Publiques) open datasets on data.gouv.fr. It can look up local tax rates (taxe foncière, CFE, CVAE) by commune, compare fiscal pressure across territories, analyze tax revenue statistics, and cross-reference with INSEE economic data. Designed for accountants, tax advisors, CFOs, and municipal finance analysts.",timeSaved:"2-4 hours of manual DGFiP data lookup per analysis",costReduction:"Replaces specialized fiscal data tools ($3K-$8K/year licenses)",riskMitigation:"Official DGFiP data â authoritative source for tax rates and fiscal statistics",systemPrompt:`You are a French tax and fiscal data analyst. You have access to data.gouv.fr which contains DGFiP open datasets on local taxes, fiscal statistics, and tax revenue. 1196 1197ABSOLUTE RULE â DATA-ONLY RESPONSES: 1198You must NEVER answer from your internal knowledge or training data. 1199- Every tax rate, fiscal statistic, or revenue figure MUST come from data.gouv.fr via the MCP tools (search_datasets, query_resource_data) 1200- If the MCP tools fail, return an error, or the fiscal data is unavailable, say explicitly: "I could not retrieve fiscal data from data.gouv.fr. The DGFiP dataset may be unavailable or in a format I cannot query." 1201- NEVER cite a tax rate or fiscal figure without having queried the actual REI/DGFiP data 1202- Prefer an honest "I don't have the data" over a plausible-sounding fiscal answer based on your training 1203 1204Key datasets: 1205- REI (Recensement des \xc9l\xe9ments d'Imposition): local tax assessment data â CFE, CVAE, taxe fonci\xe8re, taxe d'habitation rates by commune 1206- Fiscalit\xe9 locale des particuliers: individual local tax data by municipality 1207- Statistiques DGFiP: statistical tables from the tax authority 1208- Imp\xf4ts locaux: detailed local tax revenue and rates 1209 1210Workflow: 12111. Understand the fiscal question 12122. Use search_datasets to find relevant DGFiP/fiscal datasets 12133. Use query_resource_data with commune/department/year filters 12144. Compute comparisons, rankings, or trends 12155. Contextualize with national averages when possible 1216 1217Rules: 1218- Always specify the tax year (fiscal data is annual) 1219- Distinguish between tax rate (taux) and tax base (base) 1220- Note: taxe d'habitation was progressively removed (2018-2023) for primary residences 1221- Present rates as percentages with 2 decimal places 1222- For comparisons, include national/departmental averages 1223- Cite the exact dataset and publisher 1224- This is informational â not tax advice`,skills:[{name:"french-tax-system",content:`<skill name="french-tax-system"> 1225French Local Tax System (post-2023): 1226 1227For businesses: 1228- CFE (Cotisation Fonci\xe8re des Entreprises): based on rental value of property 1229- CVAE (Cotisation sur la Valeur Ajout\xe9e): being phased out (2024-2027) 1230- Taxe fonci\xe8re (propri\xe9t\xe9s b\xe2ties): property tax on buildings 1231- Taxe fonci\xe8re (propri\xe9t\xe9s non b\xe2ties): land tax 1232 1233For individuals: 1234- Taxe fonci\xe8re: property tax (paid by owner) 1235- Taxe d'habitation: abolished for primary residences (still applies to secondary residences) 1236- Taxe d'enl\xe8vement des ordures m\xe9nag\xe8res (TEOM): waste collection tax 1237 1238Tax rate components: 1239- Taux communal: set by the municipality 1240- Taux intercommunal: set by the intercommunalit\xe9 (EPCI) 1241- Taux d\xe9partemental: set by the department (transferred to communes in 2021 for TF) 1242- Taux r\xe9gional: (minimal, mostly for CVAE) 1243 1244REI data columns typically include: 1245- Code commune, nom commune 1246- Taux communal TFB (taxe fonci\xe8re b\xe2ti) 1247- Taux intercommunal 1248- Base nette imposable 1249- Produit (revenue = base \xd7 taux) 1250</skill>`}],tools:[{name:"compare_tax_rates",description:"Compares tax rates across multiple communes from query results",params:'{ "data": { "type": "array", "items": { "type": "object" }, "description": "Tax data rows" }, "communeField": { "type": "string", "description": "Column for commune name" }, "rateField": { "type": "string", "description": "Column for tax rate" } }',executeCode:`const rows = args.data || []; 1251const cf = args.communeField || 'nom_commune'; 1252const rf = args.rateField || 'taux'; 1253const parsed = rows.map(r => ({ commune: r[cf], rate: parseFloat(r[rf]) })).filter(r => r.commune && !isNaN(r.rate)); 1254parsed.sort((a, b) => b.rate - a.rate); 1255const rates = parsed.map(r => r.rate); 1256const avg = rates.length > 0 ? rates.reduce((a, b) => a + b, 0) / rates.length : 0; 1257const min = parsed[parsed.length - 1]; 1258const max = parsed[0]; 1259result = JSON.stringify({ 1260 communeCount: parsed.length, 1261 average: Math.round(avg * 100) / 100, 1262 highest: max ? { commune: max.commune, rate: max.rate } : null, 1263 lowest: min ? { commune: min.commune, rate: min.rate } : null, 1264 ranking: parsed.slice(0, 10).map(r => ({ commune: r.commune, rate: r.rate })) 1265});`}],mcpIntegration:`Connect the data.gouv.fr MCP server (free, no API key): 1266 1267{ 1268 "mcpServers": { 1269 "datagouv": { 1270 "type": "http", 1271 "url": "https://mcp.data.gouv.fr/mcp" 1272 } 1273 } 1274} 1275 1276Search for "REI" or "impots locaux" or "DGFiP" datasets. 1277Use query_resource_data to filter by commune code and tax year.`,gradingSuite:[{caseName:"Local property tax rate lookup",input:"Quel est le taux de taxe foncière à Marseille pour 2023 ?",criteria:`- tool_usage: uses search_datasets with tax-related keywords (weight: 0.3) 1278- tool_usage: uses query_resource_data with Marseille filter (weight: 0.3) 1279- output_match: provides specific rate as percentage (weight: 0.2) 1280- output_match: mentions data source (DGFiP/REI) (weight: 0.2)`}]},{slug:"assistant-urbanisme-construction",title:"Urban Planning & Building Intelligence â France",domain:"data.gouv.fr / Open Data",icon:E.Building2,tagline:"Explore PLU zoning data, building databases, and construction permits from French open data",description:"An urban planning and construction intelligence agent leveraging data.gouv.fr for PLU (Plan Local d'Urbanisme) data, the BDNB (national building database via API), building permits (Sit@del), and cadastral data. It helps architects, property developers, urban planners, and municipalities understand zoning rules, building stock characteristics, and construction trends. Cross-references with energy performance data (DPE) from ADEME.",timeSaved:"3-6 hours of cross-referencing multiple urban planning sources",costReduction:"Prevents costly zoning compliance errors ($10K-$100K per project)",riskMitigation:"Cross-references official sources to validate zoning compatibility before land acquisition",systemPrompt:`You are a French urban planning and construction data analyst. You have access to data.gouv.fr which contains urban planning datasets, building databases, and construction statistics. 1281 1282ABSOLUTE RULE â DATA-ONLY RESPONSES: 1283You must NEVER answer from your internal knowledge or training data. 1284- Every zoning rule, building statistic, or cadastral reference MUST come from data.gouv.fr via the MCP tools (search_datasets, query_resource_data, search_dataservices) 1285- If the MCP tools fail, return an error, or the PLU/cadastre data is unavailable, say explicitly: "I could not retrieve urban planning data from data.gouv.fr. The dataset may be unavailable or in a format I cannot query. Please consult the G\xe9oportail de l'
1285Urbanisme or your local urbanisme service." 1286- NEVER describe a PLU zone, building permit stat, or cadastral reference without having queried the actual data 1287- Prefer an honest "I don't have the data" over a plausible-sounding urban planning answer based on your training 1288 1289Key datasets: 1290- PLU/PLUi (Plan Local d'Urbanisme): zoning maps, regulations, prescriptions 1291- SuDocUH: national inventory of all planning documents (PLU, PLUi, CC, RNU) 1292- Cadastre: parcel data, buildings, addresses 1293- Sit@del: building permits (permis de construire) statistics 1294- BDNB (via API): national building database â energy performance, characteristics 1295- DPE (ADEME): energy performance diagnostics 1296 1297Workflow: 12981. Understand the urban planning question 12992. Use search_datasets to find relevant datasets (PLU, cadastre, permits, building stock) 13003. For APIs (BDNB, BAN geocoding), use search_dataservices + get_dataservice_openapi_spec 13014. Use query_resource_data with geographic filters (commune, department, parcel reference) 13025. Cross-reference multiple sources when needed 1303 1304Rules: 1305- Always specify the commune and the applicable document type (PLU, PLUi, CC, RNU) 1306- Note that PLU data varies significantly by commune in format and availability 1307- Distinguish between PLU zones: U (urban), AU (to urbanize), A (agricultural), N (natural) 1308- For construction permits, distinguish between PC (permis de construire) and DP (d\xe9claration pr\xe9alable) 1309- Cross-reference cadastral references when possible 1310- Note data freshness â PLU can be revised frequently 1311- This is informational â always recommend consulting the local urbanisme service for binding decisions`,skills:[{name:"plu-zones",content:`<skill name="plu-zones"> 1312PLU Zone Types: 1313- U (Urbaine): already urbanized, generally buildable 1314 - UA: dense urban center 1315 - UB: mixed residential 1316 - UC: low-density residential 1317 - UD: individual housing 1318 - UE: economic activity 1319- AU (\xc0 Urbaniser): designated for future urbanization 1320 - 1AU: immediately buildable if connected to networks 1321 - 2AU: future, requires PLU modification to open 1322- A (Agricole): protected agricultural land, very limited construction 1323 - Only buildings necessary for agricultural exploitation 1324- N (Naturelle): natural/forest zones, strictest protection 1325 - Generally no construction allowed 1326 1327Key PLU Rules: 1328- COS (Coefficient d'Occupation des Sols): abolished since Loi ALUR (2014) 1329- Emprise au sol: max building footprint ratio 1330- Hauteur maximale: max building height 1331- Recul: setback from property boundary and road 1332- Stationnement: parking requirements 1333 1334Data sources for PLU:
1335- G\xe9oportail de l'Urbanisme (GPU): official digital PLU repository 1336- data.gouv.fr: PLU open data from various communes/EPCI 1337- SuDocUH: inventory showing which document applies where 1338</skill>`}],tools:[{name:"classify_zone",description:"Classifies a PLU zone code and explains its building rules",params:'{ "zoneCode": { "type": "string", "description": "PLU zone code (e.g., UA, 1AU, N)" } }',executeCode:`const code = (args.zoneCode || '').toUpperCase().trim(); 1339const zones = { 1340 'U': { category: 'Urbaine', buildable: true, description: 'Already urbanized area, generally buildable', restrictions: 'Subject to local height, footprint, and setback rules' }, 1341 'UA': { category: 'Urbaine dense', buildable: true, description: 'Dense urban center â high density allowed', restrictions: 'Minimum height may be required, commercial ground floor often mandatory' }, 1342 'UB': { category: 'Urbaine mixte', buildable: true, description: 'Mixed residential area', restrictions: 'Standard building rules apply' }, 1343 'UC': { category: 'Urbaine pavillonnaire', buildable: true, description: 'Low-density residential', restrictions: 'Lower height limits, larger setbacks' }, 1344 'AU': { category: '\xc0 urbaniser', buildable: 'conditional', description: 'Designated for future urbanization', restrictions: 'Requires network connection and may need PLU modification' }, 1345 '1AU': { category: '\xc0 urbaniser imm\xe9diat', buildable: true, description: 'Immediately buildable if connected to networks', restrictions: 'Must follow orientation d\\'am\xe9nagement' }, 1346 '2AU': { category: '\xc0 urbaniser futur', buildable: false, description: 'Reserved for future urbanization', restrictions: 'Requires PLU revision to open for construction' }, 1347 'A': { category: 'Agricole', buildable: false, description: 'Protected agricultural land', restrictions: 'Only buildings necessary for agricultural exploitation' }, 1348 'N': { category: 'Naturelle', buildable: false, description: 'Natural and forest protection zone', restrictions: 'Generally no construction allowed' } 1349}; 1350const prefix = code.replace(/[0-9]/g, ''); 1351const match = zones[code] || zones[prefix] || zones[prefix[0]] || null; 1352if (match) result = JSON.stringify({ zone: code, ...match }); 1353else result = JSON.stringify({ zone: code, error: 'Unknown zone code', suggestion: 'Common codes: U, UA, UB, UC, AU, 1AU, 2AU, A, N' });`}],mcpIntegration:`Connect the data.gouv.fr MCP server (free, no API key): 1354 1355{ 1356 "mcpServers": { 1357 "datagouv": { 1358 "type": "http", 1359 "url": "https://mcp.data.gouv.fr/mcp" 1360 } 1361 } 1362} 1363 1364Search for "PLU", "cadastre", "permis de construire", or "urbanisme" datasets. 1365Use search_dataservices to discover BDNB API and BAN geocoding API. 1366Use get_dataservice_openapi_spec to understand API endpoints.`,gradingSuite:[{caseName:"Find PLU zoning data",input:"Je veux acheter un terrain à Nantes. Comment savoir s'il est constructible ?",criteria:`- tool_usage: uses search_datasets with PLU or urbanisme keywords (weight: 0.25) 1367- output_match: explains PLU zone types (U, AU, A, N) (weight: 0.25)
1368- output_match: mentions G\xe9oportail de l'Urbanisme or SuDocUH (weight: 0.25) 1369- output_match: recommends consulting local urbanisme service (weight: 0.25)`},{caseName:"Building stock analysis",input:"What is the energy performance profile of buildings in the 13th arrondissement of Paris?",criteria:`- tool_usage: uses search_dataservices for BDNB or DPE (weight: 0.3) 1370- tool_usage: uses get_dataservice_openapi_spec (weight: 0.2) 1371- output_match: mentions DPE ratings or energy classes (weight: 0.25) 1372- output_match: cites data source (ADEME, BDNB, or data.gouv.fr) (weight: 0.25)`}]}],I={"pr-review-guardian":{title:"Gardien de Revue de PR",domain:"DevOps / Qualité du Code",tagline:"Analyse automatique des pull requests avec vérifications de sécurité, performance et conventions",description:"Reçoit un diff de PR GitHub via webhook et produit une revue structurée : vulnérabilités (OWASP Top 10), violations de conventions, alertes de complexité cyclomatique, dépendances obsolètes et suggestions d'optimisation. Bloque le merge si le score est inférieur au seuil configurable.",timeSaved:"30-60 min par revue de PR réduites à 10 secondes",costReduction:"~45Kâ¬/an pour une équipe de 8 développeurs (temps de réviseur senior)",riskMitigation:"Détecte 92% des vulnérabilités courantes avant la revue humaine"},"database-migration-auditor":{title:"Auditeur de Migrations BDD",domain:"Backend / DBA",tagline:"Analyse des fichiers de migration pour détecter les changements cassants, risques de verrou et génération automatique de scripts de rollback",description:"Analyse les fichiers de migration SQL/ORM, détecte les opérations destructrices, évalue les risques de verrouillage de tables et génère automatiquement les scripts de rollback correspondants.",timeSaved:"2-4 heures de revue DBA par migration",costReduction:"Prévient les incidents de downtime coûtant 10Kâ¬-500K⬠chacun",riskMitigation:"100% des migrations destructrices signalées avant exécution"},"cicd-pipeline-monitor":{title:"Moniteur de Pipeline CI/CD",domain:"DevOps / SRE",tagline:"Analyse en temps réel des échecs de pipeline avec détection de cause racine et suggestions de correctifs",description:"Surveille les pipelines CI/CD en temps réel, analyse les échecs, identifie la cause racine et propose des correctifs automatisés.",timeSaved:"15-45 min par investigation d'échec de pipeline",costReduction:"30Kâ¬/an en temps développeur pour une équipe avec 5+ déploiements/jour",riskMitigation:"Réduit le temps moyen de récupération (MTTR) de 60%"},"cloud-cost-optimizer":{title:"Optimiseur de Coûts Cloud",domain:"FinOps / Infrastructure",tagline:"Analyse des données de facturation cloud et identification des opportunités d'économies avec estimations de ROI",description:"Analyse les données de facturation cloud, identifie les ressources sous-utilisées et propose des optimisations avec estimation précise du ROI.",timeSaved:"2-3 jours d'audit FinOps mensuel réduits à quelques minutes",costReduction:"Identifie généralement 20-40% d'économies (50Kâ¬-500Kâ¬/an)",riskMitigation:"Prévient les dépassements de budget avec des alertes automatisées"},"incident-postmortem-generator":{title:"Générateur de Post-Mortem d'Incidents",domain:"SRE / Opérations",tagline:"Génération automatique de post-mortems structurés à partir des logs d'incidents avec chronologie et plan d'action",description:"Génère automatiquement des post-mortems structurés à partir des logs d'incidents, avec chronologie détaillée, analyse de cause racine et plan d'action.",timeSaved:"2-4 heures par post-mortem réduites à 5 minutes",costReduction:"25Kâ¬/an pour une équipe gérant 2+ incidents/mois",riskMitigation:"Garantit que 100% des incidents ont un post-mortem documenté"},"slack-standup-synthesizer":{title:"Synthétiseur de Standups Slack",domain:"Gestion d'Ãquipe",tagline:"Agrégation des standups quotidiens depuis Slack en tableaux de bord d'équipe avec détection des blocages",description:"Agrège les standups quotidiens depuis Slack, génère des tableaux de bord d'
1372équipe et détecte automatiquement les blocages.",timeSaved:"20 min/jour pour les managers engineering (lecture + synthèse)",costReduction:"15Kâ¬/an par manager en temps productif récupéré",riskMitigation:"Blocages détectés 2x plus vite, prévenant les retards de sprint"},"contract-clause-analyzer":{title:"Analyseur de Clauses Contractuelles",domain:"Juridique / Achats",tagline:"Détection des clauses à risque, violations RGPD et protections manquantes dans les contrats",description:"Analyse les contrats pour détecter les clauses à risque, les violations RGPD et les protections manquantes, avec recommandations détaillées.",timeSaved:"1-2 heures par revue de contrat pour l'équipe juridique",costReduction:"40Kâ¬/an pour les entreprises révisant 50+ contrats/an",riskMitigation:"Empêche la signature de contrats avec des expositions cachées"},"sales-lead-qualifier":{title:"Qualificateur de Leads Commerciaux",domain:"Ventes / Prospection",tagline:"Scoring et qualification des leads entrants avec données d'enrichissement et brouillons de prospection personnalisés",description:"Score et qualifie les leads entrants, enrichit les données et génère des brouillons de prospection personnalisés.",timeSaved:"10-15 min par qualification de lead, 80% du temps de recherche SDR",costReduction:"60Kâ¬/an par SDR en temps de vente récupéré",riskMitigation:"Augmente le taux de conversion de 25% en priorisant les leads à forte intention"},"marketing-campaign-analyzer":{title:"Analyseur de Campagnes Marketing",domain:"Marketing / Croissance",tagline:"Analyse de performance multi-canal avec attribution et suggestions d'optimisation",description:"Analyse les performances des campagnes marketing sur tous les canaux avec attribution multi-touch et suggestions d'optimisation budgétaire.",timeSaved:"4-6 heures de reporting marketing hebdomadaire",costReduction:"Amélioration du ROAS de 15-25% grâce aux réallocations budgétaires basées sur les données",riskMitigation:"Prévient le gaspillage de budget sur les canaux sous-performants"},"ml-model-drift-monitor":{title:"Moniteur de Dérive de Modèles ML",domain:"MLOps / Data Science",tagline:"Détection de la dérive des données, dérive conceptuelle et dégradation des performances en production",description:"Détecte la dérive des données, la dérive conceptuelle et la dégradation des performances des modèles ML en production.",timeSaved:"Surveillance continue vs 2 heures de vérification manuelle hebdomadaire",costReduction:"Prévient la perte de revenus liée aux modèles obsolètes (impact 100Kâ¬+)",riskMitigation:"Détecte la dégradation du modèle avant qu'elle n'impacte les métriques business"},"security-vulnerability-scanner":{title:"Scanner de Vulnérabilités de Sécurité",domain:"Sécurité / Conformité",tagline:"Analyse continue de la sécurité du code avec détection CVE et conseils de remédiation",description:"Analyse en continu la sécurité du code source, détecte les CVE dans les dépendances et fournit des guides de remédiation détaillés.",timeSaved:"8-16 heures d'audit de sécurité manuel par sprint",costReduction:"80Kâ¬/an vs fréquence de tests de pénétration externes",riskMitigation:"Réduit la probabilité d'incidents de sécurité de 75%"},"onboarding-knowledge-agent":{title:"Agent de Connaissances pour l'Onboarding",domain:"Management Engineering / RH",tagline:"Accélérez l'onboarding des développeurs avec des réponses instantanées depuis la documentation interne",description:"Accélère l'onboarding des développeurs en fournissant des réponses instantanées à partir de la documentation interne.",timeSaved:"2-4 semaines d'onboarding réduites à 3-5 jours",costReduction:"25K⬠par nouveau recrutement en coût d'onboarding réduit",riskMitigation:"Réduit les interruptions des développeurs seniors de 60%"},"financial-report-analyzer":{title:"Analyseur de Rapports Financiers",domain:"Finance / Comptabilité",tagline:"Extraction de KPI, détection d'anomalies et génération de synthèses exécutives à partir de données financières",description:"Extrait les KPI clés, détecte les anomalies comptables et génère des synthèses exécutives à partir des données financières.",timeSaved:"3-5 heures par cycle de reporting financier",costReduction:"35Kâ¬/an en temps d'analyste FP&A",riskMitigation:"Détecte les anomalies comptables 10x plus vite que la revue manuelle"},"api-schema-changelog":{title:"Générateur de Changelog de Schéma API",domain:"Platform Engineering",tagline:"Détection des changements cassants entre versions d'API et génération de guides de migration",description:"Détecte les changements cassants entre les versions d'API et génère des guides de migration détaillés pour les consommateurs.",timeSaved:"1-2 heures par release d'API pour la documentation",costReduction:"Prévient les cassures d'intégration en aval (20Kâ¬+ par incident)",riskMitigation:"Zéro changement cassant silencieux atteignant la production"},"customer-feedback-classifier":{title:"Classificateur de Retours Clients",domain:"Produit / Customer Success",tagline:"Classification, priorisation et routage des retours clients vers la bonne équipe produit",description:"Classifie, priorise et route automatiquement les retours clients vers la bonne équipe produit.",timeSaved:"5-10 heures/semaine de tri manuel des retours",costReduction:"30Kâ¬/an en temps d'équipe Customer Success",riskMitigation:"Détecte les problèmes produit émergents 5x plus vite, réduisant le churn"},"agent-team-code-review":{title:"Ãquipe d'Agents : Revue de Code Full-Stack",domain:"Multi-Agent / DevOps",tagline:"Trois agents spécialistes révisent le code en parallèle, puis un coordinateur synthétise un rapport unifié",description:"Une équipe de 3 agents spécialisés (sécurité, performance, conventions) révise le code en parallèle. Chaque agent se concentre sur son domaine d'expertise et produit des conclusions indépendantes. Un agent coordinateur synthétise ensuite toutes les conclusions en un rapport unifié, dédupliqué, avec des actions prioritaires et une recommandation de merge.",timeSaved:"45-90 min par PR complexe réduites à 20 secondes d'analyse parallèle",costReduction:"~80Kâ¬/an pour une équipe de 10 développeurs (remplace 3 passes de réviseur senior)",riskMitigation:"Couverture 3x plus profonde â sécurité, performance et conventions détectées simultanément"},"pipeline-content-creator":{title:"Pipeline de Contenu : Recherche â Rédaction â SEO",domain:"Pipeline / Contenu",tagline:"Un pipeline en 3 étapes où les agents recherchent, rédigent et optimisent le contenu séquentiellement",description:"Un pipeline séquentiel en 3 étapes : l'Agent 1 recherche un sujet en parcourant plusieurs sources et en extrayant les faits clés. L'Agent 2 transforme la recherche en contenu structuré et soigné correspondant à la voix de marque. L'Agent 3 optimise le contenu pour le SEO â balises meta, densité de mots-clés, liens internes, score de lisibilité. La sortie de chaque étape alimente la suivante.",timeSaved:"4-6 heures par article réduites à 15 minutes de relecture",costReduction:"~60Kâ¬/an en remplacement des coûts de rédacteur freelance + spécialiste SEO",riskMitigation:"Voix de marque cohérente et conformité SEO sur 100% du contenu publié"},"meta-agent-builder":{title:"Méta-Agent : Architecte d'Agents IA",domain:"Méta-Agent / Plateforme",tagline:"Décrivez votre besoin en langage naturel et obtenez un agent entièrement configuré",description:"Un agent IA qui construit d'autres agents. Décrivez votre cas d'usage en langage naturel et il génère la configuration complète : prompt système, skills (ave
1372c contenu), outils (avec paramètres JSON Schema), suite de grading et instructions d'intégration MCP. Valide la spec pour la cohérence interne et suggère des améliorations basées sur les bonnes pratiques de conception d'agents.",timeSaved:"2-4 heures de configuration d'agent réduites à 5 minutes de conversation",costReduction:"Permet aux utilisateurs non-techniques de construire des agents (0⬠de formation)",riskMitigation:"Les configs générées suivent des patterns éprouvés, réduisant les erreurs de configuration de 85%"},"multi-agent-incident-response":{title:"Escouade de Réponse aux Incidents",domain:"Multi-Agent / SRE",tagline:"Un agent routeur trie les alertes vers le bon spécialiste, qui diagnostique et corrige pendant qu'un agent communication informe les parties prenantes",description:"Exécution conditionnelle d'équipe pour la réponse aux incidents. Un agent routeur lit les alertes entrantes et classifie le type d'incident (base de données, réseau, application, sécurité). L'agent spécialiste approprié diagnostique le problème à l'aide de runbooks et de métriques, puis propose un correctif. Un agent communication rédige les mises à jour de la page de statut et les notifications aux parties prenantes tout au long du processus.",timeSaved:"15-30 min de triage initial + 30-60 min de communication de statut par incident",costReduction:"~120Kâ¬/an pour une rotation d'astreinte de 5 personnes (MTTR réduit, moins de toil)",riskMitigation:"Réduit le MTTR de 65% grâce au triage automatisé et au diagnostic + communication parallèles"},"orchestrated-data-pipeline":{title:"Pipeline de Données Observable",domain:"Pipeline / Observabilité",tagline:"Un pipeline ETL entièrement tracé avec suivi des coûts en tokens, gestion des erreurs et validation qualité à chaque étape",description:"Un pipeline avec observabilité complète sur 4 étapes : Extraction (récupération des données sources), Transformation (nettoyage, normalisation, enrichissement), Validation (contrôles qualité des données), et Chargement (écriture vers la destination). Chaque étape émet des événements de session structurés avec timing, coûts en tokens et suivi des erreurs. Les règles de qualité intégrées détectent les violations de schéma, les taux de nulls et les anomalies de distribution avant le chargement.",timeSaved:"3-8 heures de débogage ETL manuel réduites à une identification instantanée de la cause racine",costReduction:"~50Kâ¬/an en temps d'ingénierie data + prévient 200Kâ¬+ de coûts liés aux données corrompues en aval",riskMitigation:"99,5% de qualité des données avec validation pré-chargement â zéro corruption silencieuse"},"analyste-donnees-publiques":{title:"Analyste Données Publiques â France",domain:"data.gouv.fr / Open Data",tagline:"Explorez, interrogez et analysez n'importe quel dataset de data.gouv.fr via le serveur MCP officiel",description:"Un agent analyste généraliste connecté au serveur MCP data.gouv.fr (9 outils). Il peut rechercher dans le catalogue français d'open data (90 000+ datasets), interroger des données tabulaires sans téléchargement, découvrir les API gouvernementales et produire des analyses structurées. Idéal pour les journalistes, chercheurs, analystes de politiques publiques et développeurs civic tech.",timeSaved:"2-6 heures de navigation manuelle sur data.gouv.fr réduites à une conversation",costReduction:"Ãlimine le besoin d'ingénieurs data pour l'analyse exploratoire (~30Kâ¬/an)",riskMitigation:"Interroge les données en direct â pas de CSV périmés ni d'écart de version"},"assistant-juridique-france":{title:"Assistant Juridique â France",domain:"data.gouv.fr / Open Data",tagline:"Recherchez les lois, règlements et conventions collectives françaises via les datasets juridiques de data.gouv.fr",description:"Un agent de recherche juridique qui exploite data.gouv.fr pour rechercher dans LEGI (codes et lois consolidés), JORF (Journal Officiel â décrets, circulaires), KALI (conventions collectives nationales) et CASS (décisions de la Cour de cassation). Il peut croiser les textes juridiques, expliquer les articles en langage clair et identifier la jurisprudence pertinente. Pas un substitut au conseil juridique â un accélérateur de recherche.",timeSaved:"1-3 heures de recherche manuelle sur Légifrance réduites à quelques minutes",costReduction:"~20Kâ¬/an en temps de recherche de collaborateur junior pour un petit cabinet",riskMitigation:"Croisement de plusieurs sources pour réduire le risque d'oublier une réglementation pertinente"},"assistant-immobilier-dvf":{title:"Analyste Immobilier â DVF France",domain:"data.gouv.fr / Open Data",tagline:"Analysez les transactions immobilières (DVF), le cadastre et les bases bâtiments depuis data.gouv.fr",description:"Un agent spécialisé dans l'analyse immobilière utilisant DVF (Demandes de Valeurs Foncières â toutes les transactions immobilières en France), les données cadastrales et la BDNB. Il peut calculer le prix/m² par commune, identifier les tendances du marché, comparer les quartiers et croiser avec les données de performance énergétique. Essentiel pour agents immobiliers, investisseurs, notaires et promoteurs.",timeSaved:"4-8 heures d'analyse de tableurs DVF réduites à une conversation",costReduction:"Remplace les abonnements spécialisés en données immobilières (5Kâ¬-15Kâ¬/an)",riskMitigation:"Données de transactions officielles DGFiP â aucun biais d'estimation ni erreur d'échantillonnage"},"veille-fiscale-comptable":{title:"Veille Fiscale & Comptable â France",domain:"data.gouv.fr / Open Data",tagline:"Interrogez les données fiscales, taux d'imposition locaux et statistiques DGFiP depuis data.gouv.fr",description:"Un agent de veille fiscale exploitant les datasets ouverts DGFiP sur data.gouv.fr. Il peut rechercher les taux d'imposition locaux (taxe foncière, CFE, CVAE) par commune, comparer la pression fiscale entre territoires, analyser les statistiques de recettes f
1372iscales et croiser avec les données économiques INSEE. Conçu pour comptables, conseillers fiscaux, DAF et analystes de finances municipales.",timeSaved:"2-4 heures de recherche manuelle DGFiP par analyse",costReduction:"Remplace les outils spécialisés de données fiscales (3Kâ¬-8Kâ¬/an de licences)",riskMitigation:"Données officielles DGFiP â source faisant autorité pour les taux d'imposition et statistiques fiscales"},"assistant-urbanisme-construction":{title:"Assistant Urbanisme & Construction â France",domain:"data.gouv.fr / Open Data",tagline:"Explorez les données PLU, bases bâtiments et permis de construire depuis data.gouv.fr",description:"Un agent d'intelligence urbanistique et construction exploitant data.gouv.fr pour les données PLU (Plan Local d'Urbanisme), la BDNB (base bâtiments nationale via API), les permis de construire (Sit@del) et le cadastre. Il aide architectes, promoteurs, urbanistes et collectivités à comprendre les règles de zonage, les caractéristiques du parc bâti et les tendances de construction. Croisement avec les données DPE de l'ADEME.",timeSaved:"3-6 heures de croisement de sources urbanistiques multiples",costReduction:"Ãvite les erreurs coûteuses de conformité zonage (10Kâ¬-100K⬠par projet)",riskMitigation:"Croisement des sources officielles pour valider la compatibilité zonage avant acquisition foncière"}};function T(){let e=(0,n.useLocale)();return(0,t.useMemo)(()=>"en"===e?R:R.map(e=>{let t=I[e.slug];return t?{...e,title:t.title,domain:t.domain,tagline:t.tagline,description:t.description,timeSaved:t.timeSaved,costReduction:t.costReduction,riskMitigation:t.riskMitigation}:e}),[e])}e.s(["useLocalizedUseCases",()=>T],198780)}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.