From 046d250ef81a862a0a92fe0b7eab646ceb85bd9d Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 10 Feb 2025 06:46:27 -0600 Subject: [PATCH 1/5] Create 13_templated_instructions.py adds an example on how to use variables in instructions --- examples/13_templated_instructions.py | 176 ++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 examples/13_templated_instructions.py diff --git a/examples/13_templated_instructions.py b/examples/13_templated_instructions.py new file mode 100644 index 0000000..335eaea --- /dev/null +++ b/examples/13_templated_instructions.py @@ -0,0 +1,176 @@ +""" +This example demonstrates how to use templated instructions that adapt based on input variables. +The template variables are automatically populated from the input model's fields. + +The templating uses Jinja2 syntax (server-side rendering): +- {{ variable }} for variable substitution +- {% if condition %} ... {% endif %} for conditionals +- {% for item in items %} ... {% endfor %} for loops +- {{ loop.index }} for loop indices + +For full Jinja2 template syntax documentation, see: +https://jinja.palletsprojects.com/en/stable/ + +It showcases: +1. Simple variable substitution +2. Conditional logic +3. Loops +4. Nested conditionals +""" + +import asyncio +from typing import List + +from pydantic import BaseModel, Field + +import workflowai +from workflowai import Model, Run + + +class CodeReviewInput(BaseModel): + """Input model for the code review agent.""" + language: str = Field( + description="The programming language of the code to review", + examples=["python", "javascript", "typescript"], + ) + code: str = Field( + description="The code to review", + ) + style_guide: str = Field( + description="The style guide to follow", + examples=["PEP 8", "Google Style", "Airbnb"], + ) + is_production: bool = Field( + description="Whether this is a production code review", + default=False, + ) + required_checks: List[str] = Field( + description="List of specific checks to perform", + default=["code style", "performance", "maintainability"], + ) + security_level: str = Field( + description="Required security level", + default="standard", + examples=["standard", "high"], + ) + + +class CodeReviewOutput(BaseModel): + """Output model containing the code review results.""" + overall_assessment: str = Field( + description="Overall assessment of the code quality", + ) + style_violations: List[str] = Field( + description="List of style guide violations", + ) + security_issues: List[str] = Field( + description="List of security concerns", + default_factory=list, + ) + suggested_improvements: List[str] = Field( + description="List of suggested improvements", + ) + + +@workflowai.agent( + id="templated-code-reviewer", + model=Model.CLAUDE_3_5_SONNET_LATEST, +) +async def review_code(review_input: CodeReviewInput) -> Run[CodeReviewOutput]: + """ + Review code based on specified parameters and guidelines. + + You are a code reviewer for {{ language }} code. + Please review the code according to the {{ style_guide }} style guide. + + {% if is_production %} + This is a PRODUCTION code review - please be extra thorough and strict about best practices. + {% else %} + This is a development code review - focus on maintainability and clarity. + {% endif %} + + Required checks to perform: + {% for check in required_checks %}{{ loop.index }}. {{ check }} + {% endfor %} + + {% if security_level == "high" %} + Additional security requirements: + - Must follow secure coding practices + - Check for potential security vulnerabilities + - Ensure all inputs are properly sanitized + {% endif %} + + Guidelines: + 1. Check for adherence to {{ style_guide }} conventions + 2. Look for potential bugs and performance issues + 3. Suggest improvements while keeping the {{ language }} best practices in mind + + {% if language == "python" %} + Python-specific checks: + - Type hints usage + - PEP 8 compliance + - Docstring format + {% elif language == "javascript" or language == "typescript" %} + JavaScript/TypeScript-specific checks: + - ESLint rules compliance + - Modern ES6+ features usage + - Browser compatibility + {% endif %} + + Please analyze the following code and provide: + 1. An overall assessment + 2. Style guide violations + 3. Security issues (if any) + 4. Suggested improvements + """ + ... + + +async def main(): + # Example 1: Python code review for development + print("\nExample 1: Python Development Code Review") + print("-" * 50) + python_code = """ +def calculate_sum(numbers): + result = 0 + for n in numbers: + result = result + n + return result + """ + + run = await review_code( + CodeReviewInput( + language="python", + code=python_code, + style_guide="PEP 8", + required_checks=["type hints", "docstring", "performance"], + ), + ) + print(run) + + # Example 2: TypeScript production code with high security + print("\nExample 2: TypeScript Production Code Review (High Security)") + print("-" * 50) + typescript_code = """ +function processUserData(data: any) { + const userId = data.id; + const query = `SELECT * FROM users WHERE id = ${userId}`; + return executeQuery(query); +} + """ + + run = await review_code( + CodeReviewInput( + language="typescript", + code=typescript_code, + style_guide="Airbnb", + is_production=True, + security_level="high", + required_checks=["security", "type safety", "SQL injection"], + ), + ) + print(run) + + +if __name__ == "__main__": + asyncio.run(main()) From 3dc3793e9a75782719832c6ce1d056c9dc503ae0 Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 10 Feb 2025 06:50:16 -0600 Subject: [PATCH 2/5] rename to example 14 --- ...{13_templated_instructions.py => 14_templated_instructions.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{13_templated_instructions.py => 14_templated_instructions.py} (100%) diff --git a/examples/13_templated_instructions.py b/examples/14_templated_instructions.py similarity index 100% rename from examples/13_templated_instructions.py rename to examples/14_templated_instructions.py From b5573a7f421cc5b1b93a4b34d06c21fc9a3a940f Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 10 Feb 2025 10:14:38 -0600 Subject: [PATCH 3/5] Update README.md --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/README.md b/README.md index 5fab7f1..3a7545f 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,63 @@ async def analyze_call_feedback(input: CallFeedbackInput) -> CallFeedbackOutput: > a newer version of the same model with the same or a lower price so calling the api with > a retired model will always work. +### Using templated instructions + +You can use [Jinja2](https://jinja.palletsprojects.com/)-style templating in your agent's instructions (docstring) to make them dynamic based on input values. The template variables are automatically populated from the fields in your input model. + +```python +class CodeReviewInput(BaseModel): + language: str = Field(description="Programming language of the code") + style_guide: str = Field(description="Style guide to follow") + is_production: bool = Field(description="Whether this is a production review") + focus_areas: List[str] = Field(description="Areas to focus on during review", default_factory=list) + +class CodeReviewOutput(BaseModel): + """Output from a code review.""" + issues: List[str] = Field( + default_factory=list, + description="List of identified issues or suggestions for improvement" + ) + compliments: List[str] = Field( + default_factory=list, + description="List of positive aspects and good practices found in the code" + ) + summary: str = Field( + description="A brief summary of the code review findings" + ) + +@workflowai.agent(id="code-review") +async def review_code(review_input: CodeReviewInput) -> CodeReviewOutput: + """ + You are a code reviewer for {{ language }} code. + Please review according to the {{ style_guide }} style guide. + + {% if is_production %} + This is a PRODUCTION review - be extra thorough and strict. + {% else %} + This is a development review - focus on maintainability. + {% endif %} + + {% if focus_areas %} + Key areas to focus on: + {% for area in focus_areas %} + {{ loop.index }}. {{ area }} + {% endfor %} + {% endif %} + """ + ... +``` + +The template uses [Jinja2](https://jinja.palletsprojects.com/) syntax and supports common templating features including: +- Variable substitution: `{{ variable }}` +- Conditionals: `{% if condition %}...{% endif %}` +- Loops: `{% for item in items %}...{% endfor %}` +- Loop indices: `{{ loop.index }}` + +See the [Jinja2 documentation](https://jinja.palletsprojects.com/) for the full template syntax and capabilities. + +We recommend using ChatGPT or CursorAI to help generate the template. + ### Version from code or deployments Setting a docstring or a model in the agent decorator signals the client that the agent parameters are From 9333d9c4bdfdeb2a1ee5d5c15e3e45050cc9f7e0 Mon Sep 17 00:00:00 2001 From: Guillaume Aquilina Date: Fri, 14 Feb 2025 09:43:24 -0500 Subject: [PATCH 4/5] fix: lint replace List --- README.md | 7 ++++--- examples/14_templated_instructions.py | 11 ++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e330f65..aa70ef7 100644 --- a/README.md +++ b/README.md @@ -207,15 +207,15 @@ class CodeReviewInput(BaseModel): language: str = Field(description="Programming language of the code") style_guide: str = Field(description="Style guide to follow") is_production: bool = Field(description="Whether this is a production review") - focus_areas: List[str] = Field(description="Areas to focus on during review", default_factory=list) + focus_areas: list[str] = Field(description="Areas to focus on during review", default_factory=list) class CodeReviewOutput(BaseModel): """Output from a code review.""" - issues: List[str] = Field( + issues: list[str] = Field( default_factory=list, description="List of identified issues or suggestions for improvement" ) - compliments: List[str] = Field( + compliments: list[str] = Field( default_factory=list, description="List of positive aspects and good practices found in the code" ) @@ -246,6 +246,7 @@ async def review_code(review_input: CodeReviewInput) -> CodeReviewOutput: ``` The template uses [Jinja2](https://jinja.palletsprojects.com/) syntax and supports common templating features including: + - Variable substitution: `{{ variable }}` - Conditionals: `{% if condition %}...{% endif %}` - Loops: `{% for item in items %}...{% endfor %}` diff --git a/examples/14_templated_instructions.py b/examples/14_templated_instructions.py index 335eaea..3e13eb8 100644 --- a/examples/14_templated_instructions.py +++ b/examples/14_templated_instructions.py @@ -19,7 +19,6 @@ """ import asyncio -from typing import List from pydantic import BaseModel, Field @@ -29,6 +28,7 @@ class CodeReviewInput(BaseModel): """Input model for the code review agent.""" + language: str = Field( description="The programming language of the code to review", examples=["python", "javascript", "typescript"], @@ -44,7 +44,7 @@ class CodeReviewInput(BaseModel): description="Whether this is a production code review", default=False, ) - required_checks: List[str] = Field( + required_checks: list[str] = Field( description="List of specific checks to perform", default=["code style", "performance", "maintainability"], ) @@ -57,17 +57,18 @@ class CodeReviewInput(BaseModel): class CodeReviewOutput(BaseModel): """Output model containing the code review results.""" + overall_assessment: str = Field( description="Overall assessment of the code quality", ) - style_violations: List[str] = Field( + style_violations: list[str] = Field( description="List of style guide violations", ) - security_issues: List[str] = Field( + security_issues: list[str] = Field( description="List of security concerns", default_factory=list, ) - suggested_improvements: List[str] = Field( + suggested_improvements: list[str] = Field( description="List of suggested improvements", ) From 2e92bd63661fc671b1c68f6ee1909275a75cfabc Mon Sep 17 00:00:00 2001 From: Pierre Date: Mon, 17 Feb 2025 09:32:38 -0700 Subject: [PATCH 5/5] feat: add code field to template output for better context --- examples/14_templated_instructions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/14_templated_instructions.py b/examples/14_templated_instructions.py index 3e13eb8..650f2b4 100644 --- a/examples/14_templated_instructions.py +++ b/examples/14_templated_instructions.py @@ -123,6 +123,9 @@ async def review_code(review_input: CodeReviewInput) -> Run[CodeReviewOutput]: 2. Style guide violations 3. Security issues (if any) 4. Suggested improvements + + The code is: + {{ code }} """ ...