diff --git a/pydantic_ai/models/__init__.py b/pydantic_ai/models/__init__.py index 81ae41033..212c3f464 100644 --- a/pydantic_ai/models/__init__.py +++ b/pydantic_ai/models/__init__.py @@ -99,4 +99,4 @@ def cached_async_http_client() -> AsyncHTTPClient: described in [encode/httpx#2026](https://github.com/encode/httpx/pull/2026), but when experimenting or showing examples, it's very useful not to, this allows multiple Agents to use a single client. """ - return AsyncHTTPClient() + return AsyncHTTPClient(timeout=30) diff --git a/pydantic_ai/models/gemini.py b/pydantic_ai/models/gemini.py index 638db390e..5ae51499a 100644 --- a/pydantic_ai/models/gemini.py +++ b/pydantic_ai/models/gemini.py @@ -346,14 +346,17 @@ class _GeminiResponse: @dataclass class _GeminiCandidates: + """See .""" + content: _GeminiContent finish_reason: Annotated[Literal['STOP'], Field(alias='finishReason')] """ - See https://ai.google.dev/api/generate-content#FinishReason, lots of other values are possible, + See , lots of other values are possible, but let's wait until we see them and know what they mean to add them here. """ - index: int - safety_ratings: Annotated[list[_GeminiSafetyRating], Field(alias='safetyRatings')] + avg_log_probs: Annotated[float, Field(alias='avgLogProbs')] | None = None + index: int | None = None + safety_ratings: Annotated[list[_GeminiSafetyRating], Field(alias='safetyRatings')] | None = None @dataclass diff --git a/pydantic_ai_examples/README.md b/pydantic_ai_examples/README.md index f2ac0974a..01ed2efc6 100644 --- a/pydantic_ai_examples/README.md +++ b/pydantic_ai_examples/README.md @@ -156,3 +156,23 @@ You can then ask the agent a question with: ```bash (uv run/python) -m pydantic_ai_examples.rag search "How do I configure logfire to work with FastAPI?" ``` + +### `chat_app.py` + +(Demonstrates: reusing chat history, serializing messages) + +**TODO**: stream responses + +Simple chat app example build with FastAPI. + +This demonstrates storing chat history between requests and using it to give the model context for new responses. + +Most of the complex logic here is in `chat_app.html` which includes the page layout and JavaScript to handle the chat. + +Run the app with: + +```bash +(uv run/python) -m pydantic_ai_examples.chat_app +``` + +Then open the app at [localhost:8000](http://localhost:8000). diff --git a/pydantic_ai_examples/chat_app.html b/pydantic_ai_examples/chat_app.html index 544f75fb6..25d8cf056 100644 --- a/pydantic_ai_examples/chat_app.html +++ b/pydantic_ai_examples/chat_app.html @@ -4,39 +4,10 @@ Chat App + -
+

Chat App

Ask me anything...

-
-
+
+
- - + +
+ +
-
+
Error occurred, check the console for more information.
@@ -103,7 +66,7 @@

Chat App

const parent = document.getElementById('conversation'); for (const message of messages) { let msgDiv = document.createElement('div'); - msgDiv.classList.add(message.role); + msgDiv.classList.add('border-top', 'pt-2', message.role); msgDiv.innerHTML = marked.parse(message.content); parent.appendChild(msgDiv); } @@ -111,7 +74,8 @@

Chat App

function onError(error) { console.error(error); - document.getElementById('error').style.display = 'block'; + document.getElementById('error').classList.remove('d-none'); + document.getElementById('spinner').classList.remove('active'); } async function fetchResponse(response) { @@ -145,16 +109,18 @@

Chat App

e.preventDefault(); const spinner = document.getElementById('spinner'); spinner.classList.add('active'); + const body = new FormData(e.target); let input = document.getElementById('prompt-input') input.value = ''; input.disabled = true; - const response = await fetch('/chat/', {method: 'POST', body: new FormData(e.target)}); + const response = await fetch('/chat/', {method: 'POST', body}); await fetchResponse(response); spinner.classList.remove('active'); } + // call onSubmit when form is submitted (e.g. user clicks the send button or hits Enter) document.querySelector('form').addEventListener('submit', (e) => onSubmit(e).catch(onError)); // load messages on page load diff --git a/pydantic_ai_examples/chat_app.py b/pydantic_ai_examples/chat_app.py index b8c69d955..9e2dfb107 100644 --- a/pydantic_ai_examples/chat_app.py +++ b/pydantic_ai_examples/chat_app.py @@ -1,3 +1,10 @@ +"""Simple chat app example build with FastAPI. + +Run with: + + uv run -m pydantic_ai_examples.chat_app +""" + from collections.abc import Iterator from dataclasses import dataclass from pathlib import Path