@axiom-lattice/agent-eval 2.1.25 → 2.1.27
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.
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +17 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/LatticeEval.ts +2 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @axiom-lattice/agent-eval@2.1.
|
|
2
|
+
> @axiom-lattice/agent-eval@2.1.27 build /home/runner/work/agentic/agentic/packages/agent-eval
|
|
3
3
|
> tsup src/index.ts --format cjs,esm --dts --sourcemap
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
[34mCLI[39m Target: es2020
|
|
9
9
|
[34mCJS[39m Build start
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[32m41.
|
|
12
|
-
[32mCJS[39m [1mdist/index.js.map [22m[32m72.
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
14
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m39.
|
|
15
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[32m71.
|
|
16
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m41.60 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m72.20 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 138ms
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m39.40 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m71.93 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 139ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 13009ms
|
|
19
19
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m10.99 KB[39m
|
|
20
20
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m10.99 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @axiom-lattice/agent-eval
|
|
2
2
|
|
|
3
|
+
## 2.1.27
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 99f4b77: add tenantid for all lattice
|
|
8
|
+
- Updated dependencies [99f4b77]
|
|
9
|
+
- @axiom-lattice/core@2.1.33
|
|
10
|
+
- @axiom-lattice/protocols@2.1.20
|
|
11
|
+
|
|
12
|
+
## 2.1.26
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [cea3047]
|
|
17
|
+
- @axiom-lattice/protocols@2.1.19
|
|
18
|
+
- @axiom-lattice/core@2.1.32
|
|
19
|
+
|
|
3
20
|
## 2.1.25
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -368,7 +368,8 @@ ${rubricsSection}
|
|
|
368
368
|
const judgeThreadId = (0, import_uuid.v4)();
|
|
369
369
|
this.lastJudgeThreadId = judgeThreadId;
|
|
370
370
|
this.log("Invoking judge agent", { agent_key: "LatticeTest", case_id: evalCase.caseId });
|
|
371
|
-
const
|
|
371
|
+
const judgeAgent = await (0, import_core.getAgentClient)("default", "LatticeTest");
|
|
372
|
+
const testResponse = await judgeAgent.invoke(
|
|
372
373
|
{
|
|
373
374
|
messages: [new import_messages.HumanMessage(testPrompt)]
|
|
374
375
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/LatticeEval.ts","../src/LatticeEvalSuite.ts","../src/LatticeEvalProject.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./LatticeEval\";\nexport * from \"./LatticeEvalSuite\";\nexport * from \"./LatticeEvalProject\";","import { getAgentClient } from \"@axiom-lattice/core\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport { v4 } from \"uuid\";\nimport type {\n LatticeEvalCase,\n LatticeEvalLogEvent,\n LatticeEvalLogLevel,\n LatticeEvalRubric,\n LatticeEvalResult,\n OutputType,\n LatticeAgentStepConfig,\n} from \"./types\";\n\n/**\n * Configuration for Lattice evaluation server\n */\nexport interface LatticeEvalConfig {\n base_url: string;\n api_key?: string;\n /**\n * When true, prints detailed execution logs for each action.\n * Defaults to true.\n */\n verbose?: boolean;\n}\n\nexport interface LatticeEvalCaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n error_stack?: string;\n duration_ms: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n logs: LatticeEvalLogEvent[];\n}\n\n\n/**\n * LatticeEval class for evaluating Lattice evaluation cases\n */\nexport class LatticeEval {\n private config: LatticeEvalConfig;\n private baseUrl: string;\n private verbose: boolean;\n private inMemoryLogs: LatticeEvalLogEvent[] = [];\n private lastThreadId?: string;\n private lastJudgeThreadId?: string;\n private lastTestPrompt?: string;\n private lastFinalOutput?: string;\n private lastDurationMs: number = 0;\n private lastMessages: Array<{ role: string; content: string; id?: string }> = [];\n\n public getLastRunMeta() {\n return {\n duration_ms: this.lastDurationMs,\n thread_id: this.lastThreadId,\n judge_thread_id: this.lastJudgeThreadId,\n test_prompt: this.lastTestPrompt,\n final_output: this.lastFinalOutput,\n messages: this.lastMessages,\n };\n }\n\n /**\n * Create a new LatticeEval instance\n * @param config Optional server configuration (defaults to localhost:3203)\n */\n constructor(config: LatticeEvalConfig) {\n this.config = config;\n this.baseUrl = this.config.base_url;\n this.verbose = this.config.verbose ?? true;\n }\n\n public getInMemoryLogs(): LatticeEvalLogEvent[] {\n return [...this.inMemoryLogs];\n }\n\n public record(\n level: LatticeEvalLogLevel,\n message: string,\n data?: Record<string, unknown>\n ) {\n const event: LatticeEvalLogEvent = {\n ts: new Date().toISOString(),\n level,\n message,\n data,\n };\n this.inMemoryLogs.push(event);\n\n if (!this.verbose) return;\n // Simple console output - only show key info, no verbose details\n if (level === \"error\") {\n const keyInfo = this.getKeyInfo(data);\n console.log(` ✗ ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.startsWith(\"Starting\")) {\n // Only show start/end of case evaluation\n const keyInfo = this.getKeyInfo(data);\n console.log(` ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.includes(\"Case evaluation completed\")) {\n // Show completion with pass/fail status and reason\n const keyInfo = this.getKeyInfo(data);\n const pass = data?.pass;\n const summary = data?.summary as string | undefined;\n const status = pass ? \"✓ PASS\" : \"✗ FAIL\";\n const reason = summary || (pass ? \"Test passed\" : \"Test failed\");\n console.log(` ${status} ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n if (reason) {\n console.log(` Reason: ${reason}`);\n }\n }\n // Skip other verbose logs in console (they're still in memory for file output)\n }\n\n private log(message: string, data?: Record<string, unknown>) {\n this.record(\"info\", message, data);\n }\n\n private getKeyInfo(data?: Record<string, unknown>): string {\n if (!data) return \"\";\n const parts: string[] = [];\n // Only show case_id, pass, final_score, error - key info only\n // Note: content_assertion is shown in the message itself, not here\n if (data.case_id) parts.push(`case=${data.case_id}`);\n if (data.pass !== undefined) parts.push(`pass=${data.pass}`);\n if (data.final_score !== undefined) parts.push(`score=${data.final_score}`);\n if (data.error) parts.push(`error=${data.error}`);\n return parts.length > 0 ? `(${parts.join(\" \")})` : \"\";\n }\n\n /**\n * Execute a single agent step and return the thread ID and response data\n */\n private async executeAgentStep(\n step: LatticeAgentStepConfig,\n threadId: string,\n inputMessage: string,\n files: Record<string, string>\n ): Promise<{ threadId: string; responseData: any }> {\n this.log(\"Executing agent step\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n has_override_input_message: Boolean(step.override_input_message),\n input_message_length: step.override_input_message\n ? step.override_input_message.length\n : inputMessage.length,\n files_count: Object.keys(files || {}).length,\n });\n\n const response = await fetch(`${this.baseUrl}/api/runs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n assistant_id: step.agent_id,\n thread_id: threadId,\n files: Object.keys(files).reduce((acc, key) => {\n acc[key] = { content: files[key].split(\"\\n\"), created_at: new Date().toISOString(), modified_at: new Date().toISOString() };\n return acc;\n }, {} as Record<string, any>),\n message: step.override_input_message || inputMessage,\n }),\n });\n\n\n const responseData: any = await response.json();\n if (responseData.error) {\n this.log(\"Agent step failed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n error: responseData.error,\n });\n throw new Error(\n `Failed to run agent ${step.agent_id}: ${responseData.error}`\n );\n }\n this.log(\"Agent step completed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n response_keys: responseData ? Object.keys(responseData) : [],\n });\n return { threadId, responseData };\n }\n\n /**\n * Extract output content based on OutputType\n */\n private async extractOutput(\n outputType: OutputType,\n agentId: string,\n threadId: string,\n runResponseData?: any\n ): Promise<string> {\n if (outputType.type === \"file_content\") {\n this.log(\"Extracting file output\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n const responseState = await fetch(\n `${this.baseUrl}/api/assistants/${agentId}/${threadId}/state`,\n {\n method: \"GET\",\n }\n );\n\n if (!responseState.ok) {\n this.log(\"Failed to fetch assistant state\", {\n agent_id: agentId,\n thread_id: threadId,\n status: responseState.status,\n statusText: responseState.statusText,\n });\n throw new Error(`Failed to get state: ${responseState.statusText}`);\n }\n\n const state: any = await responseState.json();\n const stateValues: any = state.values;\n const fileContent = stateValues.files[outputType.file_path]?.content;\n\n if (!fileContent) {\n this.log(\"File output not found in state\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n throw new Error(\n `File not found in output: ${outputType.file_path}`\n );\n }\n const content = Array.isArray(fileContent)\n ? fileContent.join(\"\\n\")\n : fileContent;\n this.log(\"File output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n } else {\n // For message_content type, get the last message from the run response\n if (runResponseData?.messages && runResponseData.messages.length > 0) {\n const content =\n runResponseData.messages[runResponseData.messages.length - 1]?.content ||\n \"\";\n this.log(\"Message output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n }\n this.log(\"No message content found in run response\", {\n agent_id: agentId,\n thread_id: threadId,\n });\n throw new Error(\"No message content found in run response\");\n }\n }\n\n /**\n * Evaluate a single Lattice evaluation case\n * @param evalCase The evaluation case to run\n * @returns Evaluation result with pass/fail status and scores\n */\n async evaluateCase(evalCase: LatticeEvalCase): Promise<LatticeEvalResult> {\n const startedAt = Date.now();\n const threadId = `${evalCase.caseId}||${v4()}`;\n this.inMemoryLogs = [];\n this.lastThreadId = threadId;\n this.lastJudgeThreadId = undefined;\n this.lastTestPrompt = undefined;\n this.lastFinalOutput = undefined;\n this.lastDurationMs = 0;\n this.lastMessages = [];\n const contentAssertion = evalCase.eval?.content_assertion || \"\";\n const message = contentAssertion\n ? `Starting: ${contentAssertion}`\n : \"Starting\";\n this.log(message, {\n case_id: evalCase.caseId,\n thread_id: threadId,\n steps_count: evalCase.steps?.length,\n output_type: evalCase.output?.type,\n content_assertion: contentAssertion,\n });\n\n // Execute all agent steps sequentially\n let currentThreadId = threadId;\n let lastResponseData: any = null;\n for (const step of evalCase.steps) {\n const result = await this.executeAgentStep(\n step,\n currentThreadId,\n evalCase.input.message,\n evalCase.input.files || {}\n );\n currentThreadId = result.threadId;\n lastResponseData = result.responseData;\n\n // Collect messages from response if available\n // Use a Set to track message IDs to avoid duplicates\n const existingIds = new Set(this.lastMessages.map(m => m.id).filter(Boolean));\n if (result.responseData?.messages && Array.isArray(result.responseData.messages)) {\n for (const msg of result.responseData.messages) {\n if (msg && typeof msg === 'object') {\n const msgId = msg.id || msg.lc_id || msg._id;\n // Skip if we've already added this message\n if (msgId && existingIds.has(msgId)) {\n continue;\n }\n\n const role = msg.role || msg.getType?.() || msg.type || 'unknown';\n let content = '';\n if (typeof msg.content === 'string') {\n content = msg.content;\n } else if (Array.isArray(msg.content)) {\n content = msg.content.map((c: any) =>\n typeof c === 'string' ? c :\n (c?.text || (typeof c === 'object' ? JSON.stringify(c) : String(c)))\n ).join('\\n');\n } else if (msg.content && typeof msg.content === 'object') {\n content = msg.content.text || JSON.stringify(msg.content);\n } else {\n content = String(msg.content || '');\n }\n\n this.lastMessages.push({\n role,\n content,\n id: msgId,\n });\n if (msgId) {\n existingIds.add(msgId);\n }\n }\n }\n }\n }\n\n // Get the final agent ID from the last step\n const finalAgentId =\n evalCase.steps[evalCase.steps.length - 1]?.agent_id || \"\";\n this.log(\"All agent steps completed\", {\n case_id: evalCase.caseId,\n final_agent_id: finalAgentId,\n final_thread_id: currentThreadId,\n });\n\n // Extract output based on output type\n const finalOutput = await this.extractOutput(\n evalCase.output,\n finalAgentId,\n currentThreadId,\n lastResponseData\n );\n this.lastFinalOutput = finalOutput;\n this.log(\"Final output extracted\", {\n case_id: evalCase.caseId,\n output_type: evalCase.output.type,\n output_length: finalOutput.length,\n });\n\n // Build test prompt\n const testCaseFilesContent = evalCase.input.files\n ? Object.keys(evalCase.input.files)\n .map(\n (key: string) =>\n `File name: ${key}\\nFile content: ${evalCase.input.files![key]}`\n )\n .join(\"\\n\\n\")\n : \"\";\n\n // Determine output type description\n const outputTypeDescription = evalCase.output.type === \"file_content\"\n ? `虚拟产物(文件:${evalCase.output.file_path})`\n : \"消息内容\";\n\n const defaultRubrics: LatticeEvalRubric[] = [\n {\n dimension: \"correctness\",\n weight: 100,\n description:\n \"整体正确性,是否符合预期输出描述。\",\n },\n ];\n\n const evalRubrics =\n evalCase.eval.eval_rubrics && evalCase.eval.eval_rubrics.length > 0\n ? evalCase.eval.eval_rubrics\n : defaultRubrics;\n this.log(\"Prepared evaluation rubrics\", {\n case_id: evalCase.caseId,\n rubrics_count: evalRubrics.length,\n rubric_dimensions: evalRubrics.map((r) => r.dimension),\n });\n\n const rubricsSection = `\\n## 评估指标(Evaluation Rubrics)\\n${evalRubrics\n .map(\n (r) =>\n `- **${r.dimension}**(权重:${r.weight}):${r.description}`\n )\n .join(\"\\n\")}`;\n\n const testPrompt = `# 角色\n你是一名资深的 AI Agent 评估专家,负责根据预设的指标(Rubrics)对 Agent 的执行结果进行\"黑盒测试\"判定。\n\n# 输入信息\n测试框架将为你提供以下四个核心上下文:\n\n1. **用户意图(User Intent)**:${evalCase.input.message}\n\n2. **输入文件(Input Files)**:${testCaseFilesContent || \"无\"}\n\n3. **实际输出(Actual Output,${outputTypeDescription})**: \n${finalOutput}\n\n4. **期望输出描述(Expected Output Description)**:${evalCase.eval.content_assertion}\n${rubricsSection}\n\n# 任务\n你必须严格对照\"评估指标(Evaluation Rubrics)\"中的每一项指标,分析\"实际输出(Actual Output)\"是否达标。\n\n# 规则\n1. **客观性**:仅根据提供的上下文判定。如果标准要求\"包含数字\",但输出只有文字,即使语气再好也必须扣分。\n2. **结果校验**:如果\"实际输出\"中缺失预期的内容,或内容不符合\"评估指标\"中的标准,对应的指标应判定为失败。\n3. **证据导向**:在给出原因(reason)时,必须引用输出中的原文或虚拟产物中的具体数据片段。\n4. **加权计算**:最终分数为各项指标得分与其权重的乘积之和(0-100分制)。\n\n# 输出格式(仅JSON)\n你必须仅以 JSON 格式回复,结构如下:\n{\n \"pass\": true | false,\n \"final_score\": number,\n \"dimension_results\": [\n {\n \"name\": \"指标名称\",\n \"score\": number,\n \"reason\": \"具体的扣分或给分理由,需引用证据\"\n }\n ],\n \"summary\": \"对 Agent 表现的整体评价\"\n}\n\n注意:如果 final_score >= 80 且没有致命性错误,pass 应为 true;否则为 false。`;\n this.lastTestPrompt = testPrompt;\n\n // Invoke judge agent\n const judgeThreadId = v4();\n this.lastJudgeThreadId = judgeThreadId;\n this.log(\"Invoking judge agent\", { agent_key: \"LatticeTest\", case_id: evalCase.caseId });\n const testResponse = await getAgentClient(\"LatticeTest\").invoke(\n {\n messages: [new HumanMessage(testPrompt)],\n },\n {\n configurable: {\n thread_id: judgeThreadId,\n },\n }\n );\n this.log(\"Judge agent responded\", {\n case_id: evalCase.caseId,\n messages_count: testResponse?.messages?.length,\n });\n\n const testResultContent: any =\n testResponse.messages[testResponse.messages.length - 1]?.content || \"\";\n this.log(\"Judge raw output received\", {\n case_id: evalCase.caseId,\n output_length:\n typeof testResultContent === \"string\" ? testResultContent.length : undefined,\n });\n\n // Parse JSON response from judge agent\n let parsedResult: {\n pass?: boolean;\n final_score?: number;\n dimension_results?: Array<{ name: string; score: number; reason: string }>;\n summary?: string;\n } = {};\n\n try {\n // Try to extract JSON from the response (handle code blocks or plain JSON)\n const jsonMatch = testResultContent.match(/```(?:json)?\\s*(\\{[\\s\\S]*\\})\\s*```/) ||\n testResultContent.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n parsedResult = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n this.log(\"Parsed judge JSON successfully\", {\n case_id: evalCase.caseId,\n parsed_keys: Object.keys(parsedResult || {}),\n });\n } else {\n this.log(\"No JSON detected in judge output; will fallback\", {\n case_id: evalCase.caseId,\n });\n }\n } catch (error) {\n // If JSON parsing fails, fall back to keyword-based parsing\n console.warn(\"Failed to parse JSON from judge agent response, falling back to keyword-based parsing:\", error);\n this.log(\"Failed to parse judge JSON; falling back\", {\n case_id: evalCase.caseId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n // Determine pass status\n let pass: boolean;\n if (parsedResult.pass !== undefined) {\n pass = parsedResult.pass;\n this.log(\"Pass determined from parsedResult.pass\", { case_id: evalCase.caseId, pass });\n } else if (parsedResult.final_score !== undefined) {\n pass = parsedResult.final_score >= 80;\n this.log(\"Pass determined from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: parsedResult.final_score,\n pass,\n });\n } else {\n // Fallback to keyword-based parsing\n pass = testResultContent.toLowerCase().includes(\"pass\") ||\n testResultContent.toLowerCase().includes(\"success\") ||\n testResultContent.toLowerCase().includes(\"通过\") ||\n testResultContent.toLowerCase().includes(\"符合\");\n this.log(\"Pass determined from keyword fallback\", { case_id: evalCase.caseId, pass });\n }\n\n // Extract dimension results\n let dimensionResults: Array<{ name: string; score: number; reason: string }> = [];\n\n if (parsedResult.dimension_results && parsedResult.dimension_results.length > 0) {\n // Use parsed dimension results from JSON\n dimensionResults = parsedResult.dimension_results;\n this.log(\"Using parsed dimension_results from judge\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n } else if (evalRubrics.length > 0) {\n // Fallback: create dimension results structure if rubrics are provided but not parsed\n dimensionResults = evalRubrics.map((rubric) => ({\n name: rubric.dimension,\n score: 0,\n reason: \"\",\n }));\n this.log(\"No dimension_results parsed; using rubric skeleton\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n }\n\n // Calculate final score\n let finalScore: number;\n if (parsedResult.final_score !== undefined) {\n finalScore = parsedResult.final_score;\n this.log(\"Final score taken from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n });\n } else if (dimensionResults.length > 0 && evalRubrics.length > 0) {\n // Calculate weighted average if rubrics are provided\n const rubricMap = new Map(evalRubrics.map((r) => [r.dimension, r.weight]));\n const totalWeight = Array.from(rubricMap.values()).reduce((sum, w) => sum + w, 0);\n\n if (totalWeight > 0) {\n finalScore = dimensionResults.reduce((sum, result) => {\n const weight = rubricMap.get(result.name) || 1;\n return sum + (result.score * weight);\n }, 0) / totalWeight;\n } else {\n // Fallback to simple average if no weights\n finalScore = dimensionResults.reduce((sum, result) => sum + result.score, 0) / dimensionResults.length;\n }\n this.log(\"Final score computed from dimension_results\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n total_weight: totalWeight,\n });\n } else {\n finalScore = pass ? 100 : 0;\n this.log(\"Final score fallback (pass-based)\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n pass,\n });\n }\n\n const summary = parsedResult.summary || testResultContent || \"\";\n this.log(\"Case evaluation completed\", {\n case_id: evalCase.caseId,\n pass,\n final_score: finalScore,\n summary,\n });\n const finishedAt = Date.now();\n this.lastDurationMs = finishedAt - startedAt;\n this.record(\"info\", \"Case duration recorded\", {\n case_id: evalCase.caseId,\n duration_ms: this.lastDurationMs,\n });\n return {\n pass,\n final_score: finalScore,\n dimension_results: dimensionResults,\n summary: parsedResult.summary || testResultContent,\n };\n }\n}\n\n/**\n * Evaluate a single Lattice evaluation case (backward compatibility function)\n * @param evalCase The evaluation case to run\n * @param config Optional server configuration (defaults to localhost:3203)\n * @returns Evaluation result with pass/fail status and scores\n * @deprecated Use LatticeEval class instead\n */\nexport async function evaluateLatticeCase(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n return evaluator.evaluateCase(evalCase);\n}\n\n/**\n * Evaluate a single Lattice evaluation case and always return logs (never throws).\n */\nexport async function evaluateLatticeCaseWithLogs(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalCaseRunResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n try {\n const result = await evaluator.evaluateCase(evalCase);\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n result,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n evaluator.record(\"error\", \"Case evaluation failed\", {\n case_id: evalCase.caseId,\n error: errorMessage,\n });\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n error: errorMessage,\n error_stack: errorStack,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n }\n}\n","import type { LLMConfig } from \"@axiom-lattice/protocols\";\nimport type {\n LatticeEvalSuiteType,\n LatticeEvalCase,\n LatticeEvalCaseType,\n LatticeEvalCaseWithTemplate,\n LatticeEvalTemplate,\n LatticeEvalLogEvent,\n LatticeEvalResult,\n} from \"./types\";\nimport {\n evaluateLatticeCaseWithLogs,\n LatticeEvalConfig,\n} from \"./LatticeEval\";\n\n/**\n * Configuration resolved from project/suite hierarchy\n */\nexport interface ResolvedConfig {\n lattice_server_config: {\n base_url: string;\n api_key?: string;\n };\n judge_agent_config?: {\n model: LLMConfig;\n };\n concurrency: number; // Number of cases to run concurrently\n}\n\n/**\n * Result with error handling\n */\nexport interface CaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n logs: LatticeEvalLogEvent[];\n duration_ms?: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n error_stack?: string;\n}\n\n/**\n * Limit concurrency of async operations with error isolation\n * Each task failure will not affect other tasks\n */\nasync function limitConcurrency<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number\n): Promise<Array<{ success: boolean; result?: T; error?: string }>> {\n const results: Array<{ success: boolean; result?: T; error?: string }> = [];\n const executing: Promise<void>[] = [];\n let index = 0;\n\n // Execute a single task with error handling\n const executeTask = async (task: () => Promise<T>, taskIndex: number): Promise<void> => {\n try {\n const result = await task();\n results[taskIndex] = { success: true, result };\n } catch (error) {\n results[taskIndex] = {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n // Never throw error here - always resolve to allow other tasks to continue\n // The error is already captured in the results array\n };\n\n // Process tasks with concurrency control\n while (index < tasks.length || executing.length > 0) {\n // Start new tasks up to concurrency limit\n while (executing.length < concurrency && index < tasks.length) {\n const task = tasks[index];\n const currentIndex = index++;\n // Wrap executeTask to ensure it never rejects, even on error\n const promise = executeTask(task, currentIndex)\n .catch((err) => {\n // This should never happen since executeTask catches all errors,\n // but add this as a safety net\n console.error(`Unexpected error in task execution:`, err);\n })\n .finally(() => {\n // Remove from executing array when done\n const idx = executing.indexOf(promise);\n if (idx > -1) {\n executing.splice(idx, 1);\n }\n });\n executing.push(promise);\n }\n\n // Wait for at least one task to complete before starting new ones\n // Since executeTask always resolves (never rejects), Promise.race is safe\n if (executing.length > 0) {\n await Promise.race(executing);\n }\n }\n\n // Wait for all remaining tasks to complete\n // Since all promises are guaranteed to resolve (never reject), Promise.allSettled is safe\n await Promise.allSettled(executing);\n\n return results;\n}\n\n/**\n * Resolve a template case to a full case\n */\nfunction resolveTemplateCase(\n templateCase: LatticeEvalCaseWithTemplate,\n templates: Map<string, LatticeEvalTemplate>\n): LatticeEvalCase {\n const template = templates.get(templateCase.templateId);\n if (!template) {\n throw new Error(`Template not found: ${templateCase.templateId}`);\n }\n\n // Merge template default_case with case-specific overrides\n const resolvedCase: LatticeEvalCase = {\n caseId: templateCase.caseId,\n input: {\n message:\n templateCase.input.message ?? template.default_case.input.message,\n files: {\n ...template.default_case.input.files,\n ...templateCase.input.files,\n },\n },\n steps: template.default_case.steps,\n output: templateCase.output || template.default_case.output,\n eval: {\n content_assertion: templateCase.eval.content_assertion,\n eval_rubrics: templateCase.eval.eval_rubrics || template.default_case.eval?.eval_rubrics,\n },\n };\n\n return resolvedCase;\n}\n\n/**\n * Check if a case is a template case\n */\nfunction isTemplateCase(\n case_: LatticeEvalCaseType\n): case_ is LatticeEvalCaseWithTemplate {\n return \"templateId\" in case_;\n}\n\n/**\n * LatticeEvalSuite class manages a suite of evaluation cases\n * with suite-level configuration\n */\nexport class LatticeEvalSuite {\n private suite: LatticeEvalSuiteType;\n private projectConfig: ResolvedConfig;\n private templates: Map<string, LatticeEvalTemplate>;\n\n constructor(\n suite: LatticeEvalSuiteType,\n projectConfig: ResolvedConfig,\n templates: Map<string, LatticeEvalTemplate> = new Map()\n ) {\n this.suite = suite;\n this.projectConfig = projectConfig;\n this.templates = templates;\n }\n\n /**\n * Get resolved configuration from project\n */\n private getResolvedConfig(): ResolvedConfig {\n return this.projectConfig;\n }\n\n /**\n * Get suite name\n */\n getSuiteName(): string {\n return this.suite.suiteName;\n }\n\n /**\n * Get suite version\n */\n getVersion(): string | undefined {\n return this.suite.version;\n }\n\n /**\n * Get all cases in this suite (resolved from templates if needed)\n */\n getCases(): LatticeEvalCase[] {\n return this.suite.cases.map((case_) => {\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n });\n }\n\n /**\n * Get a specific case by ID (resolved from template if needed)\n */\n getCase(caseId: string): LatticeEvalCase | undefined {\n const case_ = this.suite.cases.find((c) => c.caseId === caseId);\n if (!case_) {\n return undefined;\n }\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n }\n\n /**\n * Run a single case in this suite with error handling\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(caseId: string): Promise<CaseRunResult> {\n try {\n const evalCase = this.getCase(caseId);\n if (!evalCase) {\n return {\n caseId,\n error: `Case not found: ${caseId}`,\n logs: [],\n };\n }\n\n const config = this.getResolvedConfig();\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n };\n } catch (error) {\n return {\n caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n };\n }\n }\n\n /**\n * Run all cases in this suite with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runAllCases(concurrency?: number): Promise<CaseRunResult[]> {\n const config = this.getResolvedConfig();\n const maxConcurrency = concurrency ?? config.concurrency;\n\n // Create tasks for all cases\n const tasks = this.suite.cases.map((case_) => async () => {\n try {\n // Resolve template case if needed\n const evalCase: LatticeEvalCase = isTemplateCase(case_)\n ? resolveTemplateCase(case_, this.templates)\n : case_;\n\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId: evalCase.caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n } as CaseRunResult;\n } catch (error) {\n return {\n caseId: case_.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n } as CaseRunResult;\n }\n });\n\n // Run with concurrency limit\n const taskResults = await limitConcurrency(tasks, maxConcurrency);\n\n // Map results to CaseRunResult format\n return taskResults.map((taskResult, index) => {\n if (taskResult.success && taskResult.result) {\n return taskResult.result;\n }\n return {\n caseId: this.suite.cases[index].caseId,\n error: taskResult.error || \"Unknown error\",\n logs: [],\n };\n });\n }\n}\n","import type {\n LatticeEvalBatchReport,\n LatticeEvalProjectType,\n LatticeEvalReportConfig,\n LatticeEvalTemplate,\n} from \"./types\";\nimport { LatticeEvalSuite, ResolvedConfig, CaseRunResult } from \"./LatticeEvalSuite\";\nimport {\n registerModelLattice,\n registerAgentLattice,\n AgentType,\n AgentConfig,\n} from \"@axiom-lattice/core\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\n\n/**\n * LatticeEvalProject class manages a project with multiple evaluation suites\n * with project-level configuration\n */\nexport class LatticeEvalProject {\n private project: LatticeEvalProjectType;\n private suites: Map<string, LatticeEvalSuite> = new Map();\n private reportConfig?: LatticeEvalReportConfig;\n\n constructor(project: LatticeEvalProjectType) {\n this.project = project;\n this.reportConfig = project.report_config;\n\n // Register judge model\n const judgeModelKey = `${this.project.projectName}_judge_model`;\n registerModelLattice(judgeModelKey, this.project.judge_agent_config.model);\n\n // Register judge agent\n const judgeAgentKey = \"LatticeTest\";\n const judgeAgentConfig: AgentConfig = {\n key: judgeAgentKey,\n name: \"Lattice Test Judge Agent\",\n description: \"Judge agent for evaluating Lattice test cases\",\n type: AgentType.REACT,\n prompt: \"\", // No prompt as requested\n modelKey: judgeModelKey,\n };\n registerAgentLattice(judgeAgentConfig);\n\n // Build resolved config for project\n const projectConfig: ResolvedConfig = {\n lattice_server_config: {\n base_url: this.project.lattice_server_config.base_url,\n api_key: this.project.lattice_server_config.api_key,\n },\n judge_agent_config: this.project.judge_agent_config,\n concurrency: this.project.concurrency ?? 1,\n };\n\n // Build templates map\n const templatesMap = new Map<string, LatticeEvalTemplate>();\n if (this.project.templates) {\n for (const template of this.project.templates) {\n templatesMap.set(template.templateId, template);\n }\n }\n\n // Initialize all suites with project config and templates\n for (const suite of this.project.suites) {\n this.suites.set(\n suite.suiteName,\n new LatticeEvalSuite(suite, projectConfig, templatesMap)\n );\n }\n }\n\n /**\n * Get project name\n */\n getProjectName(): string {\n return this.project.projectName;\n }\n\n /**\n * Get project version\n */\n getVersion(): string | undefined {\n return this.project.version;\n }\n\n /**\n * Get project description\n */\n getDescription(): string | undefined {\n return this.project.description;\n }\n\n /**\n * Get all suite names\n */\n getSuiteNames(): string[] {\n return Array.from(this.suites.keys());\n }\n\n /**\n * Get a specific suite by name\n */\n getSuite(suiteName: string): LatticeEvalSuite | undefined {\n return this.suites.get(suiteName);\n }\n\n /**\n * Run a specific case in a specific suite\n * @param suiteName The suite name\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(suiteName: string, caseId: string): Promise<CaseRunResult> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n return {\n caseId,\n error: `Suite not found: ${suiteName}`,\n logs: [],\n };\n }\n return suite.runCase(caseId);\n }\n\n /**\n * Run all cases in a specific suite with concurrency control and error isolation\n * @param suiteName The suite name\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runSuite(suiteName: string, concurrency?: number): Promise<CaseRunResult[]> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n throw new Error(`Suite not found: ${suiteName}`);\n }\n return suite.runAllCases(concurrency);\n }\n\n /**\n * Run all cases in all suites with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Map of suite names to their case run results\n */\n async runAllSuites(concurrency?: number): Promise<Map<string, CaseRunResult[]>> {\n const results = new Map<string, CaseRunResult[]>();\n\n for (const suiteName of this.getSuiteNames()) {\n try {\n const suiteResults = await this.runSuite(suiteName, concurrency);\n results.set(suiteName, suiteResults);\n } catch (error) {\n // If suite execution fails, create error results for all cases\n const suite = this.getSuite(suiteName);\n if (suite) {\n const errorResults: CaseRunResult[] = suite.getCases().map((c) => ({\n caseId: c.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n }));\n results.set(suiteName, errorResults);\n }\n }\n }\n\n return results;\n }\n\n /**\n * Run all suites as a \"batch\", build a report, and optionally write it to disk.\n */\n async runAllSuitesBatch(concurrency?: number): Promise<{\n batch_id: string;\n batch_dir?: string;\n results: Map<string, CaseRunResult[]>;\n report: LatticeEvalBatchReport;\n }> {\n const started_at = new Date().toISOString();\n const batch_id =\n this.reportConfig?.batch_id ||\n `${Date.now()}`;\n\n console.log(`\\nRunning batch: ${this.project.projectName} (${this.getSuiteNames().length} suites)`);\n\n const results = await this.runAllSuites(concurrency);\n\n let total_cases = 0;\n let passed_cases = 0;\n let failed_cases = 0;\n\n const suites: LatticeEvalBatchReport[\"suites\"] = [];\n const durations: number[] = [];\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteTotal = caseResults.length;\n const suitePassed = caseResults.filter((r) => r.result?.pass).length;\n const suiteFailed = suiteTotal - suitePassed;\n\n total_cases += suiteTotal;\n passed_cases += suitePassed;\n failed_cases += suiteFailed;\n\n suites.push({\n suiteName,\n total_cases: suiteTotal,\n passed_cases: suitePassed,\n failed_cases: suiteFailed,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n pass: r.result?.pass,\n final_score: r.result?.final_score,\n error: r.error,\n })),\n });\n\n for (const r of caseResults) {\n if (typeof r.duration_ms === \"number\") durations.push(r.duration_ms);\n }\n }\n\n const finished_at = new Date().toISOString();\n const report: LatticeEvalBatchReport = {\n batch_id,\n started_at,\n finished_at,\n project: {\n projectName: this.project.projectName,\n version: this.project.version,\n description: this.project.description,\n },\n summary: {\n total_cases,\n passed_cases,\n failed_cases,\n pass_rate: total_cases > 0 ? passed_cases / total_cases : 0,\n },\n suites,\n };\n\n const batch_dir = await this.maybeWriteBatchArtifacts(\n batch_id,\n report,\n results\n );\n\n console.log(`\\n=== Summary ===`);\n console.log(`Total: ${report.summary.total_cases} | Passed: ${report.summary.passed_cases} | Failed: ${report.summary.failed_cases} | Pass Rate: ${(report.summary.pass_rate * 100).toFixed(2)}%`);\n if (batch_dir) {\n console.log(`\\nResults saved to: ${batch_dir}`);\n }\n\n return { batch_id, batch_dir, results, report };\n }\n\n private generateCaseMarkdown(\n index: number,\n suiteName: string,\n caseResult: CaseRunResult,\n payload: any\n ): string {\n const lines: string[] = [];\n const status = caseResult.result?.pass ? \"✅ PASS\" : \"❌ FAIL\";\n\n lines.push(`# Test ${index}: ${status}`);\n lines.push(``);\n lines.push(`- **Suite**: ${suiteName}`);\n lines.push(`- **Case ID**: ${caseResult.caseId}`);\n lines.push(`- **Status**: ${caseResult.result?.pass ? \"PASS\" : \"FAIL\"}`);\n if (typeof payload.duration === \"number\") {\n lines.push(`- **Duration**: ${(payload.duration / 1000).toFixed(2)}s`);\n }\n if (payload.threadId) {\n lines.push(`- **Thread ID**: ${payload.threadId}`);\n }\n if (payload.judgeThreadId) {\n lines.push(`- **Judge Thread ID**: ${payload.judgeThreadId}`);\n }\n lines.push(``);\n\n if (caseResult.result) {\n lines.push(`## Result`);\n lines.push(``);\n lines.push(`- **Final Score**: ${caseResult.result.final_score}`);\n lines.push(`- **Summary**: ${caseResult.result.summary || \"N/A\"}`);\n lines.push(``);\n\n if (caseResult.result.dimension_results && caseResult.result.dimension_results.length > 0) {\n lines.push(`## Dimension Results`);\n lines.push(``);\n for (const dim of caseResult.result.dimension_results) {\n lines.push(`### ${dim.name}`);\n lines.push(`- **Score**: ${dim.score}`);\n lines.push(`- **Reason**: ${dim.reason}`);\n lines.push(``);\n }\n }\n }\n\n if (caseResult.error) {\n lines.push(`## Error`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(caseResult.error);\n if (caseResult.error_stack) {\n lines.push(``);\n lines.push(caseResult.error_stack);\n }\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.messages && Array.isArray(payload.messages) && payload.messages.length > 0) {\n lines.push(`## Conversation Messages`);\n lines.push(``);\n for (let i = 0; i < payload.messages.length; i++) {\n const msg = payload.messages[i];\n const role = msg.role || 'unknown';\n const content = msg.content || '';\n lines.push(`### Message ${i + 1} (${role})`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(content);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n }\n\n if (payload.finalOutput) {\n lines.push(`## Final Output`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.finalOutput);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.testPrompt) {\n lines.push(`## Test Prompt`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.testPrompt);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private generateMarkdownSummary(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): string {\n const lines: string[] = [];\n lines.push(`# Lattice Eval Batch Summary`);\n lines.push(``);\n lines.push(`- **Project**: ${report.project.projectName}`);\n if (report.project.version) lines.push(`- **Version**: ${report.project.version}`);\n if (report.project.description) lines.push(`- **Description**: ${report.project.description}`);\n lines.push(`- **Batch ID**: ${batch_id}`);\n lines.push(`- **Started**: ${report.started_at}`);\n lines.push(`- **Finished**: ${report.finished_at}`);\n lines.push(``);\n\n lines.push(`## Overview`);\n lines.push(``);\n lines.push(`| Metric | Value |`);\n lines.push(`|---|---:|`);\n lines.push(`| Total cases | ${report.summary.total_cases} |`);\n lines.push(`| Passed | ${report.summary.passed_cases} |`);\n lines.push(`| Failed | ${report.summary.failed_cases} |`);\n lines.push(`| Pass rate | ${(report.summary.pass_rate * 100).toFixed(2)}% |`);\n lines.push(``);\n\n lines.push(`## Suites`);\n lines.push(``);\n for (const suite of report.suites) {\n lines.push(`### ${suite.suiteName}`);\n lines.push(``);\n lines.push(`| Case | Status | Score | Duration (ms) | Thread |`);\n lines.push(`|---|---|---:|---:|---|`);\n const suiteResults = results.get(suite.suiteName) || [];\n for (const r of suiteResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const score = r.result?.final_score ?? \"\";\n const dur = typeof r.duration_ms === \"number\" ? r.duration_ms : \"\";\n const thread = r.thread_id ?? \"\";\n lines.push(`| ${r.caseId} | ${status} | ${score} | ${dur} | ${thread} |`);\n }\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private async maybeWriteBatchArtifacts(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): Promise<string | undefined> {\n const config = this.reportConfig;\n if (!config?.output_dir) return undefined;\n\n const batchDir = path.join(config.output_dir, batch_id);\n await mkdir(batchDir, { recursive: true });\n\n const writeReportJson = config.write_report_json ?? true;\n const writeCaseLogs = config.write_case_logs ?? true;\n\n if (writeReportJson) {\n await writeFile(\n path.join(batchDir, \"report.json\"),\n JSON.stringify(report, null, 2),\n \"utf-8\"\n );\n }\n\n // Write richer results.json (similar to TestRunner)\n const resultsJsonPath = path.join(batchDir, \"results.json\");\n const resultsJson = {\n executionTimestamp: batch_id,\n summary: report.summary,\n report,\n results: Array.from(results.entries()).map(([suiteName, caseResults]) => ({\n suiteName,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n passed: r.result?.pass === true,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? {\n message: r.error,\n stack: r.error_stack,\n }\n : undefined,\n duration: r.duration_ms,\n testPrompt: r.test_prompt,\n finalOutput: r.final_output,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n })),\n })),\n };\n await writeFile(resultsJsonPath, JSON.stringify(resultsJson, null, 2), \"utf-8\");\n\n // Write summary.md\n const summaryMdPath = path.join(batchDir, \"summary.md\");\n const summaryMd = this.generateMarkdownSummary(batch_id, report, results);\n await writeFile(summaryMdPath, summaryMd, \"utf-8\");\n\n // Write per-case detailed json and markdown\n const individualDir = path.join(batchDir, \"individual\");\n await mkdir(individualDir, { recursive: true });\n let index = 1;\n for (const [suiteName, caseResults] of results.entries()) {\n for (const r of caseResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const baseFilename = `test-${index}-${suiteName}-${r.caseId}-${status}`.replace(/[\\/\\\\]/g, \"_\");\n\n // Write JSON\n const jsonPath = path.join(individualDir, `${baseFilename}.json`);\n const payload = {\n index,\n suiteName,\n caseId: r.caseId,\n passed: r.result?.pass === true,\n result: r.result,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? { message: r.error, stack: r.error_stack }\n : undefined,\n duration: r.duration_ms,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n finalOutput: r.final_output,\n testPrompt: r.test_prompt,\n messages: r.messages,\n };\n await writeFile(jsonPath, JSON.stringify(payload, null, 2), \"utf-8\");\n\n // Write Markdown\n const mdPath = path.join(individualDir, `${baseFilename}.md`);\n const mdContent = this.generateCaseMarkdown(index, suiteName, r, payload);\n await writeFile(mdPath, mdContent, \"utf-8\");\n\n index += 1;\n }\n }\n\n if (writeCaseLogs) {\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteDir = path.join(batchDir, \"cases\", suiteName);\n await mkdir(suiteDir, { recursive: true });\n for (const r of caseResults) {\n await writeFile(\n path.join(suiteDir, `${r.caseId}.logs.json`),\n JSON.stringify(r.logs || [], null, 2),\n \"utf-8\"\n );\n }\n }\n }\n\n return batchDir;\n }\n}\n"],"mappings":"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","names":["import_core","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/LatticeEval.ts","../src/LatticeEvalSuite.ts","../src/LatticeEvalProject.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./LatticeEval\";\nexport * from \"./LatticeEvalSuite\";\nexport * from \"./LatticeEvalProject\";","import { getAgentClient } from \"@axiom-lattice/core\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport { v4 } from \"uuid\";\nimport type {\n LatticeEvalCase,\n LatticeEvalLogEvent,\n LatticeEvalLogLevel,\n LatticeEvalRubric,\n LatticeEvalResult,\n OutputType,\n LatticeAgentStepConfig,\n} from \"./types\";\n\n/**\n * Configuration for Lattice evaluation server\n */\nexport interface LatticeEvalConfig {\n base_url: string;\n api_key?: string;\n /**\n * When true, prints detailed execution logs for each action.\n * Defaults to true.\n */\n verbose?: boolean;\n}\n\nexport interface LatticeEvalCaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n error_stack?: string;\n duration_ms: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n logs: LatticeEvalLogEvent[];\n}\n\n\n/**\n * LatticeEval class for evaluating Lattice evaluation cases\n */\nexport class LatticeEval {\n private config: LatticeEvalConfig;\n private baseUrl: string;\n private verbose: boolean;\n private inMemoryLogs: LatticeEvalLogEvent[] = [];\n private lastThreadId?: string;\n private lastJudgeThreadId?: string;\n private lastTestPrompt?: string;\n private lastFinalOutput?: string;\n private lastDurationMs: number = 0;\n private lastMessages: Array<{ role: string; content: string; id?: string }> = [];\n\n public getLastRunMeta() {\n return {\n duration_ms: this.lastDurationMs,\n thread_id: this.lastThreadId,\n judge_thread_id: this.lastJudgeThreadId,\n test_prompt: this.lastTestPrompt,\n final_output: this.lastFinalOutput,\n messages: this.lastMessages,\n };\n }\n\n /**\n * Create a new LatticeEval instance\n * @param config Optional server configuration (defaults to localhost:3203)\n */\n constructor(config: LatticeEvalConfig) {\n this.config = config;\n this.baseUrl = this.config.base_url;\n this.verbose = this.config.verbose ?? true;\n }\n\n public getInMemoryLogs(): LatticeEvalLogEvent[] {\n return [...this.inMemoryLogs];\n }\n\n public record(\n level: LatticeEvalLogLevel,\n message: string,\n data?: Record<string, unknown>\n ) {\n const event: LatticeEvalLogEvent = {\n ts: new Date().toISOString(),\n level,\n message,\n data,\n };\n this.inMemoryLogs.push(event);\n\n if (!this.verbose) return;\n // Simple console output - only show key info, no verbose details\n if (level === \"error\") {\n const keyInfo = this.getKeyInfo(data);\n console.log(` ✗ ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.startsWith(\"Starting\")) {\n // Only show start/end of case evaluation\n const keyInfo = this.getKeyInfo(data);\n console.log(` ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.includes(\"Case evaluation completed\")) {\n // Show completion with pass/fail status and reason\n const keyInfo = this.getKeyInfo(data);\n const pass = data?.pass;\n const summary = data?.summary as string | undefined;\n const status = pass ? \"✓ PASS\" : \"✗ FAIL\";\n const reason = summary || (pass ? \"Test passed\" : \"Test failed\");\n console.log(` ${status} ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n if (reason) {\n console.log(` Reason: ${reason}`);\n }\n }\n // Skip other verbose logs in console (they're still in memory for file output)\n }\n\n private log(message: string, data?: Record<string, unknown>) {\n this.record(\"info\", message, data);\n }\n\n private getKeyInfo(data?: Record<string, unknown>): string {\n if (!data) return \"\";\n const parts: string[] = [];\n // Only show case_id, pass, final_score, error - key info only\n // Note: content_assertion is shown in the message itself, not here\n if (data.case_id) parts.push(`case=${data.case_id}`);\n if (data.pass !== undefined) parts.push(`pass=${data.pass}`);\n if (data.final_score !== undefined) parts.push(`score=${data.final_score}`);\n if (data.error) parts.push(`error=${data.error}`);\n return parts.length > 0 ? `(${parts.join(\" \")})` : \"\";\n }\n\n /**\n * Execute a single agent step and return the thread ID and response data\n */\n private async executeAgentStep(\n step: LatticeAgentStepConfig,\n threadId: string,\n inputMessage: string,\n files: Record<string, string>\n ): Promise<{ threadId: string; responseData: any }> {\n this.log(\"Executing agent step\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n has_override_input_message: Boolean(step.override_input_message),\n input_message_length: step.override_input_message\n ? step.override_input_message.length\n : inputMessage.length,\n files_count: Object.keys(files || {}).length,\n });\n\n const response = await fetch(`${this.baseUrl}/api/runs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n assistant_id: step.agent_id,\n thread_id: threadId,\n files: Object.keys(files).reduce((acc, key) => {\n acc[key] = { content: files[key].split(\"\\n\"), created_at: new Date().toISOString(), modified_at: new Date().toISOString() };\n return acc;\n }, {} as Record<string, any>),\n message: step.override_input_message || inputMessage,\n }),\n });\n\n\n const responseData: any = await response.json();\n if (responseData.error) {\n this.log(\"Agent step failed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n error: responseData.error,\n });\n throw new Error(\n `Failed to run agent ${step.agent_id}: ${responseData.error}`\n );\n }\n this.log(\"Agent step completed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n response_keys: responseData ? Object.keys(responseData) : [],\n });\n return { threadId, responseData };\n }\n\n /**\n * Extract output content based on OutputType\n */\n private async extractOutput(\n outputType: OutputType,\n agentId: string,\n threadId: string,\n runResponseData?: any\n ): Promise<string> {\n if (outputType.type === \"file_content\") {\n this.log(\"Extracting file output\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n const responseState = await fetch(\n `${this.baseUrl}/api/assistants/${agentId}/${threadId}/state`,\n {\n method: \"GET\",\n }\n );\n\n if (!responseState.ok) {\n this.log(\"Failed to fetch assistant state\", {\n agent_id: agentId,\n thread_id: threadId,\n status: responseState.status,\n statusText: responseState.statusText,\n });\n throw new Error(`Failed to get state: ${responseState.statusText}`);\n }\n\n const state: any = await responseState.json();\n const stateValues: any = state.values;\n const fileContent = stateValues.files[outputType.file_path]?.content;\n\n if (!fileContent) {\n this.log(\"File output not found in state\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n throw new Error(\n `File not found in output: ${outputType.file_path}`\n );\n }\n const content = Array.isArray(fileContent)\n ? fileContent.join(\"\\n\")\n : fileContent;\n this.log(\"File output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n } else {\n // For message_content type, get the last message from the run response\n if (runResponseData?.messages && runResponseData.messages.length > 0) {\n const content =\n runResponseData.messages[runResponseData.messages.length - 1]?.content ||\n \"\";\n this.log(\"Message output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n }\n this.log(\"No message content found in run response\", {\n agent_id: agentId,\n thread_id: threadId,\n });\n throw new Error(\"No message content found in run response\");\n }\n }\n\n /**\n * Evaluate a single Lattice evaluation case\n * @param evalCase The evaluation case to run\n * @returns Evaluation result with pass/fail status and scores\n */\n async evaluateCase(evalCase: LatticeEvalCase): Promise<LatticeEvalResult> {\n const startedAt = Date.now();\n const threadId = `${evalCase.caseId}||${v4()}`;\n this.inMemoryLogs = [];\n this.lastThreadId = threadId;\n this.lastJudgeThreadId = undefined;\n this.lastTestPrompt = undefined;\n this.lastFinalOutput = undefined;\n this.lastDurationMs = 0;\n this.lastMessages = [];\n const contentAssertion = evalCase.eval?.content_assertion || \"\";\n const message = contentAssertion\n ? `Starting: ${contentAssertion}`\n : \"Starting\";\n this.log(message, {\n case_id: evalCase.caseId,\n thread_id: threadId,\n steps_count: evalCase.steps?.length,\n output_type: evalCase.output?.type,\n content_assertion: contentAssertion,\n });\n\n // Execute all agent steps sequentially\n let currentThreadId = threadId;\n let lastResponseData: any = null;\n for (const step of evalCase.steps) {\n const result = await this.executeAgentStep(\n step,\n currentThreadId,\n evalCase.input.message,\n evalCase.input.files || {}\n );\n currentThreadId = result.threadId;\n lastResponseData = result.responseData;\n\n // Collect messages from response if available\n // Use a Set to track message IDs to avoid duplicates\n const existingIds = new Set(this.lastMessages.map(m => m.id).filter(Boolean));\n if (result.responseData?.messages && Array.isArray(result.responseData.messages)) {\n for (const msg of result.responseData.messages) {\n if (msg && typeof msg === 'object') {\n const msgId = msg.id || msg.lc_id || msg._id;\n // Skip if we've already added this message\n if (msgId && existingIds.has(msgId)) {\n continue;\n }\n\n const role = msg.role || msg.getType?.() || msg.type || 'unknown';\n let content = '';\n if (typeof msg.content === 'string') {\n content = msg.content;\n } else if (Array.isArray(msg.content)) {\n content = msg.content.map((c: any) =>\n typeof c === 'string' ? c :\n (c?.text || (typeof c === 'object' ? JSON.stringify(c) : String(c)))\n ).join('\\n');\n } else if (msg.content && typeof msg.content === 'object') {\n content = msg.content.text || JSON.stringify(msg.content);\n } else {\n content = String(msg.content || '');\n }\n\n this.lastMessages.push({\n role,\n content,\n id: msgId,\n });\n if (msgId) {\n existingIds.add(msgId);\n }\n }\n }\n }\n }\n\n // Get the final agent ID from the last step\n const finalAgentId =\n evalCase.steps[evalCase.steps.length - 1]?.agent_id || \"\";\n this.log(\"All agent steps completed\", {\n case_id: evalCase.caseId,\n final_agent_id: finalAgentId,\n final_thread_id: currentThreadId,\n });\n\n // Extract output based on output type\n const finalOutput = await this.extractOutput(\n evalCase.output,\n finalAgentId,\n currentThreadId,\n lastResponseData\n );\n this.lastFinalOutput = finalOutput;\n this.log(\"Final output extracted\", {\n case_id: evalCase.caseId,\n output_type: evalCase.output.type,\n output_length: finalOutput.length,\n });\n\n // Build test prompt\n const testCaseFilesContent = evalCase.input.files\n ? Object.keys(evalCase.input.files)\n .map(\n (key: string) =>\n `File name: ${key}\\nFile content: ${evalCase.input.files![key]}`\n )\n .join(\"\\n\\n\")\n : \"\";\n\n // Determine output type description\n const outputTypeDescription = evalCase.output.type === \"file_content\"\n ? `虚拟产物(文件:${evalCase.output.file_path})`\n : \"消息内容\";\n\n const defaultRubrics: LatticeEvalRubric[] = [\n {\n dimension: \"correctness\",\n weight: 100,\n description:\n \"整体正确性,是否符合预期输出描述。\",\n },\n ];\n\n const evalRubrics =\n evalCase.eval.eval_rubrics && evalCase.eval.eval_rubrics.length > 0\n ? evalCase.eval.eval_rubrics\n : defaultRubrics;\n this.log(\"Prepared evaluation rubrics\", {\n case_id: evalCase.caseId,\n rubrics_count: evalRubrics.length,\n rubric_dimensions: evalRubrics.map((r) => r.dimension),\n });\n\n const rubricsSection = `\\n## 评估指标(Evaluation Rubrics)\\n${evalRubrics\n .map(\n (r) =>\n `- **${r.dimension}**(权重:${r.weight}):${r.description}`\n )\n .join(\"\\n\")}`;\n\n const testPrompt = `# 角色\n你是一名资深的 AI Agent 评估专家,负责根据预设的指标(Rubrics)对 Agent 的执行结果进行\"黑盒测试\"判定。\n\n# 输入信息\n测试框架将为你提供以下四个核心上下文:\n\n1. **用户意图(User Intent)**:${evalCase.input.message}\n\n2. **输入文件(Input Files)**:${testCaseFilesContent || \"无\"}\n\n3. **实际输出(Actual Output,${outputTypeDescription})**: \n${finalOutput}\n\n4. **期望输出描述(Expected Output Description)**:${evalCase.eval.content_assertion}\n${rubricsSection}\n\n# 任务\n你必须严格对照\"评估指标(Evaluation Rubrics)\"中的每一项指标,分析\"实际输出(Actual Output)\"是否达标。\n\n# 规则\n1. **客观性**:仅根据提供的上下文判定。如果标准要求\"包含数字\",但输出只有文字,即使语气再好也必须扣分。\n2. **结果校验**:如果\"实际输出\"中缺失预期的内容,或内容不符合\"评估指标\"中的标准,对应的指标应判定为失败。\n3. **证据导向**:在给出原因(reason)时,必须引用输出中的原文或虚拟产物中的具体数据片段。\n4. **加权计算**:最终分数为各项指标得分与其权重的乘积之和(0-100分制)。\n\n# 输出格式(仅JSON)\n你必须仅以 JSON 格式回复,结构如下:\n{\n \"pass\": true | false,\n \"final_score\": number,\n \"dimension_results\": [\n {\n \"name\": \"指标名称\",\n \"score\": number,\n \"reason\": \"具体的扣分或给分理由,需引用证据\"\n }\n ],\n \"summary\": \"对 Agent 表现的整体评价\"\n}\n\n注意:如果 final_score >= 80 且没有致命性错误,pass 应为 true;否则为 false。`;\n this.lastTestPrompt = testPrompt;\n\n // Invoke judge agent\n const judgeThreadId = v4();\n this.lastJudgeThreadId = judgeThreadId;\n this.log(\"Invoking judge agent\", { agent_key: \"LatticeTest\", case_id: evalCase.caseId });\n const judgeAgent = await getAgentClient(\"default\", \"LatticeTest\");\n const testResponse = await judgeAgent.invoke(\n {\n messages: [new HumanMessage(testPrompt)],\n },\n {\n configurable: {\n thread_id: judgeThreadId,\n },\n }\n );\n this.log(\"Judge agent responded\", {\n case_id: evalCase.caseId,\n messages_count: testResponse?.messages?.length,\n });\n\n const testResultContent: any =\n testResponse.messages[testResponse.messages.length - 1]?.content || \"\";\n this.log(\"Judge raw output received\", {\n case_id: evalCase.caseId,\n output_length:\n typeof testResultContent === \"string\" ? testResultContent.length : undefined,\n });\n\n // Parse JSON response from judge agent\n let parsedResult: {\n pass?: boolean;\n final_score?: number;\n dimension_results?: Array<{ name: string; score: number; reason: string }>;\n summary?: string;\n } = {};\n\n try {\n // Try to extract JSON from the response (handle code blocks or plain JSON)\n const jsonMatch = testResultContent.match(/```(?:json)?\\s*(\\{[\\s\\S]*\\})\\s*```/) ||\n testResultContent.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n parsedResult = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n this.log(\"Parsed judge JSON successfully\", {\n case_id: evalCase.caseId,\n parsed_keys: Object.keys(parsedResult || {}),\n });\n } else {\n this.log(\"No JSON detected in judge output; will fallback\", {\n case_id: evalCase.caseId,\n });\n }\n } catch (error) {\n // If JSON parsing fails, fall back to keyword-based parsing\n console.warn(\"Failed to parse JSON from judge agent response, falling back to keyword-based parsing:\", error);\n this.log(\"Failed to parse judge JSON; falling back\", {\n case_id: evalCase.caseId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n // Determine pass status\n let pass: boolean;\n if (parsedResult.pass !== undefined) {\n pass = parsedResult.pass;\n this.log(\"Pass determined from parsedResult.pass\", { case_id: evalCase.caseId, pass });\n } else if (parsedResult.final_score !== undefined) {\n pass = parsedResult.final_score >= 80;\n this.log(\"Pass determined from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: parsedResult.final_score,\n pass,\n });\n } else {\n // Fallback to keyword-based parsing\n pass = testResultContent.toLowerCase().includes(\"pass\") ||\n testResultContent.toLowerCase().includes(\"success\") ||\n testResultContent.toLowerCase().includes(\"通过\") ||\n testResultContent.toLowerCase().includes(\"符合\");\n this.log(\"Pass determined from keyword fallback\", { case_id: evalCase.caseId, pass });\n }\n\n // Extract dimension results\n let dimensionResults: Array<{ name: string; score: number; reason: string }> = [];\n\n if (parsedResult.dimension_results && parsedResult.dimension_results.length > 0) {\n // Use parsed dimension results from JSON\n dimensionResults = parsedResult.dimension_results;\n this.log(\"Using parsed dimension_results from judge\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n } else if (evalRubrics.length > 0) {\n // Fallback: create dimension results structure if rubrics are provided but not parsed\n dimensionResults = evalRubrics.map((rubric) => ({\n name: rubric.dimension,\n score: 0,\n reason: \"\",\n }));\n this.log(\"No dimension_results parsed; using rubric skeleton\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n }\n\n // Calculate final score\n let finalScore: number;\n if (parsedResult.final_score !== undefined) {\n finalScore = parsedResult.final_score;\n this.log(\"Final score taken from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n });\n } else if (dimensionResults.length > 0 && evalRubrics.length > 0) {\n // Calculate weighted average if rubrics are provided\n const rubricMap = new Map(evalRubrics.map((r) => [r.dimension, r.weight]));\n const totalWeight = Array.from(rubricMap.values()).reduce((sum, w) => sum + w, 0);\n\n if (totalWeight > 0) {\n finalScore = dimensionResults.reduce((sum, result) => {\n const weight = rubricMap.get(result.name) || 1;\n return sum + (result.score * weight);\n }, 0) / totalWeight;\n } else {\n // Fallback to simple average if no weights\n finalScore = dimensionResults.reduce((sum, result) => sum + result.score, 0) / dimensionResults.length;\n }\n this.log(\"Final score computed from dimension_results\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n total_weight: totalWeight,\n });\n } else {\n finalScore = pass ? 100 : 0;\n this.log(\"Final score fallback (pass-based)\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n pass,\n });\n }\n\n const summary = parsedResult.summary || testResultContent || \"\";\n this.log(\"Case evaluation completed\", {\n case_id: evalCase.caseId,\n pass,\n final_score: finalScore,\n summary,\n });\n const finishedAt = Date.now();\n this.lastDurationMs = finishedAt - startedAt;\n this.record(\"info\", \"Case duration recorded\", {\n case_id: evalCase.caseId,\n duration_ms: this.lastDurationMs,\n });\n return {\n pass,\n final_score: finalScore,\n dimension_results: dimensionResults,\n summary: parsedResult.summary || testResultContent,\n };\n }\n}\n\n/**\n * Evaluate a single Lattice evaluation case (backward compatibility function)\n * @param evalCase The evaluation case to run\n * @param config Optional server configuration (defaults to localhost:3203)\n * @returns Evaluation result with pass/fail status and scores\n * @deprecated Use LatticeEval class instead\n */\nexport async function evaluateLatticeCase(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n return evaluator.evaluateCase(evalCase);\n}\n\n/**\n * Evaluate a single Lattice evaluation case and always return logs (never throws).\n */\nexport async function evaluateLatticeCaseWithLogs(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalCaseRunResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n try {\n const result = await evaluator.evaluateCase(evalCase);\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n result,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n evaluator.record(\"error\", \"Case evaluation failed\", {\n case_id: evalCase.caseId,\n error: errorMessage,\n });\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n error: errorMessage,\n error_stack: errorStack,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n }\n}\n","import type { LLMConfig } from \"@axiom-lattice/protocols\";\nimport type {\n LatticeEvalSuiteType,\n LatticeEvalCase,\n LatticeEvalCaseType,\n LatticeEvalCaseWithTemplate,\n LatticeEvalTemplate,\n LatticeEvalLogEvent,\n LatticeEvalResult,\n} from \"./types\";\nimport {\n evaluateLatticeCaseWithLogs,\n LatticeEvalConfig,\n} from \"./LatticeEval\";\n\n/**\n * Configuration resolved from project/suite hierarchy\n */\nexport interface ResolvedConfig {\n lattice_server_config: {\n base_url: string;\n api_key?: string;\n };\n judge_agent_config?: {\n model: LLMConfig;\n };\n concurrency: number; // Number of cases to run concurrently\n}\n\n/**\n * Result with error handling\n */\nexport interface CaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n logs: LatticeEvalLogEvent[];\n duration_ms?: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n error_stack?: string;\n}\n\n/**\n * Limit concurrency of async operations with error isolation\n * Each task failure will not affect other tasks\n */\nasync function limitConcurrency<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number\n): Promise<Array<{ success: boolean; result?: T; error?: string }>> {\n const results: Array<{ success: boolean; result?: T; error?: string }> = [];\n const executing: Promise<void>[] = [];\n let index = 0;\n\n // Execute a single task with error handling\n const executeTask = async (task: () => Promise<T>, taskIndex: number): Promise<void> => {\n try {\n const result = await task();\n results[taskIndex] = { success: true, result };\n } catch (error) {\n results[taskIndex] = {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n // Never throw error here - always resolve to allow other tasks to continue\n // The error is already captured in the results array\n };\n\n // Process tasks with concurrency control\n while (index < tasks.length || executing.length > 0) {\n // Start new tasks up to concurrency limit\n while (executing.length < concurrency && index < tasks.length) {\n const task = tasks[index];\n const currentIndex = index++;\n // Wrap executeTask to ensure it never rejects, even on error\n const promise = executeTask(task, currentIndex)\n .catch((err) => {\n // This should never happen since executeTask catches all errors,\n // but add this as a safety net\n console.error(`Unexpected error in task execution:`, err);\n })\n .finally(() => {\n // Remove from executing array when done\n const idx = executing.indexOf(promise);\n if (idx > -1) {\n executing.splice(idx, 1);\n }\n });\n executing.push(promise);\n }\n\n // Wait for at least one task to complete before starting new ones\n // Since executeTask always resolves (never rejects), Promise.race is safe\n if (executing.length > 0) {\n await Promise.race(executing);\n }\n }\n\n // Wait for all remaining tasks to complete\n // Since all promises are guaranteed to resolve (never reject), Promise.allSettled is safe\n await Promise.allSettled(executing);\n\n return results;\n}\n\n/**\n * Resolve a template case to a full case\n */\nfunction resolveTemplateCase(\n templateCase: LatticeEvalCaseWithTemplate,\n templates: Map<string, LatticeEvalTemplate>\n): LatticeEvalCase {\n const template = templates.get(templateCase.templateId);\n if (!template) {\n throw new Error(`Template not found: ${templateCase.templateId}`);\n }\n\n // Merge template default_case with case-specific overrides\n const resolvedCase: LatticeEvalCase = {\n caseId: templateCase.caseId,\n input: {\n message:\n templateCase.input.message ?? template.default_case.input.message,\n files: {\n ...template.default_case.input.files,\n ...templateCase.input.files,\n },\n },\n steps: template.default_case.steps,\n output: templateCase.output || template.default_case.output,\n eval: {\n content_assertion: templateCase.eval.content_assertion,\n eval_rubrics: templateCase.eval.eval_rubrics || template.default_case.eval?.eval_rubrics,\n },\n };\n\n return resolvedCase;\n}\n\n/**\n * Check if a case is a template case\n */\nfunction isTemplateCase(\n case_: LatticeEvalCaseType\n): case_ is LatticeEvalCaseWithTemplate {\n return \"templateId\" in case_;\n}\n\n/**\n * LatticeEvalSuite class manages a suite of evaluation cases\n * with suite-level configuration\n */\nexport class LatticeEvalSuite {\n private suite: LatticeEvalSuiteType;\n private projectConfig: ResolvedConfig;\n private templates: Map<string, LatticeEvalTemplate>;\n\n constructor(\n suite: LatticeEvalSuiteType,\n projectConfig: ResolvedConfig,\n templates: Map<string, LatticeEvalTemplate> = new Map()\n ) {\n this.suite = suite;\n this.projectConfig = projectConfig;\n this.templates = templates;\n }\n\n /**\n * Get resolved configuration from project\n */\n private getResolvedConfig(): ResolvedConfig {\n return this.projectConfig;\n }\n\n /**\n * Get suite name\n */\n getSuiteName(): string {\n return this.suite.suiteName;\n }\n\n /**\n * Get suite version\n */\n getVersion(): string | undefined {\n return this.suite.version;\n }\n\n /**\n * Get all cases in this suite (resolved from templates if needed)\n */\n getCases(): LatticeEvalCase[] {\n return this.suite.cases.map((case_) => {\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n });\n }\n\n /**\n * Get a specific case by ID (resolved from template if needed)\n */\n getCase(caseId: string): LatticeEvalCase | undefined {\n const case_ = this.suite.cases.find((c) => c.caseId === caseId);\n if (!case_) {\n return undefined;\n }\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n }\n\n /**\n * Run a single case in this suite with error handling\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(caseId: string): Promise<CaseRunResult> {\n try {\n const evalCase = this.getCase(caseId);\n if (!evalCase) {\n return {\n caseId,\n error: `Case not found: ${caseId}`,\n logs: [],\n };\n }\n\n const config = this.getResolvedConfig();\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n };\n } catch (error) {\n return {\n caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n };\n }\n }\n\n /**\n * Run all cases in this suite with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runAllCases(concurrency?: number): Promise<CaseRunResult[]> {\n const config = this.getResolvedConfig();\n const maxConcurrency = concurrency ?? config.concurrency;\n\n // Create tasks for all cases\n const tasks = this.suite.cases.map((case_) => async () => {\n try {\n // Resolve template case if needed\n const evalCase: LatticeEvalCase = isTemplateCase(case_)\n ? resolveTemplateCase(case_, this.templates)\n : case_;\n\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId: evalCase.caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n } as CaseRunResult;\n } catch (error) {\n return {\n caseId: case_.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n } as CaseRunResult;\n }\n });\n\n // Run with concurrency limit\n const taskResults = await limitConcurrency(tasks, maxConcurrency);\n\n // Map results to CaseRunResult format\n return taskResults.map((taskResult, index) => {\n if (taskResult.success && taskResult.result) {\n return taskResult.result;\n }\n return {\n caseId: this.suite.cases[index].caseId,\n error: taskResult.error || \"Unknown error\",\n logs: [],\n };\n });\n }\n}\n","import type {\n LatticeEvalBatchReport,\n LatticeEvalProjectType,\n LatticeEvalReportConfig,\n LatticeEvalTemplate,\n} from \"./types\";\nimport { LatticeEvalSuite, ResolvedConfig, CaseRunResult } from \"./LatticeEvalSuite\";\nimport {\n registerModelLattice,\n registerAgentLattice,\n AgentType,\n AgentConfig,\n} from \"@axiom-lattice/core\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\n\n/**\n * LatticeEvalProject class manages a project with multiple evaluation suites\n * with project-level configuration\n */\nexport class LatticeEvalProject {\n private project: LatticeEvalProjectType;\n private suites: Map<string, LatticeEvalSuite> = new Map();\n private reportConfig?: LatticeEvalReportConfig;\n\n constructor(project: LatticeEvalProjectType) {\n this.project = project;\n this.reportConfig = project.report_config;\n\n // Register judge model\n const judgeModelKey = `${this.project.projectName}_judge_model`;\n registerModelLattice(judgeModelKey, this.project.judge_agent_config.model);\n\n // Register judge agent\n const judgeAgentKey = \"LatticeTest\";\n const judgeAgentConfig: AgentConfig = {\n key: judgeAgentKey,\n name: \"Lattice Test Judge Agent\",\n description: \"Judge agent for evaluating Lattice test cases\",\n type: AgentType.REACT,\n prompt: \"\", // No prompt as requested\n modelKey: judgeModelKey,\n };\n registerAgentLattice(judgeAgentConfig);\n\n // Build resolved config for project\n const projectConfig: ResolvedConfig = {\n lattice_server_config: {\n base_url: this.project.lattice_server_config.base_url,\n api_key: this.project.lattice_server_config.api_key,\n },\n judge_agent_config: this.project.judge_agent_config,\n concurrency: this.project.concurrency ?? 1,\n };\n\n // Build templates map\n const templatesMap = new Map<string, LatticeEvalTemplate>();\n if (this.project.templates) {\n for (const template of this.project.templates) {\n templatesMap.set(template.templateId, template);\n }\n }\n\n // Initialize all suites with project config and templates\n for (const suite of this.project.suites) {\n this.suites.set(\n suite.suiteName,\n new LatticeEvalSuite(suite, projectConfig, templatesMap)\n );\n }\n }\n\n /**\n * Get project name\n */\n getProjectName(): string {\n return this.project.projectName;\n }\n\n /**\n * Get project version\n */\n getVersion(): string | undefined {\n return this.project.version;\n }\n\n /**\n * Get project description\n */\n getDescription(): string | undefined {\n return this.project.description;\n }\n\n /**\n * Get all suite names\n */\n getSuiteNames(): string[] {\n return Array.from(this.suites.keys());\n }\n\n /**\n * Get a specific suite by name\n */\n getSuite(suiteName: string): LatticeEvalSuite | undefined {\n return this.suites.get(suiteName);\n }\n\n /**\n * Run a specific case in a specific suite\n * @param suiteName The suite name\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(suiteName: string, caseId: string): Promise<CaseRunResult> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n return {\n caseId,\n error: `Suite not found: ${suiteName}`,\n logs: [],\n };\n }\n return suite.runCase(caseId);\n }\n\n /**\n * Run all cases in a specific suite with concurrency control and error isolation\n * @param suiteName The suite name\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runSuite(suiteName: string, concurrency?: number): Promise<CaseRunResult[]> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n throw new Error(`Suite not found: ${suiteName}`);\n }\n return suite.runAllCases(concurrency);\n }\n\n /**\n * Run all cases in all suites with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Map of suite names to their case run results\n */\n async runAllSuites(concurrency?: number): Promise<Map<string, CaseRunResult[]>> {\n const results = new Map<string, CaseRunResult[]>();\n\n for (const suiteName of this.getSuiteNames()) {\n try {\n const suiteResults = await this.runSuite(suiteName, concurrency);\n results.set(suiteName, suiteResults);\n } catch (error) {\n // If suite execution fails, create error results for all cases\n const suite = this.getSuite(suiteName);\n if (suite) {\n const errorResults: CaseRunResult[] = suite.getCases().map((c) => ({\n caseId: c.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n }));\n results.set(suiteName, errorResults);\n }\n }\n }\n\n return results;\n }\n\n /**\n * Run all suites as a \"batch\", build a report, and optionally write it to disk.\n */\n async runAllSuitesBatch(concurrency?: number): Promise<{\n batch_id: string;\n batch_dir?: string;\n results: Map<string, CaseRunResult[]>;\n report: LatticeEvalBatchReport;\n }> {\n const started_at = new Date().toISOString();\n const batch_id =\n this.reportConfig?.batch_id ||\n `${Date.now()}`;\n\n console.log(`\\nRunning batch: ${this.project.projectName} (${this.getSuiteNames().length} suites)`);\n\n const results = await this.runAllSuites(concurrency);\n\n let total_cases = 0;\n let passed_cases = 0;\n let failed_cases = 0;\n\n const suites: LatticeEvalBatchReport[\"suites\"] = [];\n const durations: number[] = [];\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteTotal = caseResults.length;\n const suitePassed = caseResults.filter((r) => r.result?.pass).length;\n const suiteFailed = suiteTotal - suitePassed;\n\n total_cases += suiteTotal;\n passed_cases += suitePassed;\n failed_cases += suiteFailed;\n\n suites.push({\n suiteName,\n total_cases: suiteTotal,\n passed_cases: suitePassed,\n failed_cases: suiteFailed,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n pass: r.result?.pass,\n final_score: r.result?.final_score,\n error: r.error,\n })),\n });\n\n for (const r of caseResults) {\n if (typeof r.duration_ms === \"number\") durations.push(r.duration_ms);\n }\n }\n\n const finished_at = new Date().toISOString();\n const report: LatticeEvalBatchReport = {\n batch_id,\n started_at,\n finished_at,\n project: {\n projectName: this.project.projectName,\n version: this.project.version,\n description: this.project.description,\n },\n summary: {\n total_cases,\n passed_cases,\n failed_cases,\n pass_rate: total_cases > 0 ? passed_cases / total_cases : 0,\n },\n suites,\n };\n\n const batch_dir = await this.maybeWriteBatchArtifacts(\n batch_id,\n report,\n results\n );\n\n console.log(`\\n=== Summary ===`);\n console.log(`Total: ${report.summary.total_cases} | Passed: ${report.summary.passed_cases} | Failed: ${report.summary.failed_cases} | Pass Rate: ${(report.summary.pass_rate * 100).toFixed(2)}%`);\n if (batch_dir) {\n console.log(`\\nResults saved to: ${batch_dir}`);\n }\n\n return { batch_id, batch_dir, results, report };\n }\n\n private generateCaseMarkdown(\n index: number,\n suiteName: string,\n caseResult: CaseRunResult,\n payload: any\n ): string {\n const lines: string[] = [];\n const status = caseResult.result?.pass ? \"✅ PASS\" : \"❌ FAIL\";\n\n lines.push(`# Test ${index}: ${status}`);\n lines.push(``);\n lines.push(`- **Suite**: ${suiteName}`);\n lines.push(`- **Case ID**: ${caseResult.caseId}`);\n lines.push(`- **Status**: ${caseResult.result?.pass ? \"PASS\" : \"FAIL\"}`);\n if (typeof payload.duration === \"number\") {\n lines.push(`- **Duration**: ${(payload.duration / 1000).toFixed(2)}s`);\n }\n if (payload.threadId) {\n lines.push(`- **Thread ID**: ${payload.threadId}`);\n }\n if (payload.judgeThreadId) {\n lines.push(`- **Judge Thread ID**: ${payload.judgeThreadId}`);\n }\n lines.push(``);\n\n if (caseResult.result) {\n lines.push(`## Result`);\n lines.push(``);\n lines.push(`- **Final Score**: ${caseResult.result.final_score}`);\n lines.push(`- **Summary**: ${caseResult.result.summary || \"N/A\"}`);\n lines.push(``);\n\n if (caseResult.result.dimension_results && caseResult.result.dimension_results.length > 0) {\n lines.push(`## Dimension Results`);\n lines.push(``);\n for (const dim of caseResult.result.dimension_results) {\n lines.push(`### ${dim.name}`);\n lines.push(`- **Score**: ${dim.score}`);\n lines.push(`- **Reason**: ${dim.reason}`);\n lines.push(``);\n }\n }\n }\n\n if (caseResult.error) {\n lines.push(`## Error`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(caseResult.error);\n if (caseResult.error_stack) {\n lines.push(``);\n lines.push(caseResult.error_stack);\n }\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.messages && Array.isArray(payload.messages) && payload.messages.length > 0) {\n lines.push(`## Conversation Messages`);\n lines.push(``);\n for (let i = 0; i < payload.messages.length; i++) {\n const msg = payload.messages[i];\n const role = msg.role || 'unknown';\n const content = msg.content || '';\n lines.push(`### Message ${i + 1} (${role})`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(content);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n }\n\n if (payload.finalOutput) {\n lines.push(`## Final Output`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.finalOutput);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.testPrompt) {\n lines.push(`## Test Prompt`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.testPrompt);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private generateMarkdownSummary(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): string {\n const lines: string[] = [];\n lines.push(`# Lattice Eval Batch Summary`);\n lines.push(``);\n lines.push(`- **Project**: ${report.project.projectName}`);\n if (report.project.version) lines.push(`- **Version**: ${report.project.version}`);\n if (report.project.description) lines.push(`- **Description**: ${report.project.description}`);\n lines.push(`- **Batch ID**: ${batch_id}`);\n lines.push(`- **Started**: ${report.started_at}`);\n lines.push(`- **Finished**: ${report.finished_at}`);\n lines.push(``);\n\n lines.push(`## Overview`);\n lines.push(``);\n lines.push(`| Metric | Value |`);\n lines.push(`|---|---:|`);\n lines.push(`| Total cases | ${report.summary.total_cases} |`);\n lines.push(`| Passed | ${report.summary.passed_cases} |`);\n lines.push(`| Failed | ${report.summary.failed_cases} |`);\n lines.push(`| Pass rate | ${(report.summary.pass_rate * 100).toFixed(2)}% |`);\n lines.push(``);\n\n lines.push(`## Suites`);\n lines.push(``);\n for (const suite of report.suites) {\n lines.push(`### ${suite.suiteName}`);\n lines.push(``);\n lines.push(`| Case | Status | Score | Duration (ms) | Thread |`);\n lines.push(`|---|---|---:|---:|---|`);\n const suiteResults = results.get(suite.suiteName) || [];\n for (const r of suiteResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const score = r.result?.final_score ?? \"\";\n const dur = typeof r.duration_ms === \"number\" ? r.duration_ms : \"\";\n const thread = r.thread_id ?? \"\";\n lines.push(`| ${r.caseId} | ${status} | ${score} | ${dur} | ${thread} |`);\n }\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private async maybeWriteBatchArtifacts(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): Promise<string | undefined> {\n const config = this.reportConfig;\n if (!config?.output_dir) return undefined;\n\n const batchDir = path.join(config.output_dir, batch_id);\n await mkdir(batchDir, { recursive: true });\n\n const writeReportJson = config.write_report_json ?? true;\n const writeCaseLogs = config.write_case_logs ?? true;\n\n if (writeReportJson) {\n await writeFile(\n path.join(batchDir, \"report.json\"),\n JSON.stringify(report, null, 2),\n \"utf-8\"\n );\n }\n\n // Write richer results.json (similar to TestRunner)\n const resultsJsonPath = path.join(batchDir, \"results.json\");\n const resultsJson = {\n executionTimestamp: batch_id,\n summary: report.summary,\n report,\n results: Array.from(results.entries()).map(([suiteName, caseResults]) => ({\n suiteName,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n passed: r.result?.pass === true,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? {\n message: r.error,\n stack: r.error_stack,\n }\n : undefined,\n duration: r.duration_ms,\n testPrompt: r.test_prompt,\n finalOutput: r.final_output,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n })),\n })),\n };\n await writeFile(resultsJsonPath, JSON.stringify(resultsJson, null, 2), \"utf-8\");\n\n // Write summary.md\n const summaryMdPath = path.join(batchDir, \"summary.md\");\n const summaryMd = this.generateMarkdownSummary(batch_id, report, results);\n await writeFile(summaryMdPath, summaryMd, \"utf-8\");\n\n // Write per-case detailed json and markdown\n const individualDir = path.join(batchDir, \"individual\");\n await mkdir(individualDir, { recursive: true });\n let index = 1;\n for (const [suiteName, caseResults] of results.entries()) {\n for (const r of caseResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const baseFilename = `test-${index}-${suiteName}-${r.caseId}-${status}`.replace(/[\\/\\\\]/g, \"_\");\n\n // Write JSON\n const jsonPath = path.join(individualDir, `${baseFilename}.json`);\n const payload = {\n index,\n suiteName,\n caseId: r.caseId,\n passed: r.result?.pass === true,\n result: r.result,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? { message: r.error, stack: r.error_stack }\n : undefined,\n duration: r.duration_ms,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n finalOutput: r.final_output,\n testPrompt: r.test_prompt,\n messages: r.messages,\n };\n await writeFile(jsonPath, JSON.stringify(payload, null, 2), \"utf-8\");\n\n // Write Markdown\n const mdPath = path.join(individualDir, `${baseFilename}.md`);\n const mdContent = this.generateCaseMarkdown(index, suiteName, r, payload);\n await writeFile(mdPath, mdContent, \"utf-8\");\n\n index += 1;\n }\n }\n\n if (writeCaseLogs) {\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteDir = path.join(batchDir, \"cases\", suiteName);\n await mkdir(suiteDir, { recursive: true });\n for (const r of caseResults) {\n await writeFile(\n path.join(suiteDir, `${r.caseId}.logs.json`),\n JSON.stringify(r.logs || [], null, 2),\n \"utf-8\"\n );\n }\n }\n }\n\n return batchDir;\n }\n}\n"],"mappings":"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","names":["import_core","path"]}
|
package/dist/index.mjs
CHANGED
|
@@ -328,7 +328,8 @@ ${rubricsSection}
|
|
|
328
328
|
const judgeThreadId = v4();
|
|
329
329
|
this.lastJudgeThreadId = judgeThreadId;
|
|
330
330
|
this.log("Invoking judge agent", { agent_key: "LatticeTest", case_id: evalCase.caseId });
|
|
331
|
-
const
|
|
331
|
+
const judgeAgent = await getAgentClient("default", "LatticeTest");
|
|
332
|
+
const testResponse = await judgeAgent.invoke(
|
|
332
333
|
{
|
|
333
334
|
messages: [new HumanMessage(testPrompt)]
|
|
334
335
|
},
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LatticeEval.ts","../src/LatticeEvalSuite.ts","../src/LatticeEvalProject.ts"],"sourcesContent":["import { getAgentClient } from \"@axiom-lattice/core\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport { v4 } from \"uuid\";\nimport type {\n LatticeEvalCase,\n LatticeEvalLogEvent,\n LatticeEvalLogLevel,\n LatticeEvalRubric,\n LatticeEvalResult,\n OutputType,\n LatticeAgentStepConfig,\n} from \"./types\";\n\n/**\n * Configuration for Lattice evaluation server\n */\nexport interface LatticeEvalConfig {\n base_url: string;\n api_key?: string;\n /**\n * When true, prints detailed execution logs for each action.\n * Defaults to true.\n */\n verbose?: boolean;\n}\n\nexport interface LatticeEvalCaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n error_stack?: string;\n duration_ms: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n logs: LatticeEvalLogEvent[];\n}\n\n\n/**\n * LatticeEval class for evaluating Lattice evaluation cases\n */\nexport class LatticeEval {\n private config: LatticeEvalConfig;\n private baseUrl: string;\n private verbose: boolean;\n private inMemoryLogs: LatticeEvalLogEvent[] = [];\n private lastThreadId?: string;\n private lastJudgeThreadId?: string;\n private lastTestPrompt?: string;\n private lastFinalOutput?: string;\n private lastDurationMs: number = 0;\n private lastMessages: Array<{ role: string; content: string; id?: string }> = [];\n\n public getLastRunMeta() {\n return {\n duration_ms: this.lastDurationMs,\n thread_id: this.lastThreadId,\n judge_thread_id: this.lastJudgeThreadId,\n test_prompt: this.lastTestPrompt,\n final_output: this.lastFinalOutput,\n messages: this.lastMessages,\n };\n }\n\n /**\n * Create a new LatticeEval instance\n * @param config Optional server configuration (defaults to localhost:3203)\n */\n constructor(config: LatticeEvalConfig) {\n this.config = config;\n this.baseUrl = this.config.base_url;\n this.verbose = this.config.verbose ?? true;\n }\n\n public getInMemoryLogs(): LatticeEvalLogEvent[] {\n return [...this.inMemoryLogs];\n }\n\n public record(\n level: LatticeEvalLogLevel,\n message: string,\n data?: Record<string, unknown>\n ) {\n const event: LatticeEvalLogEvent = {\n ts: new Date().toISOString(),\n level,\n message,\n data,\n };\n this.inMemoryLogs.push(event);\n\n if (!this.verbose) return;\n // Simple console output - only show key info, no verbose details\n if (level === \"error\") {\n const keyInfo = this.getKeyInfo(data);\n console.log(` ✗ ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.startsWith(\"Starting\")) {\n // Only show start/end of case evaluation\n const keyInfo = this.getKeyInfo(data);\n console.log(` ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.includes(\"Case evaluation completed\")) {\n // Show completion with pass/fail status and reason\n const keyInfo = this.getKeyInfo(data);\n const pass = data?.pass;\n const summary = data?.summary as string | undefined;\n const status = pass ? \"✓ PASS\" : \"✗ FAIL\";\n const reason = summary || (pass ? \"Test passed\" : \"Test failed\");\n console.log(` ${status} ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n if (reason) {\n console.log(` Reason: ${reason}`);\n }\n }\n // Skip other verbose logs in console (they're still in memory for file output)\n }\n\n private log(message: string, data?: Record<string, unknown>) {\n this.record(\"info\", message, data);\n }\n\n private getKeyInfo(data?: Record<string, unknown>): string {\n if (!data) return \"\";\n const parts: string[] = [];\n // Only show case_id, pass, final_score, error - key info only\n // Note: content_assertion is shown in the message itself, not here\n if (data.case_id) parts.push(`case=${data.case_id}`);\n if (data.pass !== undefined) parts.push(`pass=${data.pass}`);\n if (data.final_score !== undefined) parts.push(`score=${data.final_score}`);\n if (data.error) parts.push(`error=${data.error}`);\n return parts.length > 0 ? `(${parts.join(\" \")})` : \"\";\n }\n\n /**\n * Execute a single agent step and return the thread ID and response data\n */\n private async executeAgentStep(\n step: LatticeAgentStepConfig,\n threadId: string,\n inputMessage: string,\n files: Record<string, string>\n ): Promise<{ threadId: string; responseData: any }> {\n this.log(\"Executing agent step\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n has_override_input_message: Boolean(step.override_input_message),\n input_message_length: step.override_input_message\n ? step.override_input_message.length\n : inputMessage.length,\n files_count: Object.keys(files || {}).length,\n });\n\n const response = await fetch(`${this.baseUrl}/api/runs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n assistant_id: step.agent_id,\n thread_id: threadId,\n files: Object.keys(files).reduce((acc, key) => {\n acc[key] = { content: files[key].split(\"\\n\"), created_at: new Date().toISOString(), modified_at: new Date().toISOString() };\n return acc;\n }, {} as Record<string, any>),\n message: step.override_input_message || inputMessage,\n }),\n });\n\n\n const responseData: any = await response.json();\n if (responseData.error) {\n this.log(\"Agent step failed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n error: responseData.error,\n });\n throw new Error(\n `Failed to run agent ${step.agent_id}: ${responseData.error}`\n );\n }\n this.log(\"Agent step completed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n response_keys: responseData ? Object.keys(responseData) : [],\n });\n return { threadId, responseData };\n }\n\n /**\n * Extract output content based on OutputType\n */\n private async extractOutput(\n outputType: OutputType,\n agentId: string,\n threadId: string,\n runResponseData?: any\n ): Promise<string> {\n if (outputType.type === \"file_content\") {\n this.log(\"Extracting file output\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n const responseState = await fetch(\n `${this.baseUrl}/api/assistants/${agentId}/${threadId}/state`,\n {\n method: \"GET\",\n }\n );\n\n if (!responseState.ok) {\n this.log(\"Failed to fetch assistant state\", {\n agent_id: agentId,\n thread_id: threadId,\n status: responseState.status,\n statusText: responseState.statusText,\n });\n throw new Error(`Failed to get state: ${responseState.statusText}`);\n }\n\n const state: any = await responseState.json();\n const stateValues: any = state.values;\n const fileContent = stateValues.files[outputType.file_path]?.content;\n\n if (!fileContent) {\n this.log(\"File output not found in state\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n throw new Error(\n `File not found in output: ${outputType.file_path}`\n );\n }\n const content = Array.isArray(fileContent)\n ? fileContent.join(\"\\n\")\n : fileContent;\n this.log(\"File output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n } else {\n // For message_content type, get the last message from the run response\n if (runResponseData?.messages && runResponseData.messages.length > 0) {\n const content =\n runResponseData.messages[runResponseData.messages.length - 1]?.content ||\n \"\";\n this.log(\"Message output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n }\n this.log(\"No message content found in run response\", {\n agent_id: agentId,\n thread_id: threadId,\n });\n throw new Error(\"No message content found in run response\");\n }\n }\n\n /**\n * Evaluate a single Lattice evaluation case\n * @param evalCase The evaluation case to run\n * @returns Evaluation result with pass/fail status and scores\n */\n async evaluateCase(evalCase: LatticeEvalCase): Promise<LatticeEvalResult> {\n const startedAt = Date.now();\n const threadId = `${evalCase.caseId}||${v4()}`;\n this.inMemoryLogs = [];\n this.lastThreadId = threadId;\n this.lastJudgeThreadId = undefined;\n this.lastTestPrompt = undefined;\n this.lastFinalOutput = undefined;\n this.lastDurationMs = 0;\n this.lastMessages = [];\n const contentAssertion = evalCase.eval?.content_assertion || \"\";\n const message = contentAssertion\n ? `Starting: ${contentAssertion}`\n : \"Starting\";\n this.log(message, {\n case_id: evalCase.caseId,\n thread_id: threadId,\n steps_count: evalCase.steps?.length,\n output_type: evalCase.output?.type,\n content_assertion: contentAssertion,\n });\n\n // Execute all agent steps sequentially\n let currentThreadId = threadId;\n let lastResponseData: any = null;\n for (const step of evalCase.steps) {\n const result = await this.executeAgentStep(\n step,\n currentThreadId,\n evalCase.input.message,\n evalCase.input.files || {}\n );\n currentThreadId = result.threadId;\n lastResponseData = result.responseData;\n\n // Collect messages from response if available\n // Use a Set to track message IDs to avoid duplicates\n const existingIds = new Set(this.lastMessages.map(m => m.id).filter(Boolean));\n if (result.responseData?.messages && Array.isArray(result.responseData.messages)) {\n for (const msg of result.responseData.messages) {\n if (msg && typeof msg === 'object') {\n const msgId = msg.id || msg.lc_id || msg._id;\n // Skip if we've already added this message\n if (msgId && existingIds.has(msgId)) {\n continue;\n }\n\n const role = msg.role || msg.getType?.() || msg.type || 'unknown';\n let content = '';\n if (typeof msg.content === 'string') {\n content = msg.content;\n } else if (Array.isArray(msg.content)) {\n content = msg.content.map((c: any) =>\n typeof c === 'string' ? c :\n (c?.text || (typeof c === 'object' ? JSON.stringify(c) : String(c)))\n ).join('\\n');\n } else if (msg.content && typeof msg.content === 'object') {\n content = msg.content.text || JSON.stringify(msg.content);\n } else {\n content = String(msg.content || '');\n }\n\n this.lastMessages.push({\n role,\n content,\n id: msgId,\n });\n if (msgId) {\n existingIds.add(msgId);\n }\n }\n }\n }\n }\n\n // Get the final agent ID from the last step\n const finalAgentId =\n evalCase.steps[evalCase.steps.length - 1]?.agent_id || \"\";\n this.log(\"All agent steps completed\", {\n case_id: evalCase.caseId,\n final_agent_id: finalAgentId,\n final_thread_id: currentThreadId,\n });\n\n // Extract output based on output type\n const finalOutput = await this.extractOutput(\n evalCase.output,\n finalAgentId,\n currentThreadId,\n lastResponseData\n );\n this.lastFinalOutput = finalOutput;\n this.log(\"Final output extracted\", {\n case_id: evalCase.caseId,\n output_type: evalCase.output.type,\n output_length: finalOutput.length,\n });\n\n // Build test prompt\n const testCaseFilesContent = evalCase.input.files\n ? Object.keys(evalCase.input.files)\n .map(\n (key: string) =>\n `File name: ${key}\\nFile content: ${evalCase.input.files![key]}`\n )\n .join(\"\\n\\n\")\n : \"\";\n\n // Determine output type description\n const outputTypeDescription = evalCase.output.type === \"file_content\"\n ? `虚拟产物(文件:${evalCase.output.file_path})`\n : \"消息内容\";\n\n const defaultRubrics: LatticeEvalRubric[] = [\n {\n dimension: \"correctness\",\n weight: 100,\n description:\n \"整体正确性,是否符合预期输出描述。\",\n },\n ];\n\n const evalRubrics =\n evalCase.eval.eval_rubrics && evalCase.eval.eval_rubrics.length > 0\n ? evalCase.eval.eval_rubrics\n : defaultRubrics;\n this.log(\"Prepared evaluation rubrics\", {\n case_id: evalCase.caseId,\n rubrics_count: evalRubrics.length,\n rubric_dimensions: evalRubrics.map((r) => r.dimension),\n });\n\n const rubricsSection = `\\n## 评估指标(Evaluation Rubrics)\\n${evalRubrics\n .map(\n (r) =>\n `- **${r.dimension}**(权重:${r.weight}):${r.description}`\n )\n .join(\"\\n\")}`;\n\n const testPrompt = `# 角色\n你是一名资深的 AI Agent 评估专家,负责根据预设的指标(Rubrics)对 Agent 的执行结果进行\"黑盒测试\"判定。\n\n# 输入信息\n测试框架将为你提供以下四个核心上下文:\n\n1. **用户意图(User Intent)**:${evalCase.input.message}\n\n2. **输入文件(Input Files)**:${testCaseFilesContent || \"无\"}\n\n3. **实际输出(Actual Output,${outputTypeDescription})**: \n${finalOutput}\n\n4. **期望输出描述(Expected Output Description)**:${evalCase.eval.content_assertion}\n${rubricsSection}\n\n# 任务\n你必须严格对照\"评估指标(Evaluation Rubrics)\"中的每一项指标,分析\"实际输出(Actual Output)\"是否达标。\n\n# 规则\n1. **客观性**:仅根据提供的上下文判定。如果标准要求\"包含数字\",但输出只有文字,即使语气再好也必须扣分。\n2. **结果校验**:如果\"实际输出\"中缺失预期的内容,或内容不符合\"评估指标\"中的标准,对应的指标应判定为失败。\n3. **证据导向**:在给出原因(reason)时,必须引用输出中的原文或虚拟产物中的具体数据片段。\n4. **加权计算**:最终分数为各项指标得分与其权重的乘积之和(0-100分制)。\n\n# 输出格式(仅JSON)\n你必须仅以 JSON 格式回复,结构如下:\n{\n \"pass\": true | false,\n \"final_score\": number,\n \"dimension_results\": [\n {\n \"name\": \"指标名称\",\n \"score\": number,\n \"reason\": \"具体的扣分或给分理由,需引用证据\"\n }\n ],\n \"summary\": \"对 Agent 表现的整体评价\"\n}\n\n注意:如果 final_score >= 80 且没有致命性错误,pass 应为 true;否则为 false。`;\n this.lastTestPrompt = testPrompt;\n\n // Invoke judge agent\n const judgeThreadId = v4();\n this.lastJudgeThreadId = judgeThreadId;\n this.log(\"Invoking judge agent\", { agent_key: \"LatticeTest\", case_id: evalCase.caseId });\n const testResponse = await getAgentClient(\"LatticeTest\").invoke(\n {\n messages: [new HumanMessage(testPrompt)],\n },\n {\n configurable: {\n thread_id: judgeThreadId,\n },\n }\n );\n this.log(\"Judge agent responded\", {\n case_id: evalCase.caseId,\n messages_count: testResponse?.messages?.length,\n });\n\n const testResultContent: any =\n testResponse.messages[testResponse.messages.length - 1]?.content || \"\";\n this.log(\"Judge raw output received\", {\n case_id: evalCase.caseId,\n output_length:\n typeof testResultContent === \"string\" ? testResultContent.length : undefined,\n });\n\n // Parse JSON response from judge agent\n let parsedResult: {\n pass?: boolean;\n final_score?: number;\n dimension_results?: Array<{ name: string; score: number; reason: string }>;\n summary?: string;\n } = {};\n\n try {\n // Try to extract JSON from the response (handle code blocks or plain JSON)\n const jsonMatch = testResultContent.match(/```(?:json)?\\s*(\\{[\\s\\S]*\\})\\s*```/) ||\n testResultContent.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n parsedResult = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n this.log(\"Parsed judge JSON successfully\", {\n case_id: evalCase.caseId,\n parsed_keys: Object.keys(parsedResult || {}),\n });\n } else {\n this.log(\"No JSON detected in judge output; will fallback\", {\n case_id: evalCase.caseId,\n });\n }\n } catch (error) {\n // If JSON parsing fails, fall back to keyword-based parsing\n console.warn(\"Failed to parse JSON from judge agent response, falling back to keyword-based parsing:\", error);\n this.log(\"Failed to parse judge JSON; falling back\", {\n case_id: evalCase.caseId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n // Determine pass status\n let pass: boolean;\n if (parsedResult.pass !== undefined) {\n pass = parsedResult.pass;\n this.log(\"Pass determined from parsedResult.pass\", { case_id: evalCase.caseId, pass });\n } else if (parsedResult.final_score !== undefined) {\n pass = parsedResult.final_score >= 80;\n this.log(\"Pass determined from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: parsedResult.final_score,\n pass,\n });\n } else {\n // Fallback to keyword-based parsing\n pass = testResultContent.toLowerCase().includes(\"pass\") ||\n testResultContent.toLowerCase().includes(\"success\") ||\n testResultContent.toLowerCase().includes(\"通过\") ||\n testResultContent.toLowerCase().includes(\"符合\");\n this.log(\"Pass determined from keyword fallback\", { case_id: evalCase.caseId, pass });\n }\n\n // Extract dimension results\n let dimensionResults: Array<{ name: string; score: number; reason: string }> = [];\n\n if (parsedResult.dimension_results && parsedResult.dimension_results.length > 0) {\n // Use parsed dimension results from JSON\n dimensionResults = parsedResult.dimension_results;\n this.log(\"Using parsed dimension_results from judge\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n } else if (evalRubrics.length > 0) {\n // Fallback: create dimension results structure if rubrics are provided but not parsed\n dimensionResults = evalRubrics.map((rubric) => ({\n name: rubric.dimension,\n score: 0,\n reason: \"\",\n }));\n this.log(\"No dimension_results parsed; using rubric skeleton\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n }\n\n // Calculate final score\n let finalScore: number;\n if (parsedResult.final_score !== undefined) {\n finalScore = parsedResult.final_score;\n this.log(\"Final score taken from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n });\n } else if (dimensionResults.length > 0 && evalRubrics.length > 0) {\n // Calculate weighted average if rubrics are provided\n const rubricMap = new Map(evalRubrics.map((r) => [r.dimension, r.weight]));\n const totalWeight = Array.from(rubricMap.values()).reduce((sum, w) => sum + w, 0);\n\n if (totalWeight > 0) {\n finalScore = dimensionResults.reduce((sum, result) => {\n const weight = rubricMap.get(result.name) || 1;\n return sum + (result.score * weight);\n }, 0) / totalWeight;\n } else {\n // Fallback to simple average if no weights\n finalScore = dimensionResults.reduce((sum, result) => sum + result.score, 0) / dimensionResults.length;\n }\n this.log(\"Final score computed from dimension_results\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n total_weight: totalWeight,\n });\n } else {\n finalScore = pass ? 100 : 0;\n this.log(\"Final score fallback (pass-based)\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n pass,\n });\n }\n\n const summary = parsedResult.summary || testResultContent || \"\";\n this.log(\"Case evaluation completed\", {\n case_id: evalCase.caseId,\n pass,\n final_score: finalScore,\n summary,\n });\n const finishedAt = Date.now();\n this.lastDurationMs = finishedAt - startedAt;\n this.record(\"info\", \"Case duration recorded\", {\n case_id: evalCase.caseId,\n duration_ms: this.lastDurationMs,\n });\n return {\n pass,\n final_score: finalScore,\n dimension_results: dimensionResults,\n summary: parsedResult.summary || testResultContent,\n };\n }\n}\n\n/**\n * Evaluate a single Lattice evaluation case (backward compatibility function)\n * @param evalCase The evaluation case to run\n * @param config Optional server configuration (defaults to localhost:3203)\n * @returns Evaluation result with pass/fail status and scores\n * @deprecated Use LatticeEval class instead\n */\nexport async function evaluateLatticeCase(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n return evaluator.evaluateCase(evalCase);\n}\n\n/**\n * Evaluate a single Lattice evaluation case and always return logs (never throws).\n */\nexport async function evaluateLatticeCaseWithLogs(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalCaseRunResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n try {\n const result = await evaluator.evaluateCase(evalCase);\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n result,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n evaluator.record(\"error\", \"Case evaluation failed\", {\n case_id: evalCase.caseId,\n error: errorMessage,\n });\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n error: errorMessage,\n error_stack: errorStack,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n }\n}\n","import type { LLMConfig } from \"@axiom-lattice/protocols\";\nimport type {\n LatticeEvalSuiteType,\n LatticeEvalCase,\n LatticeEvalCaseType,\n LatticeEvalCaseWithTemplate,\n LatticeEvalTemplate,\n LatticeEvalLogEvent,\n LatticeEvalResult,\n} from \"./types\";\nimport {\n evaluateLatticeCaseWithLogs,\n LatticeEvalConfig,\n} from \"./LatticeEval\";\n\n/**\n * Configuration resolved from project/suite hierarchy\n */\nexport interface ResolvedConfig {\n lattice_server_config: {\n base_url: string;\n api_key?: string;\n };\n judge_agent_config?: {\n model: LLMConfig;\n };\n concurrency: number; // Number of cases to run concurrently\n}\n\n/**\n * Result with error handling\n */\nexport interface CaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n logs: LatticeEvalLogEvent[];\n duration_ms?: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n error_stack?: string;\n}\n\n/**\n * Limit concurrency of async operations with error isolation\n * Each task failure will not affect other tasks\n */\nasync function limitConcurrency<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number\n): Promise<Array<{ success: boolean; result?: T; error?: string }>> {\n const results: Array<{ success: boolean; result?: T; error?: string }> = [];\n const executing: Promise<void>[] = [];\n let index = 0;\n\n // Execute a single task with error handling\n const executeTask = async (task: () => Promise<T>, taskIndex: number): Promise<void> => {\n try {\n const result = await task();\n results[taskIndex] = { success: true, result };\n } catch (error) {\n results[taskIndex] = {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n // Never throw error here - always resolve to allow other tasks to continue\n // The error is already captured in the results array\n };\n\n // Process tasks with concurrency control\n while (index < tasks.length || executing.length > 0) {\n // Start new tasks up to concurrency limit\n while (executing.length < concurrency && index < tasks.length) {\n const task = tasks[index];\n const currentIndex = index++;\n // Wrap executeTask to ensure it never rejects, even on error\n const promise = executeTask(task, currentIndex)\n .catch((err) => {\n // This should never happen since executeTask catches all errors,\n // but add this as a safety net\n console.error(`Unexpected error in task execution:`, err);\n })\n .finally(() => {\n // Remove from executing array when done\n const idx = executing.indexOf(promise);\n if (idx > -1) {\n executing.splice(idx, 1);\n }\n });\n executing.push(promise);\n }\n\n // Wait for at least one task to complete before starting new ones\n // Since executeTask always resolves (never rejects), Promise.race is safe\n if (executing.length > 0) {\n await Promise.race(executing);\n }\n }\n\n // Wait for all remaining tasks to complete\n // Since all promises are guaranteed to resolve (never reject), Promise.allSettled is safe\n await Promise.allSettled(executing);\n\n return results;\n}\n\n/**\n * Resolve a template case to a full case\n */\nfunction resolveTemplateCase(\n templateCase: LatticeEvalCaseWithTemplate,\n templates: Map<string, LatticeEvalTemplate>\n): LatticeEvalCase {\n const template = templates.get(templateCase.templateId);\n if (!template) {\n throw new Error(`Template not found: ${templateCase.templateId}`);\n }\n\n // Merge template default_case with case-specific overrides\n const resolvedCase: LatticeEvalCase = {\n caseId: templateCase.caseId,\n input: {\n message:\n templateCase.input.message ?? template.default_case.input.message,\n files: {\n ...template.default_case.input.files,\n ...templateCase.input.files,\n },\n },\n steps: template.default_case.steps,\n output: templateCase.output || template.default_case.output,\n eval: {\n content_assertion: templateCase.eval.content_assertion,\n eval_rubrics: templateCase.eval.eval_rubrics || template.default_case.eval?.eval_rubrics,\n },\n };\n\n return resolvedCase;\n}\n\n/**\n * Check if a case is a template case\n */\nfunction isTemplateCase(\n case_: LatticeEvalCaseType\n): case_ is LatticeEvalCaseWithTemplate {\n return \"templateId\" in case_;\n}\n\n/**\n * LatticeEvalSuite class manages a suite of evaluation cases\n * with suite-level configuration\n */\nexport class LatticeEvalSuite {\n private suite: LatticeEvalSuiteType;\n private projectConfig: ResolvedConfig;\n private templates: Map<string, LatticeEvalTemplate>;\n\n constructor(\n suite: LatticeEvalSuiteType,\n projectConfig: ResolvedConfig,\n templates: Map<string, LatticeEvalTemplate> = new Map()\n ) {\n this.suite = suite;\n this.projectConfig = projectConfig;\n this.templates = templates;\n }\n\n /**\n * Get resolved configuration from project\n */\n private getResolvedConfig(): ResolvedConfig {\n return this.projectConfig;\n }\n\n /**\n * Get suite name\n */\n getSuiteName(): string {\n return this.suite.suiteName;\n }\n\n /**\n * Get suite version\n */\n getVersion(): string | undefined {\n return this.suite.version;\n }\n\n /**\n * Get all cases in this suite (resolved from templates if needed)\n */\n getCases(): LatticeEvalCase[] {\n return this.suite.cases.map((case_) => {\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n });\n }\n\n /**\n * Get a specific case by ID (resolved from template if needed)\n */\n getCase(caseId: string): LatticeEvalCase | undefined {\n const case_ = this.suite.cases.find((c) => c.caseId === caseId);\n if (!case_) {\n return undefined;\n }\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n }\n\n /**\n * Run a single case in this suite with error handling\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(caseId: string): Promise<CaseRunResult> {\n try {\n const evalCase = this.getCase(caseId);\n if (!evalCase) {\n return {\n caseId,\n error: `Case not found: ${caseId}`,\n logs: [],\n };\n }\n\n const config = this.getResolvedConfig();\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n };\n } catch (error) {\n return {\n caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n };\n }\n }\n\n /**\n * Run all cases in this suite with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runAllCases(concurrency?: number): Promise<CaseRunResult[]> {\n const config = this.getResolvedConfig();\n const maxConcurrency = concurrency ?? config.concurrency;\n\n // Create tasks for all cases\n const tasks = this.suite.cases.map((case_) => async () => {\n try {\n // Resolve template case if needed\n const evalCase: LatticeEvalCase = isTemplateCase(case_)\n ? resolveTemplateCase(case_, this.templates)\n : case_;\n\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId: evalCase.caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n } as CaseRunResult;\n } catch (error) {\n return {\n caseId: case_.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n } as CaseRunResult;\n }\n });\n\n // Run with concurrency limit\n const taskResults = await limitConcurrency(tasks, maxConcurrency);\n\n // Map results to CaseRunResult format\n return taskResults.map((taskResult, index) => {\n if (taskResult.success && taskResult.result) {\n return taskResult.result;\n }\n return {\n caseId: this.suite.cases[index].caseId,\n error: taskResult.error || \"Unknown error\",\n logs: [],\n };\n });\n }\n}\n","import type {\n LatticeEvalBatchReport,\n LatticeEvalProjectType,\n LatticeEvalReportConfig,\n LatticeEvalTemplate,\n} from \"./types\";\nimport { LatticeEvalSuite, ResolvedConfig, CaseRunResult } from \"./LatticeEvalSuite\";\nimport {\n registerModelLattice,\n registerAgentLattice,\n AgentType,\n AgentConfig,\n} from \"@axiom-lattice/core\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\n\n/**\n * LatticeEvalProject class manages a project with multiple evaluation suites\n * with project-level configuration\n */\nexport class LatticeEvalProject {\n private project: LatticeEvalProjectType;\n private suites: Map<string, LatticeEvalSuite> = new Map();\n private reportConfig?: LatticeEvalReportConfig;\n\n constructor(project: LatticeEvalProjectType) {\n this.project = project;\n this.reportConfig = project.report_config;\n\n // Register judge model\n const judgeModelKey = `${this.project.projectName}_judge_model`;\n registerModelLattice(judgeModelKey, this.project.judge_agent_config.model);\n\n // Register judge agent\n const judgeAgentKey = \"LatticeTest\";\n const judgeAgentConfig: AgentConfig = {\n key: judgeAgentKey,\n name: \"Lattice Test Judge Agent\",\n description: \"Judge agent for evaluating Lattice test cases\",\n type: AgentType.REACT,\n prompt: \"\", // No prompt as requested\n modelKey: judgeModelKey,\n };\n registerAgentLattice(judgeAgentConfig);\n\n // Build resolved config for project\n const projectConfig: ResolvedConfig = {\n lattice_server_config: {\n base_url: this.project.lattice_server_config.base_url,\n api_key: this.project.lattice_server_config.api_key,\n },\n judge_agent_config: this.project.judge_agent_config,\n concurrency: this.project.concurrency ?? 1,\n };\n\n // Build templates map\n const templatesMap = new Map<string, LatticeEvalTemplate>();\n if (this.project.templates) {\n for (const template of this.project.templates) {\n templatesMap.set(template.templateId, template);\n }\n }\n\n // Initialize all suites with project config and templates\n for (const suite of this.project.suites) {\n this.suites.set(\n suite.suiteName,\n new LatticeEvalSuite(suite, projectConfig, templatesMap)\n );\n }\n }\n\n /**\n * Get project name\n */\n getProjectName(): string {\n return this.project.projectName;\n }\n\n /**\n * Get project version\n */\n getVersion(): string | undefined {\n return this.project.version;\n }\n\n /**\n * Get project description\n */\n getDescription(): string | undefined {\n return this.project.description;\n }\n\n /**\n * Get all suite names\n */\n getSuiteNames(): string[] {\n return Array.from(this.suites.keys());\n }\n\n /**\n * Get a specific suite by name\n */\n getSuite(suiteName: string): LatticeEvalSuite | undefined {\n return this.suites.get(suiteName);\n }\n\n /**\n * Run a specific case in a specific suite\n * @param suiteName The suite name\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(suiteName: string, caseId: string): Promise<CaseRunResult> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n return {\n caseId,\n error: `Suite not found: ${suiteName}`,\n logs: [],\n };\n }\n return suite.runCase(caseId);\n }\n\n /**\n * Run all cases in a specific suite with concurrency control and error isolation\n * @param suiteName The suite name\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runSuite(suiteName: string, concurrency?: number): Promise<CaseRunResult[]> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n throw new Error(`Suite not found: ${suiteName}`);\n }\n return suite.runAllCases(concurrency);\n }\n\n /**\n * Run all cases in all suites with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Map of suite names to their case run results\n */\n async runAllSuites(concurrency?: number): Promise<Map<string, CaseRunResult[]>> {\n const results = new Map<string, CaseRunResult[]>();\n\n for (const suiteName of this.getSuiteNames()) {\n try {\n const suiteResults = await this.runSuite(suiteName, concurrency);\n results.set(suiteName, suiteResults);\n } catch (error) {\n // If suite execution fails, create error results for all cases\n const suite = this.getSuite(suiteName);\n if (suite) {\n const errorResults: CaseRunResult[] = suite.getCases().map((c) => ({\n caseId: c.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n }));\n results.set(suiteName, errorResults);\n }\n }\n }\n\n return results;\n }\n\n /**\n * Run all suites as a \"batch\", build a report, and optionally write it to disk.\n */\n async runAllSuitesBatch(concurrency?: number): Promise<{\n batch_id: string;\n batch_dir?: string;\n results: Map<string, CaseRunResult[]>;\n report: LatticeEvalBatchReport;\n }> {\n const started_at = new Date().toISOString();\n const batch_id =\n this.reportConfig?.batch_id ||\n `${Date.now()}`;\n\n console.log(`\\nRunning batch: ${this.project.projectName} (${this.getSuiteNames().length} suites)`);\n\n const results = await this.runAllSuites(concurrency);\n\n let total_cases = 0;\n let passed_cases = 0;\n let failed_cases = 0;\n\n const suites: LatticeEvalBatchReport[\"suites\"] = [];\n const durations: number[] = [];\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteTotal = caseResults.length;\n const suitePassed = caseResults.filter((r) => r.result?.pass).length;\n const suiteFailed = suiteTotal - suitePassed;\n\n total_cases += suiteTotal;\n passed_cases += suitePassed;\n failed_cases += suiteFailed;\n\n suites.push({\n suiteName,\n total_cases: suiteTotal,\n passed_cases: suitePassed,\n failed_cases: suiteFailed,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n pass: r.result?.pass,\n final_score: r.result?.final_score,\n error: r.error,\n })),\n });\n\n for (const r of caseResults) {\n if (typeof r.duration_ms === \"number\") durations.push(r.duration_ms);\n }\n }\n\n const finished_at = new Date().toISOString();\n const report: LatticeEvalBatchReport = {\n batch_id,\n started_at,\n finished_at,\n project: {\n projectName: this.project.projectName,\n version: this.project.version,\n description: this.project.description,\n },\n summary: {\n total_cases,\n passed_cases,\n failed_cases,\n pass_rate: total_cases > 0 ? passed_cases / total_cases : 0,\n },\n suites,\n };\n\n const batch_dir = await this.maybeWriteBatchArtifacts(\n batch_id,\n report,\n results\n );\n\n console.log(`\\n=== Summary ===`);\n console.log(`Total: ${report.summary.total_cases} | Passed: ${report.summary.passed_cases} | Failed: ${report.summary.failed_cases} | Pass Rate: ${(report.summary.pass_rate * 100).toFixed(2)}%`);\n if (batch_dir) {\n console.log(`\\nResults saved to: ${batch_dir}`);\n }\n\n return { batch_id, batch_dir, results, report };\n }\n\n private generateCaseMarkdown(\n index: number,\n suiteName: string,\n caseResult: CaseRunResult,\n payload: any\n ): string {\n const lines: string[] = [];\n const status = caseResult.result?.pass ? \"✅ PASS\" : \"❌ FAIL\";\n\n lines.push(`# Test ${index}: ${status}`);\n lines.push(``);\n lines.push(`- **Suite**: ${suiteName}`);\n lines.push(`- **Case ID**: ${caseResult.caseId}`);\n lines.push(`- **Status**: ${caseResult.result?.pass ? \"PASS\" : \"FAIL\"}`);\n if (typeof payload.duration === \"number\") {\n lines.push(`- **Duration**: ${(payload.duration / 1000).toFixed(2)}s`);\n }\n if (payload.threadId) {\n lines.push(`- **Thread ID**: ${payload.threadId}`);\n }\n if (payload.judgeThreadId) {\n lines.push(`- **Judge Thread ID**: ${payload.judgeThreadId}`);\n }\n lines.push(``);\n\n if (caseResult.result) {\n lines.push(`## Result`);\n lines.push(``);\n lines.push(`- **Final Score**: ${caseResult.result.final_score}`);\n lines.push(`- **Summary**: ${caseResult.result.summary || \"N/A\"}`);\n lines.push(``);\n\n if (caseResult.result.dimension_results && caseResult.result.dimension_results.length > 0) {\n lines.push(`## Dimension Results`);\n lines.push(``);\n for (const dim of caseResult.result.dimension_results) {\n lines.push(`### ${dim.name}`);\n lines.push(`- **Score**: ${dim.score}`);\n lines.push(`- **Reason**: ${dim.reason}`);\n lines.push(``);\n }\n }\n }\n\n if (caseResult.error) {\n lines.push(`## Error`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(caseResult.error);\n if (caseResult.error_stack) {\n lines.push(``);\n lines.push(caseResult.error_stack);\n }\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.messages && Array.isArray(payload.messages) && payload.messages.length > 0) {\n lines.push(`## Conversation Messages`);\n lines.push(``);\n for (let i = 0; i < payload.messages.length; i++) {\n const msg = payload.messages[i];\n const role = msg.role || 'unknown';\n const content = msg.content || '';\n lines.push(`### Message ${i + 1} (${role})`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(content);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n }\n\n if (payload.finalOutput) {\n lines.push(`## Final Output`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.finalOutput);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.testPrompt) {\n lines.push(`## Test Prompt`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.testPrompt);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private generateMarkdownSummary(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): string {\n const lines: string[] = [];\n lines.push(`# Lattice Eval Batch Summary`);\n lines.push(``);\n lines.push(`- **Project**: ${report.project.projectName}`);\n if (report.project.version) lines.push(`- **Version**: ${report.project.version}`);\n if (report.project.description) lines.push(`- **Description**: ${report.project.description}`);\n lines.push(`- **Batch ID**: ${batch_id}`);\n lines.push(`- **Started**: ${report.started_at}`);\n lines.push(`- **Finished**: ${report.finished_at}`);\n lines.push(``);\n\n lines.push(`## Overview`);\n lines.push(``);\n lines.push(`| Metric | Value |`);\n lines.push(`|---|---:|`);\n lines.push(`| Total cases | ${report.summary.total_cases} |`);\n lines.push(`| Passed | ${report.summary.passed_cases} |`);\n lines.push(`| Failed | ${report.summary.failed_cases} |`);\n lines.push(`| Pass rate | ${(report.summary.pass_rate * 100).toFixed(2)}% |`);\n lines.push(``);\n\n lines.push(`## Suites`);\n lines.push(``);\n for (const suite of report.suites) {\n lines.push(`### ${suite.suiteName}`);\n lines.push(``);\n lines.push(`| Case | Status | Score | Duration (ms) | Thread |`);\n lines.push(`|---|---|---:|---:|---|`);\n const suiteResults = results.get(suite.suiteName) || [];\n for (const r of suiteResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const score = r.result?.final_score ?? \"\";\n const dur = typeof r.duration_ms === \"number\" ? r.duration_ms : \"\";\n const thread = r.thread_id ?? \"\";\n lines.push(`| ${r.caseId} | ${status} | ${score} | ${dur} | ${thread} |`);\n }\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private async maybeWriteBatchArtifacts(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): Promise<string | undefined> {\n const config = this.reportConfig;\n if (!config?.output_dir) return undefined;\n\n const batchDir = path.join(config.output_dir, batch_id);\n await mkdir(batchDir, { recursive: true });\n\n const writeReportJson = config.write_report_json ?? true;\n const writeCaseLogs = config.write_case_logs ?? true;\n\n if (writeReportJson) {\n await writeFile(\n path.join(batchDir, \"report.json\"),\n JSON.stringify(report, null, 2),\n \"utf-8\"\n );\n }\n\n // Write richer results.json (similar to TestRunner)\n const resultsJsonPath = path.join(batchDir, \"results.json\");\n const resultsJson = {\n executionTimestamp: batch_id,\n summary: report.summary,\n report,\n results: Array.from(results.entries()).map(([suiteName, caseResults]) => ({\n suiteName,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n passed: r.result?.pass === true,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? {\n message: r.error,\n stack: r.error_stack,\n }\n : undefined,\n duration: r.duration_ms,\n testPrompt: r.test_prompt,\n finalOutput: r.final_output,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n })),\n })),\n };\n await writeFile(resultsJsonPath, JSON.stringify(resultsJson, null, 2), \"utf-8\");\n\n // Write summary.md\n const summaryMdPath = path.join(batchDir, \"summary.md\");\n const summaryMd = this.generateMarkdownSummary(batch_id, report, results);\n await writeFile(summaryMdPath, summaryMd, \"utf-8\");\n\n // Write per-case detailed json and markdown\n const individualDir = path.join(batchDir, \"individual\");\n await mkdir(individualDir, { recursive: true });\n let index = 1;\n for (const [suiteName, caseResults] of results.entries()) {\n for (const r of caseResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const baseFilename = `test-${index}-${suiteName}-${r.caseId}-${status}`.replace(/[\\/\\\\]/g, \"_\");\n\n // Write JSON\n const jsonPath = path.join(individualDir, `${baseFilename}.json`);\n const payload = {\n index,\n suiteName,\n caseId: r.caseId,\n passed: r.result?.pass === true,\n result: r.result,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? { message: r.error, stack: r.error_stack }\n : undefined,\n duration: r.duration_ms,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n finalOutput: r.final_output,\n testPrompt: r.test_prompt,\n messages: r.messages,\n };\n await writeFile(jsonPath, JSON.stringify(payload, null, 2), \"utf-8\");\n\n // Write Markdown\n const mdPath = path.join(individualDir, `${baseFilename}.md`);\n const mdContent = this.generateCaseMarkdown(index, suiteName, r, payload);\n await writeFile(mdPath, mdContent, \"utf-8\");\n\n index += 1;\n }\n }\n\n if (writeCaseLogs) {\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteDir = path.join(batchDir, \"cases\", suiteName);\n await mkdir(suiteDir, { recursive: true });\n for (const r of caseResults) {\n await writeFile(\n path.join(suiteDir, `${r.caseId}.logs.json`),\n JSON.stringify(r.logs || [], null, 2),\n \"utf-8\"\n );\n }\n }\n }\n\n return batchDir;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/LatticeEval.ts","../src/LatticeEvalSuite.ts","../src/LatticeEvalProject.ts"],"sourcesContent":["import { getAgentClient } from \"@axiom-lattice/core\";\nimport { HumanMessage } from \"@langchain/core/messages\";\nimport { v4 } from \"uuid\";\nimport type {\n LatticeEvalCase,\n LatticeEvalLogEvent,\n LatticeEvalLogLevel,\n LatticeEvalRubric,\n LatticeEvalResult,\n OutputType,\n LatticeAgentStepConfig,\n} from \"./types\";\n\n/**\n * Configuration for Lattice evaluation server\n */\nexport interface LatticeEvalConfig {\n base_url: string;\n api_key?: string;\n /**\n * When true, prints detailed execution logs for each action.\n * Defaults to true.\n */\n verbose?: boolean;\n}\n\nexport interface LatticeEvalCaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n error_stack?: string;\n duration_ms: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n logs: LatticeEvalLogEvent[];\n}\n\n\n/**\n * LatticeEval class for evaluating Lattice evaluation cases\n */\nexport class LatticeEval {\n private config: LatticeEvalConfig;\n private baseUrl: string;\n private verbose: boolean;\n private inMemoryLogs: LatticeEvalLogEvent[] = [];\n private lastThreadId?: string;\n private lastJudgeThreadId?: string;\n private lastTestPrompt?: string;\n private lastFinalOutput?: string;\n private lastDurationMs: number = 0;\n private lastMessages: Array<{ role: string; content: string; id?: string }> = [];\n\n public getLastRunMeta() {\n return {\n duration_ms: this.lastDurationMs,\n thread_id: this.lastThreadId,\n judge_thread_id: this.lastJudgeThreadId,\n test_prompt: this.lastTestPrompt,\n final_output: this.lastFinalOutput,\n messages: this.lastMessages,\n };\n }\n\n /**\n * Create a new LatticeEval instance\n * @param config Optional server configuration (defaults to localhost:3203)\n */\n constructor(config: LatticeEvalConfig) {\n this.config = config;\n this.baseUrl = this.config.base_url;\n this.verbose = this.config.verbose ?? true;\n }\n\n public getInMemoryLogs(): LatticeEvalLogEvent[] {\n return [...this.inMemoryLogs];\n }\n\n public record(\n level: LatticeEvalLogLevel,\n message: string,\n data?: Record<string, unknown>\n ) {\n const event: LatticeEvalLogEvent = {\n ts: new Date().toISOString(),\n level,\n message,\n data,\n };\n this.inMemoryLogs.push(event);\n\n if (!this.verbose) return;\n // Simple console output - only show key info, no verbose details\n if (level === \"error\") {\n const keyInfo = this.getKeyInfo(data);\n console.log(` ✗ ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.startsWith(\"Starting\")) {\n // Only show start/end of case evaluation\n const keyInfo = this.getKeyInfo(data);\n console.log(` ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n } else if (message.includes(\"Case evaluation completed\")) {\n // Show completion with pass/fail status and reason\n const keyInfo = this.getKeyInfo(data);\n const pass = data?.pass;\n const summary = data?.summary as string | undefined;\n const status = pass ? \"✓ PASS\" : \"✗ FAIL\";\n const reason = summary || (pass ? \"Test passed\" : \"Test failed\");\n console.log(` ${status} ${message}${keyInfo ? ` ${keyInfo}` : \"\"}`);\n if (reason) {\n console.log(` Reason: ${reason}`);\n }\n }\n // Skip other verbose logs in console (they're still in memory for file output)\n }\n\n private log(message: string, data?: Record<string, unknown>) {\n this.record(\"info\", message, data);\n }\n\n private getKeyInfo(data?: Record<string, unknown>): string {\n if (!data) return \"\";\n const parts: string[] = [];\n // Only show case_id, pass, final_score, error - key info only\n // Note: content_assertion is shown in the message itself, not here\n if (data.case_id) parts.push(`case=${data.case_id}`);\n if (data.pass !== undefined) parts.push(`pass=${data.pass}`);\n if (data.final_score !== undefined) parts.push(`score=${data.final_score}`);\n if (data.error) parts.push(`error=${data.error}`);\n return parts.length > 0 ? `(${parts.join(\" \")})` : \"\";\n }\n\n /**\n * Execute a single agent step and return the thread ID and response data\n */\n private async executeAgentStep(\n step: LatticeAgentStepConfig,\n threadId: string,\n inputMessage: string,\n files: Record<string, string>\n ): Promise<{ threadId: string; responseData: any }> {\n this.log(\"Executing agent step\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n has_override_input_message: Boolean(step.override_input_message),\n input_message_length: step.override_input_message\n ? step.override_input_message.length\n : inputMessage.length,\n files_count: Object.keys(files || {}).length,\n });\n\n const response = await fetch(`${this.baseUrl}/api/runs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n assistant_id: step.agent_id,\n thread_id: threadId,\n files: Object.keys(files).reduce((acc, key) => {\n acc[key] = { content: files[key].split(\"\\n\"), created_at: new Date().toISOString(), modified_at: new Date().toISOString() };\n return acc;\n }, {} as Record<string, any>),\n message: step.override_input_message || inputMessage,\n }),\n });\n\n\n const responseData: any = await response.json();\n if (responseData.error) {\n this.log(\"Agent step failed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n error: responseData.error,\n });\n throw new Error(\n `Failed to run agent ${step.agent_id}: ${responseData.error}`\n );\n }\n this.log(\"Agent step completed\", {\n agent_id: step.agent_id,\n thread_id: threadId,\n response_keys: responseData ? Object.keys(responseData) : [],\n });\n return { threadId, responseData };\n }\n\n /**\n * Extract output content based on OutputType\n */\n private async extractOutput(\n outputType: OutputType,\n agentId: string,\n threadId: string,\n runResponseData?: any\n ): Promise<string> {\n if (outputType.type === \"file_content\") {\n this.log(\"Extracting file output\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n const responseState = await fetch(\n `${this.baseUrl}/api/assistants/${agentId}/${threadId}/state`,\n {\n method: \"GET\",\n }\n );\n\n if (!responseState.ok) {\n this.log(\"Failed to fetch assistant state\", {\n agent_id: agentId,\n thread_id: threadId,\n status: responseState.status,\n statusText: responseState.statusText,\n });\n throw new Error(`Failed to get state: ${responseState.statusText}`);\n }\n\n const state: any = await responseState.json();\n const stateValues: any = state.values;\n const fileContent = stateValues.files[outputType.file_path]?.content;\n\n if (!fileContent) {\n this.log(\"File output not found in state\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n });\n throw new Error(\n `File not found in output: ${outputType.file_path}`\n );\n }\n const content = Array.isArray(fileContent)\n ? fileContent.join(\"\\n\")\n : fileContent;\n this.log(\"File output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n file_path: outputType.file_path,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n } else {\n // For message_content type, get the last message from the run response\n if (runResponseData?.messages && runResponseData.messages.length > 0) {\n const content =\n runResponseData.messages[runResponseData.messages.length - 1]?.content ||\n \"\";\n this.log(\"Message output extracted\", {\n agent_id: agentId,\n thread_id: threadId,\n output_length: typeof content === \"string\" ? content.length : undefined,\n });\n return content;\n }\n this.log(\"No message content found in run response\", {\n agent_id: agentId,\n thread_id: threadId,\n });\n throw new Error(\"No message content found in run response\");\n }\n }\n\n /**\n * Evaluate a single Lattice evaluation case\n * @param evalCase The evaluation case to run\n * @returns Evaluation result with pass/fail status and scores\n */\n async evaluateCase(evalCase: LatticeEvalCase): Promise<LatticeEvalResult> {\n const startedAt = Date.now();\n const threadId = `${evalCase.caseId}||${v4()}`;\n this.inMemoryLogs = [];\n this.lastThreadId = threadId;\n this.lastJudgeThreadId = undefined;\n this.lastTestPrompt = undefined;\n this.lastFinalOutput = undefined;\n this.lastDurationMs = 0;\n this.lastMessages = [];\n const contentAssertion = evalCase.eval?.content_assertion || \"\";\n const message = contentAssertion\n ? `Starting: ${contentAssertion}`\n : \"Starting\";\n this.log(message, {\n case_id: evalCase.caseId,\n thread_id: threadId,\n steps_count: evalCase.steps?.length,\n output_type: evalCase.output?.type,\n content_assertion: contentAssertion,\n });\n\n // Execute all agent steps sequentially\n let currentThreadId = threadId;\n let lastResponseData: any = null;\n for (const step of evalCase.steps) {\n const result = await this.executeAgentStep(\n step,\n currentThreadId,\n evalCase.input.message,\n evalCase.input.files || {}\n );\n currentThreadId = result.threadId;\n lastResponseData = result.responseData;\n\n // Collect messages from response if available\n // Use a Set to track message IDs to avoid duplicates\n const existingIds = new Set(this.lastMessages.map(m => m.id).filter(Boolean));\n if (result.responseData?.messages && Array.isArray(result.responseData.messages)) {\n for (const msg of result.responseData.messages) {\n if (msg && typeof msg === 'object') {\n const msgId = msg.id || msg.lc_id || msg._id;\n // Skip if we've already added this message\n if (msgId && existingIds.has(msgId)) {\n continue;\n }\n\n const role = msg.role || msg.getType?.() || msg.type || 'unknown';\n let content = '';\n if (typeof msg.content === 'string') {\n content = msg.content;\n } else if (Array.isArray(msg.content)) {\n content = msg.content.map((c: any) =>\n typeof c === 'string' ? c :\n (c?.text || (typeof c === 'object' ? JSON.stringify(c) : String(c)))\n ).join('\\n');\n } else if (msg.content && typeof msg.content === 'object') {\n content = msg.content.text || JSON.stringify(msg.content);\n } else {\n content = String(msg.content || '');\n }\n\n this.lastMessages.push({\n role,\n content,\n id: msgId,\n });\n if (msgId) {\n existingIds.add(msgId);\n }\n }\n }\n }\n }\n\n // Get the final agent ID from the last step\n const finalAgentId =\n evalCase.steps[evalCase.steps.length - 1]?.agent_id || \"\";\n this.log(\"All agent steps completed\", {\n case_id: evalCase.caseId,\n final_agent_id: finalAgentId,\n final_thread_id: currentThreadId,\n });\n\n // Extract output based on output type\n const finalOutput = await this.extractOutput(\n evalCase.output,\n finalAgentId,\n currentThreadId,\n lastResponseData\n );\n this.lastFinalOutput = finalOutput;\n this.log(\"Final output extracted\", {\n case_id: evalCase.caseId,\n output_type: evalCase.output.type,\n output_length: finalOutput.length,\n });\n\n // Build test prompt\n const testCaseFilesContent = evalCase.input.files\n ? Object.keys(evalCase.input.files)\n .map(\n (key: string) =>\n `File name: ${key}\\nFile content: ${evalCase.input.files![key]}`\n )\n .join(\"\\n\\n\")\n : \"\";\n\n // Determine output type description\n const outputTypeDescription = evalCase.output.type === \"file_content\"\n ? `虚拟产物(文件:${evalCase.output.file_path})`\n : \"消息内容\";\n\n const defaultRubrics: LatticeEvalRubric[] = [\n {\n dimension: \"correctness\",\n weight: 100,\n description:\n \"整体正确性,是否符合预期输出描述。\",\n },\n ];\n\n const evalRubrics =\n evalCase.eval.eval_rubrics && evalCase.eval.eval_rubrics.length > 0\n ? evalCase.eval.eval_rubrics\n : defaultRubrics;\n this.log(\"Prepared evaluation rubrics\", {\n case_id: evalCase.caseId,\n rubrics_count: evalRubrics.length,\n rubric_dimensions: evalRubrics.map((r) => r.dimension),\n });\n\n const rubricsSection = `\\n## 评估指标(Evaluation Rubrics)\\n${evalRubrics\n .map(\n (r) =>\n `- **${r.dimension}**(权重:${r.weight}):${r.description}`\n )\n .join(\"\\n\")}`;\n\n const testPrompt = `# 角色\n你是一名资深的 AI Agent 评估专家,负责根据预设的指标(Rubrics)对 Agent 的执行结果进行\"黑盒测试\"判定。\n\n# 输入信息\n测试框架将为你提供以下四个核心上下文:\n\n1. **用户意图(User Intent)**:${evalCase.input.message}\n\n2. **输入文件(Input Files)**:${testCaseFilesContent || \"无\"}\n\n3. **实际输出(Actual Output,${outputTypeDescription})**: \n${finalOutput}\n\n4. **期望输出描述(Expected Output Description)**:${evalCase.eval.content_assertion}\n${rubricsSection}\n\n# 任务\n你必须严格对照\"评估指标(Evaluation Rubrics)\"中的每一项指标,分析\"实际输出(Actual Output)\"是否达标。\n\n# 规则\n1. **客观性**:仅根据提供的上下文判定。如果标准要求\"包含数字\",但输出只有文字,即使语气再好也必须扣分。\n2. **结果校验**:如果\"实际输出\"中缺失预期的内容,或内容不符合\"评估指标\"中的标准,对应的指标应判定为失败。\n3. **证据导向**:在给出原因(reason)时,必须引用输出中的原文或虚拟产物中的具体数据片段。\n4. **加权计算**:最终分数为各项指标得分与其权重的乘积之和(0-100分制)。\n\n# 输出格式(仅JSON)\n你必须仅以 JSON 格式回复,结构如下:\n{\n \"pass\": true | false,\n \"final_score\": number,\n \"dimension_results\": [\n {\n \"name\": \"指标名称\",\n \"score\": number,\n \"reason\": \"具体的扣分或给分理由,需引用证据\"\n }\n ],\n \"summary\": \"对 Agent 表现的整体评价\"\n}\n\n注意:如果 final_score >= 80 且没有致命性错误,pass 应为 true;否则为 false。`;\n this.lastTestPrompt = testPrompt;\n\n // Invoke judge agent\n const judgeThreadId = v4();\n this.lastJudgeThreadId = judgeThreadId;\n this.log(\"Invoking judge agent\", { agent_key: \"LatticeTest\", case_id: evalCase.caseId });\n const judgeAgent = await getAgentClient(\"default\", \"LatticeTest\");\n const testResponse = await judgeAgent.invoke(\n {\n messages: [new HumanMessage(testPrompt)],\n },\n {\n configurable: {\n thread_id: judgeThreadId,\n },\n }\n );\n this.log(\"Judge agent responded\", {\n case_id: evalCase.caseId,\n messages_count: testResponse?.messages?.length,\n });\n\n const testResultContent: any =\n testResponse.messages[testResponse.messages.length - 1]?.content || \"\";\n this.log(\"Judge raw output received\", {\n case_id: evalCase.caseId,\n output_length:\n typeof testResultContent === \"string\" ? testResultContent.length : undefined,\n });\n\n // Parse JSON response from judge agent\n let parsedResult: {\n pass?: boolean;\n final_score?: number;\n dimension_results?: Array<{ name: string; score: number; reason: string }>;\n summary?: string;\n } = {};\n\n try {\n // Try to extract JSON from the response (handle code blocks or plain JSON)\n const jsonMatch = testResultContent.match(/```(?:json)?\\s*(\\{[\\s\\S]*\\})\\s*```/) ||\n testResultContent.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n parsedResult = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n this.log(\"Parsed judge JSON successfully\", {\n case_id: evalCase.caseId,\n parsed_keys: Object.keys(parsedResult || {}),\n });\n } else {\n this.log(\"No JSON detected in judge output; will fallback\", {\n case_id: evalCase.caseId,\n });\n }\n } catch (error) {\n // If JSON parsing fails, fall back to keyword-based parsing\n console.warn(\"Failed to parse JSON from judge agent response, falling back to keyword-based parsing:\", error);\n this.log(\"Failed to parse judge JSON; falling back\", {\n case_id: evalCase.caseId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n // Determine pass status\n let pass: boolean;\n if (parsedResult.pass !== undefined) {\n pass = parsedResult.pass;\n this.log(\"Pass determined from parsedResult.pass\", { case_id: evalCase.caseId, pass });\n } else if (parsedResult.final_score !== undefined) {\n pass = parsedResult.final_score >= 80;\n this.log(\"Pass determined from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: parsedResult.final_score,\n pass,\n });\n } else {\n // Fallback to keyword-based parsing\n pass = testResultContent.toLowerCase().includes(\"pass\") ||\n testResultContent.toLowerCase().includes(\"success\") ||\n testResultContent.toLowerCase().includes(\"通过\") ||\n testResultContent.toLowerCase().includes(\"符合\");\n this.log(\"Pass determined from keyword fallback\", { case_id: evalCase.caseId, pass });\n }\n\n // Extract dimension results\n let dimensionResults: Array<{ name: string; score: number; reason: string }> = [];\n\n if (parsedResult.dimension_results && parsedResult.dimension_results.length > 0) {\n // Use parsed dimension results from JSON\n dimensionResults = parsedResult.dimension_results;\n this.log(\"Using parsed dimension_results from judge\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n } else if (evalRubrics.length > 0) {\n // Fallback: create dimension results structure if rubrics are provided but not parsed\n dimensionResults = evalRubrics.map((rubric) => ({\n name: rubric.dimension,\n score: 0,\n reason: \"\",\n }));\n this.log(\"No dimension_results parsed; using rubric skeleton\", {\n case_id: evalCase.caseId,\n dimensions_count: dimensionResults.length,\n });\n }\n\n // Calculate final score\n let finalScore: number;\n if (parsedResult.final_score !== undefined) {\n finalScore = parsedResult.final_score;\n this.log(\"Final score taken from parsedResult.final_score\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n });\n } else if (dimensionResults.length > 0 && evalRubrics.length > 0) {\n // Calculate weighted average if rubrics are provided\n const rubricMap = new Map(evalRubrics.map((r) => [r.dimension, r.weight]));\n const totalWeight = Array.from(rubricMap.values()).reduce((sum, w) => sum + w, 0);\n\n if (totalWeight > 0) {\n finalScore = dimensionResults.reduce((sum, result) => {\n const weight = rubricMap.get(result.name) || 1;\n return sum + (result.score * weight);\n }, 0) / totalWeight;\n } else {\n // Fallback to simple average if no weights\n finalScore = dimensionResults.reduce((sum, result) => sum + result.score, 0) / dimensionResults.length;\n }\n this.log(\"Final score computed from dimension_results\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n total_weight: totalWeight,\n });\n } else {\n finalScore = pass ? 100 : 0;\n this.log(\"Final score fallback (pass-based)\", {\n case_id: evalCase.caseId,\n final_score: finalScore,\n pass,\n });\n }\n\n const summary = parsedResult.summary || testResultContent || \"\";\n this.log(\"Case evaluation completed\", {\n case_id: evalCase.caseId,\n pass,\n final_score: finalScore,\n summary,\n });\n const finishedAt = Date.now();\n this.lastDurationMs = finishedAt - startedAt;\n this.record(\"info\", \"Case duration recorded\", {\n case_id: evalCase.caseId,\n duration_ms: this.lastDurationMs,\n });\n return {\n pass,\n final_score: finalScore,\n dimension_results: dimensionResults,\n summary: parsedResult.summary || testResultContent,\n };\n }\n}\n\n/**\n * Evaluate a single Lattice evaluation case (backward compatibility function)\n * @param evalCase The evaluation case to run\n * @param config Optional server configuration (defaults to localhost:3203)\n * @returns Evaluation result with pass/fail status and scores\n * @deprecated Use LatticeEval class instead\n */\nexport async function evaluateLatticeCase(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n return evaluator.evaluateCase(evalCase);\n}\n\n/**\n * Evaluate a single Lattice evaluation case and always return logs (never throws).\n */\nexport async function evaluateLatticeCaseWithLogs(\n evalCase: LatticeEvalCase,\n config?: LatticeEvalConfig\n): Promise<LatticeEvalCaseRunResult> {\n const defaultConfig: LatticeEvalConfig = {\n base_url: \"http://localhost:3203\",\n };\n const evaluator = new LatticeEval(config || defaultConfig);\n try {\n const result = await evaluator.evaluateCase(evalCase);\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n result,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n evaluator.record(\"error\", \"Case evaluation failed\", {\n case_id: evalCase.caseId,\n error: errorMessage,\n });\n const meta = evaluator.getLastRunMeta();\n return {\n caseId: evalCase.caseId,\n error: errorMessage,\n error_stack: errorStack,\n duration_ms: meta.duration_ms,\n thread_id: meta.thread_id,\n judge_thread_id: meta.judge_thread_id,\n test_prompt: meta.test_prompt,\n final_output: meta.final_output,\n messages: meta.messages,\n logs: evaluator.getInMemoryLogs(),\n };\n }\n}\n","import type { LLMConfig } from \"@axiom-lattice/protocols\";\nimport type {\n LatticeEvalSuiteType,\n LatticeEvalCase,\n LatticeEvalCaseType,\n LatticeEvalCaseWithTemplate,\n LatticeEvalTemplate,\n LatticeEvalLogEvent,\n LatticeEvalResult,\n} from \"./types\";\nimport {\n evaluateLatticeCaseWithLogs,\n LatticeEvalConfig,\n} from \"./LatticeEval\";\n\n/**\n * Configuration resolved from project/suite hierarchy\n */\nexport interface ResolvedConfig {\n lattice_server_config: {\n base_url: string;\n api_key?: string;\n };\n judge_agent_config?: {\n model: LLMConfig;\n };\n concurrency: number; // Number of cases to run concurrently\n}\n\n/**\n * Result with error handling\n */\nexport interface CaseRunResult {\n caseId: string;\n result?: LatticeEvalResult;\n error?: string;\n logs: LatticeEvalLogEvent[];\n duration_ms?: number;\n thread_id?: string;\n judge_thread_id?: string;\n test_prompt?: string;\n final_output?: string;\n messages?: Array<{ role: string; content: string; id?: string }>;\n error_stack?: string;\n}\n\n/**\n * Limit concurrency of async operations with error isolation\n * Each task failure will not affect other tasks\n */\nasync function limitConcurrency<T>(\n tasks: Array<() => Promise<T>>,\n concurrency: number\n): Promise<Array<{ success: boolean; result?: T; error?: string }>> {\n const results: Array<{ success: boolean; result?: T; error?: string }> = [];\n const executing: Promise<void>[] = [];\n let index = 0;\n\n // Execute a single task with error handling\n const executeTask = async (task: () => Promise<T>, taskIndex: number): Promise<void> => {\n try {\n const result = await task();\n results[taskIndex] = { success: true, result };\n } catch (error) {\n results[taskIndex] = {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n // Never throw error here - always resolve to allow other tasks to continue\n // The error is already captured in the results array\n };\n\n // Process tasks with concurrency control\n while (index < tasks.length || executing.length > 0) {\n // Start new tasks up to concurrency limit\n while (executing.length < concurrency && index < tasks.length) {\n const task = tasks[index];\n const currentIndex = index++;\n // Wrap executeTask to ensure it never rejects, even on error\n const promise = executeTask(task, currentIndex)\n .catch((err) => {\n // This should never happen since executeTask catches all errors,\n // but add this as a safety net\n console.error(`Unexpected error in task execution:`, err);\n })\n .finally(() => {\n // Remove from executing array when done\n const idx = executing.indexOf(promise);\n if (idx > -1) {\n executing.splice(idx, 1);\n }\n });\n executing.push(promise);\n }\n\n // Wait for at least one task to complete before starting new ones\n // Since executeTask always resolves (never rejects), Promise.race is safe\n if (executing.length > 0) {\n await Promise.race(executing);\n }\n }\n\n // Wait for all remaining tasks to complete\n // Since all promises are guaranteed to resolve (never reject), Promise.allSettled is safe\n await Promise.allSettled(executing);\n\n return results;\n}\n\n/**\n * Resolve a template case to a full case\n */\nfunction resolveTemplateCase(\n templateCase: LatticeEvalCaseWithTemplate,\n templates: Map<string, LatticeEvalTemplate>\n): LatticeEvalCase {\n const template = templates.get(templateCase.templateId);\n if (!template) {\n throw new Error(`Template not found: ${templateCase.templateId}`);\n }\n\n // Merge template default_case with case-specific overrides\n const resolvedCase: LatticeEvalCase = {\n caseId: templateCase.caseId,\n input: {\n message:\n templateCase.input.message ?? template.default_case.input.message,\n files: {\n ...template.default_case.input.files,\n ...templateCase.input.files,\n },\n },\n steps: template.default_case.steps,\n output: templateCase.output || template.default_case.output,\n eval: {\n content_assertion: templateCase.eval.content_assertion,\n eval_rubrics: templateCase.eval.eval_rubrics || template.default_case.eval?.eval_rubrics,\n },\n };\n\n return resolvedCase;\n}\n\n/**\n * Check if a case is a template case\n */\nfunction isTemplateCase(\n case_: LatticeEvalCaseType\n): case_ is LatticeEvalCaseWithTemplate {\n return \"templateId\" in case_;\n}\n\n/**\n * LatticeEvalSuite class manages a suite of evaluation cases\n * with suite-level configuration\n */\nexport class LatticeEvalSuite {\n private suite: LatticeEvalSuiteType;\n private projectConfig: ResolvedConfig;\n private templates: Map<string, LatticeEvalTemplate>;\n\n constructor(\n suite: LatticeEvalSuiteType,\n projectConfig: ResolvedConfig,\n templates: Map<string, LatticeEvalTemplate> = new Map()\n ) {\n this.suite = suite;\n this.projectConfig = projectConfig;\n this.templates = templates;\n }\n\n /**\n * Get resolved configuration from project\n */\n private getResolvedConfig(): ResolvedConfig {\n return this.projectConfig;\n }\n\n /**\n * Get suite name\n */\n getSuiteName(): string {\n return this.suite.suiteName;\n }\n\n /**\n * Get suite version\n */\n getVersion(): string | undefined {\n return this.suite.version;\n }\n\n /**\n * Get all cases in this suite (resolved from templates if needed)\n */\n getCases(): LatticeEvalCase[] {\n return this.suite.cases.map((case_) => {\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n });\n }\n\n /**\n * Get a specific case by ID (resolved from template if needed)\n */\n getCase(caseId: string): LatticeEvalCase | undefined {\n const case_ = this.suite.cases.find((c) => c.caseId === caseId);\n if (!case_) {\n return undefined;\n }\n if (isTemplateCase(case_)) {\n return resolveTemplateCase(case_, this.templates);\n }\n return case_;\n }\n\n /**\n * Run a single case in this suite with error handling\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(caseId: string): Promise<CaseRunResult> {\n try {\n const evalCase = this.getCase(caseId);\n if (!evalCase) {\n return {\n caseId,\n error: `Case not found: ${caseId}`,\n logs: [],\n };\n }\n\n const config = this.getResolvedConfig();\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n };\n } catch (error) {\n return {\n caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n };\n }\n }\n\n /**\n * Run all cases in this suite with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runAllCases(concurrency?: number): Promise<CaseRunResult[]> {\n const config = this.getResolvedConfig();\n const maxConcurrency = concurrency ?? config.concurrency;\n\n // Create tasks for all cases\n const tasks = this.suite.cases.map((case_) => async () => {\n try {\n // Resolve template case if needed\n const evalCase: LatticeEvalCase = isTemplateCase(case_)\n ? resolveTemplateCase(case_, this.templates)\n : case_;\n\n const evalConfig: LatticeEvalConfig = {\n base_url: config.lattice_server_config.base_url,\n api_key: config.lattice_server_config.api_key,\n };\n const run = await evaluateLatticeCaseWithLogs(evalCase, evalConfig);\n return {\n caseId: evalCase.caseId,\n result: run.result,\n error: run.error,\n error_stack: run.error_stack,\n duration_ms: run.duration_ms,\n thread_id: run.thread_id,\n judge_thread_id: run.judge_thread_id,\n test_prompt: run.test_prompt,\n final_output: run.final_output,\n messages: run.messages,\n logs: run.logs,\n } as CaseRunResult;\n } catch (error) {\n return {\n caseId: case_.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n } as CaseRunResult;\n }\n });\n\n // Run with concurrency limit\n const taskResults = await limitConcurrency(tasks, maxConcurrency);\n\n // Map results to CaseRunResult format\n return taskResults.map((taskResult, index) => {\n if (taskResult.success && taskResult.result) {\n return taskResult.result;\n }\n return {\n caseId: this.suite.cases[index].caseId,\n error: taskResult.error || \"Unknown error\",\n logs: [],\n };\n });\n }\n}\n","import type {\n LatticeEvalBatchReport,\n LatticeEvalProjectType,\n LatticeEvalReportConfig,\n LatticeEvalTemplate,\n} from \"./types\";\nimport { LatticeEvalSuite, ResolvedConfig, CaseRunResult } from \"./LatticeEvalSuite\";\nimport {\n registerModelLattice,\n registerAgentLattice,\n AgentType,\n AgentConfig,\n} from \"@axiom-lattice/core\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\n\n/**\n * LatticeEvalProject class manages a project with multiple evaluation suites\n * with project-level configuration\n */\nexport class LatticeEvalProject {\n private project: LatticeEvalProjectType;\n private suites: Map<string, LatticeEvalSuite> = new Map();\n private reportConfig?: LatticeEvalReportConfig;\n\n constructor(project: LatticeEvalProjectType) {\n this.project = project;\n this.reportConfig = project.report_config;\n\n // Register judge model\n const judgeModelKey = `${this.project.projectName}_judge_model`;\n registerModelLattice(judgeModelKey, this.project.judge_agent_config.model);\n\n // Register judge agent\n const judgeAgentKey = \"LatticeTest\";\n const judgeAgentConfig: AgentConfig = {\n key: judgeAgentKey,\n name: \"Lattice Test Judge Agent\",\n description: \"Judge agent for evaluating Lattice test cases\",\n type: AgentType.REACT,\n prompt: \"\", // No prompt as requested\n modelKey: judgeModelKey,\n };\n registerAgentLattice(judgeAgentConfig);\n\n // Build resolved config for project\n const projectConfig: ResolvedConfig = {\n lattice_server_config: {\n base_url: this.project.lattice_server_config.base_url,\n api_key: this.project.lattice_server_config.api_key,\n },\n judge_agent_config: this.project.judge_agent_config,\n concurrency: this.project.concurrency ?? 1,\n };\n\n // Build templates map\n const templatesMap = new Map<string, LatticeEvalTemplate>();\n if (this.project.templates) {\n for (const template of this.project.templates) {\n templatesMap.set(template.templateId, template);\n }\n }\n\n // Initialize all suites with project config and templates\n for (const suite of this.project.suites) {\n this.suites.set(\n suite.suiteName,\n new LatticeEvalSuite(suite, projectConfig, templatesMap)\n );\n }\n }\n\n /**\n * Get project name\n */\n getProjectName(): string {\n return this.project.projectName;\n }\n\n /**\n * Get project version\n */\n getVersion(): string | undefined {\n return this.project.version;\n }\n\n /**\n * Get project description\n */\n getDescription(): string | undefined {\n return this.project.description;\n }\n\n /**\n * Get all suite names\n */\n getSuiteNames(): string[] {\n return Array.from(this.suites.keys());\n }\n\n /**\n * Get a specific suite by name\n */\n getSuite(suiteName: string): LatticeEvalSuite | undefined {\n return this.suites.get(suiteName);\n }\n\n /**\n * Run a specific case in a specific suite\n * @param suiteName The suite name\n * @param caseId The case ID to run\n * @returns Case run result with error handling\n */\n async runCase(suiteName: string, caseId: string): Promise<CaseRunResult> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n return {\n caseId,\n error: `Suite not found: ${suiteName}`,\n logs: [],\n };\n }\n return suite.runCase(caseId);\n }\n\n /**\n * Run all cases in a specific suite with concurrency control and error isolation\n * @param suiteName The suite name\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Array of case run results with error handling\n */\n async runSuite(suiteName: string, concurrency?: number): Promise<CaseRunResult[]> {\n const suite = this.getSuite(suiteName);\n if (!suite) {\n throw new Error(`Suite not found: ${suiteName}`);\n }\n return suite.runAllCases(concurrency);\n }\n\n /**\n * Run all cases in all suites with concurrency control and error isolation\n * @param concurrency Optional concurrency limit (overrides project config)\n * @returns Map of suite names to their case run results\n */\n async runAllSuites(concurrency?: number): Promise<Map<string, CaseRunResult[]>> {\n const results = new Map<string, CaseRunResult[]>();\n\n for (const suiteName of this.getSuiteNames()) {\n try {\n const suiteResults = await this.runSuite(suiteName, concurrency);\n results.set(suiteName, suiteResults);\n } catch (error) {\n // If suite execution fails, create error results for all cases\n const suite = this.getSuite(suiteName);\n if (suite) {\n const errorResults: CaseRunResult[] = suite.getCases().map((c) => ({\n caseId: c.caseId,\n error: error instanceof Error ? error.message : String(error),\n logs: [],\n }));\n results.set(suiteName, errorResults);\n }\n }\n }\n\n return results;\n }\n\n /**\n * Run all suites as a \"batch\", build a report, and optionally write it to disk.\n */\n async runAllSuitesBatch(concurrency?: number): Promise<{\n batch_id: string;\n batch_dir?: string;\n results: Map<string, CaseRunResult[]>;\n report: LatticeEvalBatchReport;\n }> {\n const started_at = new Date().toISOString();\n const batch_id =\n this.reportConfig?.batch_id ||\n `${Date.now()}`;\n\n console.log(`\\nRunning batch: ${this.project.projectName} (${this.getSuiteNames().length} suites)`);\n\n const results = await this.runAllSuites(concurrency);\n\n let total_cases = 0;\n let passed_cases = 0;\n let failed_cases = 0;\n\n const suites: LatticeEvalBatchReport[\"suites\"] = [];\n const durations: number[] = [];\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteTotal = caseResults.length;\n const suitePassed = caseResults.filter((r) => r.result?.pass).length;\n const suiteFailed = suiteTotal - suitePassed;\n\n total_cases += suiteTotal;\n passed_cases += suitePassed;\n failed_cases += suiteFailed;\n\n suites.push({\n suiteName,\n total_cases: suiteTotal,\n passed_cases: suitePassed,\n failed_cases: suiteFailed,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n pass: r.result?.pass,\n final_score: r.result?.final_score,\n error: r.error,\n })),\n });\n\n for (const r of caseResults) {\n if (typeof r.duration_ms === \"number\") durations.push(r.duration_ms);\n }\n }\n\n const finished_at = new Date().toISOString();\n const report: LatticeEvalBatchReport = {\n batch_id,\n started_at,\n finished_at,\n project: {\n projectName: this.project.projectName,\n version: this.project.version,\n description: this.project.description,\n },\n summary: {\n total_cases,\n passed_cases,\n failed_cases,\n pass_rate: total_cases > 0 ? passed_cases / total_cases : 0,\n },\n suites,\n };\n\n const batch_dir = await this.maybeWriteBatchArtifacts(\n batch_id,\n report,\n results\n );\n\n console.log(`\\n=== Summary ===`);\n console.log(`Total: ${report.summary.total_cases} | Passed: ${report.summary.passed_cases} | Failed: ${report.summary.failed_cases} | Pass Rate: ${(report.summary.pass_rate * 100).toFixed(2)}%`);\n if (batch_dir) {\n console.log(`\\nResults saved to: ${batch_dir}`);\n }\n\n return { batch_id, batch_dir, results, report };\n }\n\n private generateCaseMarkdown(\n index: number,\n suiteName: string,\n caseResult: CaseRunResult,\n payload: any\n ): string {\n const lines: string[] = [];\n const status = caseResult.result?.pass ? \"✅ PASS\" : \"❌ FAIL\";\n\n lines.push(`# Test ${index}: ${status}`);\n lines.push(``);\n lines.push(`- **Suite**: ${suiteName}`);\n lines.push(`- **Case ID**: ${caseResult.caseId}`);\n lines.push(`- **Status**: ${caseResult.result?.pass ? \"PASS\" : \"FAIL\"}`);\n if (typeof payload.duration === \"number\") {\n lines.push(`- **Duration**: ${(payload.duration / 1000).toFixed(2)}s`);\n }\n if (payload.threadId) {\n lines.push(`- **Thread ID**: ${payload.threadId}`);\n }\n if (payload.judgeThreadId) {\n lines.push(`- **Judge Thread ID**: ${payload.judgeThreadId}`);\n }\n lines.push(``);\n\n if (caseResult.result) {\n lines.push(`## Result`);\n lines.push(``);\n lines.push(`- **Final Score**: ${caseResult.result.final_score}`);\n lines.push(`- **Summary**: ${caseResult.result.summary || \"N/A\"}`);\n lines.push(``);\n\n if (caseResult.result.dimension_results && caseResult.result.dimension_results.length > 0) {\n lines.push(`## Dimension Results`);\n lines.push(``);\n for (const dim of caseResult.result.dimension_results) {\n lines.push(`### ${dim.name}`);\n lines.push(`- **Score**: ${dim.score}`);\n lines.push(`- **Reason**: ${dim.reason}`);\n lines.push(``);\n }\n }\n }\n\n if (caseResult.error) {\n lines.push(`## Error`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(caseResult.error);\n if (caseResult.error_stack) {\n lines.push(``);\n lines.push(caseResult.error_stack);\n }\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.messages && Array.isArray(payload.messages) && payload.messages.length > 0) {\n lines.push(`## Conversation Messages`);\n lines.push(``);\n for (let i = 0; i < payload.messages.length; i++) {\n const msg = payload.messages[i];\n const role = msg.role || 'unknown';\n const content = msg.content || '';\n lines.push(`### Message ${i + 1} (${role})`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(content);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n }\n\n if (payload.finalOutput) {\n lines.push(`## Final Output`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.finalOutput);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n if (payload.testPrompt) {\n lines.push(`## Test Prompt`);\n lines.push(``);\n lines.push(`\\`\\`\\``);\n lines.push(payload.testPrompt);\n lines.push(`\\`\\`\\``);\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private generateMarkdownSummary(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): string {\n const lines: string[] = [];\n lines.push(`# Lattice Eval Batch Summary`);\n lines.push(``);\n lines.push(`- **Project**: ${report.project.projectName}`);\n if (report.project.version) lines.push(`- **Version**: ${report.project.version}`);\n if (report.project.description) lines.push(`- **Description**: ${report.project.description}`);\n lines.push(`- **Batch ID**: ${batch_id}`);\n lines.push(`- **Started**: ${report.started_at}`);\n lines.push(`- **Finished**: ${report.finished_at}`);\n lines.push(``);\n\n lines.push(`## Overview`);\n lines.push(``);\n lines.push(`| Metric | Value |`);\n lines.push(`|---|---:|`);\n lines.push(`| Total cases | ${report.summary.total_cases} |`);\n lines.push(`| Passed | ${report.summary.passed_cases} |`);\n lines.push(`| Failed | ${report.summary.failed_cases} |`);\n lines.push(`| Pass rate | ${(report.summary.pass_rate * 100).toFixed(2)}% |`);\n lines.push(``);\n\n lines.push(`## Suites`);\n lines.push(``);\n for (const suite of report.suites) {\n lines.push(`### ${suite.suiteName}`);\n lines.push(``);\n lines.push(`| Case | Status | Score | Duration (ms) | Thread |`);\n lines.push(`|---|---|---:|---:|---|`);\n const suiteResults = results.get(suite.suiteName) || [];\n for (const r of suiteResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const score = r.result?.final_score ?? \"\";\n const dur = typeof r.duration_ms === \"number\" ? r.duration_ms : \"\";\n const thread = r.thread_id ?? \"\";\n lines.push(`| ${r.caseId} | ${status} | ${score} | ${dur} | ${thread} |`);\n }\n lines.push(``);\n }\n\n return lines.join(\"\\n\");\n }\n\n private async maybeWriteBatchArtifacts(\n batch_id: string,\n report: LatticeEvalBatchReport,\n results: Map<string, CaseRunResult[]>\n ): Promise<string | undefined> {\n const config = this.reportConfig;\n if (!config?.output_dir) return undefined;\n\n const batchDir = path.join(config.output_dir, batch_id);\n await mkdir(batchDir, { recursive: true });\n\n const writeReportJson = config.write_report_json ?? true;\n const writeCaseLogs = config.write_case_logs ?? true;\n\n if (writeReportJson) {\n await writeFile(\n path.join(batchDir, \"report.json\"),\n JSON.stringify(report, null, 2),\n \"utf-8\"\n );\n }\n\n // Write richer results.json (similar to TestRunner)\n const resultsJsonPath = path.join(batchDir, \"results.json\");\n const resultsJson = {\n executionTimestamp: batch_id,\n summary: report.summary,\n report,\n results: Array.from(results.entries()).map(([suiteName, caseResults]) => ({\n suiteName,\n cases: caseResults.map((r) => ({\n caseId: r.caseId,\n passed: r.result?.pass === true,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? {\n message: r.error,\n stack: r.error_stack,\n }\n : undefined,\n duration: r.duration_ms,\n testPrompt: r.test_prompt,\n finalOutput: r.final_output,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n })),\n })),\n };\n await writeFile(resultsJsonPath, JSON.stringify(resultsJson, null, 2), \"utf-8\");\n\n // Write summary.md\n const summaryMdPath = path.join(batchDir, \"summary.md\");\n const summaryMd = this.generateMarkdownSummary(batch_id, report, results);\n await writeFile(summaryMdPath, summaryMd, \"utf-8\");\n\n // Write per-case detailed json and markdown\n const individualDir = path.join(batchDir, \"individual\");\n await mkdir(individualDir, { recursive: true });\n let index = 1;\n for (const [suiteName, caseResults] of results.entries()) {\n for (const r of caseResults) {\n const status = r.result?.pass ? \"PASS\" : \"FAIL\";\n const baseFilename = `test-${index}-${suiteName}-${r.caseId}-${status}`.replace(/[\\/\\\\]/g, \"_\");\n\n // Write JSON\n const jsonPath = path.join(individualDir, `${baseFilename}.json`);\n const payload = {\n index,\n suiteName,\n caseId: r.caseId,\n passed: r.result?.pass === true,\n result: r.result,\n message: r.result?.summary || r.error || \"\",\n error: r.error\n ? { message: r.error, stack: r.error_stack }\n : undefined,\n duration: r.duration_ms,\n threadId: r.thread_id,\n judgeThreadId: r.judge_thread_id,\n finalOutput: r.final_output,\n testPrompt: r.test_prompt,\n messages: r.messages,\n };\n await writeFile(jsonPath, JSON.stringify(payload, null, 2), \"utf-8\");\n\n // Write Markdown\n const mdPath = path.join(individualDir, `${baseFilename}.md`);\n const mdContent = this.generateCaseMarkdown(index, suiteName, r, payload);\n await writeFile(mdPath, mdContent, \"utf-8\");\n\n index += 1;\n }\n }\n\n if (writeCaseLogs) {\n for (const [suiteName, caseResults] of results.entries()) {\n const suiteDir = path.join(batchDir, \"cases\", suiteName);\n await mkdir(suiteDir, { recursive: true });\n for (const r of caseResults) {\n await writeFile(\n path.join(suiteDir, `${r.caseId}.logs.json`),\n JSON.stringify(r.logs || [], null, 2),\n \"utf-8\"\n );\n }\n }\n }\n\n return batchDir;\n }\n}\n"],"mappings":";AAAA,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,UAAU;AA0CZ,IAAM,cAAN,MAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BvB,YAAY,QAA2B;AAvBvC,SAAQ,eAAsC,CAAC;AAK/C,SAAQ,iBAAyB;AACjC,SAAQ,eAAsE,CAAC;AAkB7E,SAAK,SAAS;AACd,SAAK,UAAU,KAAK,OAAO;AAC3B,SAAK,UAAU,KAAK,OAAO,WAAW;AAAA,EACxC;AAAA,EAnBO,iBAAiB;AACtB,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB,WAAW,KAAK;AAAA,MAChB,iBAAiB,KAAK;AAAA,MACtB,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAYO,kBAAyC;AAC9C,WAAO,CAAC,GAAG,KAAK,YAAY;AAAA,EAC9B;AAAA,EAEO,OACL,OACA,SACA,MACA;AACA,UAAM,QAA6B;AAAA,MACjC,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,aAAa,KAAK,KAAK;AAE5B,QAAI,CAAC,KAAK,QAAS;AAEnB,QAAI,UAAU,SAAS;AACrB,YAAM,UAAU,KAAK,WAAW,IAAI;AACpC,cAAQ,IAAI,YAAO,OAAO,GAAG,UAAU,IAAI,OAAO,KAAK,EAAE,EAAE;AAAA,IAC7D,WAAW,QAAQ,WAAW,UAAU,GAAG;AAEzC,YAAM,UAAU,KAAK,WAAW,IAAI;AACpC,cAAQ,IAAI,KAAK,OAAO,GAAG,UAAU,IAAI,OAAO,KAAK,EAAE,EAAE;AAAA,IAC3D,WAAW,QAAQ,SAAS,2BAA2B,GAAG;AAExD,YAAM,UAAU,KAAK,WAAW,IAAI;AACpC,YAAM,OAAO,MAAM;AACnB,YAAM,UAAU,MAAM;AACtB,YAAM,SAAS,OAAO,gBAAW;AACjC,YAAM,SAAS,YAAY,OAAO,gBAAgB;AAClD,cAAQ,IAAI,KAAK,MAAM,IAAI,OAAO,GAAG,UAAU,IAAI,OAAO,KAAK,EAAE,EAAE;AACnE,UAAI,QAAQ;AACV,gBAAQ,IAAI,eAAe,MAAM,EAAE;AAAA,MACrC;AAAA,IACF;AAAA,EAEF;AAAA,EAEQ,IAAI,SAAiB,MAAgC;AAC3D,SAAK,OAAO,QAAQ,SAAS,IAAI;AAAA,EACnC;AAAA,EAEQ,WAAW,MAAwC;AACzD,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,QAAkB,CAAC;AAGzB,QAAI,KAAK,QAAS,OAAM,KAAK,QAAQ,KAAK,OAAO,EAAE;AACnD,QAAI,KAAK,SAAS,OAAW,OAAM,KAAK,QAAQ,KAAK,IAAI,EAAE;AAC3D,QAAI,KAAK,gBAAgB,OAAW,OAAM,KAAK,SAAS,KAAK,WAAW,EAAE;AAC1E,QAAI,KAAK,MAAO,OAAM,KAAK,SAAS,KAAK,KAAK,EAAE;AAChD,WAAO,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK,GAAG,CAAC,MAAM;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBACZ,MACA,UACA,cACA,OACkD;AAClD,SAAK,IAAI,wBAAwB;AAAA,MAC/B,UAAU,KAAK;AAAA,MACf,WAAW;AAAA,MACX,4BAA4B,QAAQ,KAAK,sBAAsB;AAAA,MAC/D,sBAAsB,KAAK,yBACvB,KAAK,uBAAuB,SAC5B,aAAa;AAAA,MACjB,aAAa,OAAO,KAAK,SAAS,CAAC,CAAC,EAAE;AAAA,IACxC,CAAC;AAED,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,aAAa;AAAA,MACvD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,cAAc,KAAK;AAAA,QACnB,WAAW;AAAA,QACX,OAAO,OAAO,KAAK,KAAK,EAAE,OAAO,CAAC,KAAK,QAAQ;AAC7C,cAAI,GAAG,IAAI,EAAE,SAAS,MAAM,GAAG,EAAE,MAAM,IAAI,GAAG,aAAY,oBAAI,KAAK,GAAE,YAAY,GAAG,cAAa,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC1H,iBAAO;AAAA,QACT,GAAG,CAAC,CAAwB;AAAA,QAC5B,SAAS,KAAK,0BAA0B;AAAA,MAC1C,CAAC;AAAA,IACH,CAAC;AAGD,UAAM,eAAoB,MAAM,SAAS,KAAK;AAC9C,QAAI,aAAa,OAAO;AACtB,WAAK,IAAI,qBAAqB;AAAA,QAC5B,UAAU,KAAK;AAAA,QACf,WAAW;AAAA,QACX,OAAO,aAAa;AAAA,MACtB,CAAC;AACD,YAAM,IAAI;AAAA,QACR,uBAAuB,KAAK,QAAQ,KAAK,aAAa,KAAK;AAAA,MAC7D;AAAA,IACF;AACA,SAAK,IAAI,wBAAwB;AAAA,MAC/B,UAAU,KAAK;AAAA,MACf,WAAW;AAAA,MACX,eAAe,eAAe,OAAO,KAAK,YAAY,IAAI,CAAC;AAAA,IAC7D,CAAC;AACD,WAAO,EAAE,UAAU,aAAa;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cACZ,YACA,SACA,UACA,iBACiB;AACjB,QAAI,WAAW,SAAS,gBAAgB;AACtC,WAAK,IAAI,0BAA0B;AAAA,QACjC,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW,WAAW;AAAA,MACxB,CAAC;AACD,YAAM,gBAAgB,MAAM;AAAA,QAC1B,GAAG,KAAK,OAAO,mBAAmB,OAAO,IAAI,QAAQ;AAAA,QACrD;AAAA,UACE,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,UAAI,CAAC,cAAc,IAAI;AACrB,aAAK,IAAI,mCAAmC;AAAA,UAC1C,UAAU;AAAA,UACV,WAAW;AAAA,UACX,QAAQ,cAAc;AAAA,UACtB,YAAY,cAAc;AAAA,QAC5B,CAAC;AACD,cAAM,IAAI,MAAM,wBAAwB,cAAc,UAAU,EAAE;AAAA,MACpE;AAEA,YAAM,QAAa,MAAM,cAAc,KAAK;AAC5C,YAAM,cAAmB,MAAM;AAC/B,YAAM,cAAc,YAAY,MAAM,WAAW,SAAS,GAAG;AAE7D,UAAI,CAAC,aAAa;AAChB,aAAK,IAAI,kCAAkC;AAAA,UACzC,UAAU;AAAA,UACV,WAAW;AAAA,UACX,WAAW,WAAW;AAAA,QACxB,CAAC;AACD,cAAM,IAAI;AAAA,UACR,6BAA6B,WAAW,SAAS;AAAA,QACnD;AAAA,MACF;AACA,YAAM,UAAU,MAAM,QAAQ,WAAW,IACrC,YAAY,KAAK,IAAI,IACrB;AACJ,WAAK,IAAI,yBAAyB;AAAA,QAChC,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW,WAAW;AAAA,QACtB,eAAe,OAAO,YAAY,WAAW,QAAQ,SAAS;AAAA,MAChE,CAAC;AACD,aAAO;AAAA,IACT,OAAO;AAEL,UAAI,iBAAiB,YAAY,gBAAgB,SAAS,SAAS,GAAG;AACpE,cAAM,UACJ,gBAAgB,SAAS,gBAAgB,SAAS,SAAS,CAAC,GAAG,WAC/D;AACF,aAAK,IAAI,4BAA4B;AAAA,UACnC,UAAU;AAAA,UACV,WAAW;AAAA,UACX,eAAe,OAAO,YAAY,WAAW,QAAQ,SAAS;AAAA,QAChE,CAAC;AACD,eAAO;AAAA,MACT;AACA,WAAK,IAAI,4CAA4C;AAAA,QACnD,UAAU;AAAA,QACV,WAAW;AAAA,MACb,CAAC;AACD,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,UAAuD;AACxE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,WAAW,GAAG,SAAS,MAAM,KAAK,GAAG,CAAC;AAC5C,SAAK,eAAe,CAAC;AACrB,SAAK,eAAe;AACpB,SAAK,oBAAoB;AACzB,SAAK,iBAAiB;AACtB,SAAK,kBAAkB;AACvB,SAAK,iBAAiB;AACtB,SAAK,eAAe,CAAC;AACrB,UAAM,mBAAmB,SAAS,MAAM,qBAAqB;AAC7D,UAAM,UAAU,mBACZ,aAAa,gBAAgB,KAC7B;AACJ,SAAK,IAAI,SAAS;AAAA,MAChB,SAAS,SAAS;AAAA,MAClB,WAAW;AAAA,MACX,aAAa,SAAS,OAAO;AAAA,MAC7B,aAAa,SAAS,QAAQ;AAAA,MAC9B,mBAAmB;AAAA,IACrB,CAAC;AAGD,QAAI,kBAAkB;AACtB,QAAI,mBAAwB;AAC5B,eAAW,QAAQ,SAAS,OAAO;AACjC,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB;AAAA,QACA;AAAA,QACA,SAAS,MAAM;AAAA,QACf,SAAS,MAAM,SAAS,CAAC;AAAA,MAC3B;AACA,wBAAkB,OAAO;AACzB,yBAAmB,OAAO;AAI1B,YAAM,cAAc,IAAI,IAAI,KAAK,aAAa,IAAI,OAAK,EAAE,EAAE,EAAE,OAAO,OAAO,CAAC;AAC5E,UAAI,OAAO,cAAc,YAAY,MAAM,QAAQ,OAAO,aAAa,QAAQ,GAAG;AAChF,mBAAW,OAAO,OAAO,aAAa,UAAU;AAC9C,cAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,kBAAM,QAAQ,IAAI,MAAM,IAAI,SAAS,IAAI;AAEzC,gBAAI,SAAS,YAAY,IAAI,KAAK,GAAG;AACnC;AAAA,YACF;AAEA,kBAAM,OAAO,IAAI,QAAQ,IAAI,UAAU,KAAK,IAAI,QAAQ;AACxD,gBAAI,UAAU;AACd,gBAAI,OAAO,IAAI,YAAY,UAAU;AACnC,wBAAU,IAAI;AAAA,YAChB,WAAW,MAAM,QAAQ,IAAI,OAAO,GAAG;AACrC,wBAAU,IAAI,QAAQ;AAAA,gBAAI,CAAC,MACzB,OAAO,MAAM,WAAW,IACrB,GAAG,SAAS,OAAO,MAAM,WAAW,KAAK,UAAU,CAAC,IAAI,OAAO,CAAC;AAAA,cACrE,EAAE,KAAK,IAAI;AAAA,YACb,WAAW,IAAI,WAAW,OAAO,IAAI,YAAY,UAAU;AACzD,wBAAU,IAAI,QAAQ,QAAQ,KAAK,UAAU,IAAI,OAAO;AAAA,YAC1D,OAAO;AACL,wBAAU,OAAO,IAAI,WAAW,EAAE;AAAA,YACpC;AAEA,iBAAK,aAAa,KAAK;AAAA,cACrB;AAAA,cACA;AAAA,cACA,IAAI;AAAA,YACN,CAAC;AACD,gBAAI,OAAO;AACT,0BAAY,IAAI,KAAK;AAAA,YACvB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,eACJ,SAAS,MAAM,SAAS,MAAM,SAAS,CAAC,GAAG,YAAY;AACzD,SAAK,IAAI,6BAA6B;AAAA,MACpC,SAAS,SAAS;AAAA,MAClB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,IACnB,CAAC;AAGD,UAAM,cAAc,MAAM,KAAK;AAAA,MAC7B,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,kBAAkB;AACvB,SAAK,IAAI,0BAA0B;AAAA,MACjC,SAAS,SAAS;AAAA,MAClB,aAAa,SAAS,OAAO;AAAA,MAC7B,eAAe,YAAY;AAAA,IAC7B,CAAC;AAGD,UAAM,uBAAuB,SAAS,MAAM,QACxC,OAAO,KAAK,SAAS,MAAM,KAAK,EAC/B;AAAA,MACC,CAAC,QACC,cAAc,GAAG;AAAA,gBAAmB,SAAS,MAAM,MAAO,GAAG,CAAC;AAAA,IAClE,EACC,KAAK,MAAM,IACZ;AAGJ,UAAM,wBAAwB,SAAS,OAAO,SAAS,iBACnD,mDAAW,SAAS,OAAO,SAAS,WACpC;AAEJ,UAAM,iBAAsC;AAAA,MAC1C;AAAA,QACE,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,aACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,cACJ,SAAS,KAAK,gBAAgB,SAAS,KAAK,aAAa,SAAS,IAC9D,SAAS,KAAK,eACd;AACN,SAAK,IAAI,+BAA+B;AAAA,MACtC,SAAS,SAAS;AAAA,MAClB,eAAe,YAAY;AAAA,MAC3B,mBAAmB,YAAY,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,IACvD,CAAC;AAED,UAAM,iBAAiB;AAAA;AAAA,EAAkC,YACtD;AAAA,MACC,CAAC,MACC,OAAO,EAAE,SAAS,6BAAS,EAAE,MAAM,eAAK,EAAE,WAAW;AAAA,IACzD,EACC,KAAK,IAAI,CAAC;AAEb,UAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8DAMI,SAAS,MAAM,OAAO;AAAA;AAAA,8DAEtB,wBAAwB,QAAG;AAAA;AAAA,wDAE5B,qBAAqB;AAAA,EAC7C,WAAW;AAAA;AAAA,0FAEgC,SAAS,KAAK,iBAAiB;AAAA,EAC1E,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BZ,SAAK,iBAAiB;AAGtB,UAAM,gBAAgB,GAAG;AACzB,SAAK,oBAAoB;AACzB,SAAK,IAAI,wBAAwB,EAAE,WAAW,eAAe,SAAS,SAAS,OAAO,CAAC;AACvF,UAAM,aAAa,MAAM,eAAe,WAAW,aAAa;AAChE,UAAM,eAAe,MAAM,WAAW;AAAA,MACpC;AAAA,QACE,UAAU,CAAC,IAAI,aAAa,UAAU,CAAC;AAAA,MACzC;AAAA,MACA;AAAA,QACE,cAAc;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AACA,SAAK,IAAI,yBAAyB;AAAA,MAChC,SAAS,SAAS;AAAA,MAClB,gBAAgB,cAAc,UAAU;AAAA,IAC1C,CAAC;AAED,UAAM,oBACJ,aAAa,SAAS,aAAa,SAAS,SAAS,CAAC,GAAG,WAAW;AACtE,SAAK,IAAI,6BAA6B;AAAA,MACpC,SAAS,SAAS;AAAA,MAClB,eACE,OAAO,sBAAsB,WAAW,kBAAkB,SAAS;AAAA,IACvE,CAAC;AAGD,QAAI,eAKA,CAAC;AAEL,QAAI;AAEF,YAAM,YAAY,kBAAkB,MAAM,oCAAoC,KAC5E,kBAAkB,MAAM,aAAa;AACvC,UAAI,WAAW;AACb,uBAAe,KAAK,MAAM,UAAU,CAAC,KAAK,UAAU,CAAC,CAAC;AACtD,aAAK,IAAI,kCAAkC;AAAA,UACzC,SAAS,SAAS;AAAA,UAClB,aAAa,OAAO,KAAK,gBAAgB,CAAC,CAAC;AAAA,QAC7C,CAAC;AAAA,MACH,OAAO;AACL,aAAK,IAAI,mDAAmD;AAAA,UAC1D,SAAS,SAAS;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AAEd,cAAQ,KAAK,0FAA0F,KAAK;AAC5G,WAAK,IAAI,4CAA4C;AAAA,QACnD,SAAS,SAAS;AAAA,QAClB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH;AAGA,QAAI;AACJ,QAAI,aAAa,SAAS,QAAW;AACnC,aAAO,aAAa;AACpB,WAAK,IAAI,0CAA0C,EAAE,SAAS,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvF,WAAW,aAAa,gBAAgB,QAAW;AACjD,aAAO,aAAa,eAAe;AACnC,WAAK,IAAI,iDAAiD;AAAA,QACxD,SAAS,SAAS;AAAA,QAClB,aAAa,aAAa;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AAEL,aAAO,kBAAkB,YAAY,EAAE,SAAS,MAAM,KACpD,kBAAkB,YAAY,EAAE,SAAS,SAAS,KAClD,kBAAkB,YAAY,EAAE,SAAS,cAAI,KAC7C,kBAAkB,YAAY,EAAE,SAAS,cAAI;AAC/C,WAAK,IAAI,yCAAyC,EAAE,SAAS,SAAS,QAAQ,KAAK,CAAC;AAAA,IACtF;AAGA,QAAI,mBAA2E,CAAC;AAEhF,QAAI,aAAa,qBAAqB,aAAa,kBAAkB,SAAS,GAAG;AAE/E,yBAAmB,aAAa;AAChC,WAAK,IAAI,6CAA6C;AAAA,QACpD,SAAS,SAAS;AAAA,QAClB,kBAAkB,iBAAiB;AAAA,MACrC,CAAC;AAAA,IACH,WAAW,YAAY,SAAS,GAAG;AAEjC,yBAAmB,YAAY,IAAI,CAAC,YAAY;AAAA,QAC9C,MAAM,OAAO;AAAA,QACb,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,EAAE;AACF,WAAK,IAAI,sDAAsD;AAAA,QAC7D,SAAS,SAAS;AAAA,QAClB,kBAAkB,iBAAiB;AAAA,MACrC,CAAC;AAAA,IACH;AAGA,QAAI;AACJ,QAAI,aAAa,gBAAgB,QAAW;AAC1C,mBAAa,aAAa;AAC1B,WAAK,IAAI,mDAAmD;AAAA,QAC1D,SAAS,SAAS;AAAA,QAClB,aAAa;AAAA,MACf,CAAC;AAAA,IACH,WAAW,iBAAiB,SAAS,KAAK,YAAY,SAAS,GAAG;AAEhE,YAAM,YAAY,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AACzE,YAAM,cAAc,MAAM,KAAK,UAAU,OAAO,CAAC,EAAE,OAAO,CAAC,KAAK,MAAM,MAAM,GAAG,CAAC;AAEhF,UAAI,cAAc,GAAG;AACnB,qBAAa,iBAAiB,OAAO,CAAC,KAAK,WAAW;AACpD,gBAAM,SAAS,UAAU,IAAI,OAAO,IAAI,KAAK;AAC7C,iBAAO,MAAO,OAAO,QAAQ;AAAA,QAC/B,GAAG,CAAC,IAAI;AAAA,MACV,OAAO;AAEL,qBAAa,iBAAiB,OAAO,CAAC,KAAK,WAAW,MAAM,OAAO,OAAO,CAAC,IAAI,iBAAiB;AAAA,MAClG;AACA,WAAK,IAAI,+CAA+C;AAAA,QACtD,SAAS,SAAS;AAAA,QAClB,aAAa;AAAA,QACb,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,OAAO;AACL,mBAAa,OAAO,MAAM;AAC1B,WAAK,IAAI,qCAAqC;AAAA,QAC5C,SAAS,SAAS;AAAA,QAClB,aAAa;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,UAAU,aAAa,WAAW,qBAAqB;AAC7D,SAAK,IAAI,6BAA6B;AAAA,MACpC,SAAS,SAAS;AAAA,MAClB;AAAA,MACA,aAAa;AAAA,MACb;AAAA,IACF,CAAC;AACD,UAAM,aAAa,KAAK,IAAI;AAC5B,SAAK,iBAAiB,aAAa;AACnC,SAAK,OAAO,QAAQ,0BAA0B;AAAA,MAC5C,SAAS,SAAS;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,aAAa;AAAA,MACb,mBAAmB;AAAA,MACnB,SAAS,aAAa,WAAW;AAAA,IACnC;AAAA,EACF;AACF;AASA,eAAsB,oBACpB,UACA,QAC4B;AAC5B,QAAM,gBAAmC;AAAA,IACvC,UAAU;AAAA,EACZ;AACA,QAAM,YAAY,IAAI,YAAY,UAAU,aAAa;AACzD,SAAO,UAAU,aAAa,QAAQ;AACxC;AAKA,eAAsB,4BACpB,UACA,QACmC;AACnC,QAAM,gBAAmC;AAAA,IACvC,UAAU;AAAA,EACZ;AACA,QAAM,YAAY,IAAI,YAAY,UAAU,aAAa;AACzD,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,aAAa,QAAQ;AACpD,UAAM,OAAO,UAAU,eAAe;AACtC,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,WAAW,KAAK;AAAA,MAChB,iBAAiB,KAAK;AAAA,MACtB,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,MAAM,UAAU,gBAAgB;AAAA,IAClC;AAAA,EACF,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,UAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAC1D,cAAU,OAAO,SAAS,0BAA0B;AAAA,MAClD,SAAS,SAAS;AAAA,MAClB,OAAO;AAAA,IACT,CAAC;AACD,UAAM,OAAO,UAAU,eAAe;AACtC,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,WAAW,KAAK;AAAA,MAChB,iBAAiB,KAAK;AAAA,MACtB,aAAa,KAAK;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,MAAM,UAAU,gBAAgB;AAAA,IAClC;AAAA,EACF;AACF;;;ACrnBA,eAAe,iBACb,OACA,aACkE;AAClE,QAAM,UAAmE,CAAC;AAC1E,QAAM,YAA6B,CAAC;AACpC,MAAI,QAAQ;AAGZ,QAAM,cAAc,OAAO,MAAwB,cAAqC;AACtF,QAAI;AACF,YAAM,SAAS,MAAM,KAAK;AAC1B,cAAQ,SAAS,IAAI,EAAE,SAAS,MAAM,OAAO;AAAA,IAC/C,SAAS,OAAO;AACd,cAAQ,SAAS,IAAI;AAAA,QACnB,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D;AAAA,IACF;AAAA,EAGF;AAGA,SAAO,QAAQ,MAAM,UAAU,UAAU,SAAS,GAAG;AAEnD,WAAO,UAAU,SAAS,eAAe,QAAQ,MAAM,QAAQ;AAC7D,YAAM,OAAO,MAAM,KAAK;AACxB,YAAM,eAAe;AAErB,YAAM,UAAU,YAAY,MAAM,YAAY,EAC3C,MAAM,CAAC,QAAQ;AAGd,gBAAQ,MAAM,uCAAuC,GAAG;AAAA,MAC1D,CAAC,EACA,QAAQ,MAAM;AAEb,cAAM,MAAM,UAAU,QAAQ,OAAO;AACrC,YAAI,MAAM,IAAI;AACZ,oBAAU,OAAO,KAAK,CAAC;AAAA,QACzB;AAAA,MACF,CAAC;AACH,gBAAU,KAAK,OAAO;AAAA,IACxB;AAIA,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,QAAQ,KAAK,SAAS;AAAA,IAC9B;AAAA,EACF;AAIA,QAAM,QAAQ,WAAW,SAAS;AAElC,SAAO;AACT;AAKA,SAAS,oBACP,cACA,WACiB;AACjB,QAAM,WAAW,UAAU,IAAI,aAAa,UAAU;AACtD,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,uBAAuB,aAAa,UAAU,EAAE;AAAA,EAClE;AAGA,QAAM,eAAgC;AAAA,IACpC,QAAQ,aAAa;AAAA,IACrB,OAAO;AAAA,MACL,SACE,aAAa,MAAM,WAAW,SAAS,aAAa,MAAM;AAAA,MAC5D,OAAO;AAAA,QACL,GAAG,SAAS,aAAa,MAAM;AAAA,QAC/B,GAAG,aAAa,MAAM;AAAA,MACxB;AAAA,IACF;AAAA,IACA,OAAO,SAAS,aAAa;AAAA,IAC7B,QAAQ,aAAa,UAAU,SAAS,aAAa;AAAA,IACrD,MAAM;AAAA,MACJ,mBAAmB,aAAa,KAAK;AAAA,MACrC,cAAc,aAAa,KAAK,gBAAgB,SAAS,aAAa,MAAM;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,eACP,OACsC;AACtC,SAAO,gBAAgB;AACzB;AAMO,IAAM,mBAAN,MAAuB;AAAA,EAK5B,YACE,OACA,eACA,YAA8C,oBAAI,IAAI,GACtD;AACA,SAAK,QAAQ;AACb,SAAK,gBAAgB;AACrB,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAoC;AAC1C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,eAAuB;AACrB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAiC;AAC/B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,WAA8B;AAC5B,WAAO,KAAK,MAAM,MAAM,IAAI,CAAC,UAAU;AACrC,UAAI,eAAe,KAAK,GAAG;AACzB,eAAO,oBAAoB,OAAO,KAAK,SAAS;AAAA,MAClD;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,QAA6C;AACnD,UAAM,QAAQ,KAAK,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AAC9D,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AACA,QAAI,eAAe,KAAK,GAAG;AACzB,aAAO,oBAAoB,OAAO,KAAK,SAAS;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,QAAwC;AACpD,QAAI;AACF,YAAM,WAAW,KAAK,QAAQ,MAAM;AACpC,UAAI,CAAC,UAAU;AACb,eAAO;AAAA,UACL;AAAA,UACA,OAAO,mBAAmB,MAAM;AAAA,UAChC,MAAM,CAAC;AAAA,QACT;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,kBAAkB;AACtC,YAAM,aAAgC;AAAA,QACpC,UAAU,OAAO,sBAAsB;AAAA,QACvC,SAAS,OAAO,sBAAsB;AAAA,MACxC;AAEA,YAAM,MAAM,MAAM,4BAA4B,UAAU,UAAU;AAClE,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,IAAI;AAAA,QACZ,OAAO,IAAI;AAAA,QACX,aAAa,IAAI;AAAA,QACjB,aAAa,IAAI;AAAA,QACjB,WAAW,IAAI;AAAA,QACf,iBAAiB,IAAI;AAAA,QACrB,aAAa,IAAI;AAAA,QACjB,cAAc,IAAI;AAAA,QAClB,UAAU,IAAI;AAAA,QACd,MAAM,IAAI;AAAA,MACZ;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL;AAAA,QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC5D,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,aAAgD;AAChE,UAAM,SAAS,KAAK,kBAAkB;AACtC,UAAM,iBAAiB,eAAe,OAAO;AAG7C,UAAM,QAAQ,KAAK,MAAM,MAAM,IAAI,CAAC,UAAU,YAAY;AACxD,UAAI;AAEF,cAAM,WAA4B,eAAe,KAAK,IAClD,oBAAoB,OAAO,KAAK,SAAS,IACzC;AAEJ,cAAM,aAAgC;AAAA,UACpC,UAAU,OAAO,sBAAsB;AAAA,UACvC,SAAS,OAAO,sBAAsB;AAAA,QACxC;AACA,cAAM,MAAM,MAAM,4BAA4B,UAAU,UAAU;AAClE,eAAO;AAAA,UACL,QAAQ,SAAS;AAAA,UACjB,QAAQ,IAAI;AAAA,UACZ,OAAO,IAAI;AAAA,UACX,aAAa,IAAI;AAAA,UACjB,aAAa,IAAI;AAAA,UACjB,WAAW,IAAI;AAAA,UACf,iBAAiB,IAAI;AAAA,UACrB,aAAa,IAAI;AAAA,UACjB,cAAc,IAAI;AAAA,UAClB,UAAU,IAAI;AAAA,UACd,MAAM,IAAI;AAAA,QACZ;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,QAAQ,MAAM;AAAA,UACd,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC5D,MAAM,CAAC;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,cAAc,MAAM,iBAAiB,OAAO,cAAc;AAGhE,WAAO,YAAY,IAAI,CAAC,YAAY,UAAU;AAC5C,UAAI,WAAW,WAAW,WAAW,QAAQ;AAC3C,eAAO,WAAW;AAAA,MACpB;AACA,aAAO;AAAA,QACL,QAAQ,KAAK,MAAM,MAAM,KAAK,EAAE;AAAA,QAChC,OAAO,WAAW,SAAS;AAAA,QAC3B,MAAM,CAAC;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC5TA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,OAAO,iBAAiB;AACjC,OAAO,UAAU;AAMV,IAAM,qBAAN,MAAyB;AAAA,EAK9B,YAAY,SAAiC;AAH7C,SAAQ,SAAwC,oBAAI,IAAI;AAItD,SAAK,UAAU;AACf,SAAK,eAAe,QAAQ;AAG5B,UAAM,gBAAgB,GAAG,KAAK,QAAQ,WAAW;AACjD,yBAAqB,eAAe,KAAK,QAAQ,mBAAmB,KAAK;AAGzE,UAAM,gBAAgB;AACtB,UAAM,mBAAgC;AAAA,MACpC,KAAK;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,MAAM,UAAU;AAAA,MAChB,QAAQ;AAAA;AAAA,MACR,UAAU;AAAA,IACZ;AACA,yBAAqB,gBAAgB;AAGrC,UAAM,gBAAgC;AAAA,MACpC,uBAAuB;AAAA,QACrB,UAAU,KAAK,QAAQ,sBAAsB;AAAA,QAC7C,SAAS,KAAK,QAAQ,sBAAsB;AAAA,MAC9C;AAAA,MACA,oBAAoB,KAAK,QAAQ;AAAA,MACjC,aAAa,KAAK,QAAQ,eAAe;AAAA,IAC3C;AAGA,UAAM,eAAe,oBAAI,IAAiC;AAC1D,QAAI,KAAK,QAAQ,WAAW;AAC1B,iBAAW,YAAY,KAAK,QAAQ,WAAW;AAC7C,qBAAa,IAAI,SAAS,YAAY,QAAQ;AAAA,MAChD;AAAA,IACF;AAGA,eAAW,SAAS,KAAK,QAAQ,QAAQ;AACvC,WAAK,OAAO;AAAA,QACV,MAAM;AAAA,QACN,IAAI,iBAAiB,OAAO,eAAe,YAAY;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAyB;AACvB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAiC;AAC/B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAqC;AACnC,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,WAAiD;AACxD,WAAO,KAAK,OAAO,IAAI,SAAS;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAQ,WAAmB,QAAwC;AACvE,UAAM,QAAQ,KAAK,SAAS,SAAS;AACrC,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,QACL;AAAA,QACA,OAAO,oBAAoB,SAAS;AAAA,QACpC,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAS,WAAmB,aAAgD;AAChF,UAAM,QAAQ,KAAK,SAAS,SAAS;AACrC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,oBAAoB,SAAS,EAAE;AAAA,IACjD;AACA,WAAO,MAAM,YAAY,WAAW;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,aAA6D;AAC9E,UAAM,UAAU,oBAAI,IAA6B;AAEjD,eAAW,aAAa,KAAK,cAAc,GAAG;AAC5C,UAAI;AACF,cAAM,eAAe,MAAM,KAAK,SAAS,WAAW,WAAW;AAC/D,gBAAQ,IAAI,WAAW,YAAY;AAAA,MACrC,SAAS,OAAO;AAEd,cAAM,QAAQ,KAAK,SAAS,SAAS;AACrC,YAAI,OAAO;AACT,gBAAM,eAAgC,MAAM,SAAS,EAAE,IAAI,CAAC,OAAO;AAAA,YACjE,QAAQ,EAAE;AAAA,YACV,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC5D,MAAM,CAAC;AAAA,UACT,EAAE;AACF,kBAAQ,IAAI,WAAW,YAAY;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAkB,aAKrB;AACD,UAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC1C,UAAM,WACJ,KAAK,cAAc,YACnB,GAAG,KAAK,IAAI,CAAC;AAEf,YAAQ,IAAI;AAAA,iBAAoB,KAAK,QAAQ,WAAW,KAAK,KAAK,cAAc,EAAE,MAAM,UAAU;AAElG,UAAM,UAAU,MAAM,KAAK,aAAa,WAAW;AAEnD,QAAI,cAAc;AAClB,QAAI,eAAe;AACnB,QAAI,eAAe;AAEnB,UAAM,SAA2C,CAAC;AAClD,UAAM,YAAsB,CAAC;AAC7B,eAAW,CAAC,WAAW,WAAW,KAAK,QAAQ,QAAQ,GAAG;AACxD,YAAM,aAAa,YAAY;AAC/B,YAAM,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE;AAC9D,YAAM,cAAc,aAAa;AAEjC,qBAAe;AACf,sBAAgB;AAChB,sBAAgB;AAEhB,aAAO,KAAK;AAAA,QACV;AAAA,QACA,aAAa;AAAA,QACb,cAAc;AAAA,QACd,cAAc;AAAA,QACd,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,UAC7B,QAAQ,EAAE;AAAA,UACV,MAAM,EAAE,QAAQ;AAAA,UAChB,aAAa,EAAE,QAAQ;AAAA,UACvB,OAAO,EAAE;AAAA,QACX,EAAE;AAAA,MACJ,CAAC;AAED,iBAAW,KAAK,aAAa;AAC3B,YAAI,OAAO,EAAE,gBAAgB,SAAU,WAAU,KAAK,EAAE,WAAW;AAAA,MACrE;AAAA,IACF;AAEA,UAAM,eAAc,oBAAI,KAAK,GAAE,YAAY;AAC3C,UAAM,SAAiC;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,aAAa,KAAK,QAAQ;AAAA,QAC1B,SAAS,KAAK,QAAQ;AAAA,QACtB,aAAa,KAAK,QAAQ;AAAA,MAC5B;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,cAAc,IAAI,eAAe,cAAc;AAAA,MAC5D;AAAA,MACA;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,KAAK;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,gBAAmB;AAC/B,YAAQ,IAAI,UAAU,OAAO,QAAQ,WAAW,cAAc,OAAO,QAAQ,YAAY,cAAc,OAAO,QAAQ,YAAY,kBAAkB,OAAO,QAAQ,YAAY,KAAK,QAAQ,CAAC,CAAC,GAAG;AACjM,QAAI,WAAW;AACb,cAAQ,IAAI;AAAA,oBAAuB,SAAS,EAAE;AAAA,IAChD;AAEA,WAAO,EAAE,UAAU,WAAW,SAAS,OAAO;AAAA,EAChD;AAAA,EAEQ,qBACN,OACA,WACA,YACA,SACQ;AACR,UAAM,QAAkB,CAAC;AACzB,UAAM,SAAS,WAAW,QAAQ,OAAO,gBAAW;AAEpD,UAAM,KAAK,UAAU,KAAK,KAAK,MAAM,EAAE;AACvC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,gBAAgB,SAAS,EAAE;AACtC,UAAM,KAAK,kBAAkB,WAAW,MAAM,EAAE;AAChD,UAAM,KAAK,iBAAiB,WAAW,QAAQ,OAAO,SAAS,MAAM,EAAE;AACvE,QAAI,OAAO,QAAQ,aAAa,UAAU;AACxC,YAAM,KAAK,oBAAoB,QAAQ,WAAW,KAAM,QAAQ,CAAC,CAAC,GAAG;AAAA,IACvE;AACA,QAAI,QAAQ,UAAU;AACpB,YAAM,KAAK,oBAAoB,QAAQ,QAAQ,EAAE;AAAA,IACnD;AACA,QAAI,QAAQ,eAAe;AACzB,YAAM,KAAK,0BAA0B,QAAQ,aAAa,EAAE;AAAA,IAC9D;AACA,UAAM,KAAK,EAAE;AAEb,QAAI,WAAW,QAAQ;AACrB,YAAM,KAAK,WAAW;AACtB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,sBAAsB,WAAW,OAAO,WAAW,EAAE;AAChE,YAAM,KAAK,kBAAkB,WAAW,OAAO,WAAW,KAAK,EAAE;AACjE,YAAM,KAAK,EAAE;AAEb,UAAI,WAAW,OAAO,qBAAqB,WAAW,OAAO,kBAAkB,SAAS,GAAG;AACzF,cAAM,KAAK,sBAAsB;AACjC,cAAM,KAAK,EAAE;AACb,mBAAW,OAAO,WAAW,OAAO,mBAAmB;AACrD,gBAAM,KAAK,OAAO,IAAI,IAAI,EAAE;AAC5B,gBAAM,KAAK,gBAAgB,IAAI,KAAK,EAAE;AACtC,gBAAM,KAAK,iBAAiB,IAAI,MAAM,EAAE;AACxC,gBAAM,KAAK,EAAE;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAEA,QAAI,WAAW,OAAO;AACpB,YAAM,KAAK,UAAU;AACrB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,WAAW,KAAK;AAC3B,UAAI,WAAW,aAAa;AAC1B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,WAAW,WAAW;AAAA,MACnC;AACA,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,EAAE;AAAA,IACf;AAEA,QAAI,QAAQ,YAAY,MAAM,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,SAAS,SAAS,GAAG;AACtF,YAAM,KAAK,0BAA0B;AACrC,YAAM,KAAK,EAAE;AACb,eAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,QAAQ,KAAK;AAChD,cAAM,MAAM,QAAQ,SAAS,CAAC;AAC9B,cAAM,OAAO,IAAI,QAAQ;AACzB,cAAM,UAAU,IAAI,WAAW;AAC/B,cAAM,KAAK,eAAe,IAAI,CAAC,KAAK,IAAI,GAAG;AAC3C,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,QAAQ;AACnB,cAAM,KAAK,OAAO;AAClB,cAAM,KAAK,QAAQ;AACnB,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAEA,QAAI,QAAQ,aAAa;AACvB,YAAM,KAAK,iBAAiB;AAC5B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,QAAQ,WAAW;AAC9B,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,EAAE;AAAA,IACf;AAEA,QAAI,QAAQ,YAAY;AACtB,YAAM,KAAK,gBAAgB;AAC3B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,QAAQ,UAAU;AAC7B,YAAM,KAAK,QAAQ;AACnB,YAAM,KAAK,EAAE;AAAA,IACf;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEQ,wBACN,UACA,QACA,SACQ;AACR,UAAM,QAAkB,CAAC;AACzB,UAAM,KAAK,8BAA8B;AACzC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,kBAAkB,OAAO,QAAQ,WAAW,EAAE;AACzD,QAAI,OAAO,QAAQ,QAAS,OAAM,KAAK,kBAAkB,OAAO,QAAQ,OAAO,EAAE;AACjF,QAAI,OAAO,QAAQ,YAAa,OAAM,KAAK,sBAAsB,OAAO,QAAQ,WAAW,EAAE;AAC7F,UAAM,KAAK,mBAAmB,QAAQ,EAAE;AACxC,UAAM,KAAK,kBAAkB,OAAO,UAAU,EAAE;AAChD,UAAM,KAAK,mBAAmB,OAAO,WAAW,EAAE;AAClD,UAAM,KAAK,EAAE;AAEb,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,YAAY;AACvB,UAAM,KAAK,mBAAmB,OAAO,QAAQ,WAAW,IAAI;AAC5D,UAAM,KAAK,cAAc,OAAO,QAAQ,YAAY,IAAI;AACxD,UAAM,KAAK,cAAc,OAAO,QAAQ,YAAY,IAAI;AACxD,UAAM,KAAK,kBAAkB,OAAO,QAAQ,YAAY,KAAK,QAAQ,CAAC,CAAC,KAAK;AAC5E,UAAM,KAAK,EAAE;AAEb,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,EAAE;AACb,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,KAAK,OAAO,MAAM,SAAS,EAAE;AACnC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,oDAAoD;AAC/D,YAAM,KAAK,yBAAyB;AACpC,YAAM,eAAe,QAAQ,IAAI,MAAM,SAAS,KAAK,CAAC;AACtD,iBAAW,KAAK,cAAc;AAC5B,cAAM,SAAS,EAAE,QAAQ,OAAO,SAAS;AACzC,cAAM,QAAQ,EAAE,QAAQ,eAAe;AACvC,cAAM,MAAM,OAAO,EAAE,gBAAgB,WAAW,EAAE,cAAc;AAChE,cAAM,SAAS,EAAE,aAAa;AAC9B,cAAM,KAAK,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM,KAAK,MAAM,GAAG,MAAM,MAAM,IAAI;AAAA,MAC1E;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,MAAc,yBACZ,UACA,QACA,SAC6B;AAC7B,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,QAAQ,WAAY,QAAO;AAEhC,UAAM,WAAW,KAAK,KAAK,OAAO,YAAY,QAAQ;AACtD,UAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAEzC,UAAM,kBAAkB,OAAO,qBAAqB;AACpD,UAAM,gBAAgB,OAAO,mBAAmB;AAEhD,QAAI,iBAAiB;AACnB,YAAM;AAAA,QACJ,KAAK,KAAK,UAAU,aAAa;AAAA,QACjC,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,kBAAkB,KAAK,KAAK,UAAU,cAAc;AAC1D,UAAM,cAAc;AAAA,MAClB,oBAAoB;AAAA,MACpB,SAAS,OAAO;AAAA,MAChB;AAAA,MACA,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,WAAW,OAAO;AAAA,QACxE;AAAA,QACA,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,UAC7B,QAAQ,EAAE;AAAA,UACV,QAAQ,EAAE,QAAQ,SAAS;AAAA,UAC3B,SAAS,EAAE,QAAQ,WAAW,EAAE,SAAS;AAAA,UACzC,OAAO,EAAE,QACL;AAAA,YACA,SAAS,EAAE;AAAA,YACX,OAAO,EAAE;AAAA,UACX,IACE;AAAA,UACJ,UAAU,EAAE;AAAA,UACZ,YAAY,EAAE;AAAA,UACd,aAAa,EAAE;AAAA,UACf,UAAU,EAAE;AAAA,UACZ,eAAe,EAAE;AAAA,QACnB,EAAE;AAAA,MACJ,EAAE;AAAA,IACJ;AACA,UAAM,UAAU,iBAAiB,KAAK,UAAU,aAAa,MAAM,CAAC,GAAG,OAAO;AAG9E,UAAM,gBAAgB,KAAK,KAAK,UAAU,YAAY;AACtD,UAAM,YAAY,KAAK,wBAAwB,UAAU,QAAQ,OAAO;AACxE,UAAM,UAAU,eAAe,WAAW,OAAO;AAGjD,UAAM,gBAAgB,KAAK,KAAK,UAAU,YAAY;AACtD,UAAM,MAAM,eAAe,EAAE,WAAW,KAAK,CAAC;AAC9C,QAAI,QAAQ;AACZ,eAAW,CAAC,WAAW,WAAW,KAAK,QAAQ,QAAQ,GAAG;AACxD,iBAAW,KAAK,aAAa;AAC3B,cAAM,SAAS,EAAE,QAAQ,OAAO,SAAS;AACzC,cAAM,eAAe,QAAQ,KAAK,IAAI,SAAS,IAAI,EAAE,MAAM,IAAI,MAAM,GAAG,QAAQ,WAAW,GAAG;AAG9F,cAAM,WAAW,KAAK,KAAK,eAAe,GAAG,YAAY,OAAO;AAChE,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,UACA,QAAQ,EAAE;AAAA,UACV,QAAQ,EAAE,QAAQ,SAAS;AAAA,UAC3B,QAAQ,EAAE;AAAA,UACV,SAAS,EAAE,QAAQ,WAAW,EAAE,SAAS;AAAA,UACzC,OAAO,EAAE,QACL,EAAE,SAAS,EAAE,OAAO,OAAO,EAAE,YAAY,IACzC;AAAA,UACJ,UAAU,EAAE;AAAA,UACZ,UAAU,EAAE;AAAA,UACZ,eAAe,EAAE;AAAA,UACjB,aAAa,EAAE;AAAA,UACf,YAAY,EAAE;AAAA,UACd,UAAU,EAAE;AAAA,QACd;AACA,cAAM,UAAU,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,OAAO;AAGnE,cAAM,SAAS,KAAK,KAAK,eAAe,GAAG,YAAY,KAAK;AAC5D,cAAM,YAAY,KAAK,qBAAqB,OAAO,WAAW,GAAG,OAAO;AACxE,cAAM,UAAU,QAAQ,WAAW,OAAO;AAE1C,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI,eAAe;AACjB,iBAAW,CAAC,WAAW,WAAW,KAAK,QAAQ,QAAQ,GAAG;AACxD,cAAM,WAAW,KAAK,KAAK,UAAU,SAAS,SAAS;AACvD,cAAM,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AACzC,mBAAW,KAAK,aAAa;AAC3B,gBAAM;AAAA,YACJ,KAAK,KAAK,UAAU,GAAG,EAAE,MAAM,YAAY;AAAA,YAC3C,KAAK,UAAU,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC;AAAA,YACpC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiom-lattice/agent-eval",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.27",
|
|
4
4
|
"description": "Agent evaluation for Axiom Lattice framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"@langchain/langgraph": "1.0.4",
|
|
25
25
|
"uuid": "^13.0.0",
|
|
26
26
|
"zod": "3.25.76",
|
|
27
|
-
"@axiom-lattice/core": "2.1.
|
|
28
|
-
"@axiom-lattice/protocols": "2.1.
|
|
27
|
+
"@axiom-lattice/core": "2.1.33",
|
|
28
|
+
"@axiom-lattice/protocols": "2.1.20"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/jest": "^29.5.12",
|
package/src/LatticeEval.ts
CHANGED
|
@@ -455,7 +455,8 @@ ${rubricsSection}
|
|
|
455
455
|
const judgeThreadId = v4();
|
|
456
456
|
this.lastJudgeThreadId = judgeThreadId;
|
|
457
457
|
this.log("Invoking judge agent", { agent_key: "LatticeTest", case_id: evalCase.caseId });
|
|
458
|
-
const
|
|
458
|
+
const judgeAgent = await getAgentClient("default", "LatticeTest");
|
|
459
|
+
const testResponse = await judgeAgent.invoke(
|
|
459
460
|
{
|
|
460
461
|
messages: [new HumanMessage(testPrompt)],
|
|
461
462
|
},
|