-
Notifications
You must be signed in to change notification settings - Fork 19
feat(templating): Add templating support for InstructionProvider #30
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
Open
Jainish-S
wants to merge
1
commit into
google:main
Choose a base branch
from
Jainish-S:feat/6-add-templating
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
contributing/samples/templating/django_content_moderator/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| from . import agent |
144 changes: 144 additions & 0 deletions
144
contributing/samples/templating/django_content_moderator/agent.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """Content moderator bot example using DjangoInstructionProvider. | ||
|
|
||
| This example demonstrates how to use Django templating for dynamic agent | ||
| instructions that leverage Django's familiar syntax and built-in filters. | ||
|
|
||
| The agent reviews user-generated content and provides moderation decisions, | ||
| showcasing Django template features like filters and for...empty tags. | ||
|
|
||
| Usage: | ||
| adk run contributing/samples/templating/django_content_moderator | ||
| """ | ||
|
|
||
| from google.adk.agents import Agent | ||
| from google.adk.agents.callback_context import CallbackContext | ||
| from google.adk_community.templating import DjangoInstructionProvider | ||
|
|
||
|
|
||
| def populate_moderation_queue(callback_context: CallbackContext): | ||
| """Populate the session state with content moderation queue. | ||
|
|
||
| In a real application, this would fetch content from a moderation system. | ||
| For this demo, we use sample data. | ||
| """ | ||
| callback_context.state['platform_name'] = 'SocialHub' | ||
| callback_context.state['moderator_name'] = 'Alex Chen' | ||
|
|
||
| callback_context.state['pending_content'] = [ | ||
| { | ||
| 'id': 'POST-001', | ||
| 'type': 'Comment', | ||
| 'author': 'user123', | ||
| 'text': 'Great product! Highly recommended.', | ||
| 'reports': 0, | ||
| 'flagged_words': [], | ||
| }, | ||
| { | ||
| 'id': 'POST-002', | ||
| 'type': 'Review', | ||
| 'author': 'angry_customer', | ||
| 'text': 'This is terrible service! Very disappointed.', | ||
| 'reports': 3, | ||
| 'flagged_words': ['terrible'], | ||
| }, | ||
| { | ||
| 'id': 'POST-003', | ||
| 'type': 'Forum Post', | ||
| 'author': 'spammer99', | ||
| 'text': 'Click here for free stuff!!!', | ||
| 'reports': 5, | ||
| 'flagged_words': ['click here', 'free'], | ||
| }, | ||
| ] | ||
|
|
||
| callback_context.state['moderation_stats'] = { | ||
| 'total_reviewed_today': 47, | ||
| 'approved': 32, | ||
| 'rejected': 10, | ||
| 'pending': 5, | ||
| } | ||
|
|
||
|
|
||
| # Define the Django template for instructions | ||
| # Django uses {{ }} for variables, {% %} for tags, and | for filters | ||
| CONTENT_MODERATOR_TEMPLATE = """ | ||
| You are a Content Moderation Agent for {{ platform_name }}. | ||
| Moderator: {{ moderator_name }} | ||
|
|
||
| MODERATION QUEUE | ||
| ================ | ||
| {% if pending_content %} | ||
| {{ pending_content|length }} item{{ pending_content|length|pluralize }} pending review: | ||
|
|
||
| {% for item in pending_content %} | ||
| [{{ item.id }}] {{ item.type }} by @{{ item.author }} | ||
| Content: "{{ item.text|truncatewords:15 }}" | ||
| Reports: {{ item.reports }} | ||
| {% if item.flagged_words %} | ||
| ⚠️ Flagged Keywords: {{ item.flagged_words|join:", " }} | ||
| {% endif %} | ||
| {% if item.reports > 2 %} | ||
| 🔴 HIGH PRIORITY - Multiple user reports! | ||
| {% elif item.reports > 0 %} | ||
| ⚠️ MEDIUM PRIORITY - User reported | ||
| {% else %} | ||
| ✅ LOW PRIORITY - No reports | ||
| {% endif %} | ||
| --- | ||
| {% endfor %} | ||
| {% else %} | ||
| ✅ Queue is clear! No content pending moderation. | ||
| {% endif %} | ||
|
|
||
| TODAY'S MODERATION STATS | ||
| ======================== | ||
| Total Reviewed: {{ moderation_stats.total_reviewed_today }} | ||
| Approved: {{ moderation_stats.approved }} ({{ moderation_stats.approved|add:0|floatformat:0 }}) | ||
| Rejected: {{ moderation_stats.rejected }} | ||
| Still Pending: {{ moderation_stats.pending }} | ||
|
|
||
| INSTRUCTIONS | ||
| ============ | ||
| Review each piece of content and determine if it should be: | ||
| 1. **APPROVED** - Complies with community guidelines | ||
| 2. **REJECTED** - Violates guidelines (spam, harassment, etc.) | ||
| 3. **FLAGGED FOR HUMAN REVIEW** - Edge case requiring manual review | ||
|
|
||
| Guidelines: | ||
| - Multiple reports or flagged keywords warrant careful review | ||
| - Consider context, not just keywords | ||
| - Err on the side of caution for borderline cases | ||
| - Be fair and consistent | ||
| - Provide clear reasoning for decisions | ||
|
|
||
| {% if pending_content %} | ||
| Prioritize items with the most reports first. | ||
| {% endif %} | ||
|
|
||
| Be objective, thorough, and protect the community while respecting free expression. | ||
| """.strip() | ||
|
|
||
| # Create the provider with the template | ||
| instruction_provider = DjangoInstructionProvider(CONTENT_MODERATOR_TEMPLATE) | ||
|
|
||
| # Create the agent | ||
| root_agent = Agent( | ||
| name='content_moderator_agent', | ||
| model='gemini-2.0-flash', | ||
| instruction=instruction_provider, | ||
| before_agent_callback=[populate_moderation_queue], | ||
| ) | ||
15 changes: 15 additions & 0 deletions
15
contributing/samples/templating/jinja2_devops_bot/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| from . import agent |
98 changes: 98 additions & 0 deletions
98
contributing/samples/templating/jinja2_devops_bot/agent.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """DevOps bot example using Jinja2InstructionProvider. | ||
|
|
||
| This example demonstrates how to use Jinja2 templating for dynamic agent | ||
| instructions that adapt based on system state. | ||
|
|
||
| The agent monitors server status and provides recommendations based on | ||
| CPU usage, using Jinja2's powerful features like loops, conditionals, | ||
| and filters. | ||
|
|
||
| Usage: | ||
| adk run contributing/samples/templating/jinja2_devops_bot | ||
| """ | ||
|
|
||
| from google.adk.agents import Agent | ||
| from google.adk.agents.callback_context import CallbackContext | ||
| from google.adk_community.templating import Jinja2InstructionProvider | ||
|
|
||
|
|
||
| def populate_system_state(callback_context: CallbackContext): | ||
| """Populate the session state with system information. | ||
|
|
||
| In a real application, this would fetch actual server metrics. | ||
| For this demo, we use sample data. | ||
| """ | ||
| callback_context.state["environment"] = "PRODUCTION" | ||
| callback_context.state["user_query"] = "" | ||
| callback_context.state["servers"] = [ | ||
| {"id": "srv-01", "role": "LoadBalancer", "cpu": 15, "memory": 45}, | ||
| {"id": "srv-02", "role": "AppServer", "cpu": 95, "memory": 88}, | ||
| {"id": "srv-03", "role": "Database", "cpu": 72, "memory": 65}, | ||
| {"id": "srv-04", "role": "Cache", "cpu": 35, "memory": 42}, | ||
| ] | ||
|
|
||
|
|
||
| # Define the Jinja2 template for instructions | ||
| DEVOPS_TEMPLATE = """ | ||
| You are a System Reliability Engineer (SRE) Assistant. | ||
|
|
||
| CURRENT SYSTEM STATUS | ||
| ===================== | ||
| Environment: {{ environment }} | ||
|
|
||
| {% if servers|length == 0 %} | ||
| ⚠️ No servers are currently online. | ||
| {% else %} | ||
| Active Servers ({{ servers|length }}): | ||
| {% for server in servers %} | ||
| - [{{ server.id }}] {{ server.role }} | ||
| CPU: {{ server.cpu }}% | Memory: {{ server.memory }}% | ||
| {% if server.cpu > 80 or server.memory > 80 %} | ||
| 🚨 CRITICAL ALERT: Resource usage is dangerously high! | ||
| {% elif server.cpu > 60 or server.memory > 60 %} | ||
| ⚠️ WARNING: Resource usage is elevated. | ||
| {% else %} | ||
| ✅ Status: Normal | ||
| {% endif %} | ||
| {% endfor %} | ||
| {% endif %} | ||
|
|
||
| INSTRUCTIONS | ||
| ============ | ||
| Based on the status above: | ||
| 1. Analyze the current system health | ||
| 2. Identify any critical issues or warnings | ||
| 3. Provide specific, actionable recommendations | ||
| 4. If user asks a question, answer it in the context of the current system state | ||
|
|
||
| {% if user_query %} | ||
| User Question: {{ user_query }} | ||
| {% endif %} | ||
|
|
||
| Be concise, technical, and prioritize critical issues. | ||
| """.strip() | ||
|
|
||
| # Create the provider with the template | ||
| instruction_provider = Jinja2InstructionProvider(DEVOPS_TEMPLATE) | ||
|
|
||
| # Create the agent | ||
| root_agent = Agent( | ||
| name="devops_sre_agent", | ||
| model="gemini-2.0-flash", | ||
| instruction=instruction_provider, | ||
| before_agent_callback=[populate_system_state], | ||
| ) |
15 changes: 15 additions & 0 deletions
15
contributing/samples/templating/mako_data_analyst/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Copyright 2025 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| from . import agent |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Django template filter
add:0|floatformat:0applied tomoderation_stats.approvedis redundant. Sincemoderation_stats.approvedis already an integer,add:0has no effect, andfloatformat:0will simply convert it to a string, which would happen anyway when rendering{{ moderation_stats.approved }}. This makes the template slightly more complex than necessary and can be simplified.