feat(harbor): add native Harbor evaluation plugin - #631
Open
Abhijeet Prasad (AbhiPrasad) wants to merge 10 commits into
Open
feat(harbor): add native Harbor evaluation plugin#631Abhijeet Prasad (AbhiPrasad) wants to merge 10 commits into
Abhijeet Prasad (AbhiPrasad) wants to merge 10 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
Abhijeet Prasad (AbhiPrasad)
marked this pull request as ready for review
August 7, 2026 14:07
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.
Adds a native Braintrust plugin for Harbor.
Setup
Requires Python 3.12+ and a minimum Harbor version of
0.16.0. The plugin ships in the normalbraintrustdistribution and Harbor discovers it through theharbor.pluginsentry point, so there is nothing to import or register.pip install harbor braintrust export BRAINTRUST_API_KEY=...Enable it by selecting the
braintrustplugin:That is the whole setup. The API key stays in the host process and is never written into Harbor config, results, manifests, or the task container.
Configuration
Options are passed as Harbor kwargs, and every option also has a
HARBOR_BRAINTRUST_*environment fallback:Precedence is
--plugin-kwarg>HARBOR_BRAINTRUST_*> default. Complex values are JSON because Harbor only accepts flat kwargs.project_name/project_idHARBOR_BRAINTRUST_PROJECT.dataset_modesync(default),nonetrajectory_modeatif(default),summary,nativecontent_modemetadata,messages(default),fullfullcurrently captures the same asmessages.score_keys/metric_keysreward_rulesclassifier_rulesinvalid_score_policymetric(default),drop,errorattachmentsnone,verifier-details(default),allallalso enablesartifact_includeglobs.max_content_bytes,max_attachment_bytes,max_total_attachment_bytesstrictfalse)What lands in Braintrust
Datasets. One managed dataset per Harbor source. Each resolved task is one record with a deterministic UUIDv5 ID, so reruns and backfill upsert instead of duplicating. Input holds task-authored semantics (identity, instruction, step instructions);
expectedstays null rather than treating solution or verifier code as expected output.Experiments. Partitioned by
(dataset identity, semantic agent config, skill digests). Agent, model, kwargs, MCP config, and skills split experiments; concurrency, retry policy, and output paths do not. Each retained finalTrialResultis one root row — execution retries do not inflate counts, while intentionaln_attemptsstay separate rows.Rewards. Harbor rewards stay authoritative and the raw dict is preserved at
metadata.harbor.raw_rewards. Classification is semantic, not range-guessing: an exactreward_rulesentry, then ascore_keys/metric_keysglob, then conventionalrewardwhen it is in[0, 1]; every other numeric reward becomes a metric even if it happens to land in[0, 1]. A missing reward with no exception is flagged as unevaluated rather than scored zero.ATIF traces are conformance-gated. A step becomes an
llmspan only with exactly one model call plus provider/model identity, canonical messages, token usage, and valid timing; a tool span needs arguments plus a correlated result or error. Anything deterministic, aggregated, truncated, or incomplete is downgraded to atasksummary with a warning on the eval root instead of being mislabeled. Missing timestamps are interpolated inside the agent phase, outliers clamped, and every repair recorded. Subagents become nested task trees.Privacy. Secret-like keys, credentials, and oversized payloads are redacted or bounded, and absolute paths are stripped from host-side metadata. Paths inside trajectory content are kept, because they name container files the agent actually operated on — redacting them would empty out filesystem tool calls.
Backfill
Backfill reuses the same identity, normalization, partitioning, reward, and ATIF core as live sync, so it reconciles an existing experiment rather than creating a second one. It never reruns trials.
Every job directory also gets a credential-free
braintrust-sync.jsonwith the dataset and experiment IDs, per-trial terminal state, retry counts, warnings, and completion state.