Skip to content

Commit 09ed9b4

Browse files
author
Pierre
authored
Merge branch 'main' into pierre-clean-docstring
2 parents 1c26afd + fd1a19c commit 09ed9b4

File tree

13 files changed

+604
-34
lines changed

13 files changed

+604
-34
lines changed

.vscode/launch.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
{
22
"version": "0.2.0",
33
"configurations": [
4+
{
5+
"name": "Python Debugger: Current File",
6+
"type": "debugpy",
7+
"request": "launch",
8+
"program": "${file}",
9+
"console": "integratedTerminal"
10+
},
411
{
512
"name": "Python: Debug Tests",
613
"type": "debugpy",

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "workflowai"
3-
version = "0.6.0.dev6"
3+
version = "0.6.0.dev8"
44
description = ""
55
authors = ["Guillaume Aquilina <[email protected]>"]
66
readme = "README.md"

tests/e2e/no_schema_test.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,13 @@ async def summarize(_: SummarizeTaskInput) -> SummarizeTaskOutput: ...
1818

1919

2020
async def test_summarize():
21-
summarized = await summarize(SummarizeTaskInput(text="Hello, world!"))
21+
summarized = await summarize(
22+
SummarizeTaskInput(
23+
text="""The first computer programmer was Ada Lovelace. She wrote the first algorithm
24+
intended to be processed by a machine in the 1840s. Her work was on Charles Babbage's
25+
proposed mechanical computer, the Analytical Engine. She is celebrated annually on Ada
26+
Lovelace Day, which promotes women in science and technology.""",
27+
),
28+
use_cache="never",
29+
)
2230
assert summarized.summary_points

tests/integration/conftest.py

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
2-
from typing import Any, Optional
2+
from collections.abc import Callable
3+
from typing import Any, Optional, Union
34
from unittest.mock import patch
45

56
import pytest
@@ -51,34 +52,70 @@ def mock_response(
5152
status_code=status_code,
5253
)
5354

54-
def mock_stream(self, task_id: str = "city-to-capital"):
55+
def mock_stream(
56+
self,
57+
task_id: str = "city-to-capital",
58+
outputs: Optional[list[dict[str, Any]]] = None,
59+
run_id: str = "1",
60+
metadata: Optional[dict[str, Any]] = None,
61+
):
62+
outputs = outputs or [
63+
{"capital": ""},
64+
{"capital": "Tok"},
65+
{"capital": "Tokyo"},
66+
]
67+
if metadata is None:
68+
metadata = {"cost_usd": 0.01, "duration_seconds": 10.1}
69+
70+
payloads = [{"id": run_id, "task_output": o} for o in outputs]
71+
72+
final_payload = {**payloads[-1], **metadata}
73+
payloads.append(final_payload)
74+
streams = [f"data: {json.dumps(p)}\n\n".encode() for p in payloads]
75+
5576
self.httpx_mock.add_response(
5677
url=f"https://run.workflowai.dev/v1/_/agents/{task_id}/schemas/1/run",
57-
stream=IteratorStream(
58-
[
59-
b'data: {"id":"1","task_output":{"capital":""}}\n\n',
60-
b'data: {"id":"1","task_output":{"capital":"Tok"}}\n\ndata: {"id":"1","task_output":{"capital":"Tokyo"}}\n\n', # noqa: E501
61-
b'data: {"id":"1","task_output":{"capital":"Tokyo"},"cost_usd":0.01,"duration_seconds":10.1}\n\n',
62-
],
63-
),
78+
stream=IteratorStream(streams),
6479
)
6580

81+
def check_register(
82+
self,
83+
task_id: str = "city-to-capital",
84+
input_schema: Optional[Union[dict[str, Any], Callable[[dict[str, Any]], None]]] = None,
85+
output_schema: Optional[Union[dict[str, Any], Callable[[dict[str, Any]], None]]] = None,
86+
):
87+
request = self.httpx_mock.get_request(url=self.REGISTER_URL)
88+
assert request is not None
89+
assert request.headers["Authorization"] == "Bearer test"
90+
assert request.headers["Content-Type"] == "application/json"
91+
assert request.headers["x-workflowai-source"] == "sdk"
92+
assert request.headers["x-workflowai-language"] == "python"
93+
94+
body = json.loads(request.content)
95+
assert body["id"] == task_id
96+
if callable(input_schema):
97+
input_schema(body["input_schema"])
98+
else:
99+
assert body["input_schema"] == input_schema or {"city": {"type": "string"}}
100+
if callable(output_schema):
101+
output_schema(body["output_schema"])
102+
else:
103+
assert body["output_schema"] == output_schema or {"capital": {"type": "string"}}
104+
66105
def check_request(
67106
self,
68107
version: Any = "production",
69108
task_id: str = "city-to-capital",
70109
task_input: Optional[dict[str, Any]] = None,
71110
**matchers: Any,
72111
):
112+
if not matchers:
113+
matchers = {"url": f"https://run.workflowai.dev/v1/_/agents/{task_id}/schemas/1/run"}
73114
request = self.httpx_mock.get_request(**matchers)
74115
assert request is not None
75-
assert request.url == f"https://run.workflowai.dev/v1/_/agents/{task_id}/schemas/1/run"
76116
body = json.loads(request.content)
77-
assert body == {
78-
"task_input": task_input or {"city": "Hello"},
79-
"version": version,
80-
"stream": False,
81-
}
117+
assert body["task_input"] == task_input or {"city": "Hello"}
118+
assert body["version"] == version
82119
assert request.headers["Authorization"] == "Bearer test"
83120
assert request.headers["Content-Type"] == "application/json"
84121
assert request.headers["x-workflowai-source"] == "sdk"

tests/integration/run_test.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ async def city_to_capital(task_input: CityToCapitalTaskInput) -> Run[CityToCapit
5252
test_client.check_request(version="staging")
5353

5454

55+
async def test_run_task_run_with_model(test_client: IntTestClient) -> None:
56+
@workflowai.agent(schema_id=1, version="staging")
57+
async def city_to_capital(task_input: CityToCapitalTaskInput) -> Run[CityToCapitalTaskOutput]: ...
58+
59+
test_client.mock_response()
60+
61+
task_input = CityToCapitalTaskInput(city="Hello")
62+
with_run = await city_to_capital(task_input, model="gpt-4o-latest")
63+
64+
assert with_run.id == "123"
65+
assert with_run.output.capital == "Tokyo"
66+
67+
test_client.check_request(version={"model": "gpt-4o-latest"})
68+
69+
5570
async def test_stream_task_run(test_client: IntTestClient) -> None:
5671
@workflowai.agent(schema_id=1)
5772
def city_to_capital(task_input: CityToCapitalTaskInput) -> AsyncIterator[CityToCapitalTaskOutput]: ...
@@ -112,27 +127,23 @@ async def city_to_capital(task_input: CityToCapitalTaskInput) -> CityToCapitalTa
112127
"input_schema": {
113128
"properties": {
114129
"city": {
115-
"title": "City",
116130
"type": "string",
117131
},
118132
},
119133
"required": [
120134
"city",
121135
],
122-
"title": "CityToCapitalTaskInput",
123136
"type": "object",
124137
},
125138
"output_schema": {
126139
"properties": {
127140
"capital": {
128-
"title": "Capital",
129141
"type": "string",
130142
},
131143
},
132144
"required": [
133145
"capital",
134146
],
135-
"title": "CityToCapitalTaskOutput",
136147
"type": "object",
137148
},
138149
}

0 commit comments

Comments
 (0)