Merge pull request #119 from TimothyZhang7/chore/fix-git-actions
chore: fix git actions
This commit is contained in:
@@ -58,89 +58,11 @@ class AnthropicProvider(LLMProvider):
|
||||
tool_executor: callable,
|
||||
max_iterations: int = 10,
|
||||
) -> LLMResponse:
|
||||
"""Run a tool-use loop until Claude produces a final response."""
|
||||
current_messages = list(messages)
|
||||
total_input_tokens = 0
|
||||
total_output_tokens = 0
|
||||
|
||||
for _ in range(max_iterations):
|
||||
response = self.client.messages.create(
|
||||
model=self.model,
|
||||
max_tokens=1024,
|
||||
system=system,
|
||||
messages=current_messages,
|
||||
tools=[self._tool_to_dict(t) for t in tools],
|
||||
)
|
||||
|
||||
total_input_tokens += response.usage.input_tokens
|
||||
total_output_tokens += response.usage.output_tokens
|
||||
|
||||
# Check if we're done (no more tool use)
|
||||
if response.stop_reason == "end_turn":
|
||||
content = ""
|
||||
for block in response.content:
|
||||
if block.type == "text":
|
||||
content += block.text
|
||||
|
||||
return LLMResponse(
|
||||
content=content,
|
||||
model=response.model,
|
||||
input_tokens=total_input_tokens,
|
||||
output_tokens=total_output_tokens,
|
||||
stop_reason=response.stop_reason,
|
||||
raw_response=response,
|
||||
)
|
||||
|
||||
# Process tool uses
|
||||
tool_uses = []
|
||||
assistant_content = []
|
||||
for block in response.content:
|
||||
if block.type == "tool_use":
|
||||
tool_uses.append(
|
||||
ToolUse(id=block.id, name=block.name, input=block.input)
|
||||
)
|
||||
assistant_content.append({
|
||||
"type": "tool_use",
|
||||
"id": block.id,
|
||||
"name": block.name,
|
||||
"input": block.input,
|
||||
})
|
||||
elif block.type == "text":
|
||||
assistant_content.append({
|
||||
"type": "text",
|
||||
"text": block.text,
|
||||
})
|
||||
|
||||
# Add assistant message with tool uses
|
||||
current_messages.append({
|
||||
"role": "assistant",
|
||||
"content": assistant_content,
|
||||
})
|
||||
|
||||
# Execute tools and add results
|
||||
tool_results = []
|
||||
for tool_use in tool_uses:
|
||||
result = tool_executor(tool_use)
|
||||
# Ensure content is never empty (Anthropic API requires non-empty content)
|
||||
content = result.content if result.content else "(empty result)"
|
||||
tool_results.append({
|
||||
"type": "tool_result",
|
||||
"tool_use_id": result.tool_use_id,
|
||||
"content": content,
|
||||
"is_error": result.is_error,
|
||||
})
|
||||
|
||||
current_messages.append({
|
||||
"role": "user",
|
||||
"content": tool_results,
|
||||
})
|
||||
|
||||
# Max iterations reached
|
||||
return LLMResponse(
|
||||
content="Max tool iterations reached",
|
||||
model=self.model,
|
||||
input_tokens=total_input_tokens,
|
||||
output_tokens=total_output_tokens,
|
||||
stop_reason="max_iterations",
|
||||
raw_response=None,
|
||||
"""Run a tool-use loop until Claude produces a final response (via LiteLLM)."""
|
||||
return self._provider.complete_with_tools(
|
||||
messages=messages,
|
||||
system=system,
|
||||
tools=tools,
|
||||
tool_executor=tool_executor,
|
||||
max_iterations=max_iterations,
|
||||
)
|
||||
|
||||
@@ -4,3 +4,6 @@
|
||||
# Testing
|
||||
pytest>=8.0
|
||||
pytest-asyncio>=0.23
|
||||
|
||||
# Linting
|
||||
ruff>=0.1.0
|
||||
|
||||
@@ -250,7 +250,7 @@ class TestAnthropicProviderBackwardCompatibility:
|
||||
def test_anthropic_provider_init_defaults(self):
|
||||
"""Test AnthropicProvider initialization with defaults."""
|
||||
provider = AnthropicProvider(api_key="test-key")
|
||||
assert provider.model == "claude-sonnet-4-20250514"
|
||||
assert provider.model == "claude-haiku-4-5-20251001"
|
||||
assert provider.api_key == "test-key"
|
||||
|
||||
def test_anthropic_provider_init_custom_model(self):
|
||||
|
||||
@@ -20,7 +20,7 @@ class TestOrchestratorLLMInitialization:
|
||||
with patch.object(LiteLLMProvider, '__init__', return_value=None) as mock_init:
|
||||
orchestrator = AgentOrchestrator()
|
||||
|
||||
mock_init.assert_called_once_with(model="claude-sonnet-4-20250514")
|
||||
mock_init.assert_called_once_with(model="claude-haiku-4-5-20251001")
|
||||
assert orchestrator._llm is not None
|
||||
|
||||
def test_uses_custom_model_parameter(self):
|
||||
|
||||
@@ -33,8 +33,9 @@ class TestRuntimeBasics:
|
||||
"""Cannot end a run that wasn't started."""
|
||||
runtime = Runtime(tmp_path)
|
||||
|
||||
with pytest.raises(RuntimeError, match="No run in progress"):
|
||||
runtime.end_run(success=True)
|
||||
# Should not raise, but log a warning instead
|
||||
runtime.end_run(success=True)
|
||||
assert runtime.current_run is None
|
||||
|
||||
def test_run_saved_on_end(self, tmp_path: Path):
|
||||
"""Run is saved to storage when ended."""
|
||||
@@ -80,13 +81,14 @@ class TestDecisionRecording:
|
||||
"""Cannot record decisions without a run."""
|
||||
runtime = Runtime(tmp_path)
|
||||
|
||||
with pytest.raises(RuntimeError, match="No run in progress"):
|
||||
runtime.decide(
|
||||
intent="Test",
|
||||
options=[{"id": "a", "description": "A"}],
|
||||
chosen="a",
|
||||
reasoning="Test",
|
||||
)
|
||||
# Should not raise, but log a warning and return empty string
|
||||
decision_id = runtime.decide(
|
||||
intent="Test",
|
||||
options=[{"id": "a", "description": "A"}],
|
||||
chosen="a",
|
||||
reasoning="Test",
|
||||
)
|
||||
assert decision_id == ""
|
||||
|
||||
def test_decision_with_node_context(self, tmp_path: Path):
|
||||
"""Test decision with node ID context."""
|
||||
|
||||
Reference in New Issue
Block a user