Skip to content

feat(run): add run URL to format_output #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 21, 2025
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
5 changes: 5 additions & 0 deletions workflowai/core/domain/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def format_output(self) -> str:
1. The output as a nicely formatted JSON object
2. The cost with $ prefix (if available)
3. The latency with 2 decimal places and 's' suffix (if available)
4. The run URL for viewing in the web UI

Example:
Output:
Expand All @@ -100,6 +101,7 @@ def format_output(self) -> str:
==================================================
Cost: $ 0.001
Latency: 1.23s
URL: https://workflowai.com/_/agents/agent-1/runs/test-id
"""
# Format the output string
output = [
Expand All @@ -115,6 +117,9 @@ def format_output(self) -> str:
if self.duration_seconds is not None:
output.append(f"Latency: {self.duration_seconds:.2f}s")

# Always add the run URL
output.append(f"URL: {self.run_url}")

return "\n".join(output)

def __str__(self) -> str:
Expand Down
38 changes: 23 additions & 15 deletions workflowai/core/domain/run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class _TestOutput(BaseModel):
@pytest.fixture
def run1() -> Run[_TestOutput]:
return Run[_TestOutput](
id="test-id",
agent_id="agent-1",
id="run-id",
agent_id="agent-id",
schema_id=1,
output=_TestOutput(message="test output"),
duration_seconds=1.0,
Expand Down Expand Up @@ -51,10 +51,12 @@ def test_different_agents(self, run1: Run[_TestOutput], run2: Run[_TestOutput]):
# 1. The output as a JSON object
# 2. The cost with $ prefix and correct precision
# 3. The latency with 2 decimal places and 's' suffix
def test_format_output() -> None:
# 4. The run URL
@patch("workflowai.env.WORKFLOWAI_APP_URL", "https://workflowai.hello")
def test_format_output_full():
run = Run[_TestOutput](
id="test-id",
agent_id="agent-1",
id="run-id",
agent_id="agent-id",
schema_id=1,
output=_TestOutput(message="hello"),
duration_seconds=1.23,
Expand All @@ -68,15 +70,17 @@ def test_format_output() -> None:
}
==================================================
Cost: $ 0.00100
Latency: 1.23s"""
Latency: 1.23s
URL: https://workflowai.hello/_/agents/agent-id/runs/run-id"""

assert run.format_output() == expected


def test_format_output_very_low_cost() -> None:
@patch("workflowai.env.WORKFLOWAI_APP_URL", "https://workflowai.hello")
def test_format_output_very_low_cost():
run = Run[_TestOutput](
id="test-id",
agent_id="agent-1",
id="run-id",
agent_id="agent-id",
schema_id=1,
output=_TestOutput(message="hello"),
duration_seconds=1.23,
Expand All @@ -90,18 +94,21 @@ def test_format_output_very_low_cost() -> None:
}
==================================================
Cost: $ 0.00005
Latency: 1.23s"""
Latency: 1.23s
URL: https://workflowai.hello/_/agents/agent-id/runs/run-id"""

assert run.format_output() == expected


# Test that format_output works correctly when cost and latency are not provided:
# 1. The output is still formatted as a JSON object
# 2. No cost or latency lines are included in the output
def test_format_output_no_cost_latency() -> None:
# 3. The run URL is still included
@patch("workflowai.env.WORKFLOWAI_APP_URL", "https://workflowai.hello")
def test_format_output_no_cost_latency():
run = Run[_TestOutput](
id="test-id",
agent_id="agent-1",
id="run-id",
agent_id="agent-id",
schema_id=1,
output=_TestOutput(message="hello"),
)
Expand All @@ -111,12 +118,13 @@ def test_format_output_no_cost_latency() -> None:
{
"message": "hello"
}
=================================================="""
==================================================
URL: https://workflowai.hello/_/agents/agent-id/runs/run-id"""

assert run.format_output() == expected


class TestRunURL:
@patch("workflowai.env.WORKFLOWAI_APP_URL", "https://workflowai.hello")
def test_run_url(self, run1: Run[_TestOutput]):
assert run1.run_url == "https://workflowai.hello/_/agents/agent-1/runs/test-id"
assert run1.run_url == "https://workflowai.hello/_/agents/agent-id/runs/run-id"