feat(acp): introduce threads (#8344)

Signed-off-by: Bradley Axen <baxen@squareup.com>
This commit is contained in:
Bradley Axen
2026-04-08 22:14:28 -07:00
committed by GitHub
parent 331d1e2efb
commit 9d7de43eec
23 changed files with 2207 additions and 880 deletions
+44 -1
View File
@@ -3,7 +3,9 @@ mod name_builder;
mod registry;
pub use model::{CanonicalModel, Limit, Modalities, Modality, Pricing};
pub use name_builder::{canonical_name, map_to_canonical_model, strip_version_suffix};
pub use name_builder::{
canonical_name, map_provider_name, map_to_canonical_model, strip_version_suffix,
};
pub use registry::CanonicalModelRegistry;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -21,6 +23,47 @@ impl ModelMapping {
}
}
/// Return recommended model names for a provider using only the bundled canonical registry.
///
/// This avoids network calls by looking up all known models for the provider,
/// filtering to text-input + tool-calling models, and sorting by release date.
/// The returned names are the canonical short names (e.g. "claude-3.5-sonnet").
///
/// TODO: This trades speed for correctness — the canonical registry may not perfectly
/// match what the provider API returns (new models not yet in the registry, deprecated
/// models still listed, or locally-installed models for providers like Ollama). Consider
/// whether to reconcile with a live API call in the background.
pub fn recommended_models_from_registry(provider: &str) -> Vec<String> {
let registry = match CanonicalModelRegistry::bundled() {
Ok(r) => r,
Err(_) => return vec![],
};
let registry_provider = map_provider_name(provider);
let all = registry.get_all_models_for_provider(registry_provider);
let mut models_with_dates: Vec<(String, Option<String>)> = all
.iter()
.filter(|m| m.modalities.input.contains(&Modality::Text) && m.tool_call)
.filter_map(|m| {
let (_, name) = m.id.split_once('/')?;
Some((name.to_string(), m.release_date.clone()))
})
.collect();
models_with_dates.sort_by(|a, b| match (&a.1, &b.1) {
(Some(date_a), Some(date_b)) => date_b.cmp(date_a),
(Some(_), None) => std::cmp::Ordering::Less,
(None, Some(_)) => std::cmp::Ordering::Greater,
(None, None) => a.0.cmp(&b.0),
});
models_with_dates
.into_iter()
.map(|(name, _)| name)
.collect()
}
pub fn maybe_get_canonical_model(provider: &str, model: &str) -> Option<CanonicalModel> {
let registry = CanonicalModelRegistry::bundled().ok()?;
@@ -39,7 +39,7 @@ fn is_meta_provider(provider: &str) -> bool {
matches!(provider, "databricks" | "tetrate" | "bedrock" | "azure")
}
fn map_provider_name(provider: &str) -> &str {
pub fn map_provider_name(provider: &str) -> &str {
match provider {
// Goose provider names that differ from models.dev names
"xai" => "x-ai",