Skip to content

Commit 24f41a1

Browse files
committed
Update agent.py
added the before_model_modifier callback which is modifying the system instruction to include the current recipe state also cleaned the agent code
1 parent 1790c4b commit 24f41a1

File tree

1 file changed

+40
-129
lines changed
  • typescript-sdk/integrations/adk-middleware/examples/shared_state

1 file changed

+40
-129
lines changed

typescript-sdk/integrations/adk-middleware/examples/shared_state/agent.py

Lines changed: 40 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
from google.adk.events import Event, EventActions
1616
from google.adk.tools import FunctionTool, ToolContext
1717
from google.genai.types import Content, Part , FunctionDeclaration
18-
18+
from google.adk.models import LlmResponse, LlmRequest
19+
from google.genai import types
1920

2021

2122
from pydantic import BaseModel, Field
@@ -157,7 +158,7 @@ def on_before_agent(callback_context: CallbackContext):
157158
"""
158159
Initialize recipe state if it doesn't exist.
159160
"""
160-
161+
print('recipe state ==>',callback_context.state.get('recipe'))
161162
if "recipe" not in callback_context.state:
162163
# Initialize with default recipe
163164
default_recipe = {
@@ -173,55 +174,48 @@ def on_before_agent(callback_context: CallbackContext):
173174
return None
174175

175176

177+
# --- Define the Callback Function ---
178+
# modifying the agent's system prompt to incude the current state of recipe
179+
def before_model_modifier(
180+
callback_context: CallbackContext, llm_request: LlmRequest
181+
) -> Optional[LlmResponse]:
182+
"""Inspects/modifies the LLM request or skips the call."""
183+
agent_name = callback_context.agent_name
184+
print(f"[Callback] Before model call for agent: {agent_name}")
185+
if agent_name == "RecipeAgent":
186+
recipe_json = "No recipe yet"
187+
if "recipe" in callback_context.state and callback_context.state["recipe"] is not None:
188+
try:
189+
recipe_json = json.dumps(callback_context.state["recipe"], indent=2)
190+
except Exception as e:
191+
recipe_json = f"Error serializing recipe: {str(e)}"
192+
# --- Modification Example ---
193+
# Add a prefix to the system instruction
194+
original_instruction = llm_request.config.system_instruction or types.Content(role="system", parts=[])
195+
prefix = f"""You are a helpful assistant for creating recipes.
196+
This is the current state of the recipe: {recipe_json}
197+
You can improve the recipe by calling the generate_recipe tool."""
198+
# Ensure system_instruction is Content and parts list exists
199+
if not isinstance(original_instruction, types.Content):
200+
# Handle case where it might be a string (though config expects Content)
201+
original_instruction = types.Content(role="system", parts=[types.Part(text=str(original_instruction))])
202+
if not original_instruction.parts:
203+
original_instruction.parts.append(types.Part(text="")) # Add an empty part if none exist
204+
205+
# Modify the text of the first part
206+
modified_text = prefix + (original_instruction.parts[0].text or "")
207+
original_instruction.parts[0].text = modified_text
208+
llm_request.config.system_instruction = original_instruction
176209

177-
shared_state_agent = LlmAgent(
178-
name="RecipeAgent",
179-
model="gemini-2.5-pro",
180-
instruction=f"""You are a helpful recipe assistant.
181-
182-
When a user asks for a recipe or wants to modify one, you MUST use the generate_recipe tool.
183210

184-
IMPORTANT RULES:
185-
1. Always use the generate_recipe tool for any recipe-related requests
186-
2. When creating a new recipe, provide at least skill_level, ingredients, and instructions
187-
3. When modifying an existing recipe, include the changes parameter to describe what was modified
188-
4. Be creative and helpful in generating complete, practical recipes
189-
5. After using the tool, provide a brief summary of what you created or changed
190211

191-
Examples of when to use the tool:
192-
- "Create a pasta recipe" → Use tool with skill_level, ingredients, instructions
193-
- "Make it vegetarian" → Use tool with special_preferences="vegetarian" and changes describing the modification
194-
- "Add some herbs" → Use tool with updated ingredients and changes describing the addition
212+
return None
195213

196-
Always provide complete, practical recipes that users can actually cook.
197-
""",
198-
tools=[generate_recipe],
199-
before_agent_callback=on_before_agent
200-
)
201214

202-
async def run_recipe_agent(user_message: str, app_name: str = "recipe_app",
203-
user_id: str = "user1", session_id: str = "session1"):
204-
"""
205-
Run the recipe agent with a user message.
206-
207-
Args:
208-
user_message: The user's input message
209-
app_name: Application name for the session
210-
user_id: User identifier
211-
session_id: Session identifier
212-
213-
Returns:
214-
The agent's response and updated session state
215-
"""
216-
217-
# Create session service
218-
219-
session_service = InMemorySessionService()
220-
agent = LlmAgent(
215+
shared_state_agent = LlmAgent(
221216
name="RecipeAgent",
222217
model="gemini-2.5-pro",
223-
instruction=f"""You are a helpful recipe assistant.
224-
218+
instruction=f"""
225219
When a user asks for a recipe or wants to modify one, you MUST use the generate_recipe tool.
226220
227221
IMPORTANT RULES:
@@ -237,92 +231,9 @@ async def run_recipe_agent(user_message: str, app_name: str = "recipe_app",
237231
- "Add some herbs" → Use tool with updated ingredients and changes describing the addition
238232
239233
Always provide complete, practical recipes that users can actually cook.
240-
USER:{user_message}
241234
""",
242235
tools=[generate_recipe],
243-
before_agent_callback=on_before_agent
244-
)
245-
246-
# Create the agent
247-
248-
# Create runner
249-
runner = Runner(
250-
agent=agent,
251-
app_name=app_name,
252-
session_service=session_service
253-
)
254-
255-
# Create or get session
256-
257-
session = await session_service.get_session(
258-
app_name=app_name,
259-
user_id=user_id,
260-
session_id=session_id
261-
)
262-
print('session already exist with session_id',session_id)
263-
if not session:
264-
print('creating session with session_id',session_id)
265-
session = await session_service.create_session(
266-
app_name=app_name,
267-
user_id=user_id,
268-
session_id=session_id
236+
before_agent_callback=on_before_agent,
237+
before_model_callback=before_model_modifier
269238
)
270239

271-
# Create new session if it doesn't exist
272-
# Create user message content
273-
user_content = Content(parts=[Part(text=user_message)])
274-
print('user_message==>',user_message)
275-
# Run the agent
276-
response_content = None
277-
async for event in runner.run_async(
278-
user_id=user_id,
279-
session_id=session_id,
280-
new_message=user_content
281-
):
282-
print(f"Event emitted: {response_content}")
283-
if event.is_final_response():
284-
response_content = event.content
285-
print(f"Agent responded: {response_content}")
286-
287-
# Get updated session to check state
288-
updated_session = await session_service.get_session(
289-
app_name=app_name,
290-
user_id=user_id,
291-
session_id=session_id
292-
)
293-
294-
return {
295-
"response": response_content,
296-
"recipe_state": updated_session.state.get("recipe"),
297-
"session_state": updated_session.state
298-
}
299-
300-
301-
# Example usage
302-
async def main():
303-
"""
304-
Example usage of the recipe agent.
305-
"""
306-
307-
# Test the agent
308-
print("=== Recipe Agent Test ===")
309-
310-
# First interaction - create a recipe
311-
result1 = await run_recipe_agent("I want to cook Biryani, create a simple Biryani recipe and use generate_recipe tool for this",session_id='123121')
312-
print(f"Response 1: {result1['response']}")
313-
print(f"Recipe State: {json.dumps(result1['recipe_state'], indent=2)}")
314-
315-
# # Second interaction - modify the recipe
316-
# result2 = await run_recipe_agent("Make it vegetarian and add some herbs")
317-
# print(f"Response 2: {result2['response']}")
318-
# print(f"Updated Recipe State: {json.dumps(result2['recipe_state'], indent=2)}")
319-
320-
# # Third interaction - adjust cooking time
321-
# result3 = await run_recipe_agent("Make it a quick 15-minute recipe")
322-
# print(f"Response 3: {result3['response']}")
323-
# print(f"Final Recipe State: {json.dumps(result3['recipe_state'], indent=2)}")
324-
325-
326-
if __name__ == "__main__":
327-
import asyncio
328-
asyncio.run(main())

0 commit comments

Comments
 (0)