Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/orchestrator/control_systems/hybrid_control_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,14 @@ async def _handle_file_operation(
if action_text in filesystem_actions and task.parameters:
# Use UnifiedTemplateResolver for template resolution
resolved_params = task.parameters.copy()
resolved_params["action"] = action_text
# Only supply the operation when the step did not state one.
# `file` names the TOOL, not an operation, so overwriting a
# caller's `action: read` with it sent action="file" to
# FileSystemTool and every such step failed with
# "Unknown filesystem action: file". The metadata-routed branch
# above already guards this; this branch did not.
if "action" not in resolved_params:
resolved_params["action"] = action_text

# Prepare template context using the unified system
template_context = self._prepare_template_context(context)
Expand Down
12 changes: 8 additions & 4 deletions tests/integration/test_pipeline_integration_infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,16 @@ async def test_pipeline_test_provider_get_model(self):
assert stats['model_usage']["pipeline-test-model"]['requests'] == 1

@pytest.mark.asyncio
async def test_pipeline_test_provider_initialization(self):
"""Test provider initialization process."""

async def test_pipeline_test_provider_async_initialization(self):
"""Test the async initialize() call.

Renamed: this shared a name with the constructor test above, so it
silently replaced it and that test never ran. The two check different
things and both are wanted.
"""
provider = PipelineTestProvider()
await provider.initialize()

assert provider.is_initialized is True

def test_pipeline_test_provider_usage_statistics(self):
Expand Down
37 changes: 26 additions & 11 deletions tests/integration/test_research_assistant_with_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ async def test_report_generator_tool(self):
recommendations=["Recommendation 1", "Recommendation 2"],
quality_score=0.85)

# Verify report
# Verify report. Tools return {success, result, error}; the report
# itself is in `result` (see #433).
assert result["success"] is True
assert "markdown" in result
assert result["word_count"] > 0
data = result["result"]
assert "markdown" in data
assert data["word_count"] > 0

markdown = result["markdown"]
markdown = data["markdown"]
assert "# Test Research Report" in markdown
assert "Finding 1" in markdown
assert "Finding 2" in markdown
Expand Down Expand Up @@ -170,10 +172,12 @@ async def test_pdf_compiler_tool(self):
# Verify result
if result["success"]:
assert output_path.exists()
assert result["file_size"] > 0
assert result["result"]["file_size"] > 0
else:
# PDF generation failed (likely pandoc not available)
assert "error" in result
# PDF generation failed (likely pandoc not available).
# `assert "error" in result` could never fail -- the envelope
# always carries that key. Assert the value instead.
assert result["error"], "a failed compile must say why"

@pytest.mark.integration
@pytest.mark.asyncio
Expand All @@ -194,12 +198,23 @@ async def test_web_search_integration(self):
# Perform real search
result = await tool.execute(query="Python asyncio tutorial", max_results=5)

# Verify results
assert "results" in result
assert len(result["results"]) > 0
# Tools return {success, result, error}; the payload is in `result`.
assert result["success"] is True, f"search failed: {result['error']}"
data = result["result"]
assert "results" in data

if not data["results"]:
# No backend reachable (missing [web] extra, or no network). This
# test is about the shape of a result, so an unavailable search
# engine is a missing prerequisite rather than a defect.
pytest.skip(
f"web search returned nothing "
f"(total_results={data.get('total_results')}); "
f"no search backend available"
)

# Check result structure
first_result = result["results"][0]
first_result = data["results"][0]
assert "snippet" in first_result
assert "rank" in first_result
assert "relevance" in first_result
Expand Down
Loading
Loading