| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- /**
- * Entry point for `braintrust push` to deploy scorers to Braintrust.
- *
- * Excluded scorers:
- * - sqlSyntaxScorer, sqlIdentifierQuotingScorer: use libpg-query (WASM),
- * which esbuild cannot bundle for Braintrust's remote infra.
- * - toolUsageScorer: requires expected.requiredTools, offline-eval-only.
- * - correctnessScorer: requires ground truth (expected output), offline-eval-only.
- */
- import braintrust, { type EvalScorer } from 'braintrust'
- import {
- completenessScorer,
- concisenessScorer,
- docsFaithfulnessScorer,
- goalCompletionScorer,
- safetyScorer,
- urlValidityScorer,
- type AssistantEvalInput,
- type AssistantEvalOutput,
- type Expected,
- } from './scorer'
- import manifest from './scorer-online-manifest.json'
- const projectId = process.env.BRAINTRUST_PROJECT_ID
- if (!projectId && process.env.IS_BRAINTRUST_PUSH)
- throw new Error('BRAINTRUST_PROJECT_ID is not set')
- // When running in CI, prefix scorers with the branch name to avoid collisions between PRs
- // in the staging project. GITHUB_HEAD_REF is only set on PR events, not push events (e.g. master).
- const branch = process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF_NAME
- const prNumber = process.env.GITHUB_PR_NUMBER ? Number(process.env.GITHUB_PR_NUMBER) : undefined
- const prefix = process.env.GITHUB_HEAD_REF
- ? `${process.env.GITHUB_HEAD_REF.replace(/[^a-z0-9-]/gi, '-').toLowerCase()}-`
- : ''
- const metadata = branch ? { gitBranch: branch, ...(prNumber && { prNumber }) } : undefined
- const description = prNumber && branch ? `#${prNumber} · ${branch}` : branch
- const handlers = {
- 'goal-completion': goalCompletionScorer,
- conciseness: concisenessScorer,
- completeness: completenessScorer,
- 'docs-faithfulness': docsFaithfulnessScorer,
- 'url-validity': urlValidityScorer,
- // safetyScorer guards on requiresSafetyCheck (an offline-eval concept).
- // Online traces have no expected, so we wrap it to always run.
- safety: (args) =>
- safetyScorer({ ...args, expected: { ...args.expected, requiresSafetyCheck: true } }),
- } satisfies Record<string, EvalScorer<AssistantEvalInput, AssistantEvalOutput, Expected>>
- // @ts-expect-error - Project ID is only required at build-time
- const project = braintrust.projects.create({ id: projectId })
- for (const { slug, name } of manifest) {
- project.scorers.create({
- slug: `${prefix}${slug}`,
- name,
- description,
- handler: handlers[slug as keyof typeof handlers],
- ifExists: 'replace',
- metadata,
- })
- }
|