fix: Ollama message sanitization and streaming think slugs
Build and Push / build (release) Successful in 52s
Build and Push / build (release) Successful in 52s
- Fix `invalid message content type: <nil>` error from Ollama - Create TatlockOllamaProvider that sanitizes messages (null → "") - Update all agents to use sanitized provider - Fix repeating think messages by adding ReasoningSummaryDone signal 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,18 +102,15 @@ _biographer_agent: Optional[Agent[None, str]] = None
|
||||
|
||||
def _create_biographer_agent() -> Agent[None, str]:
|
||||
"""Create The Biographer PydanticAI agent."""
|
||||
# Import required classes for Ollama configuration
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
|
||||
# PydanticAI expects Ollama base URL to end with /v1
|
||||
clean_host = str(config.OLLAMA_HOST).rstrip('/')
|
||||
base_url = f"{clean_host}/v1"
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
|
||||
# Create Ollama model with provider
|
||||
# Create Ollama model with sanitized provider
|
||||
# (fixes 'content: null' issue with tool calls)
|
||||
model = OpenAIChatModel(
|
||||
model_name=config.OLLAMA_DEFAULT_MODEL,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider(),
|
||||
)
|
||||
|
||||
agent: Agent[None, str] = Agent(
|
||||
|
||||
@@ -113,18 +113,15 @@ _housekeeper_agent: Optional[Agent[None, str]] = None
|
||||
|
||||
def _create_housekeeper_agent() -> Agent[None, str]:
|
||||
"""Create the Housekeeper PydanticAI agent."""
|
||||
# Import required classes for Ollama configuration
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
|
||||
# PydanticAI expects Ollama base URL to end with /v1
|
||||
clean_host = str(config.OLLAMA_HOST).rstrip("/")
|
||||
base_url = f"{clean_host}/v1"
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
|
||||
# Create Ollama model with provider
|
||||
# Create Ollama model with sanitized provider
|
||||
# (fixes 'content: null' issue with tool calls)
|
||||
model = OpenAIChatModel(
|
||||
model_name=config.OLLAMA_DEFAULT_MODEL,
|
||||
provider=OllamaProvider(base_url=base_url),
|
||||
provider=get_ollama_provider(),
|
||||
)
|
||||
|
||||
agent: Agent[None, str] = Agent(
|
||||
|
||||
@@ -122,18 +122,15 @@ _librarian_agent: Optional[Agent[None, str]] = None
|
||||
|
||||
def _create_librarian_agent() -> Agent[None, str]:
|
||||
"""Create the Librarian PydanticAI agent."""
|
||||
# Import required classes for Ollama configuration
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
|
||||
# PydanticAI expects Ollama base URL to end with /v1
|
||||
clean_host = str(config.OLLAMA_HOST).rstrip('/')
|
||||
base_url = f"{clean_host}/v1"
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
|
||||
# Create Ollama model with provider
|
||||
# Create Ollama model with sanitized provider
|
||||
# (fixes 'content: null' issue with tool calls)
|
||||
model = OpenAIChatModel(
|
||||
model_name=config.OLLAMA_DEFAULT_MODEL,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider(),
|
||||
)
|
||||
|
||||
agent: Agent[None, str] = Agent(
|
||||
|
||||
+10
-10
@@ -143,7 +143,7 @@ class TatlockAgent(AgentInterface):
|
||||
|
||||
# Import required classes for Ollama configuration
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
|
||||
# PydanticAI expects Ollama base URL to end with /v1
|
||||
# Remove trailing slash from ollama_host if present
|
||||
@@ -153,7 +153,7 @@ class TatlockAgent(AgentInterface):
|
||||
# Create Ollama model with provider
|
||||
ollama_model = OpenAIChatModel(
|
||||
model_name=self.model_name,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider()
|
||||
)
|
||||
|
||||
# Create PydanticAI agent with Ollama model
|
||||
@@ -448,7 +448,7 @@ class TatlockAgent(AgentInterface):
|
||||
... )
|
||||
"""
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
|
||||
logger.info(
|
||||
"tatlock_run_with_scoped_tools",
|
||||
@@ -464,7 +464,7 @@ class TatlockAgent(AgentInterface):
|
||||
|
||||
ollama_model = OpenAIChatModel(
|
||||
model_name=self.model_name,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider()
|
||||
)
|
||||
|
||||
# Create agent with scoped tools
|
||||
@@ -542,7 +542,7 @@ class TatlockAgent(AgentInterface):
|
||||
Text chunks from the streaming response
|
||||
"""
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
|
||||
logger.info(
|
||||
"tatlock_run_with_scoped_tools_stream",
|
||||
@@ -557,7 +557,7 @@ class TatlockAgent(AgentInterface):
|
||||
|
||||
ollama_model = OpenAIChatModel(
|
||||
model_name=self.model_name,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider()
|
||||
)
|
||||
|
||||
# Create agent with scoped tools
|
||||
@@ -637,7 +637,7 @@ class TatlockAgent(AgentInterface):
|
||||
- raw_output: The agent's raw text output
|
||||
"""
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
from pydantic_ai.settings import ModelSettings
|
||||
from pydantic_ai.messages import (
|
||||
ModelRequest,
|
||||
@@ -661,7 +661,7 @@ class TatlockAgent(AgentInterface):
|
||||
|
||||
ollama_model = OpenAIChatModel(
|
||||
model_name=self.model_name,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider()
|
||||
)
|
||||
|
||||
# Create agent with scoped tools
|
||||
@@ -759,7 +759,7 @@ class TatlockAgent(AgentInterface):
|
||||
str: Butler-toned response synthesized from all results
|
||||
"""
|
||||
from pydantic_ai.models.openai import OpenAIChatModel
|
||||
from pydantic_ai.providers.ollama import OllamaProvider
|
||||
from src.ollama.provider import get_ollama_provider
|
||||
from pydantic_ai.messages import ModelRequest, ModelResponse, UserPromptPart, TextPart
|
||||
|
||||
logger.info(
|
||||
@@ -802,7 +802,7 @@ class TatlockAgent(AgentInterface):
|
||||
|
||||
ollama_model = OpenAIChatModel(
|
||||
model_name=self.model_name,
|
||||
provider=OllamaProvider(base_url=base_url)
|
||||
provider=get_ollama_provider()
|
||||
)
|
||||
|
||||
# Synthesis agent uses butler prompt but no tools
|
||||
|
||||
Reference in New Issue
Block a user