Skip to content

fix(api): provider endpoint mismatches preventing copilot save#511

Open
ibhagwan wants to merge 1 commit intospacedriveapp:mainfrom
ibhagwan:fix/copilot-provider-endpoints
Open

fix(api): provider endpoint mismatches preventing copilot save#511
ibhagwan wants to merge 1 commit intospacedriveapp:mainfrom
ibhagwan:fix/copilot-provider-endpoints

Conversation

@ibhagwan
Copy link
Copy Markdown
Contributor

Fix #415

And remove three endpoint mismatches between frontend and backend caused the GitHub Copilot provider's save, test, and remove buttons to fail with 405 Method Not Allowed. These affected all providers for save.

  • change update_provider annotation from post to put to match frontend
  • fix test button URL from /providers/test to /providers/test-model
  • add github-copilot entry in build_test_llm_config since default_provider_config returns None for providers that require token exchange
  • widen GITHUB_COPILOT_DEFAULT_BASE_URL visibility to pub(crate)
  • add unit test for build_test_llm_config with github-copilot

fix(api): Copilot provider shows as available after remove when env var is set

get_providers fell back to the GITHUB_COPILOT_API_KEY env var when the TOML key was absent, so the provider stayed visible in settings after a remove — the env var can't be unset from a running process.

Only check the TOML key for Copilot status in the config-exists path. The env var fallback remains for the no-config-file case (fresh install).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Ensure GitHub Copilot is auto-registered in test LLM configs when missing; add pre-removal checks that detect provider keys in TOML, secrets, or environment and prevent TOML deletion if an env var is active; expose Copilot base URL and helper at crate scope and add a unit test validating registration.

Changes

Cohort / File(s) Summary
Provider logic & tests
src/api/providers.rs
In build_test_llm_config insert a github-copilot ProviderConfig via copilot_default_provider_config when no default exists; in delete_provider parse config.toml early to check llm.<key> (resolving secret: and env:) and check corresponding *_API_KEY or Ollama env vars — if an env var is set, return success: false with guidance instead of deleting TOML; add build_test_llm_config_registers_github_copilot_provider test.
Config visibility & helpers
src/config/providers.rs, src/config.rs
Changed GITHUB_COPILOT_DEFAULT_BASE_URL visibility to pub(crate) and added pub fn copilot_default_provider_config(...) in providers.rs; re-exported GITHUB_COPILOT_DEFAULT_BASE_URL and copilot_default_provider_config as pub(crate) from src/config.rs; updated test comment to exclude github_copilot_key shorthand from shorthand-provider registration checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • jamiepine
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly addresses a primary issue in the PR: fixing provider endpoint mismatches preventing Copilot operations.
Description check ✅ Passed The description is fully related to the changeset, explaining multiple fixes: endpoint mismatches, github-copilot entry addition, and env var fallback behavior.
Linked Issues check ✅ Passed The PR addresses all coding requirements from #415: recognizing github-copilot as a valid provider, adding test support, fixing endpoint mismatches, and preventing env var masking of removal.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing Copilot provider functionality and endpoint mismatches specified in linked issue #415.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vsumner
Copy link
Copy Markdown
Collaborator

vsumner commented Mar 29, 2026

Review Summary

P2 Suggestion (non-blocking)

The Copilot special case in build_test_llm_config duplicates provider construction logic. Consider extracting a shared helper or documenting why default_provider_config can't handle this pattern.

P3 Architecture Note

The sandbox refactoring (deleting detection.rs and 4 test files) appears unrelated to the Copilot endpoint fixes. If this is intentional cleanup, it should ideally be a separate PR for cleaner history.

@ibhagwan
Copy link
Copy Markdown
Contributor Author

P3 Architecture Note
The sandbox refactoring (deleting detection.rs and 4 test files) appears unrelated to the Copilot endpoint fixes. If this is intentional cleanup, it should ideally be a separate PR for cleaner history.

This PR does not modify detection.rs at all, probably a local leftover during the review?

