Skip to content

Commit 9aeed8d

Browse files
committed
Merge branch 'README-changes' of https://github.com/WorkflowAI/python-sdk into README-changes
2 parents 28fe645 + bc4791d commit 9aeed8d

File tree

12 files changed

+137
-36
lines changed

12 files changed

+137
-36
lines changed

.github/workflows/examples.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,7 @@ jobs:
2727
run: poetry install --all-extras
2828

2929
- name: Run all example scripts
30-
run: |
31-
# Find all Python files in examples directory
32-
find examples -name "*.py" -type f | while read -r script; do
33-
echo "Running example: $script"
34-
poetry run python "$script"
35-
if [ $? -ne 0 ]; then
36-
echo "Error: Failed to run $script"
37-
exit 1
38-
fi
39-
done
30+
run: ARGS="-vv" make test.examples
4031
env:
4132
WORKFLOWAI_API_KEY: ${{ secrets.WORKFLOWAI_TEST_API_KEY }}
4233

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ test:
3131
.PHONY: lock
3232
lock:
3333
poetry lock --no-update
34+
35+
test.examples:
36+
poetry run pytest examples -n=5 ${ARGS}

examples/01_basic_agent.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ async def main():
9090
return
9191

9292
# Example 2: Using Tokyo
93-
print("\nExample 2: Using Tokyo")
94-
print("-" * 50)
95-
run = await get_capital_info.run(CityInput(city="Tokyo"))
96-
print(run)
93+
# print("\nExample 2: Using Tokyo")
94+
# print("-" * 50)
95+
# run = await get_capital_info.run(CityInput(city="Tokyo"))
96+
# print(run)
9797

9898
# Fetch and display completions for the Tokyo example
9999
await display_completions(run)

examples/17_multi_model_consensus_with_tools.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import asyncio
2222

23+
import pytest
2324
from pydantic import BaseModel, Field
2425

2526
import workflowai
@@ -131,6 +132,7 @@ async def combine_responses(responses_input: CombinerInput) -> CombinedOutput:
131132
...
132133

133134

135+
@pytest.mark.xfail(reason="Example is flaky")
134136
async def main():
135137
# Example: Scientific explanation
136138
print("\nExample: Scientific Concept")

examples/workflows/agent_delegation.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import asyncio
1818
from typing import Optional
1919

20+
import pytest
2021
from pydantic import BaseModel, Field
2122

2223
import workflowai
@@ -118,7 +119,7 @@ async def delegate_task(agent_input: DelegateInput) -> DelegateOutput:
118119

119120
@workflowai.agent(
120121
id="orchestrator",
121-
model=Model.GPT_4O_LATEST,
122+
model=Model.GEMINI_2_0_FLASH_LATEST,
122123
tools=[delegate_task],
123124
)
124125
async def orchestrator_agent(agent_input: OrchestratorInput) -> OrchestratorOutput:
@@ -148,6 +149,7 @@ async def orchestrator_agent(agent_input: OrchestratorInput) -> OrchestratorOutp
148149
...
149150

150151

152+
@pytest.mark.xfail(reason="Example is flaky")
151153
async def main():
152154
# Example: Software architecture task
153155
print("\nExample: Software Architecture Design")

poetry.lock

Lines changed: 36 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "workflowai"
3-
version = "0.6.6"
3+
version = "0.6.7"
44
description = "Python SDK for WorkflowAI"
55
authors = ["Guillaume Aquilina <guillaume@workflowai.com>"]
66
readme = "README.md"
@@ -20,6 +20,7 @@ ruff = "^0.9.6"
2020
freezegun = "^1.5.1"
2121
pre-commit = "^4.0.1"
2222
pytest-httpx = "^0.35.0"
23+
pytest-xdist = "^3.1.0"
2324
python-dotenv = "^1.0.1"
2425
typer = "^0.15.1"
2526
rich = "^13.7.1"

