-
Notifications
You must be signed in to change notification settings - Fork 5.4k
feat: openrouter out of the box experience for goose installations #3507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
46cc640
first pass at flow with CLI
michaelneale 172d67d
checkpoint
michaelneale bebb16b
now has gui
michaelneale 0bd7230
Merge branch 'main' into micn/install-with-openrouter
michaelneale 0cd926c
tidy up
michaelneale 5a8f563
some test coverage
michaelneale 9e58a88
setup in cli correctly
michaelneale 921ce72
move logic to goose crate where it should be
michaelneale 94608f3
slightly less ominous warning, but may only be at dev time
michaelneale be9da5c
Merge branch 'main' into micn/install-with-openrouter
michaelneale 538204f
message
michaelneale 8040864
Merge branch 'main' into micn/install-with-openrouter
michaelneale d5899e6
run it with option to show providers
michaelneale 81fa3a0
fix up goose configure to offer openrouter login when fresh
michaelneale a54703a
Merge branch 'main' into micn/install-with-openrouter
michaelneale 9056916
Merge branch 'main' into micn/install-with-openrouter
michaelneale 56dc6f6
cli shouldn't change
michaelneale 39cba52
change path for openrouter flow, remove comments, tidy up tests based…
michaelneale a49e252
tidy up
michaelneale b7264b7
addressing feedback
michaelneale df0767b
Merge branch 'main' into micn/install-with-openrouter
michaelneale d261cb8
fmt
michaelneale b6d7eb9
error goes to welcome like before
michaelneale e86828b
adding to base list for openrouter
michaelneale 8b43170
closing/restart
michaelneale 41656d3
Merge branch 'main' into micn/install-with-openrouter
michaelneale e2600f1
Merge branch 'main' into micn/install-with-openrouter
michaelneale 838997d
don't need this for singular UI client
michaelneale f72603b
Merge branch 'main' into micn/install-with-openrouter
michaelneale b4be209
will now refresh correctly
michaelneale 67bca4b
cleanup
michaelneale File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| use crate::state::AppState; | ||
| use axum::{extract::State, http::StatusCode, routing::post, Json, Router}; | ||
| use goose::config::signup_openrouter::OpenRouterAuth; | ||
| use goose::config::{configure_openrouter, Config}; | ||
| use once_cell::sync::Lazy; | ||
| use serde::Serialize; | ||
| use std::sync::Arc; | ||
| use tokio::sync::Mutex; | ||
|
|
||
| // Global mutex to ensure only one OAuth flow at a time | ||
| static OAUTH_FLOW_MUTEX: Lazy<Arc<Mutex<()>>> = Lazy::new(|| Arc::new(Mutex::new(()))); | ||
|
|
||
| #[derive(Serialize)] | ||
| pub struct SetupResponse { | ||
| pub success: bool, | ||
| pub message: String, | ||
| } | ||
|
|
||
| pub fn routes(state: Arc<AppState>) -> Router { | ||
| Router::new() | ||
| .route("/setup/openrouter/start", post(start_openrouter_setup)) | ||
|
michaelneale marked this conversation as resolved.
Outdated
|
||
| .with_state(state) | ||
| } | ||
|
|
||
| async fn start_openrouter_setup( | ||
|
michaelneale marked this conversation as resolved.
|
||
| State(_state): State<Arc<AppState>>, | ||
| ) -> Result<Json<SetupResponse>, StatusCode> { | ||
| tracing::info!("Starting OpenRouter setup flow"); | ||
|
|
||
| // Try to acquire the mutex with a timeout to prevent concurrent OAuth flows | ||
| let _lock = match tokio::time::timeout( | ||
| std::time::Duration::from_secs(1), | ||
| OAUTH_FLOW_MUTEX.lock(), | ||
| ) | ||
| .await | ||
| { | ||
| Ok(lock) => lock, | ||
| Err(_) => { | ||
| tracing::warn!("OAuth flow is already in progress"); | ||
| return Ok(Json(SetupResponse { | ||
| success: false, | ||
| message: "Authentication flow is already in progress. Please wait.".to_string(), | ||
| })); | ||
| } | ||
| }; | ||
|
|
||
| tracing::info!("Acquired OAuth flow lock"); | ||
|
|
||
| // Run the existing PKCE flow | ||
|
michaelneale marked this conversation as resolved.
Outdated
|
||
| let mut auth_flow = OpenRouterAuth::new().map_err(|e| { | ||
| tracing::error!("Failed to initialize auth flow: {}", e); | ||
| StatusCode::INTERNAL_SERVER_ERROR | ||
| })?; | ||
|
|
||
| tracing::info!("Auth flow initialized, starting complete_flow"); | ||
|
|
||
| match auth_flow.complete_flow().await { | ||
| Ok(api_key) => { | ||
| // The complete_flow only returns the API key, we need to save the configuration | ||
| tracing::info!("Got API key, configuring OpenRouter..."); | ||
|
|
||
| // Configure everything using the common function | ||
| let config = Config::global(); | ||
|
|
||
| // Use the common configuration function | ||
| if let Err(e) = configure_openrouter(config, api_key) { | ||
| tracing::error!("Failed to configure OpenRouter: {}", e); | ||
| return Ok(Json(SetupResponse { | ||
| success: false, | ||
| message: format!("Failed to configure OpenRouter: {}", e), | ||
| })); | ||
| } | ||
|
|
||
| tracing::info!("OpenRouter setup completed successfully"); | ||
| Ok(Json(SetupResponse { | ||
| success: true, | ||
| message: "OpenRouter setup completed successfully".to_string(), | ||
| })) | ||
| } | ||
| Err(e) => { | ||
| tracing::error!("OpenRouter setup failed: {}", e); | ||
| Ok(Json(SetupResponse { | ||
| success: false, | ||
| message: format!("Setup failed: {}", e), | ||
| })) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[tokio::test] | ||
| async fn test_oauth_flow_mutex() { | ||
|
michaelneale marked this conversation as resolved.
Outdated
|
||
| // Test that the OAuth flow mutex is properly initialized and prevents concurrent flows | ||
| let lock1 = OAUTH_FLOW_MUTEX.try_lock(); | ||
| assert!(lock1.is_ok(), "First lock should succeed"); | ||
|
|
||
| // Try to acquire second lock while first is held | ||
| let lock2_result = tokio::time::timeout( | ||
| std::time::Duration::from_millis(100), | ||
| OAUTH_FLOW_MUTEX.lock(), | ||
| ) | ||
| .await; | ||
|
|
||
| assert!( | ||
| lock2_result.is_err(), | ||
| "Second lock should timeout while first is held" | ||
| ); | ||
|
|
||
| // Drop first lock | ||
| drop(lock1); | ||
|
|
||
| // Now second lock should succeed | ||
| let lock2 = OAUTH_FLOW_MUTEX.try_lock(); | ||
| assert!( | ||
| lock2.is_ok(), | ||
| "Second lock should succeed after first is dropped" | ||
| ); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.