skills/cx-callback-generator/SKILL.md
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.
npx skillsauth add Yash-Kavaiya/cx-callback-generator-skills cx-callback-generatorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate production-ready Python callback code for CX Agent Studio agents through an interactive Q&A workflow.
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 invokedafter_agent_callback — Run code after the agent completesbefore_model_callback — Run code before the LLM callafter_model_callback — Run code after the LLM responsebefore_tool_callback — Run code before a tool executesafter_tool_callback — Run code after a tool returnsQuestion 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:
For after_agent_callback:
For before_model_callback:
For after_model_callback:
For before_tool_callback:
For after_tool_callback:
Question 3 — Session Variables (single select): Ask if they need to read or write session variables:
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:
get_order_status)"After gathering requirements, generate the Python code following these rules:
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 jsonimport reimport randomfrom datetime import datetimeAvailable classes (no import needed — they're injected by the runtime):
CallbackContext — Access .variables dict, .agent_name stringLlmRequest — Access .contents (list of Content objects)LlmResponse — Create with LlmResponse(content=Content(parts=[...])) or LlmResponse.from_parts(parts=[...])Content — Holds .parts list and .role stringPart — 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 .nameReturn value conventions:
None → pass through (no override, let the default behavior continue)before_agent_callback: returning Content skips the agent entirelybefore_model_callback: returning LlmResponse skips the LLM callbefore_tool_callback: returning a dict skips the tool executionafter_* callbacks: returning a value replaces the original outputSession variable access pattern:
# Read with default
value = callback_context.variables.get('key_name', default_value)
# Write
callback_context.variables['key_name'] = new_value
callback_context.variables for session state (not global variables)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:
Testing tips — How to verify the callback works in the simulator
After presenting the code, ask if the user wants to:
before_tool_callback, offer an after_tool_callback for the same tool)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 |
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
CallbackContext.variables persists across the entire sessionPart.from_json(data=json_string) with mime_type application/jsontools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.