tests/fixtures/completions2.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"completions": [
3+
{
4+
"messages": [
5+
{
6+
"role": "assistant",
7+
"content": [
8+
{
9+
"type": "text",
10+
"text": "<instructions>\\nFind the capital city of the country where the input city is located.\\n\\nGuidelines:\\n1. First identify the country where the input city is located\\n2. Then provide the capital city of that country\\n3. Include an interesting historical or cultural fact about the capital\\n4. Be accurate and precise with geographical information\\n5. If the input city is itself the capital, still provide the information\\n</instructions>\\n\\nInput will be provided in the user message using a JSON following the schema:\\n```json\\n{\\n \"description\": \"Input model for the city-to-capital agent.\",\\n \"properties\": {\\n \"city\": {\\n \"description\": \"The name of the city for which to find the country\\'s capital\",\\n \"examples\": [\\n \"Paris\",\\n \"New York\",\\n \"Tokyo\"\\n ],\\n \"type\": \"string\"\\n }\\n },\\n \"required\": [\\n \"city\"\\n ],\\n \"type\": \"object\"\\n}\\n```\\n\\nReturn a single JSON object enforcing the following schema:\\n```json\\n{\\n \"description\": \"Output model containing information about the capital city.\",\\n \"properties\": {\\n \"country\": {\\n \"description\": \"The country where the input city is located\",\\n \"examples\": [\\n \"France\",\\n \"United States\",\\n \"Japan\"\\n ],\\n \"type\": \"string\"\\n },\\n \"capital\": {\\n \"description\": \"The capital city of the country\",\\n \"examples\": [\\n \"Paris\",\\n \"Washington D.C.\",\\n \"Tokyo\"\\n ],\\n \"type\": \"string\"\\n },\\n \"fun_fact\": {\\n \"description\": \"An interesting fact about the capital city\",\\n \"examples\": [\\n \"Paris has been the capital of France since 508 CE\"\\n ],\\n \"type\": \"string\"\\n }\\n },\\n \"required\": [\\n \"capital\",\\n \"country\",\\n \"fun_fact\"\\n ],\\n \"type\": \"object\"\\n}\\n```"
11+
}
12+
]
13+
},
14+
{
15+
"role": "user",
16+
"content": [
17+
{
18+
"type": "text",
19+
"text": "Input is:\\n```json\\n{\\n \"city\": \"Paris\"\\n}\\n```"
20+
}
21+
]
22+
}
23+
],
24+
"response": "{\\n \"country\": \"France\",\\n \"capital\": \"Paris\",\\n \"fun_fact\": \"Paris became the capital of France in 508 CE when Clovis I, the first King of the Franks, made the city his seat of power. It\\'s one of the oldest capital cities in Europe and was originally called Lutetia during the Roman period.\"\\n}",
25+
"usage": {
26+
"completion_token_count": 88,
27+
"completion_cost_usd": 0.00132,
28+
"prompt_token_count": 516,
29+
"prompt_cost_usd": 0.0015480000000000001,
30+
"model_context_window_size": 200000
31+
},
32+
"duration_seconds": 4.13,
33+
"provider": "anthropic"
34+
}
35+
]
36+
}

workflowai/core/client/agent_test.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from workflowai.core.client.client import (
2121
WorkflowAI,
2222
)
23-
from workflowai.core.domain.completion import Completion, CompletionUsage, Message
23+
from workflowai.core.domain.completion import Completion, CompletionUsage, Message, TextContent
2424
from workflowai.core.domain.errors import MaxTurnsReachedError, WorkflowAIError
2525
from workflowai.core.domain.run import Run
2626
from workflowai.core.domain.tool_call import ToolCallRequest
@@ -1131,6 +1131,24 @@ async def test_fetch_completions(self, agent: Agent[HelloTaskInput, HelloTaskOut
11311131
),
11321132
]
11331133

1134+
async def test_fetch_completions_content_list(
1135+
self,
1136+
agent: Agent[HelloTaskInput, HelloTaskOutput],
1137+
httpx_mock: HTTPXMock,
1138+
):
1139+
"""Test that fetch_completions correctly fetches and returns completions
1140+
when the message content is a list of objects"""
1141+
# Mock the HTTP response instead of the API client method
1142+
httpx_mock.add_response(
1143+
url="http://localhost:8000/v1/_/agents/123/runs/1/completions",
1144+
json=fixtures_json("completions2.json"),
1145+
)
1146+
1147+
completions = await agent.fetch_completions("1")
1148+
assert len(completions) == 1
1149+
assert isinstance(completions[0].messages[0].content, list)
1150+
assert isinstance(completions[0].messages[0].content[0], TextContent)
1151+
11341152

11351153
class TestStream:
11361154
async def test_stream(self, httpx_mock: HTTPXMock, agent: Agent[HelloTaskInput, HelloTaskOutput]):

workflowai/core/domain/completion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class Message(BaseModel):
7373
"""A message in a completion."""
7474

7575
role: str = ""
76-
content: Union[str, MessageContent] = Field(default="")
76+
content: Union[str, list[MessageContent]] = Field(default="")
7777

7878

7979
class Completion(BaseModel):

0 commit comments

Comments
 (0)