@ibhagwan ibhagwan force-pushed the fix/copilot-provider-endpoints branch 2 times, most recently from 0904a72 to 80a69de Compare April 2, 2026 11:33
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/api/providers.rs`:
- Around line 497-503: The tuple elements for the LLM provider flags are passed
in the wrong order—swap the values so they match the declaration order
(github_copilot then azure) instead of passing azure first and
copilot_configured second; update the tuple construction that currently chains
doc.get("llm")... .is_some_and(|url| !url.trim().is_empty()), copilot_configured
to use github_copilot, azure (or the matching variable names you declared) so
github_copilot aligns with its declared variable and azure aligns with its
declared variable.
- Around line 210-224: The ProviderConfig literal for "github-copilot" is
missing required fields api_version and deployment; update the struct literal in
the providers.insert block to include those fields (matching how other
ProviderConfig instances are created) — e.g. add api_version: None and
deployment: None (or the empty/default values used elsewhere in the codebase) so
the ProviderConfig for GitHub Copilot compiles alongside the existing fields
(api_type, base_url, api_key, name, use_bearer_auth, extra_headers).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bc77f7ac-8040-4688-9697-eb7bd4e271f8

📥 Commits

Reviewing files that changed from the base of the PR and between 0904a72 and 80a69de.

📒 Files selected for processing (3)
  • src/api/providers.rs
  • src/config.rs
  • src/config/providers.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/config.rs

@ibhagwan ibhagwan force-pushed the fix/copilot-provider-endpoints branch 3 times, most recently from 6359cee to a4d7f6c Compare April 2, 2026 11:52
@ibhagwan
Copy link
Copy Markdown
Contributor Author

ibhagwan commented Apr 2, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/api/providers.rs (1)

847-856: ⚠️ Potential issue | 🔴 Critical

Backend/frontend HTTP method mismatch will cause save to fail with 405 Method Not Allowed.

The backend annotation now expects PUT, but the frontend updateProvider function (interface/src/api/client.ts:1596-1606) still uses method: "POST":

updateProvider: async (...) => {
    const response = await fetch(`${getApiBase()}/providers`, {
        method: "POST",  // ← Frontend uses POST
        ...
    });
}

This mismatch will break the provider update functionality. Either update the frontend to use PUT in this PR or revert the backend to POST to maintain consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/providers.rs` around lines 847 - 856, The route annotation for
Provider updates in the backend (the #[utoipa::path(... put ...)] on the
providers endpoint) expects HTTP PUT, but the frontend function updateProvider
in interface/src/api/client.ts still sends method: "POST", causing 405 errors;
fix by making the client use PUT to match the backend (or alternatively change
the backend annotation back to POST), i.e., update the request method in
updateProvider to "PUT" so it aligns with the utoipa #[put] path for the
/providers endpoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/api/providers.rs`:
- Around line 847-856: The route annotation for Provider updates in the backend
(the #[utoipa::path(... put ...)] on the providers endpoint) expects HTTP PUT,
but the frontend function updateProvider in interface/src/api/client.ts still
sends method: "POST", causing 405 errors; fix by making the client use PUT to
match the backend (or alternatively change the backend annotation back to POST),
i.e., update the request method in updateProvider to "PUT" so it aligns with the
utoipa #[put] path for the /providers endpoint.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: de4633a5-6c01-49e6-855e-3d5f06ae9d1d

📥 Commits

Reviewing files that changed from the base of the PR and between 5c85557 and a4d7f6c.

📒 Files selected for processing (3)
  • src/api/providers.rs
  • src/config.rs
  • src/config/providers.rs

@ibhagwan ibhagwan force-pushed the fix/copilot-provider-endpoints branch from a4d7f6c to 9c40bf2 Compare April 2, 2026 12:32
@ibhagwan
Copy link
Copy Markdown
Contributor Author

ibhagwan commented Apr 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ibhagwan
Copy link
Copy Markdown
Contributor Author

ibhagwan commented Apr 2, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/api/providers.rs (1)

210-226: Consider centralizing Copilot provider bootstrap config.

This literal can drift from other Copilot config construction paths. A small shared helper for the common fields (api_type, name, auth mode, default base URL) would reduce divergence risk over time.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/providers.rs` around lines 210 - 226, The GitHub Copilot provider
construction in the providers.rs branch (provider == "github-copilot")
duplicates common fields and may drift; extract a shared helper (e.g., a
function named make_copilot_provider_config or an associated constructor like
ProviderConfig::copilot_default) that returns a ProviderConfig populated with
the common values (api_type = ApiType::OpenAiChatCompletions, base_url =
GITHUB_COPILOT_DEFAULT_BASE_URL, name = "GitHub Copilot", use_bearer_auth =
true, and other defaults), then replace the inline ProviderConfig creation here
to call that helper and only override instance-specific fields such as api_key
(set to credential) and any api_version/deployment if needed; ensure
LlmManager::get_copilot_token usage remains compatible with the new helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/api/providers.rs`:
- Around line 1624-1637: The current env-var removal check only looks for a
single env_var computed as env_var = format!("{}_API_KEY",
provider.to_uppercase().replace("-", "_")) and sets env_configured accordingly;
for the "ollama" provider you must also consider OLLAMA_BASE_URL, otherwise the
handler can report removal while Ollama remains configured. Update the logic
around env_var and env_configured (and the early return that constructs
ProviderUpdateResponse) to check a list of environment variables: always check
the computed "<PROVIDER>_API_KEY", and if provider == "ollama" also check
"OLLAMA_BASE_URL"; set env_configured to true if any of these are
present/non-empty, and update the response message to mention all relevant env
var names when returning early.

---

Nitpick comments:
In `@src/api/providers.rs`:
- Around line 210-226: The GitHub Copilot provider construction in the
providers.rs branch (provider == "github-copilot") duplicates common fields and
may drift; extract a shared helper (e.g., a function named
make_copilot_provider_config or an associated constructor like
ProviderConfig::copilot_default) that returns a ProviderConfig populated with
the common values (api_type = ApiType::OpenAiChatCompletions, base_url =
GITHUB_COPILOT_DEFAULT_BASE_URL, name = "GitHub Copilot", use_bearer_auth =
true, and other defaults), then replace the inline ProviderConfig creation here
to call that helper and only override instance-specific fields such as api_key
(set to credential) and any api_version/deployment if needed; ensure
LlmManager::get_copilot_token usage remains compatible with the new helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9ec80f32-dc5d-4249-8619-22972a087b2e

📥 Commits

Reviewing files that changed from the base of the PR and between 5c85557 and ee7d255.

📒 Files selected for processing (3)
  • src/api/providers.rs
  • src/config.rs
  • src/config/providers.rs

@ibhagwan ibhagwan force-pushed the fix/copilot-provider-endpoints branch 8 times, most recently from e8a76df to a3ef45d Compare April 8, 2026 15:20
@ibhagwan ibhagwan force-pushed the fix/copilot-provider-endpoints branch from a3ef45d to 0a9730f Compare April 12, 2026 21:15
@ibhagwan
Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 12, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/api/providers.rs (2)

1525-1537: ⚠️ Potential issue | 🟠 Major

Delay Copilot token cleanup until removal is actually allowed.

This clears the cached token and in-memory token before the later TOML/env checks can reject the delete. On env-backed or no-config-file setups, the endpoint returns success: false after already mutating provider state. Move the Copilot cleanup onto the successful removal path.

Also applies to: 1589-1659

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/providers.rs` around lines 1525 - 1537, The Copilot token removal
(both the filesystem removal using
crate::github_copilot_auth::credentials_path(...) and the in-memory clear via
llm_manager.clear_copilot_token()) is happening before the provider delete is
validated; move both cleanup actions so they only run after the code path that
confirms the provider was successfully removed (i.e., after the successful
TOML/env checks and the branch that returns success). Update the handler logic
to defer calling tokio::fs::remove_file(&token_path).await and
manager.clear_copilot_token().await until inside the post-success block, and
apply the same change to the other similar block around the second occurrence
(the code region referenced by lines 1589-1659). Ensure you reference and modify
the token_path creation and manager.clear_copilot_token() calls together so no
state is mutated on failed deletes.

