-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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?
Changes from 16 commits
311395d
afd8a4e
ab2ff90
4513c8f
e60d3ea
43e6890
4f15966
185a6be
a632cbf
eb10f47
18b21a5
b417485
0f1c113
2b58f59
735da97
65bb646
b19479e
8268267
843f588
99ad3aa
d933b2c
fe93dad
5224e56
128c05a
b35bcfd
59bf2b6
e4ebcca
f69a730
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # `pydantic_ai.models.grok` | ||
|
|
||
| ## Setup | ||
|
|
||
| For details on how to set up authentication with this model, see [model configuration for Grok](../../models/grok.md). | ||
|
|
||
| ::: pydantic_ai.models.grok |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Grok | ||
|
|
||
| ## Install | ||
|
|
||
| To use `GrokModel`, you need to either install `pydantic-ai`, or install `pydantic-ai-slim` with the `grok` optional group: | ||
|
|
||
| ```bash | ||
| pip/uv-add "pydantic-ai-slim[grok]" | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| To use Grok from [xAI](https://x.ai/api) through their API, go to [console.x.ai]https://console.x.ai) and follow your nose until you find the place to create an API key. | ||
|
|
||
| ## Environment variable | ||
|
|
||
| Once you have the API key, you can set it as an environment variable: | ||
|
|
||
| ```bash | ||
| export XAI_API_KEY='your-api-key' | ||
| ``` | ||
|
|
||
| You can then use `GrokModel` by name: | ||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
|
|
||
| agent = Agent('grok:grok-4-fast-non-reasoning') | ||
| ... | ||
| ``` | ||
|
|
||
| Or initialise the model directly with just the model name: | ||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
| from pydantic_ai.models.grok import GrokModel | ||
|
|
||
| model = GrokModel('grok-4-fast-non-reasoning') | ||
| agent = Agent(model) | ||
| ... | ||
| ``` | ||
|
|
||
| You can provide your own `api_key` inline like so: | ||
|
|
||
| ```python | ||
| from pydantic_ai import Agent | ||
| from pydantic_ai.models.grok import GrokModel | ||
|
|
||
| model = GrokModel('grok-4-fast-non-reasoning', api_key='your-api-key') | ||
| agent = Agent(model) | ||
| ... | ||
| ``` | ||
|
|
||
| You can also customize the `GrokModel` with a custom `xai_sdk.AsyncClient`: | ||
|
|
||
| ```python | ||
| from xai_sdk import AsyncClient | ||
| async_client = AsyncClient(api_key='your-api-key') | ||
|
|
||
| from pydantic_ai import Agent | ||
| from pydantic_ai.models.grok import GrokModel | ||
|
|
||
| model = GrokModel('grok-4-fast-non-reasoning', client=async_client) | ||
| agent = Agent(model) | ||
| ... | ||
| ``` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're going to include this example, we should have a doc under |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| """Example of using Grok's server-side web_search tool. | ||
|
|
||
| This agent: | ||
| 1. Uses web_search to find the hottest performing stock yesterday | ||
| 2. Provides buy analysis for the user | ||
| """ | ||
|
|
||
| import os | ||
|
|
||
| import logfire | ||
| from pydantic import BaseModel, Field | ||
|
|
||
| from pydantic_ai import ( | ||
| Agent, | ||
| BuiltinToolCallPart, | ||
| WebSearchTool, | ||
| ) | ||
| from pydantic_ai.models.grok import GrokModel | ||
|
|
||
| logfire.configure() | ||
| logfire.instrument_pydantic_ai() | ||
|
|
||
| # Configure for xAI API | ||
| xai_api_key = os.getenv('XAI_API_KEY') | ||
| if not xai_api_key: | ||
| raise ValueError('XAI_API_KEY environment variable is required') | ||
|
|
||
|
|
||
| # Create the model using GrokModel with server-side tools | ||
| model = GrokModel('grok-4-fast', api_key=xai_api_key) | ||
|
|
||
|
|
||
| class StockAnalysis(BaseModel): | ||
| """Analysis of top performing stock.""" | ||
|
|
||
| stock_symbol: str = Field(description='Stock ticker symbol') | ||
| current_price: float = Field(description='Current stock price') | ||
| buy_analysis: str = Field(description='Brief analysis for whether to buy the stock') | ||
|
|
||
|
|
||
| # This agent uses server-side web search to research stocks | ||
| stock_analysis_agent = Agent[None, StockAnalysis]( | ||
| model=model, | ||
| output_type=StockAnalysis, | ||
| builtin_tools=[WebSearchTool()], | ||
| system_prompt=( | ||
| 'You are a stock analysis assistant. ' | ||
| 'Use web_search to find the hottest performing stock from yesterday on NASDAQ. ' | ||
| 'Provide the current price and a brief buy analysis explaining whether this is a good buy.' | ||
| ), | ||
| ) | ||
|
|
||
|
|
||
| async def main(): | ||
| """Run the stock analysis agent.""" | ||
| query = 'What was the hottest performing stock on NASDAQ yesterday?' | ||
|
|
||
| print('π Starting stock analysis...\n') | ||
| print(f'Query: {query}\n') | ||
|
|
||
| async with stock_analysis_agent.run_stream(query) as result: | ||
| # Stream responses as they happen | ||
| async for message, _is_last in result.stream_responses(): | ||
| for part in message.parts: | ||
| if isinstance(part, BuiltinToolCallPart): | ||
| print(f'π§ Server-side tool: {part.tool_name}') | ||
|
|
||
| # Access output after streaming is complete | ||
| output = await result.get_output() | ||
|
|
||
| print('\nβ Analysis complete!\n') | ||
|
|
||
| print(f'π Top Stock: {output.stock_symbol}') | ||
| print(f'π° Current Price: ${output.current_price:.2f}') | ||
| print(f'\nπ Buy Analysis:\n{output.buy_analysis}') | ||
|
|
||
| # Show usage statistics | ||
| usage = result.usage() | ||
| print('\nπ Usage Statistics:') | ||
| print(f' Requests: {usage.requests}') | ||
| print(f' Input Tokens: {usage.input_tokens}') | ||
| print(f' Output Tokens: {usage.output_tokens}') | ||
| print(f' Total Tokens: {usage.total_tokens}') | ||
|
|
||
| # Show server-side tools usage if available | ||
| if usage.details and 'server_side_tools_used' in usage.details: | ||
| print(f' Server-Side Tools: {usage.details["server_side_tools_used"]}') | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| import asyncio | ||
|
|
||
| asyncio.run(main()) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -175,6 +175,9 @@ | |
| 'grok:grok-3-mini-fast', | ||
| 'grok:grok-4', | ||
| 'grok:grok-4-0709', | ||
| 'grok:grok-4-fast-non-reasoning', | ||
| 'grok:grok-4-fast-reasoning', | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| 'grok:grok-code-fast-1', | ||
| 'groq:deepseek-r1-distill-llama-70b', | ||
| 'groq:deepseek-r1-distill-qwen-32b', | ||
| 'groq:distil-whisper-large-v3-en', | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.