nodebench-mcp 2.58.0 → 2.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,428 @@
1
+ /**
2
+ * searchQualityEval.ts — Gemini Flash Lite LLM Judge eval harness for search quality.
3
+ *
4
+ * Runs 50+ test queries against the search route, judges each result using
5
+ * both boolean structural checks AND Gemini 3.1 Flash Lite semantic judge,
6
+ * detects regressions, and produces fix suggestions.
7
+ *
8
+ * Usage:
9
+ * npx tsx packages/mcp-local/src/benchmarks/searchQualityEval.ts [--base-url http://localhost:5191]
10
+ *
11
+ * Env: GEMINI_API_KEY (loads from .env.local if not in environment)
12
+ *
13
+ * Flywheel: run → judge → diagnose → fix → re-run → compare
14
+ */
15
+ import { getDb } from "../db.js";
16
+ import { readFileSync } from "fs";
17
+ import { join } from "path";
18
+ /* ─── Load env ─────────────────────────────────────────────────────────────── */
19
+ function loadEnv() {
20
+ if (process.env.GEMINI_API_KEY)
21
+ return;
22
+ const paths = [".env.local", ".env", "../.env.local", "../../.env.local"];
23
+ for (const p of paths) {
24
+ try {
25
+ const content = readFileSync(join(process.cwd(), p), "utf-8");
26
+ for (const line of content.split("\n")) {
27
+ const match = line.match(/^(GEMINI_API_KEY)\s*=\s*(.+)$/);
28
+ if (match) {
29
+ process.env[match[1]] = match[2].trim();
30
+ console.log(`[env] Loaded GEMINI_API_KEY from ${p}`);
31
+ return;
32
+ }
33
+ }
34
+ }
35
+ catch { /* file not found */ }
36
+ }
37
+ }
38
+ loadEnv();
39
+ /* ─── Test Corpus (50+ queries, 10 categories) ─────────────────────────────── */
40
+ const TEST_CORPUS = [
41
+ // ── Weekly Reset (6 queries) ──
42
+ { id: "wr-01", query: "Generate my founder weekly reset — what changed, main contradiction, next 3 moves", lens: "founder", expectedType: "weekly_reset", category: "weekly_reset" },
43
+ { id: "wr-02", query: "founder weekly reset", lens: "founder", expectedType: "weekly_reset", category: "weekly_reset" },
44
+ { id: "wr-03", query: "Weekly reset for my startup", lens: "founder", expectedType: "weekly_reset", category: "weekly_reset" },
45
+ { id: "wr-04", query: "Give me the founder reset for this week", lens: "ceo", expectedType: "weekly_reset", category: "weekly_reset" },
46
+ { id: "wr-05", query: "What's my weekly summary and next moves?", lens: "founder", expectedType: "weekly_reset", category: "weekly_reset" },
47
+ { id: "wr-06", query: "founder weekly", lens: "founder", expectedType: "weekly_reset", category: "weekly_reset" },
48
+ // ── Pre-Delegation (4 queries) ──
49
+ { id: "pd-01", query: "Build a pre-delegation packet for my agent", lens: "founder", expectedType: "pre_delegation", category: "pre_delegation" },
50
+ { id: "pd-02", query: "Create an agent-ready delegation packet", lens: "founder", expectedType: "pre_delegation", category: "pre_delegation" },
51
+ { id: "pd-03", query: "Prepare a handoff brief for my AI agent", lens: "ceo", expectedType: "pre_delegation", category: "pre_delegation" },
52
+ { id: "pd-04", query: "Agent delegation packet with context", lens: "founder", expectedType: "pre_delegation", category: "pre_delegation" },
53
+ // ── Important Changes (4 queries) ──
54
+ { id: "ic-01", query: "What changed in the last 7 days?", lens: "founder", expectedType: "important_change", category: "important_change" },
55
+ { id: "ic-02", query: "Show me important changes since my last session", lens: "ceo", expectedType: "important_change", category: "important_change" },
56
+ { id: "ic-03", query: "What's different since yesterday?", lens: "founder", expectedType: "important_change", category: "important_change" },
57
+ { id: "ic-04", query: "Recent important changes and contradictions", lens: "investor", expectedType: "important_change", category: "important_change" },
58
+ // ── Company Search (10 queries) ──
59
+ { id: "cs-01", query: "Analyze Anthropic's competitive position in the foundation model market", lens: "investor", expectedType: "company_search", category: "company_search" },
60
+ { id: "cs-02", query: "Tell me about Shopify's AI commerce strategy", lens: "ceo", expectedType: "company_search", category: "company_search" },
61
+ { id: "cs-03", query: "Search Rogo AI — what do they do and who did they acquire?", lens: "banker", expectedType: "company_search", category: "company_search" },
62
+ { id: "cs-04", query: "Analyze OpenAI's enterprise positioning", lens: "investor", expectedType: "company_search", category: "company_search" },
63
+ { id: "cs-05", query: "Research Stripe's payments infrastructure moat", lens: "investor", expectedType: "company_search", category: "company_search" },
64
+ { id: "cs-06", query: "Tell me about Linear's product strategy", lens: "founder", expectedType: "company_search", category: "company_search" },
65
+ { id: "cs-07", query: "Analyze Perplexity AI search positioning", lens: "investor", expectedType: "company_search", category: "company_search" },
66
+ { id: "cs-08", query: "Company profile for Mistral AI", lens: "banker", expectedType: "company_search", category: "company_search" },
67
+ { id: "cs-09", query: "Diligence on Vercel's developer platform", lens: "investor", expectedType: "company_search", category: "company_search" },
68
+ { id: "cs-10", query: "Research Databricks data lakehouse strategy", lens: "ceo", expectedType: "company_search", category: "company_search" },
69
+ // ── Competitor Analysis (4 queries) ──
70
+ { id: "cp-01", query: "Compare NodeBench vs Supermemory in the memory/context space", lens: "founder", expectedType: "competitor", category: "competitor" },
71
+ { id: "cp-02", query: "NodeBench versus Perplexity — what's the difference?", lens: "investor", expectedType: "competitor", category: "competitor" },
72
+ { id: "cp-03", query: "Compare Linear vs Jira for engineering teams", lens: "ceo", expectedType: "competitor", category: "competitor" },
73
+ { id: "cp-04", query: "How does Anthropic compare to OpenAI for enterprise?", lens: "banker", expectedType: "competitor", category: "competitor" },
74
+ // ── Own Entity / My Company (6 queries) ──
75
+ { id: "me-01", query: "Summarize my current company state", lens: "ceo", expectedType: "company_search", category: "own_entity" },
76
+ { id: "me-02", query: "What's the status of my startup?", lens: "founder", expectedType: "general", category: "own_entity" },
77
+ { id: "me-03", query: "Show me my company's key metrics and risks", lens: "investor", expectedType: "company_search", category: "own_entity" },
78
+ { id: "me-04", query: "What are the biggest contradictions in my business right now?", lens: "founder", expectedType: "important_change", category: "own_entity" },
79
+ { id: "me-05", query: "Generate an investor update for my company", lens: "founder", expectedType: "general", category: "own_entity" },
80
+ { id: "me-06", query: "What should I tell my board this quarter?", lens: "ceo", expectedType: "general", category: "own_entity" },
81
+ // ── Multi-Entity (4 queries) ──
82
+ { id: "mt-01", query: "Compare Anthropic, OpenAI, and Google in the AI race", lens: "investor", expectedType: "competitor", category: "multi_entity" },
83
+ { id: "mt-02", query: "What changed in AI commerce for Shopify, Amazon, and Google?", lens: "ceo", expectedType: "important_change", category: "multi_entity" },
84
+ { id: "mt-03", query: "Analyze the competitive landscape: Stripe vs Adyen vs Square", lens: "banker", expectedType: "competitor", category: "multi_entity" },
85
+ { id: "mt-04", query: "Top 3 risks across Anthropic, Mistral, and Meta AI", lens: "investor", expectedType: "company_search", category: "multi_entity" },
86
+ // ── Role-Specific (6 queries, one per lens) ──
87
+ { id: "rl-01", query: "What should I build next?", lens: "founder", expectedType: "general", category: "role_specific" },
88
+ { id: "rl-02", query: "What deals should I be looking at?", lens: "banker", expectedType: "general", category: "role_specific" },
89
+ { id: "rl-03", query: "What regulatory risks should I track as a legal advisor?", lens: "legal", expectedType: "general", category: "role_specific" },
90
+ { id: "rl-04", query: "Explain the AI landscape for my thesis", lens: "student", expectedType: "general", category: "role_specific" },
91
+ { id: "rl-05", query: "What portfolio companies need attention?", lens: "investor", expectedType: "general", category: "role_specific" },
92
+ { id: "rl-06", query: "What should I present to the board?", lens: "ceo", expectedType: "general", category: "role_specific" },
93
+ // ── Upload-Related (4 queries) ──
94
+ { id: "up-01", query: "Analyze this meeting transcript and extract action items", lens: "founder", expectedType: "general", category: "upload_context" },
95
+ { id: "up-02", query: "Build a diligence memo from these meeting notes", lens: "banker", expectedType: "general", category: "upload_context" },
96
+ { id: "up-03", query: "Extract key entities from my uploaded documents", lens: "founder", expectedType: "general", category: "upload_context" },
97
+ { id: "up-04", query: "Summarize and find contradictions in my research files", lens: "investor", expectedType: "general", category: "upload_context" },
98
+ // ── Edge Cases (6 queries) ──
99
+ { id: "ec-01", query: "a", lens: "founder", expectedType: "general", category: "edge_case" },
100
+ { id: "ec-02", query: "What is the meaning of life?", lens: "student", expectedType: "general", category: "edge_case" },
101
+ { id: "ec-03", query: "", lens: "founder", expectedType: "general", category: "edge_case" },
102
+ { id: "ec-04", query: "!@#$%^&*()", lens: "founder", expectedType: "general", category: "edge_case" },
103
+ { id: "ec-05", query: "SELECT * FROM users WHERE 1=1; DROP TABLE users;--", lens: "founder", expectedType: "general", category: "edge_case" },
104
+ { id: "ec-06", query: "a".repeat(5000), lens: "founder", expectedType: "general", category: "edge_case" },
105
+ ];
106
+ /* ─── Structural Checks ───────────────────────────────────────────────────── */
107
+ function structuralCheck(queryDef, response, latencyMs) {
108
+ const data = response ?? {};
109
+ const r = data.result ?? {};
110
+ const entity = r.canonicalEntity ?? {};
111
+ const entityName = entity.name ?? data.entity ?? r.entityName ?? "";
112
+ const answer = entity.canonicalMission ?? r.answer ?? "";
113
+ const confidence = entity.identityConfidence ?? r.confidence ?? 0;
114
+ const variables = r.signals ?? r.variables ?? [];
115
+ const changes = r.whatChanged ?? r.changes ?? [];
116
+ const risks = r.contradictions ?? r.risks ?? [];
117
+ const nextQuestions = r.nextQuestions ?? r.nextActions ?? [];
118
+ const sourceCount = (changes.length ?? 0) + (variables.length ?? 0);
119
+ // For edge cases (empty/SQL injection/long), relax some checks
120
+ const isEdgeCase = queryDef.category === "edge_case";
121
+ const checks = {
122
+ hasEntityName: isEdgeCase || (!!entityName && entityName.length > 0),
123
+ hasAnswer: isEdgeCase || (!!answer && answer.length > 0),
124
+ hasConfidence: isEdgeCase || (typeof confidence === "number" && confidence > 0),
125
+ hasVariables: isEdgeCase || (Array.isArray(variables) && variables.length > 0),
126
+ hasChanges: isEdgeCase || (Array.isArray(changes) && changes.length > 0),
127
+ hasRisks: isEdgeCase || (Array.isArray(risks) && risks.length > 0),
128
+ hasNextQuestions: isEdgeCase || (Array.isArray(nextQuestions) && nextQuestions.length > 0),
129
+ confidenceAbove40: isEdgeCase || confidence >= 40,
130
+ sourceCountAbove0: isEdgeCase || sourceCount > 0,
131
+ answerLengthAbove50: isEdgeCase || answer.length >= 50,
132
+ noErrorInResponse: !data.error && data.success !== false,
133
+ latencyUnder10s: latencyMs < 10_000,
134
+ correctClassification: isEdgeCase || data.classification === queryDef.expectedType,
135
+ };
136
+ return { checks, entityName, answer, confidence };
137
+ }
138
+ /* ─── Gemini Flash Lite Judge ──────────────────────────────────────────────── */
139
+ const GEMINI_MODEL = process.env.GEMINI_MODEL ?? "gemini-2.5-flash";
140
+ const GEMINI_URL = `https://generativelanguage.googleapis.com/v1beta/models/${GEMINI_MODEL}:generateContent`;
141
+ async function callGeminiJudge(queryDef, response) {
142
+ const apiKey = process.env.GEMINI_API_KEY;
143
+ if (!apiKey)
144
+ return null;
145
+ const r = response?.result ?? {};
146
+ const entity = r.canonicalEntity ?? {};
147
+ const resultSnippet = JSON.stringify(r).slice(0, 3000);
148
+ const prompt = `You are an LLM judge evaluating a search API response from NodeBench, an entity intelligence workspace.
149
+
150
+ USER QUERY: "${queryDef.query}"
151
+ USER ROLE: ${queryDef.lens}
152
+ EXPECTED CLASSIFICATION: ${queryDef.expectedType}
153
+ ACTUAL CLASSIFICATION: ${response?.classification ?? "unknown"}
154
+ CATEGORY: ${queryDef.category}
155
+
156
+ API RESPONSE (truncated):
157
+ ${resultSnippet}
158
+
159
+ Evaluate this response against these 7 criteria. For each, return pass (true/false) and brief reasoning:
160
+
161
+ 1. RELEVANT_ENTITY: Does the response identify a relevant entity or workspace for this query?
162
+ 2. USEFUL_ANSWER: Is the answer/summary useful and relevant to what was asked?
163
+ 3. ACTIONABLE_SIGNALS: Does it provide signals, variables, or changes that help the user decide?
164
+ 4. RISK_AWARENESS: Does it surface risks, contradictions, or things to watch?
165
+ 5. NEXT_STEPS: Does it suggest useful follow-up questions or actions?
166
+ 6. ROLE_APPROPRIATE: Is the response shaped appropriately for the ${queryDef.lens} role?
167
+ 7. NO_HALLUCINATION: Does the response avoid making up specific facts/numbers it couldn't know?
168
+
169
+ IMPORTANT: This is a search API that may return default/placeholder signals for entities it hasn't deeply researched yet. That's acceptable — judge whether the STRUCTURE and RELEVANCE are correct, not whether it has real-time data.
170
+
171
+ Return ONLY valid JSON (no markdown, no code fences):
172
+ {
173
+ "verdict": "pass" or "fail",
174
+ "score": 0-100,
175
+ "criteria": [
176
+ { "name": "RELEVANT_ENTITY", "pass": true/false, "reasoning": "brief" },
177
+ { "name": "USEFUL_ANSWER", "pass": true/false, "reasoning": "brief" },
178
+ { "name": "ACTIONABLE_SIGNALS", "pass": true/false, "reasoning": "brief" },
179
+ { "name": "RISK_AWARENESS", "pass": true/false, "reasoning": "brief" },
180
+ { "name": "NEXT_STEPS", "pass": true/false, "reasoning": "brief" },
181
+ { "name": "ROLE_APPROPRIATE", "pass": true/false, "reasoning": "brief" },
182
+ { "name": "NO_HALLUCINATION", "pass": true/false, "reasoning": "brief" }
183
+ ],
184
+ "fixSuggestions": ["suggestion1", "suggestion2"]
185
+ }`;
186
+ try {
187
+ const resp = await fetch(`${GEMINI_URL}?key=${apiKey}`, {
188
+ method: "POST",
189
+ headers: { "Content-Type": "application/json" },
190
+ body: JSON.stringify({
191
+ contents: [{ parts: [{ text: prompt }] }],
192
+ generationConfig: {
193
+ temperature: 0.1,
194
+ maxOutputTokens: 1024,
195
+ responseMimeType: "application/json",
196
+ },
197
+ }),
198
+ signal: AbortSignal.timeout(15_000),
199
+ });
200
+ if (!resp.ok) {
201
+ console.log(` ⚠️ Gemini ${resp.status}: ${(await resp.text()).slice(0, 100)}`);
202
+ return null;
203
+ }
204
+ const json = await resp.json();
205
+ const text = json?.candidates?.[0]?.content?.parts?.[0]?.text;
206
+ if (!text)
207
+ return null;
208
+ // Parse JSON — handle markdown fences, thinking tags, trailing commas
209
+ let cleaned = text
210
+ .replace(/```json\n?/g, "").replace(/```\n?/g, "")
211
+ .replace(/<think>[\s\S]*?<\/think>/g, "")
212
+ .trim();
213
+ // Extract JSON object if surrounded by other text
214
+ const jsonMatch = cleaned.match(/\{[\s\S]*\}/);
215
+ if (jsonMatch)
216
+ cleaned = jsonMatch[0];
217
+ // Fix trailing commas before } or ]
218
+ cleaned = cleaned.replace(/,\s*([\]}])/g, "$1");
219
+ const parsed = JSON.parse(cleaned);
220
+ // Validate structure
221
+ if (!parsed.verdict || !Array.isArray(parsed.criteria))
222
+ return null;
223
+ return parsed;
224
+ }
225
+ catch (err) {
226
+ console.log(` ⚠️ Gemini judge error: ${err?.message?.slice(0, 80)}`);
227
+ return null;
228
+ }
229
+ }
230
+ /* ─── Runner ───────────────────────────────────────────────────────────────── */
231
+ async function runEval(baseUrl) {
232
+ const runId = `eval_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
233
+ const results = [];
234
+ const hasGemini = !!process.env.GEMINI_API_KEY;
235
+ // Filter out empty query for API (would get 400)
236
+ const corpus = TEST_CORPUS.filter(q => q.query.length > 0 && q.query.length < 10000);
237
+ console.log(`\n🔍 Search Quality Eval — ${corpus.length} queries against ${baseUrl}`);
238
+ console.log(`🤖 Judge: ${hasGemini ? GEMINI_MODEL : "Structural only (no GEMINI_API_KEY)"}`);
239
+ console.log("─".repeat(80));
240
+ for (const queryDef of corpus) {
241
+ const startMs = Date.now();
242
+ let response = {};
243
+ try {
244
+ const resp = await fetch(`${baseUrl}/search`, {
245
+ method: "POST",
246
+ headers: { "Content-Type": "application/json" },
247
+ body: JSON.stringify({ query: queryDef.query, lens: queryDef.lens }),
248
+ signal: AbortSignal.timeout(15_000),
249
+ });
250
+ response = await resp.json();
251
+ response._httpStatus = resp.status;
252
+ }
253
+ catch (err) {
254
+ response = { error: true, message: err?.message ?? "Fetch failed", _httpStatus: 0 };
255
+ }
256
+ const latencyMs = Date.now() - startMs;
257
+ const { checks, entityName, answer, confidence } = structuralCheck(queryDef, response, latencyMs);
258
+ const structuralPassCount = Object.values(checks).filter(Boolean).length;
259
+ const structuralTotal = Object.keys(checks).length;
260
+ const structuralPass = structuralPassCount === structuralTotal;
261
+ // Gemini judge (skip for edge cases and if no API key)
262
+ let geminiResult = null;
263
+ if (hasGemini && queryDef.category !== "edge_case") {
264
+ geminiResult = await callGeminiJudge(queryDef, response);
265
+ }
266
+ const geminiPass = geminiResult?.verdict === "pass";
267
+ // Combined: structural must pass. Gemini must pass IF it returned a verdict. Skip (null/error) doesn't fail.
268
+ const combinedPass = structuralPass && (queryDef.category === "edge_case" || !geminiResult || geminiPass);
269
+ const result = {
270
+ queryId: queryDef.id,
271
+ query: queryDef.query.slice(0, 80),
272
+ lens: queryDef.lens,
273
+ expectedType: queryDef.expectedType,
274
+ actualType: response?.classification ?? "unknown",
275
+ latencyMs,
276
+ structuralChecks: checks,
277
+ structuralScore: `${structuralPassCount}/${structuralTotal}`,
278
+ structuralPass,
279
+ geminiVerdict: geminiResult ? geminiResult.verdict : (queryDef.category === "edge_case" ? "skip" : undefined),
280
+ geminiScore: geminiResult?.score,
281
+ geminiReasoning: geminiResult?.criteria?.filter(c => !c.pass).map(c => `${c.name}: ${c.reasoning}`).join("; "),
282
+ geminiFailing: geminiResult?.criteria?.filter(c => !c.pass).map(c => c.name),
283
+ geminiFixSuggestions: geminiResult?.fixSuggestions,
284
+ combinedPass,
285
+ responseSnippet: JSON.stringify(response).slice(0, 300),
286
+ };
287
+ results.push(result);
288
+ // Print result line
289
+ const sIcon = structuralPass ? "✅" : "❌";
290
+ const gIcon = geminiResult ? (geminiPass ? "🟢" : "🔴") : (queryDef.category === "edge_case" ? "⏭️" : "⬜");
291
+ console.log(`${sIcon}${gIcon} [${result.queryId}] S:${result.structuralScore} G:${geminiResult?.score ?? "-"}% | ${latencyMs}ms | ${result.actualType} | ${queryDef.query.slice(0, 45)}`);
292
+ if (!structuralPass) {
293
+ const failing = Object.entries(checks).filter(([, v]) => !v).map(([k]) => k);
294
+ console.log(` ↳ Structural: ${failing.join(", ")}`);
295
+ }
296
+ if (geminiResult && !geminiPass) {
297
+ const failing = geminiResult.criteria.filter(c => !c.pass).map(c => c.name);
298
+ console.log(` ↳ Gemini: ${failing.join(", ")}`);
299
+ if (geminiResult.fixSuggestions?.length) {
300
+ console.log(` ↳ Fix: ${geminiResult.fixSuggestions[0]?.slice(0, 80)}`);
301
+ }
302
+ }
303
+ }
304
+ // Compute report
305
+ const structuralPassed = results.filter(r => r.structuralPass).length;
306
+ const geminiJudged = results.filter(r => r.geminiVerdict && r.geminiVerdict !== "skip");
307
+ const geminiPassed = geminiJudged.filter(r => r.geminiVerdict === "pass").length;
308
+ const combinedPassed = results.filter(r => r.combinedPass).length;
309
+ const avgLatencyMs = results.length > 0 ? results.reduce((s, r) => s + r.latencyMs, 0) / results.length : 0;
310
+ // Regression detection
311
+ const regressions = [];
312
+ const improvements = [];
313
+ try {
314
+ const db = getDb();
315
+ db.exec(`CREATE TABLE IF NOT EXISTS eval_runs (
316
+ run_id TEXT PRIMARY KEY, timestamp TEXT, base_url TEXT,
317
+ total_queries INTEGER, passed INTEGER, failed INTEGER,
318
+ pass_rate REAL, avg_latency_ms REAL, results_json TEXT,
319
+ judge_model TEXT, structural_pass_rate REAL, gemini_pass_rate REAL,
320
+ created_at INTEGER
321
+ )`);
322
+ const lastRun = db.prepare(`SELECT * FROM eval_runs ORDER BY created_at DESC LIMIT 1`).get();
323
+ if (lastRun) {
324
+ const lastResults = JSON.parse(lastRun.results_json ?? "[]");
325
+ for (const current of results) {
326
+ const prev = lastResults.find(r => r.queryId === current.queryId);
327
+ if (prev) {
328
+ if (prev.combinedPass && !current.combinedPass)
329
+ regressions.push(`${current.queryId}: was passing, now failing`);
330
+ if (!prev.combinedPass && current.combinedPass)
331
+ improvements.push(`${current.queryId}: was failing, now passing`);
332
+ }
333
+ }
334
+ }
335
+ db.prepare(`INSERT INTO eval_runs (run_id, timestamp, base_url, total_queries, passed, failed, pass_rate, avg_latency_ms, results_json, judge_model, structural_pass_rate, gemini_pass_rate, created_at)
336
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(runId, new Date().toISOString(), baseUrl, results.length, combinedPassed, results.length - combinedPassed, results.length > 0 ? combinedPassed / results.length : 0, avgLatencyMs, JSON.stringify(results), hasGemini ? GEMINI_MODEL : "heuristic", results.length > 0 ? structuralPassed / results.length : 0, geminiJudged.length > 0 ? geminiPassed / geminiJudged.length : 0, Date.now());
337
+ }
338
+ catch { /* non-fatal */ }
339
+ // Self-diagnosis
340
+ const failingCategories = {};
341
+ const geminiFailingCriteria = {};
342
+ for (const r of results) {
343
+ if (!r.combinedPass) {
344
+ const cat = TEST_CORPUS.find(q => q.id === r.queryId)?.category ?? "unknown";
345
+ failingCategories[cat] = (failingCategories[cat] ?? 0) + 1;
346
+ }
347
+ if (r.geminiFailing) {
348
+ for (const f of r.geminiFailing) {
349
+ geminiFailingCriteria[f] = (geminiFailingCriteria[f] ?? 0) + 1;
350
+ }
351
+ }
352
+ }
353
+ const diagnosisParts = [];
354
+ if (Object.keys(failingCategories).length > 0) {
355
+ const sorted = Object.entries(failingCategories).sort((a, b) => b[1] - a[1]);
356
+ diagnosisParts.push(`Weakest categories: ${sorted.map(([k, v]) => `${k}(${v})`).join(", ")}`);
357
+ }
358
+ if (Object.keys(geminiFailingCriteria).length > 0) {
359
+ const sorted = Object.entries(geminiFailingCriteria).sort((a, b) => b[1] - a[1]);
360
+ diagnosisParts.push(`Most-failed Gemini criteria: ${sorted.map(([k, v]) => `${k}(${v})`).join(", ")}`);
361
+ }
362
+ const diagnosisSummary = diagnosisParts.join(". ") || "All passing — no diagnosis needed.";
363
+ const report = {
364
+ runId,
365
+ timestamp: new Date().toISOString(),
366
+ baseUrl,
367
+ judgeModel: hasGemini ? GEMINI_MODEL : "heuristic",
368
+ totalQueries: results.length,
369
+ structuralPassRate: results.length > 0 ? structuralPassed / results.length : 0,
370
+ geminiPassRate: geminiJudged.length > 0 ? geminiPassed / geminiJudged.length : 0,
371
+ combinedPassRate: results.length > 0 ? combinedPassed / results.length : 0,
372
+ avgLatencyMs: Math.round(avgLatencyMs),
373
+ results,
374
+ regressions,
375
+ improvements,
376
+ diagnosisSummary,
377
+ };
378
+ // Print summary
379
+ console.log("\n" + "═".repeat(80));
380
+ console.log(`📊 EVAL REPORT: ${runId}`);
381
+ console.log(` Judge model: ${report.judgeModel}`);
382
+ console.log(` Structural: ${structuralPassed}/${results.length} (${(report.structuralPassRate * 100).toFixed(1)}%)`);
383
+ if (geminiJudged.length > 0) {
384
+ console.log(` Gemini: ${geminiPassed}/${geminiJudged.length} (${(report.geminiPassRate * 100).toFixed(1)}%)`);
385
+ }
386
+ console.log(` Combined: ${combinedPassed}/${results.length} (${(report.combinedPassRate * 100).toFixed(1)}%)`);
387
+ console.log(` Avg latency: ${report.avgLatencyMs}ms`);
388
+ console.log(` Diagnosis: ${diagnosisSummary}`);
389
+ if (regressions.length > 0) {
390
+ console.log(` 🔴 REGRESSIONS: ${regressions.length}`);
391
+ regressions.forEach(r => console.log(` - ${r}`));
392
+ }
393
+ if (improvements.length > 0) {
394
+ console.log(` 🟢 IMPROVEMENTS: ${improvements.length}`);
395
+ improvements.forEach(r => console.log(` - ${r}`));
396
+ }
397
+ // Print category breakdown
398
+ const categories = [...new Set(TEST_CORPUS.map(q => q.category))];
399
+ console.log("\n Category breakdown:");
400
+ for (const cat of categories) {
401
+ const catResults = results.filter(r => TEST_CORPUS.find(q => q.id === r.queryId)?.category === cat);
402
+ const catPassed = catResults.filter(r => r.combinedPass).length;
403
+ const icon = catPassed === catResults.length ? "✅" : "⚠️";
404
+ console.log(` ${icon} ${cat}: ${catPassed}/${catResults.length}`);
405
+ }
406
+ console.log("═".repeat(80));
407
+ return report;
408
+ }
409
+ /* ─── CLI entry ────────────────────────────────────────────────────────────── */
410
+ const baseUrl = process.argv.find(a => a.startsWith("--base-url="))?.split("=")[1]
411
+ ?? process.argv[process.argv.indexOf("--base-url") + 1]
412
+ ?? "http://localhost:3100";
413
+ runEval(baseUrl).then(report => {
414
+ if (report.regressions.length > 0) {
415
+ console.log("\n💥 Regressions detected — exiting with code 1");
416
+ process.exit(1);
417
+ }
418
+ if (report.combinedPassRate < 0.5) {
419
+ console.log(`\n⚠️ Combined pass rate below 50% (${(report.combinedPassRate * 100).toFixed(1)}%) — exiting with code 1`);
420
+ process.exit(1);
421
+ }
422
+ console.log("\n✅ Eval complete — no regressions");
423
+ }).catch(err => {
424
+ console.error("Eval failed:", err);
425
+ process.exit(2);
426
+ });
427
+ export { runEval, TEST_CORPUS };
428
+ //# sourceMappingURL=searchQualityEval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchQualityEval.js","sourceRoot":"","sources":["../../src/benchmarks/searchQualityEval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,kFAAkF;AAElF,SAAS,OAAO;IACd,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO;IACvC,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAC1E,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9D,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAC1D,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBACxC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,EAAE,CAAC,CAAC;oBACrD,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,OAAO,EAAE,CAAC;AA0CV,kFAAkF;AAElF,MAAM,WAAW,GAMZ;IACH,iCAAiC;IACjC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,mFAAmF,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;IACpL,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;IACvH,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,6BAA6B,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;IAC9H,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,yCAAyC,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;IACtI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,0CAA0C,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;IAC3I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;IAEjH,mCAAmC;IACnC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,4CAA4C,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IACjJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,yCAAyC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC9I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,yCAAyC,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC1I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,sCAAsC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAE3I,sCAAsC;IACtC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,kCAAkC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;IAC3I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,iDAAiD,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;IACtJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,mCAAmC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;IAC5I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,6CAA6C,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;IAEvJ,oCAAoC;IACpC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,yEAAyE,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC/K,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,8CAA8C,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC/I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,4DAA4D,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAChK,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,yCAAyC,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC/I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,gDAAgD,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IACtJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,yCAAyC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC9I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,0CAA0C,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAChJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,gCAAgC,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IACpI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,0CAA0C,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAChJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,6CAA6C,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAE9I,wCAAwC;IACxC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,8DAA8D,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE;IAC3J,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,sDAAsD,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE;IACpJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,8CAA8C,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE;IACvI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,sDAAsD,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE;IAElJ,4CAA4C;IAC5C,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,oCAAoC,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE;IACjI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,kCAAkC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE;IAC5H,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,4CAA4C,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE;IAC9I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,+DAA+D,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,YAAY,EAAE;IAClK,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,4CAA4C,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE;IACtI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,2CAA2C,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE;IAEjI,iCAAiC;IACjC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,sDAAsD,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE;IACtJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,8DAA8D,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,cAAc,EAAE;IAC/J,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,8DAA8D,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE;IAC5J,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,oDAAoD,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE;IAExJ,gDAAgD;IAChD,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,2BAA2B,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;IACxH,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,oCAAoC,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;IAChI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,0DAA0D,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;IACrJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,wCAAwC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;IACrI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,0CAA0C,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;IACxI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,qCAAqC,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE;IAE9H,mCAAmC;IACnC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,0DAA0D,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IACxJ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,iDAAiD,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC9I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,iDAAiD,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAC/I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,wDAAwD,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE;IAEvJ,+BAA+B;IAC/B,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;IAC5F,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;IACvH,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;IAC3F,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;IACrG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,oDAAoD,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;IAC7I,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE;CAC1G,CAAC;AAEF,iFAAiF;AAEjF,SAAS,eAAe,CAAC,QAA+B,EAAE,QAAa,EAAE,SAAiB;IAMxF,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,eAAe,IAAI,EAAE,CAAC;IAEvC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,kBAAkB,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;IACjD,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAChD,MAAM,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC;IAC7D,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAEpE,+DAA+D;IAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC;IAErD,MAAM,MAAM,GAA4B;QACtC,aAAa,EAAE,UAAU,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACpE,SAAS,EAAE,UAAU,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACxD,aAAa,EAAE,UAAU,IAAI,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,GAAG,CAAC,CAAC;QAC/E,YAAY,EAAE,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9E,UAAU,EAAE,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACxE,QAAQ,EAAE,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAClE,gBAAgB,EAAE,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1F,iBAAiB,EAAE,UAAU,IAAI,UAAU,IAAI,EAAE;QACjD,iBAAiB,EAAE,UAAU,IAAI,WAAW,GAAG,CAAC;QAChD,mBAAmB,EAAE,UAAU,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE;QACtD,iBAAiB,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;QACxD,eAAe,EAAE,SAAS,GAAG,MAAM;QACnC,qBAAqB,EAAE,UAAU,IAAI,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,YAAY;KACnF,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACpD,CAAC;AAED,kFAAkF;AAElF,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,kBAAkB,CAAC;AACpE,MAAM,UAAU,GAAG,2DAA2D,YAAY,kBAAkB,CAAC;AAS7G,KAAK,UAAU,eAAe,CAC5B,QAA+B,EAC/B,QAAa;IAEb,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC1C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,CAAC,GAAG,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,CAAC,CAAC,eAAe,IAAI,EAAE,CAAC;IACvC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG;;eAEF,QAAQ,CAAC,KAAK;aAChB,QAAQ,CAAC,IAAI;2BACC,QAAQ,CAAC,YAAY;yBACvB,QAAQ,EAAE,cAAc,IAAI,SAAS;YAClD,QAAQ,CAAC,QAAQ;;;EAG3B,aAAa;;;;;;;;;oEASqD,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;;;EAmB/E,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,QAAQ,MAAM,EAAE,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;gBACzC,gBAAgB,EAAE;oBAChB,WAAW,EAAE,GAAG;oBAChB,eAAe,EAAE,IAAI;oBACrB,gBAAgB,EAAE,kBAAkB;iBACrC;aACF,CAAC;YACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACjF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAS,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QAC9D,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,sEAAsE;QACtE,IAAI,OAAO,GAAG,IAAI;aACf,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;aACjD,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC;aACxC,IAAI,EAAE,CAAC;QACV,kDAAkD;QAClD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC/C,IAAI,SAAS;YAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACtC,oCAAoC;QACpC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAsB,CAAC;QAExD,qBAAqB;QACrB,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,kFAAkF;AAElF,KAAK,UAAU,OAAO,CAAC,OAAe;IACpC,MAAM,KAAK,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE/C,iDAAiD;IACjD,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IAErF,OAAO,CAAC,GAAG,CAAC,8BAA8B,MAAM,CAAC,MAAM,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,qCAAqC,EAAE,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,IAAI,QAAQ,GAAQ,EAAE,CAAC;QAEvB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,SAAS,EAAE;gBAC5C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACpE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,CAAC,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7B,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;QACrC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,QAAQ,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,cAAc,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QACtF,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAClG,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACzE,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,cAAc,GAAG,mBAAmB,KAAK,eAAe,CAAC;QAE/D,uDAAuD;QACvD,IAAI,YAAY,GAA6B,IAAI,CAAC;QAClD,IAAI,SAAS,IAAI,QAAQ,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACnD,YAAY,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,UAAU,GAAG,YAAY,EAAE,OAAO,KAAK,MAAM,CAAC;QACpD,6GAA6G;QAC7G,MAAM,YAAY,GAAG,cAAc,IAAI,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;QAE1G,MAAM,MAAM,GAAe;YACzB,OAAO,EAAE,QAAQ,CAAC,EAAE;YACpB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,UAAU,EAAE,QAAQ,EAAE,cAAc,IAAI,SAAS;YACjD,SAAS;YACT,gBAAgB,EAAE,MAAM;YACxB,eAAe,EAAE,GAAG,mBAAmB,IAAI,eAAe,EAAE;YAC5D,cAAc;YACd,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7G,WAAW,EAAE,YAAY,EAAE,KAAK;YAChC,eAAe,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9G,aAAa,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5E,oBAAoB,EAAE,YAAY,EAAE,cAAc;YAClD,YAAY;YACZ,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;SACxD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAErB,oBAAoB;QACpB,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACzC,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3G,OAAO,CAAC,GAAG,CACT,GAAG,KAAK,GAAG,KAAK,KAAK,MAAM,CAAC,OAAO,OAAO,MAAM,CAAC,eAAe,MAAM,YAAY,EAAE,KAAK,IAAI,GAAG,OAAO,SAAS,QAAQ,MAAM,CAAC,UAAU,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAC7K,CAAC;QACF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7E,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5E,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,IAAI,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,aAAa,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC;IACtE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACjF,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;IAClE,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5G,uBAAuB;IACvB,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,EAAE,CAAC,IAAI,CAAC;;;;;;MAMN,CAAC,CAAC;QAEJ,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC,GAAG,EAAS,CAAC;QACpG,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,WAAW,GAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;YAC3E,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;gBAClE,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,YAAY;wBAAE,WAAW,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,4BAA4B,CAAC,CAAC;oBACjH,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY;wBAAE,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,4BAA4B,CAAC,CAAC;gBACpH,CAAC;YACH,CAAC;QACH,CAAC;QAED,EAAE,CAAC,OAAO,CACR;sDACgD,CACjD,CAAC,GAAG,CACH,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EACxD,cAAc,EAAE,OAAO,CAAC,MAAM,GAAG,cAAc,EAC/C,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EACxD,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EACrC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,EACtC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAC1D,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAChE,IAAI,CAAC,GAAG,EAAE,CACX,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;IAE3B,iBAAiB;IACjB,MAAM,iBAAiB,GAA2B,EAAE,CAAC;IACrD,MAAM,qBAAqB,GAA2B,EAAE,CAAC;IACzD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,IAAI,SAAS,CAAC;YAC7E,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YACpB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;gBAChC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,cAAc,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,cAAc,CAAC,IAAI,CAAC,gCAAgC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,gBAAgB,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,oCAAoC,CAAC;IAE3F,MAAM,MAAM,GAAe;QACzB,KAAK;QACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO;QACP,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW;QAClD,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,kBAAkB,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9E,cAAc,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAChF,gBAAgB,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1E,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;QACtC,OAAO;QACP,WAAW;QACX,YAAY;QACZ,gBAAgB;KACjB,CAAC;IAEF,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvH,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,mBAAmB,YAAY,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,cAAc,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpH,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,mBAAmB,gBAAgB,EAAE,CAAC,CAAC;IACnD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QACxD,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,uBAAuB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,2BAA2B;IAC3B,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,KAAK,GAAG,CAAC,CAAC;QACpG,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;QAChE,MAAM,IAAI,GAAG,SAAS,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,kFAAkF;AAElF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;OAC7E,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;OACpD,uBAAuB,CAAC;AAE7B,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC7B,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,MAAM,CAAC,gBAAgB,GAAG,GAAG,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,MAAM,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;QACxH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACb,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAoC,CAAC"}
@@ -9,6 +9,7 @@
9
9
  * 2. Session Delta — hero card with strategy/competitors/contradictions/attention
10
10
  * 3. Trajectory Score — sparkline + 7 dimension bars
11
11
  * 4. Event Ledger — last 20 events with actor badges and type filters
12
+ * 4b. Agent Trajectory — waterfall timeline + step list for session actions
12
13
  * 5. Important Changes — status summary + actionable change cards
13
14
  * 6. Path Replay — horizontal scrollable session path
14
15
  * 7. Time Rollups — period tabs + metric grid with delta badges