1589-1659: ⚠️ Potential issue | 🟠 Major

The env-backed removal fix still misses the cases from #415.

This new guard only runs after a config file has been found, so fresh installs configured purely via env vars still short-circuit with "No config file found". And even when it does run, get_providers() still falls back to GITHUB_COPILOT_API_KEY when config.toml exists, so Copilot remains visible after deleting the TOML key. You'll need to handle the no-config-file path here and special-case Copilot in the config-exists branch of get_providers().

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/api/providers.rs` around lines 1589 - 1659, The removal flow currently
returns "No config file found" before checking env-backed providers and
get_providers() still falls back to GITHUB_COPILOT_API_KEY when a config exists
but the Copilot TOML key was removed; move or duplicate the env-var detection
logic so that when config_path doesn't exist you still compute env_vars (using
the same provider.as_str() branch) and check std::env::var to return the
environment-variable warning instead of "No config file found", and separately
update get_providers() to special-case Copilot so it does not unconditionally
fall back to GITHUB_COPILOT_API_KEY when a config.toml exists but the Copilot
key was removed (ensure the TOML key presence check used in has_toml_key and the
secrets_store logic remains authoritative for Copilot visibility).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/api/providers.rs`:
- Around line 1525-1537: The Copilot token removal (both the filesystem removal
using crate::github_copilot_auth::credentials_path(...) and the in-memory clear
via llm_manager.clear_copilot_token()) is happening before the provider delete
is validated; move both cleanup actions so they only run after the code path
that confirms the provider was successfully removed (i.e., after the successful
TOML/env checks and the branch that returns success). Update the handler logic
to defer calling tokio::fs::remove_file(&token_path).await and
manager.clear_copilot_token().await until inside the post-success block, and
apply the same change to the other similar block around the second occurrence
(the code region referenced by lines 1589-1659). Ensure you reference and modify
the token_path creation and manager.clear_copilot_token() calls together so no
state is mutated on failed deletes.
- Around line 1589-1659: The removal flow currently returns "No config file
found" before checking env-backed providers and get_providers() still falls back
to GITHUB_COPILOT_API_KEY when a config exists but the Copilot TOML key was
removed; move or duplicate the env-var detection logic so that when config_path
doesn't exist you still compute env_vars (using the same provider.as_str()
branch) and check std::env::var to return the environment-variable warning
instead of "No config file found", and separately update get_providers() to
special-case Copilot so it does not unconditionally fall back to
GITHUB_COPILOT_API_KEY when a config.toml exists but the Copilot key was removed
(ensure the TOML key presence check used in has_toml_key and the secrets_store
logic remains authoritative for Copilot visibility).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8bb9da64-cd5f-4845-987b-3e97817ff1fc

