-
- {scenario.name || 'Unnamed Scenario'}
-
- {scenario.description && (
-
{scenario.description}
- )}
-
- {scenario.isOwner && (
-
- )}
- {scenario.isOwner && (
-
- )}
+
+
+ {scenario.name || 'Unnamed Scenario'}
+
+ {scenario.description && (
+
{scenario.description}
+ )}
{scenario.isOwner && (
{/* Run Details (Expanded) */}
- {expandedRunId === run.id && (
-
-
- {/* Evaluator */}
- {run.evaluator?.verdict && (
-
-
- LLM Evaluation
-
-
-
- {run.evaluator.model && (
-
- {run.evaluator.model}
-
- )}
-
- {run.evaluator?.reason && (
-
- {run.evaluator.reason}
-
- )}
-
- )}
-
- {/* Usage Stats */}
-
-
- Usage
-
- {run.usage ? (
-
-
- Duration:{' '}
-
- {formatDuration(run.usage.executionTimeMs || null)}
-
-
-
- Tokens:{' '}
-
- {run.usage.totalTokens?.toLocaleString() || '—'}
-
-
-
- Retries:{' '}
- {run.retryCount}
-
-
- ) : (
-
- No usage data available
-
- )}
-
-
- {/* Output (if owner) */}
- {run.output && (
-
-
- Output
-
-
- {run.output}
-
-
- )}
-
- {/* Error Log (if owner and error) */}
- {run.errorLog && (
-
-
- Error Log
-
-
- {run.errorLog}
-
-
- )}
-
- {/* Conversation History */}
- {run.conversation && (
-
-
-
- Conversation History
-
-
-
-
-
-
- {viewMode === 'debug' ? (
-
-
-
- Raw Messages ({run.conversation.length})
-
-
-
-
- {JSON.stringify(run.conversation, null, 2)}
-
-
- ) : (
-
- {run.conversation.map((msg) => (
-
- {msg.role === 'USER' && (
-
- )}
- {msg.role === 'ASSISTANT' && (
-
- {msg.content && (
-
- )}
-
- )}
- {msg.role === 'TOOL' && (
-
-
-
-
- {msg.toolName || 'Unknown Tool'}
-
- {msg.toolResult && (
-
-
- {typeof msg.toolResult === 'string'
- ? msg.toolResult
- : JSON.stringify(msg.toolResult, null, 2)}
-
-
- )}
-
-
-
- )}
-
- ))}
-
- )}
-
- )}
-
- )}
+ {expandedRunId === run.id &&
}
))}
diff --git a/apps/web/vitest.config.mjs b/apps/web/vitest.config.mjs
new file mode 100644
index 0000000..ae04c3b
--- /dev/null
+++ b/apps/web/vitest.config.mjs
@@ -0,0 +1,22 @@
+import { resolve, dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { defineConfig } from 'vitest/config';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+
+export default defineConfig({
+ test: {
+ globals: true,
+ environment: 'node',
+ include: ['src/**/*.test.ts'],
+ exclude: ['src/test/integration/**/*.test.ts', 'node_modules/**'],
+ setupFiles: ['./src/test/setup.ts'],
+ testTimeout: 30000, // 30s for API calls
+ },
+ resolve: {
+ alias: {
+ '~': resolve(__dirname, './src'),
+ },
+ },
+});
diff --git a/apps/web/vitest.integration.config.mjs b/apps/web/vitest.integration.config.mjs
new file mode 100644
index 0000000..3ea45d4
--- /dev/null
+++ b/apps/web/vitest.integration.config.mjs
@@ -0,0 +1,27 @@
+import { resolve, dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { defineConfig } from 'vitest/config';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+
+export default defineConfig({
+ test: {
+ globals: true,
+ environment: 'node',
+ include: ['src/test/integration/**/*.integration.test.ts'],
+ setupFiles: ['./src/test/integration/setup-integration.ts'],
+ testTimeout: 60000, // 60s for API calls to production
+ // Run tests sequentially to avoid race conditions on shared test data
+ sequence: {
+ concurrent: false,
+ },
+ // Fail fast on integration tests
+ bail: 5,
+ },
+ resolve: {
+ alias: {
+ '~': resolve(__dirname, './src'),
+ },
+ },
+});