-
Notifications
You must be signed in to change notification settings - Fork 1.5k
XaiModel with tests and stock analysis agent #3400
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
base: main
Are you sure you want to change the base?
Conversation
|
@brightsparc Thanks Julian! Let me know when this is ready for review or if you have any questions. |
|
Due to using otel in our own SDK, I did notice an error when running the pydantic ai code in async.io loop: We could disable our tracing with |
@brightsparc Looks like grok-4-fast is not on https://github.com/pydantic/genai-prices/blob/main/prices/providers/x_ai.yml yet. Contribution welcome! (See contrib docs) Failing tests: I believe we just need to add the xAI env var to the list here: pydantic-ai/tests/test_examples.py Lines 179 to 182 in c096d99
This one should be fixed by running Looks like we need the new
Do you have example code for me that triggers it? |
I will make a separate PR here
Added this:
Not sure I follow this
You can run the following command to repo that error: |
|
This PR is stale, and will be closed in 3 days if no reply is received. |
DouweM
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.
@brightsparc Thanks for your patience here! Left some more feedback, and can you please look at the merge conflicts with main?
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.
Let's remove this example
| from ..profiles import ModelProfileSpec | ||
| from ..profiles.grok import GrokModelProfile | ||
| from ..providers import Provider, infer_provider | ||
| from ..providers.xai import XaiModelName |
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.
Let's move this inside try/except ImportError above as it also depends on the SDK
| See [xAI SDK documentation](https://docs.x.ai/docs) for more details on these parameters. | ||
| """ | ||
|
|
||
| xai_logprobs: bool |
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.
We have logprobs on the base ModelSettings so no need to include it 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.
Also note that we're not currently giving the user a way to access the logprobs. In OpenAI models, we do this using ModelResponse.provider_details['logprobs'] or TextPart.provider_details['logprobs'].
If we list xAI under supported providers for ModelSettings.logprobs, we should make sure we do that.
| Corresponds to the `web_search_call.action.sources` value of the `include` parameter in the Responses API. | ||
| """ | ||
|
|
||
| xai_include_x_search_outputs: bool |
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.
x_search isn't supported yet so let's leave this out for now
|
|
||
| if tool_call.status == chat_types.chat_pb2.ToolCallStatus.TOOL_CALL_STATUS_COMPLETED: | ||
| # Tool completed - emit return part with result | ||
| tool_result_content = XaiModel.get_tool_result_content(response.content) |
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.
See above, it confuses me that response.content is both text, and the builtin tool return value
| if tool_call.status == chat_types.chat_pb2.ToolCallStatus.TOOL_CALL_STATUS_COMPLETED: | ||
| # Tool completed - emit return part with result | ||
| tool_result_content = XaiModel.get_tool_result_content(response.content) | ||
| return_part = BuiltinToolReturnPart( |
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.
As in non-streaming, we probably need a BuiltinToolCallPart as well
| # xAI supports JSON object output | ||
| supports_json_object_output=True, | ||
| # Default to 'native' for structured output since xAI supports it well | ||
| default_structured_output_mode='native', |
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.
Let's default to tool in line with other models (meaning we can drop this field as that's already the default)
|
|
||
|
|
||
| # https://docs.x.ai/docs/models | ||
| XaiModelName = str | AllModels |
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.
With other providers, we have this in the model file instead, so let's move it just for consistency, unless there's a particular reason we cant
| * OpenAI (some models, not o1) | ||
| * Groq | ||
| * Anthropic | ||
| * Grok |
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.
We can drop this one right
This PR includes support for
GrokModelwhich uses the xai-sdk-python library, which supports chat completion, tool calling, and built-in server side tool calls.I have included a series of tests, as well as an example for a stock analysis agent that uses search and code execution, and returns results in the form of a local tool call.
Below is what the output looks like in logfire. It includes custom spans emmited from the xai-sdk.
Cost is coming back as Unknown so it would be good to understand how we can populate this.