Remove support for structured output
This commit is contained in:
parent
83ea6347b6
commit
aa9fdf051d
7 changed files with 11 additions and 69 deletions
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
- **LLMJudge**: Custom evaluator now accepts `ModelConfig` instead of a model name string
|
||||
- **Docling upgrade**: docling-core ≥2.70.2 (schema 1.10.0), docling ≥2.81.0. Adds field data model support for structured form/KV content, wide table chunking fixes, and rich table cell hang fix
|
||||
- **pydantic-ai ≥1.70.0**: Bumped minimum version. Removed `structured_output_type` helper — all supported providers now handle native structured output, so agents pass result types directly
|
||||
|
||||
## [0.34.1] - 2026-03-16
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from haiku.rag.config import Config
|
|||
from haiku.rag.config.models import AppConfig, ModelConfig
|
||||
from haiku.rag.store.models import SearchResult
|
||||
from haiku.rag.tools.search import create_search_toolset
|
||||
from haiku.rag.utils import get_model, structured_output_type
|
||||
from haiku.rag.utils import get_model
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -66,7 +66,7 @@ class QuestionAnswerAgent:
|
|||
agent: Agent[_QARunDeps, RawSearchAnswer] = Agent( # ty: ignore[invalid-assignment]
|
||||
model=model,
|
||||
deps_type=_QARunDeps,
|
||||
output_type=structured_output_type(RawSearchAnswer, model),
|
||||
output_type=RawSearchAnswer,
|
||||
instructions=system_prompt,
|
||||
toolsets=[search_toolset],
|
||||
retries=3,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from haiku.rag.agents.research.prompts import (
|
|||
from haiku.rag.agents.research.state import ResearchDeps, ResearchState
|
||||
from haiku.rag.config import Config
|
||||
from haiku.rag.config.models import AppConfig
|
||||
from haiku.rag.utils import build_prompt, get_model, structured_output_type
|
||||
from haiku.rag.utils import build_prompt, get_model
|
||||
|
||||
|
||||
def format_context_for_prompt(context: ResearchContext) -> str:
|
||||
|
|
@ -68,7 +68,7 @@ async def _iterative_plan_logic(
|
|||
model = get_model(model_config, config)
|
||||
plan_agent: Agent[ResearchDependencies, IterativePlanResult] = Agent( # type: ignore[assignment]
|
||||
model=model,
|
||||
output_type=structured_output_type(IterativePlanResult, model),
|
||||
output_type=IterativePlanResult,
|
||||
instructions=effective_prompt,
|
||||
retries=3,
|
||||
deps_type=ResearchDependencies,
|
||||
|
|
@ -118,7 +118,7 @@ async def _search_one_step_logic(
|
|||
model = get_model(model_config, config)
|
||||
agent: Agent[ResearchDependencies, RawSearchAnswer] = Agent( # type: ignore[assignment]
|
||||
model=model,
|
||||
output_type=structured_output_type(RawSearchAnswer, model),
|
||||
output_type=RawSearchAnswer,
|
||||
instructions=search_prompt,
|
||||
retries=3,
|
||||
deps_type=ResearchDependencies,
|
||||
|
|
@ -220,7 +220,7 @@ def build_research_graph(
|
|||
model = get_model(model_config, config)
|
||||
agent: Agent[ResearchDependencies, ResearchReport] = Agent( # type: ignore[assignment]
|
||||
model=model,
|
||||
output_type=structured_output_type(ResearchReport, model),
|
||||
output_type=ResearchReport,
|
||||
instructions=synthesis_prompt,
|
||||
retries=3,
|
||||
deps_type=ResearchDependencies,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from haiku.rag.agents.rlm.dependencies import RLMDeps
|
|||
from haiku.rag.agents.rlm.models import CodeExecution, RLMResult
|
||||
from haiku.rag.agents.rlm.prompts import RLM_SYSTEM_PROMPT
|
||||
from haiku.rag.config.models import AppConfig
|
||||
from haiku.rag.utils import get_model, structured_output_type
|
||||
from haiku.rag.utils import get_model
|
||||
|
||||
|
||||
def create_rlm_agent(config: AppConfig) -> Agent[RLMDeps, RLMResult]:
|
||||
|
|
@ -25,7 +25,7 @@ def create_rlm_agent(config: AppConfig) -> Agent[RLMDeps, RLMResult]:
|
|||
agent: Agent[RLMDeps, RLMResult] = Agent( # type: ignore[invalid-assignment]
|
||||
model,
|
||||
deps_type=RLMDeps,
|
||||
output_type=structured_output_type(RLMResult, model),
|
||||
output_type=RLMResult,
|
||||
instructions=RLM_SYSTEM_PROMPT,
|
||||
retries=3,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -318,20 +318,6 @@ def get_model(
|
|||
return f"{provider}:{model}"
|
||||
|
||||
|
||||
def structured_output_type(
|
||||
result_type: type,
|
||||
model: Any,
|
||||
max_retries: int = 3,
|
||||
) -> Any:
|
||||
"""Return a NativeOutput or ToolOutput wrapper based on model capability."""
|
||||
from pydantic_ai.models import Model
|
||||
from pydantic_ai.output import NativeOutput, ToolOutput
|
||||
|
||||
if isinstance(model, Model) and model.profile.supports_json_schema_output:
|
||||
return NativeOutput(result_type)
|
||||
return ToolOutput(result_type, max_retries=max_retries)
|
||||
|
||||
|
||||
def format_bytes(num_bytes: int) -> str:
|
||||
"""Format bytes as human-readable string."""
|
||||
size = float(num_bytes)
|
||||
|
|
|
|||
|
|
@ -15,24 +15,11 @@ def vcr_cassette_dir():
|
|||
|
||||
|
||||
class TestCreateRLMAgent:
|
||||
def test_creates_agent_native_output_when_supported(self):
|
||||
from pydantic_ai.output import NativeOutput
|
||||
|
||||
def test_creates_agent(self):
|
||||
agent = create_rlm_agent(Config)
|
||||
assert isinstance(agent, Agent)
|
||||
assert agent.deps_type is RLMDeps
|
||||
assert isinstance(agent.output_type, NativeOutput)
|
||||
assert agent.output_type.outputs is RLMResult
|
||||
|
||||
def test_creates_agent_native_output_for_ollama(self):
|
||||
from pydantic_ai.output import NativeOutput
|
||||
|
||||
config = AppConfig()
|
||||
config.rlm.model.name = "qwen3"
|
||||
agent = create_rlm_agent(config)
|
||||
assert isinstance(agent, Agent)
|
||||
assert isinstance(agent.output_type, NativeOutput)
|
||||
assert agent.output_type.outputs is RLMResult
|
||||
assert agent.output_type is RLMResult
|
||||
|
||||
def test_agent_has_execute_code_tool(self):
|
||||
agent = create_rlm_agent(Config)
|
||||
|
|
|
|||
|
|
@ -139,38 +139,6 @@ Emoji test: 🚀 ✅ 📝"""
|
|||
assert "🚀" in result_markdown
|
||||
|
||||
|
||||
def test_structured_output_type_native():
|
||||
from pydantic_ai.output import NativeOutput
|
||||
|
||||
from haiku.rag.utils import structured_output_type
|
||||
|
||||
model = get_model(ModelConfig(provider="openai", name="gpt-4o"))
|
||||
result = structured_output_type(str, model)
|
||||
assert isinstance(result, NativeOutput)
|
||||
assert result.outputs is str
|
||||
|
||||
|
||||
def test_structured_output_type_ollama_native():
|
||||
from pydantic_ai.output import NativeOutput
|
||||
|
||||
from haiku.rag.utils import structured_output_type
|
||||
|
||||
model = get_model(ModelConfig(provider="ollama", name="qwen3"))
|
||||
result = structured_output_type(str, model)
|
||||
assert isinstance(result, NativeOutput)
|
||||
assert result.outputs is str
|
||||
|
||||
|
||||
def test_structured_output_type_string_model():
|
||||
from pydantic_ai.output import ToolOutput
|
||||
|
||||
from haiku.rag.utils import structured_output_type
|
||||
|
||||
result = structured_output_type(str, "unknown:model")
|
||||
assert isinstance(result, ToolOutput)
|
||||
assert result.output is str
|
||||
|
||||
|
||||
def test_get_model_ollama():
|
||||
"""Test get_model returns OpenAIChatModel for Ollama."""
|
||||
model_config = ModelConfig(provider="ollama", name="llama3")
|
||||
|
|
|
|||
Loading…
Reference in a new issue