fix: VMware Tanzu Platform provider - bug fixes, streaming, UI improvements#8126
fix: VMware Tanzu Platform provider - bug fixes, streaming, UI improvements#8126DOsinga merged 4 commits intoblock:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fba205de08
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| .get_param::<String>(&var.name) | ||
| .ok() | ||
| .or_else(|| var.default.clone()); |
There was a problem hiding this comment.
Parse streaming override as bool
resolve_config reads *_STREAMING with get_param::<String>(), but config/env parsing can return native booleans for values like TANZU_AI_STREAMING=false. In that case deserialization to String fails, .ok() drops the override, and the code falls back to the default ("true" in tanzu.json), so users cannot disable streaming via normal environment variable syntax.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch. Fixed — resolve_config now tries get_param:: first, then falls back to get_param::, so both YAML string "true" and native bool true are handled correctly.
| } | ||
|
|
||
| function getBooleanValue(parameter: ConfigKey): boolean { | ||
| const val = getRenderValue(parameter).toLowerCase(); |
There was a problem hiding this comment.
Normalize boolean config before calling toLowerCase
The form assumes getRenderValue() always returns a string, but read() can yield booleans (for example when config/env contains unquoted true/false). When that happens, getRenderValue(parameter) can be a boolean and toLowerCase() throws at runtime, breaking provider configuration UI for those users.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch. Fixed — getBooleanValue now wraps the value with String() before calling toLowerCase(), handling both string and native boolean returns from config.
fba205d to
fd2973f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fd2973fdb2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
crates/goose/src/providers/openai.rs
Outdated
| Some(global_config.get_secret::<String>(&config.api_key_env).map_err(|_| { | ||
| anyhow::anyhow!( | ||
| "Required API key {} is not set. Configure it via `goose configure` or set the {} environment variable.", |
There was a problem hiding this comment.
Preserve secret-read errors when loading API key
This map_err(|_| ...) rewrites every get_secret failure into "API key is not set", including non-NotFound cases like keyring access failures or deserialization errors. In those cases users get a misleading remediation path and lose the real root cause, which makes provider setup/debugging much harder. Please only translate NotFound into this friendly message and propagate other error variants unchanged.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good point. Fixed — map_err now matches on ConfigError::NotFound to give the friendly "not set" message, and propagates all other error variants (keyring failures, deserialization errors, etc.) with their original context.
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Host "Make failed! Trying with squirrel only..." -ForegroundColor Yellow | ||
| npx electron-forge make --targets=@electron-forge/maker-squirrel | ||
| } |
There was a problem hiding this comment.
Exit script when fallback installer build fails
When electron-forge make fails, the fallback make --targets=@electron-forge/maker-squirrel is executed but its exit code is never checked. If that fallback also fails (e.g., missing maker dependency), the script still continues to "Build Complete" and exits successfully, which can silently produce no installer in automation or manual release workflows.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch. Fixed — the fallback build now checks LASTEXITCODE and exits with error if it also fails.
fd2973f to
f97a328
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f97a328da2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (val === '' && parameter.default) { | ||
| return parameter.default.toLowerCase() === 'true'; |
There was a problem hiding this comment.
Preserve false values for boolean provider toggles
Boolean config values read as native false get collapsed to an empty render value and then this fallback path applies the default, so a stored false (for example TANZU_AI_STREAMING=false from config/env) is shown as checked and can be written back as true on submit. This makes the new streaming toggle unreliable for users who explicitly disabled it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Good catch — native bool false was indeed falsy and got collapsed to empty string. Fixed by using explicit String() conversion on serverValue instead of the || operator.
| pnpm run generate-api | ||
| Write-Host " API types generated." -ForegroundColor Green |
There was a problem hiding this comment.
Fail fast when API type generation exits non-zero
The script does not check $LASTEXITCODE after pnpm run generate-api, so a generator failure is treated as success and the build continues into packaging/installer steps with stale or missing generated API types. This can silently produce broken release artifacts in CI or manual release runs.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed — added LASTEXITCODE check after generate-api step.
…ements - Fix lazy env var expansion (resolve at instantiation, not registration) - Fix API key error handling (explicit error instead of silent 401) - Fix input backspace bug (controlled component for all fields) - Rename to "VMware Tanzu Platform" with updated description - Enable streaming with user-toggleable checkbox - Add VMware Tanzu logo to provider UI - Add primary field to EnvVarConfig for UI visibility - Add boolean parameter rendering as checkboxes in provider form - Regenerate OpenAPI schema for EnvVarConfig.primary field - Add CLI testing guide and user documentation - Add Windows build script Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> Signed-off-by: Nick Kuhn <[email protected]>
f97a328 to
2fa76f7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2fa76f7cd4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| --- | ||
| sidebar_position: 15 | ||
| title: VMware Tanzu Platform | ||
| description: Connect Goose to VMware Tanzu Platform AI Services |
There was a problem hiding this comment.
Use lowercase goose in docs copy
documentation/AGENTS.md requires the product name to always be written as lowercase goose within the documentation tree, but this new guide introduces Goose in user-facing text (and repeats it in multiple places), which violates the documented style contract for this directory and should be normalized before merge.
Useful? React with 👍 / 👎.
| if (val === '' && parameter.default) { | ||
| return parameter.default.toLowerCase() === 'true'; |
There was a problem hiding this comment.
Preserve explicit false for boolean provider toggles
This default branch makes an empty render value fall back to the parameter default, so users with an explicit false value can be shown true and have that written back on submit. Fresh evidence: loadConfigValues still gates assignment with if (configValue), so when /config/read returns JSON false (for example TANZU_AI_STREAMING: false), the stored value is dropped before the new boolean rendering path runs, and this fallback re-enables the toggle.
Useful? React with 👍 / 👎.
- loadConfigValues: preserve explicit false from server (if (configValue) dropped native boolean false, causing stored TANZU_AI_STREAMING=false to be replaced by the default true on next load) - docs: lowercase goose per documentation/AGENTS.md brand guidelines - remove binary .docx file (does not belong in source repo) Signed-off-by: Douwe Osinga <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d6aa6b75d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| ## Prerequisites | ||
|
|
||
| - Goose CLI built from the `feat/tanzu-ai-provider` branch |
There was a problem hiding this comment.
Use lowercase goose in docs per style guide
documentation/AGENTS.md requires the product name to be written as lowercase goose throughout the documentation tree, but this new guide uses Goose in user-facing copy (for example, in the prerequisites line here, and again later in the file). This violates the documented docs standard and should be normalized before merge.
Useful? React with 👍 / 👎.
Signed-off-by: Douwe Osinga <[email protected]>
* main: (337 commits) fix: replace panics with user-friendly errors in CLI session builder (#7901) fix: read GOOSE_CONTEXT_LIMIT from config.yaml, not just env vars (#7900) fix: deliver truncation notice as separate content block (#7899) fix: use platform-appropriate commands in developer extension instructions (#7898) fix: replace any with proper SVG types in icon components (#7873) chore: remove debug console.log statements, stale comments, and dead code (#8142) feat: Gemini OAuth provider (#8129) chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /documentation (#8123) feat: show installed skills in UI (#7910) fix(deps): gate keyring platform features behind target-specific deps (#8039) chore(deps): bump yaml from 2.8.2 to 2.8.3 in /evals/open-model-gym/suite (#8124) fix: strip message wrapper in CLI session title generation (#7996) fix(providers): fall back to configured models when models endpoint fetch fails (#7530) chore(deps): bump brace-expansion from 5.0.3 to 5.0.5 in /evals/open-model-gym/suite (#8139) fix: prevent Ollama provider from hanging on tool-calling requests (#7723) fix: VMware Tanzu Platform provider - bug fixes, streaming, UI improvements (#8126) feat: allow GOOSE_CLI_SHOW_THINKING to be set in config.yaml (#8097) fix: GitHub Copilot auth fails to open browser in Desktop app (#6957) (#8019) fix(ci): produce .tar.gz archives for Zed ACP registry compatibility (#8054) feat: add GOOSE_SHOW_FULL_OUTPUT config to disable tool output truncation (#7919) ... # Conflicts: # crates/goose/src/providers/formats/openai.rs
…ements (block#8126) Signed-off-by: Nick Kuhn <[email protected]> Signed-off-by: Douwe Osinga <[email protected]> Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Douwe Osinga <[email protected]> Signed-off-by: Cameron Yick <[email protected]>
* main: (337 commits) fix: replace panics with user-friendly errors in CLI session builder (#7901) fix: read GOOSE_CONTEXT_LIMIT from config.yaml, not just env vars (#7900) fix: deliver truncation notice as separate content block (#7899) fix: use platform-appropriate commands in developer extension instructions (#7898) fix: replace any with proper SVG types in icon components (#7873) chore: remove debug console.log statements, stale comments, and dead code (#8142) feat: Gemini OAuth provider (#8129) chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /documentation (#8123) feat: show installed skills in UI (#7910) fix(deps): gate keyring platform features behind target-specific deps (#8039) chore(deps): bump yaml from 2.8.2 to 2.8.3 in /evals/open-model-gym/suite (#8124) fix: strip message wrapper in CLI session title generation (#7996) fix(providers): fall back to configured models when models endpoint fetch fails (#7530) chore(deps): bump brace-expansion from 5.0.3 to 5.0.5 in /evals/open-model-gym/suite (#8139) fix: prevent Ollama provider from hanging on tool-calling requests (#7723) fix: VMware Tanzu Platform provider - bug fixes, streaming, UI improvements (#8126) feat: allow GOOSE_CLI_SHOW_THINKING to be set in config.yaml (#8097) fix: GitHub Copilot auth fails to open browser in Desktop app (#6957) (#8019) fix(ci): produce .tar.gz archives for Zed ACP registry compatibility (#8054) feat: add GOOSE_SHOW_FULL_OUTPUT config to disable tool output truncation (#7919) ... # Conflicts: # crates/goose/src/providers/formats/openai.rs
Summary
This PR fixes several bugs and adds improvements to the VMware Tanzu Platform (formerly "Tanzu AI Services") provider that was merged in v1.28.0. We apologize for not catching these issues in the initial PR — they surfaced during hands-on validation across macOS, Linux (Ubuntu 22.04), and Windows 11 with both single-model and multi-model Tanzu AI Services plans.
Bug Fixes
Env var expansion at wrong time —
${TANZU_AI_ENDPOINT}was expanded at provider registration (startup), before the user configured the provider via the UI. The expansion silently failed, leaving the raw placeholder in the base URL, causingInvalid base URL '${TANZU_AI_ENDPOINT}/openai/v1/chat/completions': relative URL without a base. Fixed by moving expansion into a lazy closure that runs at provider instantiation time.Missing API key silently ignored —
OpenAiProvider::from_custom_config()used.ok()on the secret lookup, falling back toNoAuth. Users got cryptic 401 errors instead of a clear message. Now returns:"Required API key TANZU_AI_API_KEY is not set. Configure it via goose configure or set the TANZU_AI_API_KEY environment variable."Required TANZU_AI_ENDPOINT hidden in UI — All
env_varsconfig keys were hardcoded toprimary=false, hiding required fields in a collapsed "Show options" section. Addedprimaryfield toEnvVarConfigstruct, defaulting to the value ofrequiredwhen unset.Input backspace bug —
getRenderValue()returnedundefinedfor secret fields and fell back toserverValuefor non-secret fields when the user cleared the input (empty string is falsy in JS). This caused the input to snap back to the stored URL and broke backspace on Linux. Fixed by checkingentry?.value !== undefinedinstead of truthy check.Improvements
supports_streaming: true) with a user-toggleableTANZU_AI_STREAMINGconfig parameterenv_varwith a"true"/"false"default now renders as a checkbox toggle instead of a text input (generic improvement, benefits all declarative providers)Files Changed
declarative_providers.rsprimaryfield onEnvVarConfig,resolve_config()with streaming override, updated teststanzu.jsonTANZU_AI_STREAMINGenv var withprimary: trueopenai.rs.ok()provider_registry.rsprimarydefaults torequiredfor env_var config keysinit.rsDefaultProviderSetupForm.tsxProviderLogo.tsxtanzu_ailogo mappingtanzu*.pngproviders.mdtanzu-ai-services.mdtanzu-cli-testing-guide.mdbuild-windows.ps1Test Plan
Extensive manual testing was performed across all three platforms with real VMware Tanzu Platform environments:
Environments Tested
Tanzu Plans Tested
tanzu-Qwen3-Coder-30B-A3B-vllm-v1) — Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8tanzu-all-models) — 4 models including Qwen3-Coder, gpt-oss-120b, gpt-oss-20b, nomic-embedFunctional Tests
/openai/v1/models)goose sessionwith env vars (TANZU_AI_ENDPOINT,TANZU_AI_API_KEY)CF CLI Validation (end-to-end)
cf marketplace -e genai— lists planscf create-service genai <plan> <name> --wait— creates instancecf create-service-key <instance> <key> --wait— creates credentialscf service-key <instance> <key>— retrieves credentialscf delete-service-keyandcf delete-serviceAutomated Tests
test_tanzu_json_deserializes— JSON config parsingtest_tanzu_declarative_provider_registry_wiring— provider registrationtest_expand_env_vars_*— all 6 env var expansion teststest_existing_json_files_still_deserialize_without_new_fields— backwards compatibilitytest_openai_compatible_providers_config_keys— config key wiringcargo check— clean🤖 Generated with Claude Code