mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
perf: upgrade dependencies across common, cf-webapp, and cf-api (#2599)
## Summary - **common**: Upgraded to Prisma 6.19.3, TypeScript 5.9.3, Prettier 3.8.2. Published as `@codeflash-ai/common@1.0.31` — fixes Prisma type widening caused by cross-package version mismatch - **cf-webapp**: 20+ dependency upgrades including posthog-js (1.127→1.367), lucide-react (0.563→1.8), tailwind-merge (2→3), marked (16→18), react-markdown (9→10), zod (3→4). Fixes lucide v1 icon renames and react-markdown v10 API changes - **cf-api**: 30+ dependency upgrades aligned with common. Prisma 6.19.3, Sentry 10.48, posthog-node 5.29, marked 18, resend 6.10 ## Motivation Testing hypothesis that outdated dependencies cause bundle bloat and runtime regressions. posthog-js alone was 240 minor versions behind and loads on every page. lucide-react v1 rewrote the icon system with better tree-shaking. tailwind-merge v3 has a smaller/faster runtime used in every `cn()` call. ## Root cause fix The Prisma type widening errors (`string | Date | null` instead of `string`) were caused by `@codeflash-ai/common` being published with Prisma ^6.13 types while consumers installed a different version. Aligning all packages to ^6.19.3 and republishing common fixed it properly. ## Test plan - [ ] cf-webapp builds and type-checks cleanly - [ ] cf-api builds cleanly - [ ] No runtime regressions in dashboard, observability pages - [ ] Prisma types resolve correctly (no widening)
This commit is contained in:
parent
f9d78e5cf2
commit
ec39cd5190
10 changed files with 3823 additions and 4300 deletions
2896
js/cf-api/package-lock.json
generated
2896
js/cf-api/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -24,47 +24,47 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@awaitjs/express": "^0.9.0",
|
||||
"@azure/identity": "^4.12.0",
|
||||
"@azure/keyvault-keys": "^4.7.2",
|
||||
"@azure/keyvault-secrets": "^4.7.0",
|
||||
"@azure/identity": "^4.13.1",
|
||||
"@azure/keyvault-keys": "^4.10.0",
|
||||
"@azure/keyvault-secrets": "^4.11.1",
|
||||
"@codeflash-ai/code-suggester": "^5.0.4",
|
||||
"@codeflash-ai/common": "^1.0.28",
|
||||
"@octokit/app": "^16.0.1",
|
||||
"@octokit/auth-app": "^8.0.1",
|
||||
"@octokit/core": "^7.0.2",
|
||||
"@codeflash-ai/common": "^1.0.31",
|
||||
"@octokit/app": "^16.1.2",
|
||||
"@octokit/auth-app": "^8.2.0",
|
||||
"@octokit/core": "^7.0.6",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^15.0.0",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"@octokit/webhooks": "^14.0.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/context-async-hooks": "^1.30.1",
|
||||
"@prisma/client": "^6.13.0",
|
||||
"@sentry/node": "^10.27.0",
|
||||
"@sentry/opentelemetry": "^10.8.0",
|
||||
"@sentry/profiling-node": "^10.27.0",
|
||||
"@slack/web-api": "^7.4.0",
|
||||
"@types/node": "^22.10.5",
|
||||
"auth0": "^4.29.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.5.0",
|
||||
"express": "^4.19.2",
|
||||
"express-rate-limit": "^7.5.0",
|
||||
"marked": "^16.0.0",
|
||||
"@octokit/rest": "^22.0.1",
|
||||
"@octokit/webhooks": "^14.2.0",
|
||||
"@opentelemetry/api": "^1.9.1",
|
||||
"@opentelemetry/context-async-hooks": "^2.6.1",
|
||||
"@prisma/client": "^6.19.3",
|
||||
"@sentry/node": "^10.48.0",
|
||||
"@sentry/opentelemetry": "^10.48.0",
|
||||
"@sentry/profiling-node": "^10.48.0",
|
||||
"@slack/web-api": "^7.15.0",
|
||||
"@types/node": "^22.15.29",
|
||||
"auth0": "^4.37.0",
|
||||
"body-parser": "^1.20.4",
|
||||
"cors": "^2.8.6",
|
||||
"dotenv": "^16.6.1",
|
||||
"express": "^4.22.1",
|
||||
"express-rate-limit": "^8.3.2",
|
||||
"marked": "^18.0.0",
|
||||
"node-cron": "^4.2.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"octokit": "^5.0.2",
|
||||
"posthog-node": "^4.0.0",
|
||||
"resend": "^4.6.0",
|
||||
"octokit": "^5.0.5",
|
||||
"posthog-node": "^5.29.2",
|
||||
"resend": "^6.10.0",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"tsx": "^4.1.4"
|
||||
"tsx": "^4.21.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "^20.1.2",
|
||||
"@types/body-parser": "^1.19.5",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/body-parser": "^1.19.6",
|
||||
"@types/cors": "^2.8.19",
|
||||
"@types/express": "^4.17.25",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/supertest": "^6.0.3",
|
||||
"@types/supertest": "^7.2.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
|
|
@ -72,11 +72,11 @@
|
|||
"eslint-plugin-import": "^2.29.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"lint-staged": "^15.4.3",
|
||||
"prettier": "^3.4.2",
|
||||
"prisma": "^6.13.0",
|
||||
"supertest": "^7.1.1",
|
||||
"ts-jest": "^29.3.4",
|
||||
"lint-staged": "^16.4.0",
|
||||
"prettier": "^3.8.2",
|
||||
"prisma": "^6.19.3",
|
||||
"supertest": "^7.2.2",
|
||||
"ts-jest": "^29.4.9",
|
||||
"ts-node": "^10.9.2"
|
||||
},
|
||||
"prisma": {
|
||||
|
|
|
|||
2452
js/cf-webapp/package-lock.json
generated
2452
js/cf-webapp/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -20,14 +20,14 @@
|
|||
"format:check": "prettier --check \"**/*.{js,ts,tsx,json,md}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.74.0",
|
||||
"@anthropic-ai/sdk": "^0.87.0",
|
||||
"@auth0/nextjs-auth0": "^4",
|
||||
"@codeflash-ai/common": "^1.0.30",
|
||||
"@hookform/resolvers": "^3.3.2",
|
||||
"@codeflash-ai/common": "^1.0.31",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.72.0",
|
||||
"@opentelemetry/sdk-node": "^0.214.0",
|
||||
"@prisma/client": "^6.7.0",
|
||||
"@prisma/client": "^6.19.3",
|
||||
"@prisma/instrumentation": "^7.6.0",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||
|
|
@ -42,10 +42,10 @@
|
|||
"@radix-ui/react-tooltip": "^1.1.4",
|
||||
"@sentry/nextjs": "^10.38.0",
|
||||
"@sentry/opentelemetry": "^10.47.0",
|
||||
"@types/node": "^24.3.0",
|
||||
"@types/node": "^25.6.0",
|
||||
"@types/pg": "^8.10.9",
|
||||
"@types/react": "19.2.13",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"chart.js": "^4.4.9",
|
||||
"chartjs-plugin-datalabels": "^2.2.0",
|
||||
|
|
@ -54,8 +54,8 @@
|
|||
"date-fns": "^4.1.0",
|
||||
"diff": "^8.0.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lucide-react": "^0.563.0",
|
||||
"marked": "^16.1.1",
|
||||
"lucide-react": "^1.8.0",
|
||||
"marked": "^18.0.0",
|
||||
"motion": "^12.38.0",
|
||||
"next": "^16.2.3",
|
||||
"next-themes": "^0.4.6",
|
||||
|
|
@ -64,24 +64,24 @@
|
|||
"papaparse": "^5.5.3",
|
||||
"pg": "^8.11.3",
|
||||
"postcss": "^8",
|
||||
"posthog-js": "1.127.0",
|
||||
"posthog-node": "^4.0.1",
|
||||
"posthog-js": "^1.367.0",
|
||||
"posthog-node": "^5.29.2",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"react": "19.2.4",
|
||||
"react": "^19.2.5",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "19.2.4",
|
||||
"react-dom": "^19.2.5",
|
||||
"react-hook-form": "^7.48.2",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-resizable-panels": "^4.6.4",
|
||||
"react-syntax-highlighter": "^16.1.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"sharp": "^0.34.2",
|
||||
"sonner": "^2.0.6",
|
||||
"tailwind-merge": "^2.0.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"web-tree-sitter": "^0.26.5",
|
||||
"zod": "^3.22.4"
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "^16.2.2",
|
||||
|
|
@ -91,18 +91,18 @@
|
|||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"baseline-browser-mapping": "^2.9.11",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.1.6",
|
||||
"eslint": "^10.2.0",
|
||||
"eslint-config-next": "^16.2.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"jsdom": "^24.1.0",
|
||||
"lint-staged": "^15.4.3",
|
||||
"prettier": "3.2.5",
|
||||
"prisma": "^6.7.0",
|
||||
"jsdom": "^29.0.2",
|
||||
"lint-staged": "^16.4.0",
|
||||
"prettier": "^3.8.2",
|
||||
"prisma": "^6.19.3",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"tree-sitter-cli": "^0.26.3",
|
||||
"tree-sitter-python": "^0.25.0",
|
||||
"typescript": "^5.4.5",
|
||||
"vitest": "^3.0.8"
|
||||
"typescript": "~5.4.5",
|
||||
"vitest": "^4.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
|
|
@ -119,8 +119,6 @@
|
|||
]
|
||||
},
|
||||
"overrides": {
|
||||
"@types/react": "19.2.13",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"dompurify": "3.3.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {
|
|||
AlertCircle,
|
||||
Timer,
|
||||
DollarSign,
|
||||
Github,
|
||||
GitFork,
|
||||
Terminal,
|
||||
Hash,
|
||||
Code as CodeIcon,
|
||||
|
|
@ -53,7 +53,7 @@ export function TraceSummary({
|
|||
const statusColor = getStatusColor(status)
|
||||
const StatusIcon = getStatusIcon(status)
|
||||
|
||||
const SourceIcon = source.toLowerCase().includes("github") ? Github : Terminal
|
||||
const SourceIcon = source.toLowerCase().includes("github") ? GitFork : Terminal
|
||||
|
||||
return (
|
||||
<div className="bg-white dark:bg-zinc-950 rounded-sm p-6 border border-zinc-200 dark:border-zinc-800">
|
||||
|
|
@ -128,4 +128,4 @@ export function TraceSummary({
|
|||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -6,7 +6,7 @@ import {
|
|||
DollarSign,
|
||||
Hash,
|
||||
Code as CodeIcon,
|
||||
Github,
|
||||
GitFork,
|
||||
Terminal,
|
||||
AlertCircle,
|
||||
XCircle,
|
||||
|
|
@ -31,7 +31,8 @@ export default async function TracePage(props: TracePageProps) {
|
|||
|
||||
// Use prefix matching (first 33 chars) to group multi-model calls that share the same base trace_id
|
||||
const tracePrefix = trace_id.substring(0, 33)
|
||||
const { rawLlmCalls, errors, optimizationFeatures, optimizationEvent } = await getTraceData(tracePrefix)
|
||||
const { rawLlmCalls, errors, optimizationFeatures, optimizationEvent } =
|
||||
await getTraceData(tracePrefix)
|
||||
|
||||
const traceSource = getCallSource(optimizationEvent?.event_type || null, null)
|
||||
|
||||
|
|
@ -68,16 +69,17 @@ export default async function TracePage(props: TracePageProps) {
|
|||
(optimizationFeatures?.explanations_post as Record<string, string>) || {}
|
||||
|
||||
// Best candidate (first in ranking) and whether it was used for PR
|
||||
const rankingData = optimizationFeatures?.ranking as
|
||||
| { ranking?: string[]; explanation?: string }
|
||||
| null
|
||||
const rankingData = optimizationFeatures?.ranking as {
|
||||
ranking?: string[]
|
||||
explanation?: string
|
||||
} | null
|
||||
const bestCandidateId = rankingData?.ranking?.[0] ?? null
|
||||
const pullRequestRaw = optimizationFeatures?.pull_request
|
||||
const usedForPr = Boolean(
|
||||
pullRequestRaw != null &&
|
||||
typeof pullRequestRaw === "object" &&
|
||||
!Array.isArray(pullRequestRaw) &&
|
||||
Object.keys(pullRequestRaw as Record<string, unknown>).length > 0,
|
||||
typeof pullRequestRaw === "object" &&
|
||||
!Array.isArray(pullRequestRaw) &&
|
||||
Object.keys(pullRequestRaw as Record<string, unknown>).length > 0,
|
||||
)
|
||||
|
||||
// Map candidate ID to rank position (1-based, 1 = best)
|
||||
|
|
@ -139,7 +141,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
const orderedTypes = [...new Set(llmCalls.map(c => c.call_type || "unknown"))]
|
||||
|
||||
// Create a map of call_type to LLM call for candidate linking
|
||||
const callTypeToLlmCall = new Map<string, typeof llmCalls[0]>()
|
||||
const callTypeToLlmCall = new Map<string, (typeof llmCalls)[0]>()
|
||||
llmCalls.forEach(call => {
|
||||
if (call.call_type && !callTypeToLlmCall.has(call.call_type)) {
|
||||
callTypeToLlmCall.set(call.call_type, call)
|
||||
|
|
@ -183,8 +185,8 @@ export default async function TracePage(props: TracePageProps) {
|
|||
Summary Metrics
|
||||
</h4>
|
||||
<p>
|
||||
View key metrics including status, source, duration, cost, tokens, and number
|
||||
of generated candidates for this optimization request.
|
||||
View key metrics including status, source, duration, cost, tokens, and number of
|
||||
generated candidates for this optimization request.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -202,8 +204,9 @@ export default async function TracePage(props: TracePageProps) {
|
|||
Generated Candidates
|
||||
</h4>
|
||||
<p>
|
||||
Code optimization candidates generated during this trace. Each candidate includes
|
||||
an explanation and the generated code. Use the copy button to copy candidate code.
|
||||
Code optimization candidates generated during this trace. Each candidate
|
||||
includes an explanation and the generated code. Use the copy button to copy
|
||||
candidate code.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -234,25 +237,19 @@ export default async function TracePage(props: TracePageProps) {
|
|||
<AlertCircle className="h-4 w-4" />
|
||||
)}
|
||||
<span>Status</span>
|
||||
<InfoIcon
|
||||
content="Overall trace status based on all contained calls"
|
||||
side="top"
|
||||
/>
|
||||
<InfoIcon content="Overall trace status based on all contained calls" side="top" />
|
||||
</div>
|
||||
<div className={`text-xl font-bold ${statusColor}`}>{status}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 font-medium mb-2">
|
||||
{traceSource.toLowerCase().includes("github") ? (
|
||||
<Github className="h-4 w-4" />
|
||||
<GitFork className="h-4 w-4" />
|
||||
) : (
|
||||
<Terminal className="h-4 w-4" />
|
||||
)}
|
||||
<span>Source</span>
|
||||
<InfoIcon
|
||||
content="Where this optimization was triggered from"
|
||||
side="top"
|
||||
/>
|
||||
<InfoIcon content="Where this optimization was triggered from" side="top" />
|
||||
</div>
|
||||
<div className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
<span className="px-2 py-1 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded text-sm">
|
||||
|
|
@ -264,10 +261,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
<div className="flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 font-medium mb-2">
|
||||
<Timer className="h-4 w-4" />
|
||||
<span>Duration</span>
|
||||
<InfoIcon
|
||||
content="Total time from first call to last call completion"
|
||||
side="top"
|
||||
/>
|
||||
<InfoIcon content="Total time from first call to last call completion" side="top" />
|
||||
</div>
|
||||
<div className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
{(totalDuration / 1000).toFixed(2)}s
|
||||
|
|
@ -277,10 +271,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
<div className="flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 font-medium mb-2">
|
||||
<DollarSign className="h-4 w-4" />
|
||||
<span>Cost</span>
|
||||
<InfoIcon
|
||||
content="Sum of all LLM call costs in this trace"
|
||||
side="top"
|
||||
/>
|
||||
<InfoIcon content="Sum of all LLM call costs in this trace" side="top" />
|
||||
</div>
|
||||
<div className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
${totalCost.toFixed(4)}
|
||||
|
|
@ -290,10 +281,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
<div className="flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 font-medium mb-2">
|
||||
<Hash className="h-4 w-4" />
|
||||
<span>Tokens</span>
|
||||
<InfoIcon
|
||||
content="Total tokens (prompt + completion) across all calls"
|
||||
side="top"
|
||||
/>
|
||||
<InfoIcon content="Total tokens (prompt + completion) across all calls" side="top" />
|
||||
</div>
|
||||
<div className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
{totalTokens.toLocaleString()}
|
||||
|
|
@ -303,10 +291,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
<div className="flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 font-medium mb-2">
|
||||
<CodeIcon className="h-4 w-4" />
|
||||
<span>Candidates</span>
|
||||
<InfoIcon
|
||||
content="Number of valid optimization candidates generated"
|
||||
side="top"
|
||||
/>
|
||||
<InfoIcon content="Number of valid optimization candidates generated" side="top" />
|
||||
</div>
|
||||
<div className="text-xl font-bold text-gray-900 dark:text-white">
|
||||
{optimizationCandidates.length}
|
||||
|
|
@ -353,7 +338,8 @@ export default async function TracePage(props: TracePageProps) {
|
|||
</h4>
|
||||
<p>
|
||||
Click any call to expand and see detailed metrics including token usage,
|
||||
latency, and timestamp. Use "View full details" to see prompts and responses.
|
||||
latency, and timestamp. Use "View full details" to see prompts and
|
||||
responses.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -431,25 +417,33 @@ export default async function TracePage(props: TracePageProps) {
|
|||
{/* Call details */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-x-6 gap-y-3 text-sm">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">Tokens</span>
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">
|
||||
Tokens
|
||||
</span>
|
||||
<span className="text-gray-900 dark:text-white font-medium">
|
||||
{call.total_tokens?.toLocaleString() ?? "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">Latency</span>
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">
|
||||
Latency
|
||||
</span>
|
||||
<span className="text-gray-900 dark:text-white font-medium">
|
||||
{call.latency_ms ? `${call.latency_ms}ms` : "N/A"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">Time</span>
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">
|
||||
Time
|
||||
</span>
|
||||
<span className="text-gray-900 dark:text-white font-medium">
|
||||
{new Date(call.created_at).toLocaleTimeString()}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col sm:col-span-2 lg:col-span-1">
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">Details</span>
|
||||
<span className="text-gray-500 dark:text-gray-400 text-xs mb-1">
|
||||
Details
|
||||
</span>
|
||||
<Link
|
||||
href={`/observability/llm-call/${call.id}`}
|
||||
className="text-blue-600 dark:text-blue-400 hover:underline text-sm font-medium inline-block"
|
||||
|
|
@ -478,88 +472,92 @@ export default async function TracePage(props: TracePageProps) {
|
|||
</div>
|
||||
<div className="space-y-2">
|
||||
{candidatesForType.map(candidate => {
|
||||
const isBest =
|
||||
bestCandidateId != null && candidate.id === bestCandidateId
|
||||
const isBest = bestCandidateId != null && candidate.id === bestCandidateId
|
||||
const showUsedForPr = isBest && usedForPr
|
||||
const rank = candidateRankMap.get(candidate.id)
|
||||
return (
|
||||
<details
|
||||
key={candidate.id}
|
||||
className={`rounded-lg border ${
|
||||
isBest
|
||||
? "border-emerald-500 dark:border-emerald-600 bg-emerald-50/50 dark:bg-emerald-900/20"
|
||||
: "border-gray-200 dark:border-gray-600"
|
||||
}`}
|
||||
>
|
||||
<summary className="p-3 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 flex items-center justify-between rounded-lg">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="font-medium text-gray-900 dark:text-white">
|
||||
Candidate {candidate.index}
|
||||
</span>
|
||||
<span className="font-mono text-xs text-gray-500 dark:text-gray-400">
|
||||
{candidate.id.substring(0, 8)}...
|
||||
</span>
|
||||
{rank != null && (
|
||||
<span className="bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
Rank #{rank}
|
||||
<details
|
||||
key={candidate.id}
|
||||
className={`rounded-lg border ${
|
||||
isBest
|
||||
? "border-emerald-500 dark:border-emerald-600 bg-emerald-50/50 dark:bg-emerald-900/20"
|
||||
: "border-gray-200 dark:border-gray-600"
|
||||
}`}
|
||||
>
|
||||
<summary className="p-3 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 flex items-center justify-between rounded-lg">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<span className="font-medium text-gray-900 dark:text-white">
|
||||
Candidate {candidate.index}
|
||||
</span>
|
||||
)}
|
||||
{isBest && (
|
||||
<span className="bg-emerald-100 dark:bg-emerald-900 text-emerald-800 dark:text-emerald-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
Best
|
||||
<span className="font-mono text-xs text-gray-500 dark:text-gray-400">
|
||||
{candidate.id.substring(0, 8)}...
|
||||
</span>
|
||||
)}
|
||||
{showUsedForPr && (
|
||||
<span className="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
Used for PR
|
||||
</span>
|
||||
)}
|
||||
{candidate.model && (
|
||||
<span className="bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 text-xs px-2 py-0.5 rounded">
|
||||
{candidate.model}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-gray-400 text-sm">▼</span>
|
||||
</summary>
|
||||
<div className="p-3 pt-0 border-t border-gray-200 dark:border-gray-600 mt-2 space-y-3">
|
||||
{candidateExplanations[candidate.id] && (
|
||||
<div>
|
||||
<div className="flex items-center gap-1.5 mb-1">
|
||||
<CodeIcon className="h-3.5 w-3.5 text-gray-500 dark:text-gray-400" />
|
||||
<h5 className="text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
Explanation
|
||||
</h5>
|
||||
{rank != null && (
|
||||
<span className="bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
Rank #{rank}
|
||||
</span>
|
||||
)}
|
||||
{isBest && (
|
||||
<span className="bg-emerald-100 dark:bg-emerald-900 text-emerald-800 dark:text-emerald-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
Best
|
||||
</span>
|
||||
)}
|
||||
{showUsedForPr && (
|
||||
<span className="bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs px-2 py-0.5 rounded font-semibold">
|
||||
Used for PR
|
||||
</span>
|
||||
)}
|
||||
{candidate.model && (
|
||||
<span className="bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 text-xs px-2 py-0.5 rounded">
|
||||
{candidate.model}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-gray-400 text-sm">▼</span>
|
||||
</summary>
|
||||
<div className="p-3 pt-0 border-t border-gray-200 dark:border-gray-600 mt-2 space-y-3">
|
||||
{candidateExplanations[candidate.id] && (
|
||||
<div>
|
||||
<div className="flex items-center gap-1.5 mb-1">
|
||||
<CodeIcon className="h-3.5 w-3.5 text-gray-500 dark:text-gray-400" />
|
||||
<h5 className="text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
Explanation
|
||||
</h5>
|
||||
</div>
|
||||
<p className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap leading-relaxed">
|
||||
{candidateExplanations[candidate.id]}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap leading-relaxed">
|
||||
{candidateExplanations[candidate.id]}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h5 className="text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
Code
|
||||
</h5>
|
||||
<CopyButton text={candidate.code} label="candidate code" size="sm" />
|
||||
</div>
|
||||
<pre className="bg-gray-900 text-gray-100 p-3 rounded-lg overflow-x-auto text-xs font-mono leading-relaxed">
|
||||
<code>{candidate.code}</code>
|
||||
</pre>
|
||||
</div>
|
||||
{llmCallForType && (
|
||||
)}
|
||||
<div>
|
||||
<Link
|
||||
href={`/observability/llm-call/${llmCallForType.id}`}
|
||||
className="text-blue-600 dark:text-blue-400 hover:underline text-sm font-medium inline-flex items-center gap-1"
|
||||
>
|
||||
View LLM Call Details →
|
||||
</Link>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h5 className="text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
Code
|
||||
</h5>
|
||||
<CopyButton
|
||||
text={candidate.code}
|
||||
label="candidate code"
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
<pre className="bg-gray-900 text-gray-100 p-3 rounded-lg overflow-x-auto text-xs font-mono leading-relaxed">
|
||||
<code>{candidate.code}</code>
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</details>
|
||||
)})}
|
||||
{llmCallForType && (
|
||||
<div>
|
||||
<Link
|
||||
href={`/observability/llm-call/${llmCallForType.id}`}
|
||||
className="text-blue-600 dark:text-blue-400 hover:underline text-sm font-medium inline-flex items-center gap-1"
|
||||
>
|
||||
View LLM Call Details →
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</details>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -598,9 +596,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
{errors.length > 0 ? (
|
||||
<>
|
||||
<AlertCircle className="h-5 w-5 text-red-600 dark:text-red-400" />
|
||||
<h2 className="text-xl font-bold text-red-600 dark:text-red-400">
|
||||
Errors
|
||||
</h2>
|
||||
<h2 className="text-xl font-bold text-red-600 dark:text-red-400">Errors</h2>
|
||||
<span className="bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 text-sm px-2.5 py-0.5 rounded font-semibold">
|
||||
{errors.length}
|
||||
</span>
|
||||
|
|
@ -619,15 +615,13 @@ export default async function TracePage(props: TracePageProps) {
|
|||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
{errors.map(error => {
|
||||
const isTestFailure = error.error_type === "test_failure"
|
||||
const errorContext = error.context as
|
||||
| {
|
||||
test_name?: string
|
||||
failure_reason?: string
|
||||
test_output?: string
|
||||
expected?: string
|
||||
actual?: string
|
||||
}
|
||||
| null
|
||||
const errorContext = error.context as {
|
||||
test_name?: string
|
||||
failure_reason?: string
|
||||
test_output?: string
|
||||
expected?: string
|
||||
actual?: string
|
||||
} | null
|
||||
|
||||
return (
|
||||
<div key={error.id} className="p-6 border-l-4 border-red-500">
|
||||
|
|
@ -728,9 +722,7 @@ export default async function TracePage(props: TracePageProps) {
|
|||
) : (
|
||||
<div className="flex flex-col items-center justify-center py-12 text-center">
|
||||
<CheckCircle className="h-16 w-16 text-green-500 dark:text-green-400 mb-4" />
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
||||
All Clear!
|
||||
</h3>
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">All Clear!</h3>
|
||||
<p className="text-gray-500 dark:text-gray-400 text-sm">
|
||||
This trace completed successfully with no errors detected.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -781,104 +781,105 @@ const MonacoDiffViewer: React.FC<MonacoDiffViewerProps> = ({
|
|||
</button>
|
||||
{showGeneratedTests && (
|
||||
<div className="mt-2 sm:mt-3 bg-slate-800/50 rounded-lg p-2 sm:p-3 max-h-48 sm:max-h-64 overflow-y-auto scrollbar-thin scrollbar-thumb-slate-600 scrollbar-track-slate-800">
|
||||
<ReactMarkdown
|
||||
className="prose prose-sm prose-invert max-w-none"
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
pre: ({ children, ...props }) => {
|
||||
return (
|
||||
<div className="not-prose">
|
||||
<pre className="bg-slate-900/50 rounded-md overflow-x-auto" {...props}>
|
||||
<div className="prose prose-sm prose-invert max-w-none">
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={{
|
||||
pre: ({ children, ...props }) => {
|
||||
return (
|
||||
<div className="not-prose">
|
||||
<pre className="bg-slate-900/50 rounded-md overflow-x-auto" {...props}>
|
||||
{children}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
code: props => {
|
||||
const { inline, className, children, ...restProps } = props as {
|
||||
inline?: boolean
|
||||
className?: string
|
||||
children: React.ReactNode
|
||||
[key: string]: unknown
|
||||
}
|
||||
const match = /language-(\w+)/.exec(className || "")
|
||||
const language = match ? match[1] : null
|
||||
|
||||
return !inline && language ? (
|
||||
<SyntaxHighlighter
|
||||
style={vscDarkPlus}
|
||||
language={language}
|
||||
PreTag="div"
|
||||
className="!bg-slate-900/50 !text-[10px] sm:!text-xs rounded-md"
|
||||
customStyle={{
|
||||
margin: 0,
|
||||
padding: "0.5rem",
|
||||
backgroundColor: "rgb(15 23 42 / 0.5)",
|
||||
fontSize: "0.625rem",
|
||||
lineHeight: "1.4",
|
||||
}}
|
||||
{...restProps}
|
||||
>
|
||||
{String(children).replace(/\n$/, "")}
|
||||
</SyntaxHighlighter>
|
||||
) : (
|
||||
<code
|
||||
className="bg-slate-700/50 px-1 py-0.5 rounded text-[10px] sm:text-xs text-cyan-300 font-mono"
|
||||
{...restProps}
|
||||
>
|
||||
{children}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
code: props => {
|
||||
const { inline, className, children, ...restProps } = props as {
|
||||
inline?: boolean
|
||||
className?: string
|
||||
children: React.ReactNode
|
||||
[key: string]: unknown
|
||||
}
|
||||
const match = /language-(\w+)/.exec(className || "")
|
||||
const language = match ? match[1] : null
|
||||
|
||||
return !inline && language ? (
|
||||
<SyntaxHighlighter
|
||||
style={vscDarkPlus}
|
||||
language={language}
|
||||
PreTag="div"
|
||||
className="!bg-slate-900/50 !text-[10px] sm:!text-xs rounded-md"
|
||||
customStyle={{
|
||||
margin: 0,
|
||||
padding: "0.5rem",
|
||||
backgroundColor: "rgb(15 23 42 / 0.5)",
|
||||
fontSize: "0.625rem",
|
||||
lineHeight: "1.4",
|
||||
}}
|
||||
{...restProps}
|
||||
>
|
||||
{String(children).replace(/\n$/, "")}
|
||||
</SyntaxHighlighter>
|
||||
) : (
|
||||
<code
|
||||
className="bg-slate-700/50 px-1 py-0.5 rounded text-[10px] sm:text-xs text-cyan-300 font-mono"
|
||||
{...restProps}
|
||||
>
|
||||
</code>
|
||||
)
|
||||
},
|
||||
p: ({ children }) => (
|
||||
<p className="text-xs sm:text-sm text-slate-300 mb-2 sm:mb-3">{children}</p>
|
||||
),
|
||||
h1: ({ children }) => (
|
||||
<h1 className="text-base sm:text-lg font-bold text-white mb-1.5 sm:mb-2">
|
||||
{children}
|
||||
</code>
|
||||
)
|
||||
},
|
||||
p: ({ children }) => (
|
||||
<p className="text-xs sm:text-sm text-slate-300 mb-2 sm:mb-3">{children}</p>
|
||||
),
|
||||
h1: ({ children }) => (
|
||||
<h1 className="text-base sm:text-lg font-bold text-white mb-1.5 sm:mb-2">
|
||||
{children}
|
||||
</h1>
|
||||
),
|
||||
h2: ({ children }) => (
|
||||
<h2 className="text-sm sm:text-base font-semibold text-white mb-1.5 sm:mb-2">
|
||||
{children}
|
||||
</h2>
|
||||
),
|
||||
h3: ({ children }) => (
|
||||
<h3 className="text-xs sm:text-sm font-semibold text-white mb-1">
|
||||
{children}
|
||||
</h3>
|
||||
),
|
||||
ul: ({ children }) => (
|
||||
<ul className="list-disc list-inside text-xs sm:text-sm text-slate-300 mb-2 sm:mb-3">
|
||||
{children}
|
||||
</ul>
|
||||
),
|
||||
ol: ({ children }) => (
|
||||
<ol className="list-decimal list-inside text-xs sm:text-sm text-slate-300 mb-2 sm:mb-3">
|
||||
{children}
|
||||
</ol>
|
||||
),
|
||||
li: ({ children }) => (
|
||||
<li className="text-xs sm:text-sm text-slate-300 mb-0.5 sm:mb-1">
|
||||
{children}
|
||||
</li>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{(() => {
|
||||
// Check if generatedTests already has markdown code blocks
|
||||
const testsContent = metadata.generatedTests.trim()
|
||||
const hasCodeBlocks = testsContent.includes("```")
|
||||
</h1>
|
||||
),
|
||||
h2: ({ children }) => (
|
||||
<h2 className="text-sm sm:text-base font-semibold text-white mb-1.5 sm:mb-2">
|
||||
{children}
|
||||
</h2>
|
||||
),
|
||||
h3: ({ children }) => (
|
||||
<h3 className="text-xs sm:text-sm font-semibold text-white mb-1">
|
||||
{children}
|
||||
</h3>
|
||||
),
|
||||
ul: ({ children }) => (
|
||||
<ul className="list-disc list-inside text-xs sm:text-sm text-slate-300 mb-2 sm:mb-3">
|
||||
{children}
|
||||
</ul>
|
||||
),
|
||||
ol: ({ children }) => (
|
||||
<ol className="list-decimal list-inside text-xs sm:text-sm text-slate-300 mb-2 sm:mb-3">
|
||||
{children}
|
||||
</ol>
|
||||
),
|
||||
li: ({ children }) => (
|
||||
<li className="text-xs sm:text-sm text-slate-300 mb-0.5 sm:mb-1">
|
||||
{children}
|
||||
</li>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{(() => {
|
||||
// Check if generatedTests already has markdown code blocks
|
||||
const testsContent = metadata.generatedTests.trim()
|
||||
const hasCodeBlocks = testsContent.includes("```")
|
||||
|
||||
// If it doesn't have code blocks, wrap it as Python code
|
||||
if (!hasCodeBlocks) {
|
||||
return "```python\n" + testsContent + "\n```"
|
||||
}
|
||||
// If it doesn't have code blocks, wrap it as Python code
|
||||
if (!hasCodeBlocks) {
|
||||
return "```python\n" + testsContent + "\n```"
|
||||
}
|
||||
|
||||
// Otherwise, return as-is
|
||||
return testsContent
|
||||
})()}
|
||||
</ReactMarkdown>
|
||||
// Otherwise, return as-is
|
||||
return testsContent
|
||||
})()}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
923
js/common/package-lock.json
generated
923
js/common/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@codeflash-ai/common",
|
||||
"version": "1.0.30",
|
||||
"version": "1.0.31",
|
||||
"main": "dist/src/index.js",
|
||||
"types": "dist/src/index.d.ts",
|
||||
"repository": {
|
||||
|
|
@ -15,25 +15,25 @@
|
|||
"format:check": "prettier --check \"**/*.{js,ts,json,md}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/identity": "^4.2.0",
|
||||
"@azure/keyvault-secrets": "^4.8.0",
|
||||
"@azure/msal-node": "^2.9.0",
|
||||
"@prisma/client": "^6.13.0",
|
||||
"stripe": "^18.2.0"
|
||||
"@azure/identity": "^4.13.1",
|
||||
"@azure/keyvault-secrets": "^4.11.1",
|
||||
"@azure/msal-node": "^2.16.3",
|
||||
"@prisma/client": "^6.19.3",
|
||||
"stripe": "^18.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.22.0",
|
||||
"@types/node": "^20.10.1",
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@types/node": "^20.19.39",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-react": "^7.37.4",
|
||||
"globals": "^16.0.0",
|
||||
"lint-staged": "^16.1.6",
|
||||
"prettier": "^3.3.0",
|
||||
"prisma": "^6.13.0",
|
||||
"globals": "^16.5.0",
|
||||
"lint-staged": "^16.4.0",
|
||||
"prettier": "^3.8.2",
|
||||
"prisma": "^6.19.3",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"typescript": "^5.0.0",
|
||||
"typescript-eslint": "^8.26.1"
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.58.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
|
|
|
|||
Loading…
Reference in a new issue