Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
144ef4d
feat(catalog): replace Databricks model-label tokenizer with models.d…
Jul 29, 2026
3855850
fix(catalog): address pass-1 review blockers on Databricks model-labe…
Jul 29, 2026
be7d66f
fix(catalog): route all model rows through the shared label resolver
Jul 30, 2026
485b362
chore: merge origin/main into databricks model-label registry
Jul 30, 2026
4d47f48
feat(agent): Phase 1 — model-capability manifest, generator, and test…
wpfleger96 Jul 31, 2026
847f2c5
Merge remote-tracking branch 'origin/main' into duncan/databricks-mod…
Jul 31, 2026
cc00060
feat(agent): Phase 2 — wire Rust and TS consumers to generated model-…
wpfleger96 Aug 3, 2026
b0b5718
chore: sync umbrella with origin/main (Cargo.lock + ci.yml updates)
wpfleger96 Aug 3, 2026
126647e
refactor(models): Phase 3 — retire old hand tables and shrink manifes…
wpfleger96 Aug 3, 2026
94ef5fe
docs(models): remove MODEL_CAPABILITIES.md reference doc
Aug 3, 2026
dd6e3a9
fix(models): address Kalvin-review: gpt-segment/left-boundary/luna-te…
Aug 4, 2026
aa962f1
Merge remote-tracking branch 'origin/main' into duncan/model-manifest…
Aug 4, 2026
bca1d5d
fix(models): close round-2 gaps: 6-axis Rust harness + gpt-neox honesty
Aug 4, 2026
b6162be
fix(models): round-3 corrective pass — boundary strip, gpt-version-se…
Aug 4, 2026
7862cd3
style(models): biome format buzzAgentConfig.test.mjs prototype-key re…
Aug 4, 2026
46f0d44
fix(models): type DEFAULT_FALLBACK to satisfy CapabilityResult (TS2322)
Aug 4, 2026
15aa135
fix(test): correct stale gpt5-4 family default comment (none → medium)
Aug 4, 2026
0c02ca7
feat(manifest): consolidate label authority — fold registry_labels in…
Aug 4, 2026
f24e30c
chore: merge origin/main — resolve catalog.rs conflict (auth semantic…
Aug 4, 2026
77c24ef
chore(manifest): remove dead registry_labels key
Aug 4, 2026
0e6aacf
fix(buzz-agent): curate display name in configured_model_fallback
Aug 4, 2026
1e9df55
fix(manifest): enforce registry_label exclusion on family rules; test…
Aug 5, 2026
817b887
test(file-size): fix fileOverrides integration test under GITHUB_ACTIONS
Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
web: ${{ steps.filter.outputs.web }}
mobile: ${{ steps.filter.outputs.mobile }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

Check warning

Code scanning / zizmor

detects commit SHAs that don't match their version comment tags Warning

detects commit SHAs that don't match their version comment tags
with:
fetch-depth: 2
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
Expand Down Expand Up @@ -130,6 +130,50 @@
- name: Unit tests
run: just test-unit

model-capabilities:
name: Model Capabilities (regen + corpus + schema + buzz-agent tests)
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
save-if: ${{ github.event_name != 'pull_request' }}

- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '24'
package-manager-cache: false

- name: Regenerate artifacts
run: node scripts/generate-model-capabilities.mjs

- name: Diff check — fail if generated files are stale
run: |
if ! git diff --exit-code \
crates/buzz-agent/src/generated_model_capabilities.rs \
desktop/src/features/agents/ui/modelCapabilities.ts; then
echo ""
echo "ERROR: Generated model-capability files are stale."
echo "Run: node scripts/generate-model-capabilities.mjs"
echo "Then commit the regenerated files."
exit 1
fi
echo "✓ All generated files are up to date."

- name: Run corpus (TS interpreter via --experimental-strip-types)
run: node --experimental-strip-types scripts/run-corpus.mjs

- name: Validate manifest (schema-negative tests)
run: node --test scripts/test-manifest-validator.mjs

- name: Run buzz-agent unit tests (normative corpus + generated interpreter)
run: cargo test -p buzz-agent --lib

desktop-core:
name: Desktop Core
runs-on: ubuntu-latest
Expand Down
88 changes: 81 additions & 7 deletions crates/buzz-agent/src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

use std::sync::Arc;

use crate::generated_model_capabilities::DATABRICKS_MODEL_NAMES;

use reqwest::Client;

use crate::{
Expand All @@ -23,8 +25,25 @@ use crate::{
types::AgentError,
};

/// Returns the curated display name for a Databricks endpoint ID, or the raw
/// ID when no entry exists in the registry.
///
/// The registry (`DATABRICKS_MODEL_NAMES`) is generated from the manifest
/// (`scripts/model-capabilities.json`) exact records for the `databricks_v2`
/// provider and covers the ~30 managed Databricks endpoints. Any custom or
/// workspace endpoint not in the table is returned untouched — no heuristic
/// guessing.
pub(crate) fn databricks_model_name(id: &str) -> &str {
DATABRICKS_MODEL_NAMES
.iter()
.find(|(k, _)| *k == id)
.map(|(_, v)| *v)
.unwrap_or(id)
}

/// A discovered model entry: `id` is the picker value, `name` is the display
/// label (same as `id` for Databricks — the API has no separate display name).
/// label (curated from models.dev for known managed endpoints; raw ID for
/// custom/unknown endpoints).
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ModelEntry {
pub id: String,
Expand All @@ -34,8 +53,10 @@ pub struct ModelEntry {
/// Known Databricks AI Gateway v2 models — used only when an authenticated
/// `api/ai-gateway/v2/endpoints` call succeeds with an empty list.
/// Mirrors goose's `DATABRICKS_V2_KNOWN_MODELS`.
pub const DATABRICKS_V2_KNOWN_MODELS: &[&str] =
&["databricks-gpt-5-5", "databricks-claude-opus-4-7"];
///
/// Phase 2 cutover: this is now a re-export of the generated constant in
/// `generated_model_capabilities`. Phase 3 removes the old hand-maintained list.
pub use crate::generated_model_capabilities::DATABRICKS_V2_KNOWN_MODELS;

const AUTHENTICATED_EMPTY_CATALOG_SUFFIX: &str = " (default catalog)";

Expand All @@ -44,7 +65,10 @@ fn authenticated_empty_v2_catalog() -> Vec<ModelEntry> {
.iter()
.map(|id| ModelEntry {
id: id.to_string(),
name: format!("{id}{AUTHENTICATED_EMPTY_CATALOG_SUFFIX}"),
name: format!(
"{}{AUTHENTICATED_EMPTY_CATALOG_SUFFIX}",
databricks_model_name(id)
),
})
.collect()
}
Expand Down Expand Up @@ -206,7 +230,7 @@ pub(crate) fn parse_v1_endpoints(json: &serde_json::Value) -> Result<Vec<ModelEn

Some(ModelEntry {
id: name.clone(),
name,
name: databricks_model_name(&name).to_string(),
})
})
.collect();
Expand Down Expand Up @@ -371,7 +395,7 @@ pub(crate) fn parse_v2_endpoints_page(
Some(V2Endpoint {
entry: ModelEntry {
id: name.clone(),
name,
name: databricks_model_name(&name).to_string(),
},
created_ms: endpoint_created_ms(endpoint),
})
Expand Down Expand Up @@ -649,8 +673,12 @@ mod tests {
let ids: Vec<&str> = models.iter().map(|model| model.id.as_str()).collect();

assert_eq!(ids, DATABRICKS_V2_KNOWN_MODELS);
// Each entry carries the curated display name (not the raw ID) plus the
// " (default catalog)" suffix to distinguish this authenticated-but-empty
// slate from a live discovery result.
assert!(models.iter().all(|model| {
model.name == format!("{}{AUTHENTICATED_EMPTY_CATALOG_SUFFIX}", model.id)
let curated = databricks_model_name(&model.id);
model.name == format!("{curated}{AUTHENTICATED_EMPTY_CATALOG_SUFFIX}")
}));
}

Expand All @@ -665,4 +693,50 @@ mod tests {
assert!(!is_chat_capable_endpoint("databricks-gte-large-en"));
assert!(!is_chat_capable_endpoint("databricks-qwen3-embedding-0-6b"));
}
// ---------------------------------------------------------------------------
// Databricks model name registry
// ---------------------------------------------------------------------------

#[test]
fn databricks_model_name_known_id_returns_curated_name() {
assert_eq!(databricks_model_name("databricks-gpt-5-5"), "GPT-5.5");
assert_eq!(
databricks_model_name("databricks-claude-opus-4-7"),
"Claude Opus 4.7"
);
assert_eq!(
databricks_model_name("databricks-gpt-oss-120b"),
"GPT OSS 120B"
);
}

#[test]
fn databricks_model_name_unknown_custom_endpoint_returns_raw_id() {
// Custom workspace endpoints must never be guessed — pass through unchanged.
assert_eq!(
databricks_model_name("databricks-team-2025-01"),
"databricks-team-2025-01"
);
assert_eq!(
databricks_model_name("databricks-finance-2025-01-30"),
"databricks-finance-2025-01-30"
);
assert_eq!(
databricks_model_name("some-unknown-endpoint"),
"some-unknown-endpoint"
);
}

#[test]
fn v2_known_models_fallback_entries_get_curated_names() {
// The DATABRICKS_V2_KNOWN_MODELS constant lists IDs that are in the
// registry, so their fallback entries must carry curated names.
for id in DATABRICKS_V2_KNOWN_MODELS {
let name = databricks_model_name(id);
assert_ne!(
name, *id,
"known model {id} should have a curated name, not raw ID"
);
}
}
}
Loading
Loading