﻿{
    "cells":  [
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "# Module 8 Self-Driven Lab\n",
                                     "\n",
                                     "Use this notebook as your workspace for **Reliability \u0026 Error Handling**. The answer-key notebook sits next to this file. Work through each checkpoint before comparing against the completed version.\n"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "# Module 8 â€” Reliability \u0026 Error Handling\n",
                                     "\n",
                                     "Three patterns for resilient agentic pipelines:\n",
                                     "\n",
                                     "1. **Programmatic tool calling** â€” let Claude loop through tool calls inside `code_execution_20260120` so only the relevant slice reaches the context window.\n",
                                     "2. **Structured error responses** â€” return JSON with `errorCategory`, `isRetryable`, and `message` so Claude can reason about retry vs. pivot.\n",
                                     "3. **PostToolUse hooks** â€” normalize tool output before the model sees it.\n",
                                     "\n",
                                     "\u003e **ZDR note:** programmatic tool calling is **not ZDR-eligible** (execution state held server-side)."
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 1. Structured error response from a tool handler\n",
                                     "\n",
                                     "Raw string errors give Claude no actionable signal. Categorize and tag retryability â€” that\u0027s what drives the agentic loop\u0027s decision."
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# Setup cell. Run this before the exercise cells below.\n",
                                     "class _DemoCRM:\n",
                                     "    def search_contacts(self, query):\n",
                                     "        raise TimeoutError(\"demo: pretend the CRM is slow\")\n",
                                     "\n",
                                     "crm_client = _DemoCRM()\n",
                                     "\n",
                                     "def handle_crm_tool(tool_input):\n",
                                     "    try:\n",
                                     "        result = crm_client.search_contacts(tool_input[\"query\"])\n",
                                     "        return {\"contacts\": result}\n",
                                     "    except TimeoutError:\n",
                                     "        return {\n",
                                     "            \"errorCategory\": \"API_TIMEOUT\",\n",
                                     "            \"isRetryable\": True,\n",
                                     "            \"message\": \"CRM API timed out after 30s. Retry with a narrower query.\",\n",
                                     "        }\n",
                                     "    except PermissionError:\n",
                                     "        return {\n",
                                     "            \"errorCategory\": \"INVALID_PERMISSIONS\",\n",
                                     "            \"isRetryable\": False,\n",
                                     "            \"message\": \"API key lacks read access to the contacts endpoint. Escalate to admin.\",\n",
                                     "        }\n",
                                     "\n",
                                     "import json\n",
                                     "print(json.dumps(handle_crm_tool({\"query\": \"warm-leads\"}), indent=2))"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## 2. PostToolUse hook config\n",
                                     "\n",
                                     "Hooks run shell commands after each tool call but **before** the result reaches the model. Use them to normalize date formats, currency, or encoding so Claude always sees uniform data. The cell below scaffolds the JSON config; install it under `.claude/hooks.json` for Claude Code."
                                 ]
                  },
                  {
                      "cell_type":  "code",
                      "execution_count":  null,
                      "metadata":  {

                                   },
                      "outputs":  [

                                  ],
                      "source":  [
                                     "# Setup cell. Run this before the exercise cells below.\n",
                                     "from pathlib import Path\n",
                                     "\n",
                                     "hooks_config = \u0027\u0027\u0027{\n",
                                     "  \"hooks\": {\n",
                                     "    \"PostToolUse\": [\n",
                                     "      {\n",
                                     "        \"matcher\": {\"tool_name\": \"fetch_crm_data\"},\n",
                                     "        \"hooks\": [\n",
                                     "          {\n",
                                     "            \"type\": \"command\",\n",
                                     "            \"command\": \"python normalize_dates.py\"\n",
                                     "          }\n",
                                     "        ]\n",
                                     "      }\n",
                                     "    ]\n",
                                     "  }\n",
                                     "}\n",
                                     "\u0027\u0027\u0027\n",
                                     "\n",
                                     "Path(\"module8_demo\").mkdir(exist_ok=True)\n",
                                     "Path(\"module8_demo/hooks.json\").write_text(hooks_config, encoding=\"utf-8\")\n",
                                     "print(\"wrote module8_demo/hooks.json\")"
                                 ]
                  },
                  {
                      "cell_type":  "markdown",
                      "metadata":  {

                                   },
                      "source":  [
                                     "## Reflection\n",
                                     "\n",
                                     "Before opening the answer key, write down what worked, what failed, and which API behavior or agent-design rule you would rely on in production.\n"
                                 ]
                  }
              ],
    "metadata":  {
                     "kernelspec":  {
                                        "display_name":  "Python 3",
                                        "language":  "python",
                                        "name":  "python3"
                                    },
                     "language_info":  {
                                           "name":  "python",
                                           "version":  "3.9"
                                       }
                 },
    "nbformat":  4,
    "nbformat_minor":  5
}
