-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Generic retry and error parsing #3558
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
Conversation
sorry, hadn't seen your version of this, just the the jackjack - I like the configbuilder thing from yours, I'll add that in a follow up. mostly what stops me from getting this in, is the testing |
Resolved merge conflicts in provider files by keeping retry logic from HEAD branch. Fixed compilation issues with async closures and reference handling.
|
this is ready for review @michaelneale - I incorporated the client logic from the other PR. I left out connection pooling as the LLMs tell me we already had that |
|
/cc @ahau-square for visibility |
jamadeo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a great improvement -- how do we satisfactorily test?
I think there is a subtle bug in your ApiClient .with_ methods though
|
|
||
| /// Fetch supported models from Anthropic; returns Err on failure, Ok(None) if not present | ||
| async fn fetch_supported_models_async(&self) -> Result<Option<Vec<String>>, ProviderError> { | ||
| async fn fetch_supported_models(&self) -> Result<Option<Vec<String>>, ProviderError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for renaming this
| None => return Err(StatusCode::BAD_REQUEST), | ||
| }; | ||
|
|
||
| let model_config = ModelConfig::new(&model).map_err(|_| StatusCode::BAD_REQUEST)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be nice if we could include text with these, but maybe leave that for another change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree - I didn't quickly see how that works though. there's a whole bunch of other handlers that would be helped
| #[allow(dead_code)] | ||
| OAuth(OAuthConfig), | ||
| Custom(Box<dyn AuthProvider>), | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
|
|
||
| impl ApiClient { | ||
| pub fn new(host: String, auth: AuthMethod) -> Result<Self> { | ||
| Self::with_timeout(host, auth, Duration::from_secs(600)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const DEFAULT_TIMEOUT = ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| self.client = Client::builder() | ||
| .timeout(self.timeout) | ||
| .default_headers(self.default_headers.clone()) | ||
| .build()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these .with_ methods look like they could be chained because they take a reference but they make a new client every time -- maybe a builder would be better? .with_timeout().with_headers() won't do the expected thing right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit clunky and maybe a builder pattern would be better, but since these methods also set the timeout and the headers on themselves it should work, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry yes you're right, I think I got mixed up because with_timeout is not a method after all
| } | ||
| } | ||
|
|
||
| pub struct ApiRequestBuilder<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you could just use an owned String for path and drop the lifetime here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks
I don't know how we satisfactory test this other than making sure we have keys for all providers and then have scenario tests for all of them or some such. |
* main: Token counting in Auto-compact uses provider metadata (#3788) docs: Add YouTube link to Git MCP Tutorial (#3831) feat: more robust client initialization for the app (#3830) Build app bundles on release branches always (#3789) fix param order of debug_conversation_fixer (#3796) Fix directory switcher not working in active chat sessions and file browser not defaulting to current session directory path (#3791) File completion in CLI (#3822)
|
Aside: how well does the retry work in databricks? I haven't found it working for me lately (well I keep hitting things which I thought were retry-able, upstream errors etc)? |
| "Claude and other models from Anthropic", | ||
| ANTHROPIC_DEFAULT_MODEL, | ||
| vec
This lifts the retry mechanism out of the databricks provider and also the error parsing so we can generally call it. it would be good to discuss this and merge it and then apply it to all the other things
fixes #887