📥 Commits

Reviewing files that changed from the base of the PR and between 55ad26a and 0a9730f.

📒 Files selected for processing (3)
  • src/api/providers.rs
  • src/config.rs
  • src/config/providers.rs

… and remove

Fix spacedriveapp#415

Three endpoint mismatches between frontend and backend caused the
GitHub Copilot provider's save, test, and remove buttons to fail
with 405 Method Not Allowed. These affected all providers for save.

- change update_provider annotation from post to put to match frontend
- fix test button URL from /providers/test to /providers/test-model
- add github-copilot entry in build_test_llm_config since
  default_provider_config returns None for providers that require
  token exchange
- widen GITHUB_COPILOT_DEFAULT_BASE_URL visibility to pub(crate)
- add unit test for build_test_llm_config with github-copilot

fix(api): Copilot provider shows as available after remove when env var is set

get_providers fell back to the GITHUB_COPILOT_API_KEY env var when the
TOML key was absent, so the provider stayed visible in settings after
a remove — the env var can't be unset from a running process.

Only check the TOML key for Copilot status in the config-exists path.
The env var fallback remains for the no-config-file case (fresh install).

fix(api): make Copilot provider visibility consistent with other providers

- Change Copilot from TOML-only check to has_value() pattern, consistent with
  all other providers. Now env var GITHUB_COPILOT_API_KEY works like other
  provider env vars in get_providers().

- Add helpful error message in delete_provider() when attempting to remove
  a provider that is only configured via environment variable. The message
  explains which env var to unset and that a restart is required.
  For Ollama, checks both OLLAMA_BASE_URL and OLLAMA_API_KEY env vars.

- Add comment in test explaining why github_copilot_key is excluded from
  all_shorthand_keys_register_providers_via_toml test (uses token exchange,
  not standard shorthand registration).

- Extract copilot_default_provider_config() helper to reduce duplication in
  Copilot provider construction.
@ibhagwan ibhagwan force-pushed the fix/copilot-provider-endpoints branch from 0a9730f to 80333f7 Compare April 13, 2026 12:38
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.

Github Copilot provider not working

2 participants