Skip to content

fix: support keyless openai-compatible endpoints - #5909

Draft
kalvinnchau wants to merge 12 commits into
mainfrom
am/openai-compat-config
Draft

fix: support keyless openai-compatible endpoints#5909
kalvinnchau wants to merge 12 commits into
mainfrom
am/openai-compat-config

Conversation

@kalvinnchau

Copy link
Copy Markdown
Contributor

Summary

  • make the OpenAI-compatible base URL a first-class required field across agent create, edit, defaults, and onboarding surfaces
  • preserve a distinct OpenAiCompat runtime provider with an explicit HTTP(S) endpoint and optional API key
  • omit bearer authentication from model discovery and inference when the compatible endpoint has no key
  • keep official OpenAI key-required and retain its default endpoint behavior

Validation

  • full desktop frontend suite: 4,957 tests passed
  • full desktop Tauri package: 2,433 tests passed; 15 keychain-only tests ignored
  • focused buzz-agent configuration and request-header regression tests passed
  • pre-commit formatting, lint, and file-size ratchets passed

Known unrelated failure

The full buzz-agent package still has one MCP cancellation regression that reproduces on current origin/main; the provider-specific runtime tests pass. This PR does not modify that cancellation path.

@kalvinnchau
kalvinnchau requested a review from a team as a code owner August 14, 2026 21:09
kalvinnchau

This comment was marked as resolved.

@kalvinnchau
kalvinnchau marked this pull request as draft August 14, 2026 22:33
@kalvinnchau
kalvinnchau force-pushed the am/openai-compat-config branch from 7d5509d to f2ea1b7 Compare August 15, 2026 20:03

@themiguelamador themiguelamador left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found four issues that need to be incorporated before this is ready:

  1. The edit dialog's new base-URL validity check ignores the persona env layer for an existing agent that already inherits its harness. Backend readiness accepts the inherited OPENAI_COMPAT_BASE_URL, but the dialog computes compatibleBaseUrlInherited from agent/global/file state only, so Save stays disabled. The fix recognizes persona inheritance while preserving an explicit local blank as a shadow.
  2. The persona provider transition still uses the presence of a managed API-key field as proof that discovery requires a key. Selecting openai-compat with no key therefore clears an existing custom model even though this PR makes that key optional. The fix consults the provider's actual required-env-key contract.
  3. Desktop readiness treats whitespace-only env values as present, while the runtime trims and rejects the compatible base URL. This reports an agent as ready even though it will fail at launch. The fix aligns Buzz Agent and Goose readiness/file checks with the runtime's blank-value semantics.
  4. crates/buzz-agent/README.md still tells vLLM/llama.cpp/Ollama users to select openai, omits openai-compat from the provider list, and documents a default compatible URL rather than the new required explicit endpoint. The fix updates examples, the configuration table, provider matrix, and authentication behavior.

Verified fix: Complear/buzz branch review/pr-5909-fix, commit 9eaf3ac545dff4d1d5b0c6614c43a01326e42380.

Validation: full Desktop frontend suite (4,960 tests), Desktop TypeScript/static/file-size checks, focused Tauri readiness test, full buzz-agent suite, strict buzz-agent clippy, and Rust formatting all pass.

@wpfleger96 wpfleger96 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 combined feedback from two independent review passes. Both passes independently confirmed all four issues in the existing review (the inherited-URL gate in the edit dialog, the model-clearing on switch to openai-compat, the untrimmed readiness checks, and the stale buzz-agent README) — treating that convergence as strong confirmation those are real, so not re-litigating them here. The inline comments below are the additional findings that aren't on the PR yet. Also worth noting the branch is currently conflicting with main and needs a rebase.

),
"openai" if present_nonempty(openai_key) => Ok(Provider::OpenAi),
"openai" => Err("config: OPENAI_COMPAT_API_KEY required".into()),
"openai-compat" => Ok(Provider::OpenAiCompat),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 I think this creates a silent break for existing records: on main, openai-compat resolves to Provider::OpenAi with the https://api.openai.com/v1 default, but after this change it hard-requires OPENAI_COMPAT_BASE_URL with no default. An agent saved today with provider=openai-compat + key and no base URL works, then flips to NotReady/startup-error after upgrade. There's precedent for boot migrations (the databricks v1→v2 rewrite) — either migrate openai-compat-without-URL records to openai, or call out the intentional break in the PR description.

parse_openai_api(env("OPENAI_COMPAT_API").as_deref())?,
),
Provider::OpenAiCompat => (
env("OPENAI_COMPAT_API_KEY")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 now that openai and openai-compat are distinct providers with distinct trust boundaries, they still share OPENAI_COMPAT_API_KEY. Global-defaults env merges into per-agent effective env, and the dialogs deliberately preserve credential env vars across provider switches — so a key configured for api.openai.com gets bearer-sent to whatever custom base URL a compat agent points at. It's pre-existing exposure, but this PR is the moment the providers split, so it feels like the right time to either give compat its own key var or scrub the inherited key unless it was set explicitly for the compat agent. If the shared var is intentional, a note on the accepted risk would do.

} else {
base_url.unwrap_or_else(|| "https://api.openai.com/v1".to_string())
};
validate_openai_compat_base_url(&base_url)?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 small asymmetry: this now runs validate_openai_compat_base_url on the official openai path too, but runtime Provider::OpenAi still reads the URL via plain env_or with no validation. So discovery rejects a query/fragment URL that inference would happily use. Probably fine to validate both, but as written discovery fails where the runtime works.

}

#[test]
fn optional_compat_key_allows_explicit_blank_to_shadow_process_env() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 nit: this test mutates process env with set_var without taking the env/path lock other tests in this crate use. The unique key name makes a collision unlikely, but it's inconsistent with the crate's own pattern for env-mutating tests.

am added 9 commits August 18, 2026 16:17
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Clear provider-owned endpoint state when leaving openai-compatible configurations and reject base URLs with ambiguous or secret-bearing components.

Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>

Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
@kalvinnchau
kalvinnchau force-pushed the am/openai-compat-config branch from bad9d97 to e2ef27d Compare August 18, 2026 23:33
am added 3 commits August 18, 2026 16:55
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Signed-off-by: am <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants