Skip to content

Commit ce85f56

Browse files
author
Pierre
committed
Merge main into pierre-readme, keeping pierre-readme changes for README.md
2 parents 3c1370a + 93f3a47 commit ce85f56

31 files changed

+1996
-87
lines changed

examples/02_agent_with_tools.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""
2+
This example demonstrates how to create a WorkflowAI agent that uses tools to enhance its capabilities.
3+
It showcases:
4+
5+
1. Using built-in WorkflowAI tools (@search-google)
6+
2. Creating and using custom tools
7+
3. Combining multiple tools in a single agent
8+
"""
9+
10+
import asyncio
11+
from datetime import date, datetime
12+
from zoneinfo import ZoneInfo
13+
14+
from pydantic import BaseModel, Field
15+
16+
import workflowai
17+
from workflowai import Model
18+
19+
20+
def get_current_date() -> str:
21+
"""Return today's date in ISO format (YYYY-MM-DD)"""
22+
return datetime.now(tz=ZoneInfo("UTC")).date().isoformat()
23+
24+
25+
def calculate_days_between(date1: str, date2: str) -> int:
26+
"""Calculate the number of days between two dates in ISO format (YYYY-MM-DD)"""
27+
d1 = date.fromisoformat(date1)
28+
d2 = date.fromisoformat(date2)
29+
return abs((d2 - d1).days)
30+
31+
32+
class HistoricalEventInput(BaseModel):
33+
"""Input model for querying historical events."""
34+
query: str = Field(
35+
description="A query about a historical event",
36+
examples=[
37+
"When was the first moon landing?",
38+
"When did World War II end?",
39+
"When was the Declaration of Independence signed?",
40+
],
41+
)
42+
43+
44+
class HistoricalEventOutput(BaseModel):
45+
"""Output model containing information about a historical event."""
46+
event_date: str = Field(
47+
description="The date of the event in ISO format (YYYY-MM-DD)",
48+
examples=["1969-07-20", "1945-09-02", "1776-07-04"],
49+
)
50+
event_description: str = Field(
51+
description="A brief description of the event",
52+
examples=[
53+
"Apollo 11 astronauts Neil Armstrong and Buzz Aldrin became the first humans to land on the Moon",
54+
"Japan formally surrendered to the Allied Powers aboard the USS Missouri in Tokyo Bay",
55+
],
56+
)
57+
days_since_event: int = Field(
58+
description="Number of days between the event and today",
59+
examples=[19876, 28490, 90123],
60+
)
61+
62+
63+
@workflowai.agent(
64+
id="historical-event-analyzer",
65+
model=Model.GEMINI_1_5_FLASH_LATEST,
66+
tools=[get_current_date, calculate_days_between],
67+
)
68+
async def analyze_historical_event(event_input: HistoricalEventInput) -> HistoricalEventOutput:
69+
"""
70+
Find information about historical events and calculate days since they occurred.
71+
72+
You have access to these tools:
73+
1. @search-google - Use this to find accurate information about events
74+
2. get_current_date - Use this to get today's date for calculating days since the event
75+
3. calculate_days_between - Calculate days between two dates (format: YYYY-MM-DD)
76+
77+
Guidelines:
78+
1. Use @search-google to find accurate event information
79+
2. Use get_current_date to get today's date
80+
3. Use calculate_days_between to compute days since the event
81+
4. Return dates in ISO format (YYYY-MM-DD)
82+
5. Be precise with dates and descriptions
83+
"""
84+
...
85+
86+
87+
async def main():
88+
# Example: Query about the moon landing
89+
print("\nExample: First Moon Landing")
90+
print("-" * 50)
91+
run = await analyze_historical_event.run(
92+
HistoricalEventInput(query="When was the first moon landing?"),
93+
)
94+
print(run)
95+
96+
# Example: Query about World War II
97+
print("\nExample: End of World War II")
98+
print("-" * 50)
99+
run = await analyze_historical_event.run(
100+
HistoricalEventInput(query="When did World War II end?"),
101+
)
102+
print(run)
103+
104+
105+
if __name__ == "__main__":
106+
asyncio.run(main())

examples/14_templated_instructions.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""
2+
This example demonstrates how to use templated instructions that adapt based on input variables.
3+
The template variables are automatically populated from the input model's fields.
4+
5+
The templating uses Jinja2 syntax (server-side rendering):
6+
- {{ variable }} for variable substitution
7+
- {% if condition %} ... {% endif %} for conditionals
8+
- {% for item in items %} ... {% endfor %} for loops
9+
- {{ loop.index }} for loop indices
10+
11+
For full Jinja2 template syntax documentation, see:
12+
https://jinja.palletsprojects.com/en/stable/
13+
14+
It showcases:
15+
1. Simple variable substitution
16+
2. Conditional logic
17+
3. Loops
18+
4. Nested conditionals
19+
"""
20+
21+
import asyncio
22+
23+
from pydantic import BaseModel, Field
24+
25+
import workflowai
26+
from workflowai import Model, Run
27+
28+
29+
class CodeReviewInput(BaseModel):
30+
"""Input model for the code review agent."""
31+
32+
language: str = Field(
33+
description="The programming language of the code to review",
34+
examples=["python", "javascript", "typescript"],
35+
)
36+
code: str = Field(
37+
description="The code to review",
38+
)
39+
style_guide: str = Field(
40+
description="The style guide to follow",
41+
examples=["PEP 8", "Google Style", "Airbnb"],
42+
)
43+
is_production: bool = Field(
44+
description="Whether this is a production code review",
45+
default=False,
46+
)
47+
required_checks: list[str] = Field(
48+
description="List of specific checks to perform",
49+
default=["code style", "performance", "maintainability"],
50+
)
51+
security_level: str = Field(
52+
description="Required security level",
53+
default="standard",
54+
examples=["standard", "high"],
55+
)
56+
57+
58+
class CodeReviewOutput(BaseModel):
59+
"""Output model containing the code review results."""
60+
61+
overall_assessment: str = Field(
62+
description="Overall assessment of the code quality",
63+
)
64+
style_violations: list[str] = Field(
65+
description="List of style guide violations",
66+
)
67+
security_issues: list[str] = Field(
68+
description="List of security concerns",
69+
default_factory=list,
70+
)
71+
suggested_improvements: list[str] = Field(
72+
description="List of suggested improvements",
73+
)
74+
75+
76+
@workflowai.agent(
77+
id="templated-code-reviewer",
78+
model=Model.CLAUDE_3_5_SONNET_LATEST,
79+
)
80+
async def review_code(review_input: CodeReviewInput) -> Run[CodeReviewOutput]:
81+
"""
82+
Review code based on specified parameters and guidelines.
83+
84+
You are a code reviewer for {{ language }} code.
85+
Please review the code according to the {{ style_guide }} style guide.
86+
87+
{% if is_production %}
88+
This is a PRODUCTION code review - please be extra thorough and strict about best practices.
89+
{% else %}
90+
This is a development code review - focus on maintainability and clarity.
91+
{% endif %}
92+
93+
Required checks to perform:
94+
{% for check in required_checks %}{{ loop.index }}. {{ check }}
95+
{% endfor %}
96+
97+
{% if security_level == "high" %}
98+
Additional security requirements:
99+
- Must follow secure coding practices
100+
- Check for potential security vulnerabilities
101+
- Ensure all inputs are properly sanitized
102+
{% endif %}
103+
104+
Guidelines:
105+
1. Check for adherence to {{ style_guide }} conventions
106+
2. Look for potential bugs and performance issues
107+
3. Suggest improvements while keeping the {{ language }} best practices in mind
108+
109+
{% if language == "python" %}
110+
Python-specific checks:
111+
- Type hints usage
112+
- PEP 8 compliance
113+
- Docstring format
114+
{% elif language == "javascript" or language == "typescript" %}
115+
JavaScript/TypeScript-specific checks:
116+
- ESLint rules compliance
117+
- Modern ES6+ features usage
118+
- Browser compatibility
119+
{% endif %}
120+
121+
Please analyze the following code and provide:
122+
1. An overall assessment
123+
2. Style guide violations
124+
3. Security issues (if any)
125+
4. Suggested improvements
126+
127+
The code is:
128+
{{ code }}
129+
"""
130+
...
131+
132+
133+
async def main():
134+
# Example 1: Python code review for development
135+
print("\nExample 1: Python Development Code Review")
136+
print("-" * 50)
137+
python_code = """
138+
def calculate_sum(numbers):
139+
result = 0
140+
for n in numbers:
141+
result = result + n
142+
return result
143+
"""
144+
145+
run = await review_code(
146+
CodeReviewInput(
147+
language="python",
148+
code=python_code,
149+
style_guide="PEP 8",
150+
required_checks=["type hints", "docstring", "performance"],
151+
),
152+
)
153+
print(run)
154+
155+
# Example 2: TypeScript production code with high security
156+
print("\nExample 2: TypeScript Production Code Review (High Security)")
157+
print("-" * 50)
158+
typescript_code = """
159+
function processUserData(data: any) {
160+
const userId = data.id;
161+
const query = `SELECT * FROM users WHERE id = ${userId}`;
162+
return executeQuery(query);
163+
}
164+
"""
165+
166+
run = await review_code(
167+
CodeReviewInput(
168+
language="typescript",
169+
code=typescript_code,
170+
style_guide="Airbnb",
171+
is_production=True,
172+
security_level="high",
173+
required_checks=["security", "type safety", "SQL injection"],
174+
),
175+
)
176+
print(run)
177+
178+
179+
if __name__ == "__main__":
180+
asyncio.run(main())

0 commit comments

Comments
 (0)