feat(harbor): add native Braintrust evaluation plugin - #631
Draft
Abhijeet Prasad (AbhiPrasad) wants to merge 5 commits into
Draft
feat(harbor): add native Braintrust evaluation plugin#631Abhijeet Prasad (AbhiPrasad) wants to merge 5 commits into
Abhijeet Prasad (AbhiPrasad) wants to merge 5 commits into
Conversation
Abhijeet Prasad (AbhiPrasad)
force-pushed
the
abhi-harbor-integration
branch
2 times, most recently
from
July 30, 2026 23:25
efe6f72 to
9807ac4
Compare
Abhijeet Prasad (AbhiPrasad)
force-pushed
the
abhi-harbor-integration
branch
from
July 30, 2026 23:30
9807ac4 to
6c07449
Compare
Register HarborPlugin through the harbor.plugins entry point. Users install harbor and braintrust, configure standard Braintrust credentials plus optional HARBOR_BRAINTRUST_* settings, and select it with `--plugin braintrust`. The public Python API also exposes HarborPlugin and backfill_job for explicit construction and offline synchronization. Sync resolved tasks into Braintrust datasets, partition experiments by semantic agent configuration, and reconcile each retained Harbor trial into an eval trace with lifecycle spans, rewards, classifications, ATIF LLM/tool detail, errors, usage, attachments, and provenance metadata. Deterministic identities and braintrust-sync.json make resume and backfill idempotent. Add the pinned Harbor 0.20 test session, pure contract coverage using real Harbor models, and a VCR-backed round trip through the real Braintrust SDK.
Abhijeet Prasad (AbhiPrasad)
force-pushed
the
abhi-harbor-integration
branch
from
August 4, 2026 22:31
98a5222 to
6bd9cfa
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves SDK-64.
Overview
Adds a native Braintrust plugin for Harbor 0.20. Harbor continues to own task execution, containers, concurrency, retries, and verification; the plugin reconciles Harbor's authoritative final results into Braintrust datasets, experiments, scores, and traces.
This is intentionally not an OTLP adapter and does not call
braintrust.Eval()—Harbor already owns the evaluation loop.The detailed design is in
docs/harbor-braintrust-plugin-design.md.Setup and usage
Harbor requires Python 3.12+. The plugin ships in the normal Braintrust distribution and is discovered through the
harbor.pluginsentry-point group—users do not need to import or register it manually.Run it by selecting the
braintrustplugin:Plugin options can be supplied as Harbor kwargs:
Every constructor option has an equivalent
HARBOR_BRAINTRUST_*environment fallback. Precedence is:Standard
BRAINTRUST_API_KEY,BRAINTRUST_ORG_NAME, andBRAINTRUST_APP_URLcontinue to configure the Braintrust connection.Common configuration
project_name/PROJECTorPROJECT_NAMEproject_id.dataset_mode/DATASET_MODEsync(default) ornone.trajectory_mode/TRAJECTORY_MODEatif(default),summary, ornative.content_mode/CONTENT_MODEmetadata,messages(default), orfull.attachments/ATTACHMENTSnone,verifier-details(default), orall.artifact_include/ARTIFACT_INCLUDEattachments=all.score_keys,metric_keysreward_rulesclassifier_rulesinvalid_score_policymetric(default),drop, orerror.stricttrueto raise where Harbor permits.max_content_bytes,max_attachment_bytes,max_total_attachment_bytesPublic Python API
The public surface is intentionally small and Harbor-specific:
HarborPluginHarbor normally constructs this class through entry-point discovery. It can also be instantiated directly by code embedding Harbor:
It implements Harbor's asynchronous
on_job_start(job)andon_job_end(job_result)protocol. Blocking Braintrust/filesystem work runs off Harbor's event loop.backfill_jobOffline backfill uses the same identity, normalization, partitioning, reward, ATIF, and persistence core as online sync:
Backfill reads Harbor's persisted config, lock, job result, trial results, trajectories, verifier details, and artifact manifests. It does not rerun trials.
What appears in Braintrust
Datasets and records
Dataset sync is enabled by default.
expectedremains null unless Harbor eventually provides a safe expected-output adapter; solution and verifier code are never treated as expected output.Experiments and eval rows
A Harbor job is partitioned by:
Concurrency, retry policy, and output paths do not split experiments. Agent/model/kwargs, MCP configuration, resume behavior, safe environment configuration, and skill digests do.
Each retained final
TrialResultbecomes one rootevalrow. Harbor execution retries do not create extra experiment rows. Intentionaln_attemptsremain separate rows.Root and canonical
taskspans share the same input, expected value, bounded output, or error. Output selection prefers standardized agent metadata, then the final non-copied ATIF agent message, per-step final messages, and finally a small status object.Rewards, metrics, and classifications
Harbor rewards remain authoritative and the complete raw reward dictionary is retained at
metadata.harbor.raw_rewards.Reward classification is semantic rather than range-only:
reward_rulesentry.score_keys/metric_keysglob.rewardis a score only when it is in[0, 1].invalid_score_policy.[0, 1].Normalized rewards create direct
scorechildren withpurpose="scorer"; scores are not duplicated on the eval root. Explicit classifier rules create directclassifierchildren and grouped root classifications. One malformed classifier records a local warning/error without dropping the trial's numeric rewards.Lifecycle and ATIF traces
Harbor's recorded timestamps shape the lifecycle tree:
ATIF detail is conformance-gated:
llmleaf must represent exactly one model call and have provider/model identity, canonical messages, token usage, and valid timing.tasksummaries rather than mislabeled.Metadata, errors, and attachments
Every root includes a collision-safe
metadata.harbornamespace with job/trial/task/agent/model identity, attempt/retry information, raw rewards, trajectory availability, custom metadata, reconciliation warnings, and artifact-manifest summaries.reward-details.jsonis bounded, normalized, redacted, and attached to scorer output by default.agent_execution.output.artifactswith per-file and total limits.Resume, retries, backfill, and failure isolation
Trial hooks feed reducer-based state machines, but authoritative rows are only dispatched from final
JobResult.trial_resultsreconciliation. This prevents failed retry candidates from inflating experiment counts.Deterministic dataset record IDs, experiment names, root IDs, and child span IDs make resume and backfill converge. Every job directory receives a credential-free
braintrust-sync.jsoncontaining project/job identity, dataset and experiment IDs, trial terminal state, retry counts, warnings/errors, synced trial IDs, and completion state.Default behavior isolates observability failures:
strict=Trueopts into raising unrecoverable failures where Harbor permits.Packaging and tests
braintrust.integrations.harbor:HarborPluginas thebraintrustentry inharbor.plugins.harbor==0.20.0nox matrix session that skips interpreters below Python 3.12.Trajectorythrough the real Braintrust SDK, uploads the emitted hierarchy, fetches it from Braintrust, and asserts persisted LLM/tool ordering, payloads, metrics, and span origin.Validation performed locally:
test_harbor(latest): 9 passedtest_core: 611 passed, 62 skipped, 12 xfailed