| name | cx-callback-generator |
| description | Generate production-ready Python callback code for Google Cloud CX Agent Studio agents. Use this skill whenever the user wants to write, create, or generate a callback for CX Agent Studio, Conversational Agents, or Dialogflow CX Playbooks. Trigger on any mention of "callback", "before_model_callback", "after_model_callback", "before_tool_callback", "after_tool_callback", "before_agent_callback", "after_agent_callback", "custom_payloads", "CallbackContext", "session variable update in callback", "guardrail callback", "input validation callback", "PII redaction callback", "tool chaining callback", or any request to hook into the agent execution lifecycle with Python code. Also trigger when the user says "write callback code", "add a callback", "callback for my agent", "intercept LLM call", "modify tool response", "inject context", or asks how to use callbacks in CX Agent Studio. Even if the user just says "callback" in the context of conversational AI or agent development, use this skill.
|
CX Agent Studio Callback Code Generator
Generate production-ready Python callback code for CX Agent Studio agents through an interactive Q&A workflow.
Workflow
Step 1: Ask the User What They Need
Before writing any code, gather requirements by asking these questions interactively. Use the ask_user_input_v0 tool to present choices as clickable widgets.
Question 1 — Callback Type (single select):
Ask which callback type they need:
before_agent_callback — Run code before the agent is invoked
after_agent_callback — Run code after the agent completes
before_model_callback — Run code before the LLM call
after_model_callback — Run code after the LLM response
before_tool_callback — Run code before a tool executes
after_tool_callback — Run code after a tool returns
Question 2 — Use Case Pattern (single select, adapt options to selected callback type):
Ask what they want to accomplish. Map to the callback type:
For before_agent_callback:
- Set up / initialize session variables
- Validate session state before agent runs
- Conditionally skip agent invocation
- Custom setup logic
For after_agent_callback:
- Post-execution cleanup or logging
- Modify / override agent response
- Update counters or state after agent runs
- Trigger downstream actions
For before_model_callback:
- Input policy enforcement / guardrails
- Inject context variables into prompt
- Skip LLM call and return cached/static response
- Handle failed tool responses gracefully
- Custom input transformation
For after_model_callback:
- Append disclaimers / formatting to response
- PII redaction from model output
- Inject survey / feedback links on session end
- Add custom JSON payload to response
- Custom output transformation
For before_tool_callback:
- Validate tool input arguments
- Enrich tool inputs with session data
- Return mocked/cached tool response (skip execution)
- Rate limiting on tool calls
- Authorization check before tool execution
For after_tool_callback:
- Transform / enrich tool response
- Save tool results to session variables
- Chain additional logic after tool completes
- Audit logging of tool calls
- Error handling / fallback for failed tools
Question 3 — Session Variables (single select):
Ask if they need to read or write session variables:
- Yes — I need to read AND write session variables
- Read only — I just need to read existing variables
- No — No session variable interaction needed
If they answered Yes or Read only, ask a follow-up in prose:
"What session variable names do you need? (e.g., customer_id, order_status, is_authenticated). Also mention if any should have default values."
Question 4 — Specific Details (open-ended, ask in prose):
Based on their selections, ask targeted follow-up questions. Examples:
- For policy enforcement: "What topics or keywords should be blocked?"
- For PII redaction: "Which PII types? (SSN, credit card, email, phone, etc.)"
- For tool-specific callbacks: "What is the tool name? (e.g.,
get_order_status)"
- For disclaimers: "What disclaimer text should be appended?"
- For custom payloads: "What JSON structure should the payload have?"
- For rate limiting: "What is the max number of calls allowed?"
Step 2: Generate the Callback Code
After gathering requirements, generate the Python code following these rules:
Code Structure Rules
- Function signature must match the callback type exactly:
before_agent_callback(callback_context: CallbackContext) -> Optional[Content]
after_agent_callback(callback_context: CallbackContext) -> Optional[Content]
before_model_callback(callback_context: CallbackContext, llm_request: LlmRequest) -> Optional[LlmResponse]
after_model_callback(callback_context: CallbackContext, llm_response: LlmResponse) -> Optional[LlmResponse]
before_tool_callback(tool: Tool, input: dict[str, Any], callback_context: CallbackContext) -> Optional[dict[str, Any]]
after_tool_callback(tool: Tool, input: dict[str, Any], callback_context: CallbackContext, tool_response: dict) -> Optional[dict]
-
Available imports (only these are available in the CX Agent Studio Python runtime):
import json
import re
import random
from datetime import datetime
- Standard Python built-ins
-
Available classes (no import needed — they're injected by the runtime):
CallbackContext — Access .variables dict, .agent_name string
LlmRequest — Access .contents (list of Content objects)
LlmResponse — Create with LlmResponse(content=Content(parts=[...])) or LlmResponse.from_parts(parts=[...])
Content — Holds .parts list and .role string
Part — Create with Part(text=...), Part.from_text(...), Part.from_json(data=...), Part.from_end_session(reason=...), Part(function_call=FunctionCall(...)). Check with .has_function_call(name), .has_function_response(name)
FunctionCall — Create with FunctionCall(name=..., args={...})
Tool — Access .name
-
Return value conventions:
- Return
None → pass through (no override, let the default behavior continue)
- Return a value → override the default behavior
- For
before_agent_callback: returning Content skips the agent entirely
- For
before_model_callback: returning LlmResponse skips the LLM call
- For
before_tool_callback: returning a dict skips the tool execution
- For
after_* callbacks: returning a value replaces the original output
-
Session variable access pattern:
value = callback_context.variables.get('key_name', default_value)
callback_context.variables['key_name'] = new_value
- Always include:
- Docstring explaining what the callback does
- Inline comments for complex logic
- Error handling with try/except for anything that could fail
- Type hints in the function signature
Code Quality Checklist
Step 3: Present the Output
Present the generated code in a clean format with:
-
Callback type label — Which callback this is
-
Purpose summary — One-line description
-
The Python code block — Ready to paste into CX Agent Studio
-
Session variables table — If applicable, list all variables read/written with their types and purposes
-
Setup instructions — How to add this callback in the CX Agent Studio console:
- Open the agent settings
- Click "Add code"
- Select the callback type
- Paste the code
- Click Save
-
Testing tips — How to verify the callback works in the simulator
Step 4: Offer Iterations
After presenting the code, ask if the user wants to:
- Modify the logic
- Add additional callback types for the same agent
- Add error handling or logging
- Generate a companion callback (e.g., if they wrote a
before_tool_callback, offer an after_tool_callback for the same tool)
- Generate a custom payload version
Reference Files
Read these for advanced patterns and complete code templates:
| File | When to Read |
|---|
references/callback-patterns.md | For all 6 callback types with multiple real-world code patterns per type |
references/custom-payloads.md | When the user needs custom JSON payloads in responses |
references/variables-guide.md | When the user asks about session variables, scoping, types, or naming |
Quick Reference: Callback Execution Flow
User message arrives
│
├─ before_agent_callback ← Setup / validation / skip agent
│
├─ before_model_callback ← Input guardrails / context injection / skip LLM
│ │
│ ├─ [LLM processes]
│ │
│ └─ after_model_callback ← Output formatting / PII redaction / payloads
│
├─ before_tool_callback ← Validate args / mock response / rate limit
│ │
│ ├─ [Tool executes]
│ │
│ └─ after_tool_callback ← Transform response / save to variables / audit
│
└─ after_agent_callback ← Cleanup / counters / override response
Important Notes
- Callback function names are FIXED — the runtime finds them by name
- Helper functions can have any name — define them above or below the main function
- Multiple callbacks of the same type execute in definition order
CallbackContext.variables persists across the entire session
- Custom payloads use
Part.from_json(data=json_string) with mime_type application/json
- The LLM never sees custom payloads — they're only in the final API response
- Always test callbacks in the CX Agent Studio simulator before deploying