{
  "_comment": "Fix: Artisan tools (GitWorkspace, SafeFileOperations, GatedBash) registered in realTools so the agent form tool catalog and server seed stay aligned.",
  "version": "2.0",
  "buckets": {
    "model-options": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Model option row in this list."
    },
    "assistant-prefill": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Assistant prefill message in this list."
    },
    "parameters": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Callable parameter row in this list."
    },
    "triggers-active": {
      "click": true,
      "drag": "move-reorder",
      "preview": "full",
      "hoverable": true,
      "hoverChipContent": "Trigger row in Active."
    },
    "triggers-available": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Preset preview shelf. Drag a preview into Active. Drop an Active row here to discard."
    },
    "knowledge-table": {
      "click": true,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Skill in Table."
    },
    "knowledge-shelf": {
      "click": true,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Skill in Shelf."
    },
    "knowledge-library": {
      "click": true,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Skill in Library."
    },
    "knowledge-available": {
      "click": false,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Skill in Available."
    },
    "tools-bench": {
      "click": true,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Table: always-callable tools injected into the model API."
    },
    "tools-shed": {
      "click": true,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Shelf: metadata-only tools; discover via tool_lookup or meta-tools."
    },
    "tools-store": {
      "click": true,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Store: catalog search only; use tool_lookup before promotion to Table."
    },
    "tools-available": {
      "click": false,
      "drag": "move",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Tool in Available."
    },
    "two-bucket-returns-selected": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Selected structured-output preset. Drag to reorder."
    },
    "two-bucket-returns-pool": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Preset pool: drag into Selected; pool keeps a copy."
    },
    "two-bucket-st-compaction-style-selected": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Selected short-term compaction style. Drag to reorder."
    },
    "two-bucket-st-compaction-style-pool": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Style pool: drag into Selected; pool keeps a copy."
    },
    "two-bucket-st-compaction-triggers-selected": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Selected short-term compaction triggers. Drag to reorder."
    },
    "two-bucket-st-compaction-triggers-pool": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Trigger pool: drag into Selected; pool keeps a copy."
    },
    "two-bucket-lt-compaction-style-selected": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Selected long-term compaction style. Drag to reorder."
    },
    "two-bucket-lt-compaction-style-pool": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Style pool: drag into Selected; pool keeps a copy."
    },
    "two-bucket-lt-compaction-triggers-selected": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Selected long-term compaction triggers. Drag to reorder."
    },
    "two-bucket-lt-compaction-triggers-pool": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Trigger pool: drag into Selected; pool keeps a copy."
    },
    "two-bucket-lt-merge-selected": {
      "click": true,
      "drag": "move-reorder",
      "preview": "basic",
      "hoverable": true,
      "hoverChipContent": "Selected long-term merge style. Drag to reorder."
    },
    "two-bucket-lt-merge-pool": {
      "click": false,
      "drag": "duplicate-out",
      "preview": "minimal",
      "hoverable": true,
      "hoverChipContent": "Merge style pool: drag into Selected; pool keeps a copy."
    }
  },
  "items": {
    "trigger-preview": {
      "defaultBucket": "triggers-available",
      "validBuckets": ["triggers-available", "triggers-active"],
      "preview": "minimal",
      "hoverContent": "Preview preset: drag into Active to spawn a full trigger row from this template."
    },
    "trigger-row": {
      "defaultBucket": "triggers-available",
      "validBuckets": ["triggers-available", "triggers-active"],
      "preview": "full",
      "hoverContent": "Trigger row (Active): reorder in place. Drag onto Available to discard. Tap row chrome (outside inputs) for the graph."
    },
    "knowledge-facet": {
      "defaultBucket": "knowledge-available",
      "validBuckets": [
        "knowledge-available",
        "knowledge-table",
        "knowledge-shelf",
        "knowledge-library"
      ],
      "preview": "minimal",
      "hoverContent": "Knowledge skill: drag into Table, Shelf, Library, or back to Available."
    },
    "tool": {
      "defaultBucket": "tools-available",
      "validBuckets": ["tools-available", "tools-bench", "tools-shed", "tools-store"],
      "exportFields": {
        "bucket": "table | shelf | store (Table / Shelf / Store tier; maps from UI bench/shed/store)",
        "tool_type": "action | knowledge | internal | agent_handover"
      },
      "preview": "minimal",
      "hoverContent": "Tool: drag into Table (bench), Shelf (shed), or Store; exported as bucket table|shelf|store with tool_type.",
      "implementation": "ToolExecutor",
      "configSchema": { "type": "object", "additionalProperties": true },
      "testHarness": "runs-with-mock-input"
    },
    "model-option": {
      "defaultBucket": "model-options",
      "validBuckets": ["model-options"],
      "preview": "basic",
      "hoverContent": "Model option (primary or fallback). Edit inline; click the row (outside inputs) for cache and transport."
    },
    "assistant-prefill-message": {
      "defaultBucket": "assistant-prefill",
      "validBuckets": ["assistant-prefill"],
      "preview": "basic",
      "hoverContent": "Assistant prefill message: edit role and content inline; click the row (outside inputs) for the full editor."
    },
    "parameter-row": {
      "defaultBucket": "parameters",
      "validBuckets": ["parameters"],
      "preview": "basic",
      "hoverContent": "Callable parameter: title strip shows name, type, and required; click Default summary for the editor. Drag from empty card chrome to reorder."
    },
    "memory-two-bucket-chip": {
      "defaultBucket": "two-bucket-st-compaction-style-pool",
      "validBuckets": [
        "two-bucket-st-compaction-style-selected",
        "two-bucket-st-compaction-style-pool",
        "two-bucket-st-compaction-triggers-selected",
        "two-bucket-st-compaction-triggers-pool",
        "two-bucket-lt-compaction-style-selected",
        "two-bucket-lt-compaction-style-pool",
        "two-bucket-lt-compaction-triggers-selected",
        "two-bucket-lt-compaction-triggers-pool",
        "two-bucket-lt-merge-selected",
        "two-bucket-lt-merge-pool"
      ],
      "preview": "minimal",
      "hoverContent": "Memory preset: drag between Selected and Available within this control. Tap when placed on Selected for placement notes."
    }
  },
  "hoverUi": {
    "showDelayMs": 450
  },
  "twoBucketMemoryPresets": {
    "compaction": [
      ["llm_summarize", "LLM summarize"],
      ["keep_last_n", "Keep last N"],
      ["vector_compress", "Vector compress"],
      ["sliding_window", "Sliding window"],
      ["custom", "Custom (trigger graph)"],
      ["none", "None"]
    ],
    "compactrig": [
      ["after_n_turns", "After N turns"],
      ["token_threshold", "Token threshold"],
      ["time_idle", "Time / idle"],
      ["manual", "Manual"],
      ["scheduled", "Scheduled"]
    ],
    "merge": [
      ["last_write_wins", "Last write wins"],
      ["three_way", "Three-way"],
      ["union", "Union"],
      ["none", "None"]
    ]
  },
  "agentTemplates": {
    "defaultKey": "chat-v3"
  },
  "triggerPresets": {
    "defaults": {
      "keyword": { "id": "trigger_keyword", "condition_keywords": "help,reminder,stop", "condition_regex": "", "run_mode": "sync" },
      "regex": { "id": "trigger_regex", "condition_keywords": "", "condition_regex": "^(hi|hello|hey)\\b", "run_mode": "sync" },
      "tool": { "id": "trigger_tool", "condition_keywords": "", "condition_regex": "", "run_mode": "async" },
      "schedule": { "id": "trigger_schedule", "condition_keywords": "", "condition_regex": "", "run_mode": "deferred" },
      "schedule_cron": { "id": "trigger_cron", "condition_keywords": "", "condition_regex": "0 9 * * *", "run_mode": "deferred" },
      "webhook": { "id": "trigger_webhook", "condition_keywords": "", "condition_regex": "", "run_mode": "async" },
      "llm_eval": { "id": "trigger_llm_eval", "condition_keywords": "", "condition_regex": "", "run_mode": "sync" },
      "custom": { "id": "trigger_custom", "condition_keywords": "", "condition_regex": "", "run_mode": "sync" },
      "on_new_message": {
        "id": "trigger_on_new_message",
        "condition_keywords": "",
        "condition_regex": "",
        "run_mode": "sync",
        "graph_json": {
          "root": { "x": 20, "y": 20 },
          "nodes": [
            { "id": "iid1", "type": "agent_instance_id", "x": 40, "y": 48 },
            { "id": "mem1", "type": "short_term_memory", "x": 40, "y": 128 },
            { "id": "call_model_1", "type": "call_agent_model", "x": 40, "y": 208, "payload": { "socket_ports": [] } }
          ],
          "edges": [
            { "from": "__root:exe_o", "to": "iid1:exe_i" },
            { "from": "iid1:exe_o", "to": "mem1:exe_i" },
            { "from": "mem1:exe_o", "to": "call_model_1:exe_i" },
            { "from": "iid1:dout_agent_instance_id", "to": "mem1:din_instance_id" },
            { "from": "mem1:dout_messages_json", "to": "call_model_1:din_context" },
            { "from": "__root:dout_user_message", "to": "call_model_1:din_param_prompt" }
          ]
        }
      },
      "on_load": {
        "id": "trigger_on_load",
        "condition_keywords": "",
        "condition_regex": "",
        "run_mode": "sync",
        "enabled": true,
        "graph_json": {
          "root": { "x": 20, "y": 20 },
          "nodes": [
            {
              "id": "attach_root",
              "type": "ui_attach",
              "x": 40,
              "y": 48,
              "payload": {
                "element_id": "root",
                "element_type": "ui_blank_box",
                "parent_id": "__host__",
                "anchor": "internal_center"
              }
            },
            {
              "id": "attach_scroll",
              "type": "ui_attach",
              "x": 40,
              "y": 128,
              "payload": {
                "element_id": "transcript",
                "element_type": "ui_scroll",
                "parent_id": "root",
                "anchor": "internal_top",
                "direction": "vertical"
              }
            },
            {
              "id": "attach_input",
              "type": "ui_attach",
              "x": 40,
              "y": 208,
              "payload": {
                "element_id": "message_input",
                "element_type": "ui_text_input",
                "parent_id": "root",
                "anchor": "bottom_center",
                "placeholder": "Message…"
              }
            },
            {
              "id": "bind_input",
              "type": "ui_bind_trigger",
              "x": 40,
              "y": 288,
              "payload": {
                "element_id": "message_input",
                "trigger_event": "submit",
                "hook": "on_user_message",
                "param": "prompt"
              }
            }
          ],
          "edges": [
            { "from": "__root:exe_o", "to": "attach_root:exe_i" },
            { "from": "attach_root:exe_o", "to": "attach_scroll:exe_i" },
            { "from": "attach_scroll:exe_o", "to": "attach_input:exe_i" },
            { "from": "attach_input:exe_o", "to": "bind_input:exe_i" }
          ]
        }
      },
      "on_agent_started": { "id": "trigger_on_agent_started", "condition_keywords": "", "condition_regex": "", "run_mode": "sync" },
      "after_model_response": { "id": "trigger_after_model_response", "condition_keywords": "", "condition_regex": "", "run_mode": "sync" },
      "model_response_stream": { "id": "trigger_on_model_response_stream", "condition_keywords": "", "condition_regex": "", "run_mode": "sync" },
      "on_memory_compact": {
        "id": "trigger_on_memory_compact",
        "condition_keywords": "",
        "condition_regex": "",
        "run_mode": "sync",
        "enabled": true,
        "graph_json": {
          "root": { "x": 20, "y": 20 },
          "nodes": [
            { "id": "hist1", "type": "message_history", "x": 40, "y": 48 },
            { "id": "compact_out1", "type": "compaction_out", "x": 40, "y": 128 }
          ],
          "edges": [
            { "from": "__root:exe_o", "to": "hist1:exe_i" },
            { "from": "hist1:exe_o", "to": "compact_out1:exe_i" },
            { "from": "hist1:dout_messages_json", "to": "compact_out1:din_messages_json" }
          ]
        }
      },
      "file_change_watcher": { "id": "trigger_file_change", "condition_keywords": "", "condition_regex": "", "run_mode": "async" },
      "multi_trigger": {
        "id": "trigger_multi",
        "condition_keywords": "",
        "condition_regex": "",
        "run_mode": "sync",
        "child_triggers": []
      }
    },
    "previews": {
      "keyword": { "label": "Keyword", "line": "Match keywords", "preview": "basic", "basicNote": "Fills condition_keywords when you duplicate into Active." },
      "regex": { "label": "Regex", "line": "condition_regex pattern", "preview": "basic", "basicNote": "Good for anchored openers (^…\\b)." },
      "tool": { "label": "Tool", "line": "Tool name pattern" },
      "schedule": { "label": "Schedule", "line": "Time-based" },
      "schedule_cron": { "label": "Cron", "line": "Cron expression" },
      "webhook": { "label": "Webhook", "line": "Inbound webhook" },
      "llm_eval": { "label": "LLM eval", "line": "LLM gate" },
      "custom": { "label": "Custom", "line": "Custom handler" },
      "on_new_message": { "label": "On new message", "line": "Fire when a new user message arrives" },
      "on_load": {
        "label": "On load (Chat Lab UI)",
        "line": "Build graph-driven interaction shell when a Chat Lab instance opens (v3 export)"
      },
      "on_agent_started": { "label": "Agent started", "line": "Fire once when the agent run begins" },
      "after_model_response": { "label": "After model responds", "line": "Fire when the assistant finishes a reply (Chat lab / preview)" },
      "model_response_stream": { "label": "Model response stream", "line": "Fire on each streamed token chunk while the model is replying (no tools)" },
      "on_memory_compact": {
        "label": "On memory compact",
        "line": "Fire when short/long-term compaction triggers run with Custom style"
      },
      "file_change_watcher": { "label": "File watcher", "line": "Filesystem change (server-side)" },
      "multi_trigger": {
        "label": "Multi-trigger",
        "line": "Several triggers in one active row — each runs its own graph independently",
        "preview": "basic",
        "basicNote": "Click the row to edit the bundle; use Edit graph on each child."
      }
    }
  },
  "triggerGraphEventKinds": {
    "labels": {
      "logic": "Logic",
      "loop": "Loop",
      "branch": "Branch",
      "merge": "Merge",
      "filter": "Filter",
      "transform": "Transform",
      "delay": "Delay",
      "on_error": "On error",
      "webhook": "Webhook",
      "script": "Script",
      "schedule": "Schedule",
      "batch": "Batch",
      "parallel": "Parallel",
      "map": "Map",
      "reduce": "Reduce",
      "tool_call": "Tool call",
      "load_agent": "Load agent",
      "call_agent": "Call agent",
      "call_agent_model": "Call agent model",
      "execute_tool_calls": "Execute tool calls",
      "message_append": "Message append",
      "text": "Text",
      "message_history": "Message history",
      "agent_instance_id": "Agent instance id",
      "short_term_memory": "Short-term memory",
      "llm_summarize": "LLM summarize",
      "sliding_window": "Sliding window",
      "keep_last_n": "Keep last N",
      "vector_compress": "Vector compress",
      "compaction_out": "Compaction out",
      "wait": "Wait",
      "wait_for_user_input": "User input",
      "ui_attach": "UI attach",
      "ui_append": "UI append",
      "ui_set_text": "UI set text",
      "ui_bind_trigger": "UI bind trigger",
      "ui_enable": "UI enable",
      "ui_disable": "UI disable",
      "ui_redraw": "UI redraw",
      "ui_clear": "UI clear",
      "ui_graph_canvas": "UI graph canvas"
    },
    "help": {
      "logic": "Conditional routing.",
      "loop": "Iteration or retry-shaped step.",
      "branch": "Exclusive true/false fork (one arm only).",
      "merge": "Barrier: join parallel branches, then continue downstream.",
      "filter": "Pass/drop gates.",
      "transform": "Reshape payloads between sockets.",
      "delay": "Wait before downstream steps.",
      "on_error": "Failure-path continuation.",
      "webhook": "External-call-shaped node.",
      "script": "Custom-handler-shaped node.",
      "schedule": "Time-aligned cue.",
      "batch": "Batching/grouping cue.",
      "parallel": "Fan-out: run all exe_o successors concurrently until a shared merge node.",
      "merge": "Barrier: join parallel branches, then continue downstream.",
      "map": "Per-element subflow cue.",
      "reduce": "Aggregate-to-one cue.",
      "tool_call": "Configure one catalog tool per node (Active). Registry fields drive ports: green sockets are inputs, violet outputs. Bottom green/blue are execution flow in/out.",
      "load_agent": "Configure a registered or inline agent and output its JSON. Wire Agent JSON into a Call agent node's agent input.",
      "call_agent": "Run an agent from a wired Agent JSON input (typically from Load agent). Param, knowledge, tool, and memory sockets follow that agent's harness.",
      "call_agent_model": "Call this agent's catalog model. Wire message context (JSON), optional param sockets, and read response + updated messages out.",
      "execute_tool_calls": "Parse tool_calls from the last model message, execute via ToolExecutor, promote Shelf/Store discoveries to the active Table set (lifecycle decay), and loop back to the model node when needed.",
      "message_append": "Append a role + content turn to a wired message context (JSON). Output is the updated context for downstream model or transform nodes.",
      "text": "Constant or wired text: edit in the node textbox or wire the text input socket. Outputs text for param sockets and transforms.",
      "message_history": "Expose conversation messages from the harness run as data outputs. Wire into transform or call-agent param sockets.",
      "agent_instance_id": "Publish the agent instance id from this run (Chat lab instance_id). Wire into short-term memory or transforms.",
      "short_term_memory": "Load user/assistant turns for a wired agent instance id (server conversation store). Output messages JSON for call-agent model context.",
      "llm_summarize": "Drop older turns, LLM-summarize them into compact memory; keep recent tail by message count OR token budget (whichever binds first).",
      "sliding_window": "Keep only the newest messages whose estimated tokens fit the sliding window budget.",
      "keep_last_n": "Keep only the last N user/assistant messages (tools preserved at end).",
      "vector_compress": "Like LLM summarize, plus TF-IDF highlight lines from dropped content for retrieval-style context.",
      "compaction_out": "Sink for custom compaction: wire messages into the input socket; that context becomes the model prompt for the next run after compaction fires.",
      "wait": "Pause execution for a labeled wait (preview caps sleep at 5s). Outputs status on the data port.",
      "wait_for_user_input": "Pause until the user submits input in Chat lab (textbox, button, dropdown, or nested dropdown). Wire exe_cancel_o for cancelled input (value \"input cancelled\").",
      "ui_attach": "Create a UI element and attach it to a parent anchor (Chat Lab v3). Use on the on_load graph.",
      "ui_append": "Append a child element to a ui_scroll (e.g. message bubble).",
      "ui_set_text": "Update text on ui_text or ui_text_input.",
      "ui_bind_trigger": "Wire a UI element event to a harness hook (e.g. input submit → on_user_message).",
      "ui_enable": "Re-enable interaction on a UI element (e.g. after pause).",
      "ui_disable": "Disable interaction on a UI element.",
      "ui_redraw": "Invalidate and redraw a UI subtree.",
      "ui_clear": "Remove children from a scroll or container.",
      "ui_graph_canvas": "Embedded opt-in graph editor surface (allowed_nodes whitelist)."
    }
  },
  "realTools": [
    "Agents::WebSearchTool",
    "Agents::BrowsePageTool",
    "Agents::CurrentDateTimeTool",
    "Agents::CodeInterpreterTool",
    "Agents::CalculatorTool",
    "Agents::WikipediaSearchTool",
    "Agents::GitHubCreateIssueTool",
    "Agents::GitHubSearchCodeTool",
    "Agents::FileReadTool",
    "Agents::FileWriteTool",
    "Agents::APIRequestTool",
    "Agents::EmailSendStubTool",
    "Agents::DatabaseQueryTool",
    "Agents::GitWorkspaceTool",
    "Agents::SafeFileOperationsTool",
    "Agents::GatedBashTool"
  ],
  "toolDefinitions": {
    "Agents::WebSearchTool": {
      "rubyClass": "AgentStudioServer::Tools::WebSearchTool",
      "implementation": "web_search",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::BrowsePageTool": {
      "rubyClass": "AgentStudioServer::Tools::BrowsePageTool",
      "implementation": "http_fetch",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::CurrentDateTimeTool": {
      "rubyClass": "AgentStudioServer::Tools::CurrentDateTimeTool",
      "implementation": "server_clock",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::CodeInterpreterTool": {
      "rubyClass": "AgentStudioServer::Tools::CodeInterpreterTool",
      "implementation": "sandbox_exec",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::CalculatorTool": {
      "rubyClass": "AgentStudioServer::Tools::CalculatorTool",
      "implementation": "safe_eval",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::WikipediaSearchTool": {
      "rubyClass": "AgentStudioServer::Tools::WikipediaSearchTool",
      "implementation": "wikipedia_api",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::GitHubCreateIssueTool": {
      "rubyClass": "AgentStudioServer::Tools::GitHubCreateIssueTool",
      "implementation": "octokit",
      "testHarness": "requires_env"
    },
    "Agents::GitHubSearchCodeTool": {
      "rubyClass": "AgentStudioServer::Tools::GitHubSearchCodeTool",
      "implementation": "octokit",
      "testHarness": "requires_env"
    },
    "Agents::FileReadTool": {
      "rubyClass": "AgentStudioServer::Tools::FileReadTool",
      "implementation": "filesystem_jailed",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::FileWriteTool": {
      "rubyClass": "AgentStudioServer::Tools::FileWriteTool",
      "implementation": "filesystem_jailed",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::APIRequestTool": {
      "rubyClass": "AgentStudioServer::Tools::APIRequestTool",
      "implementation": "net_http",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::EmailSendStubTool": {
      "rubyClass": "AgentStudioServer::Tools::EmailSendStubTool",
      "implementation": "log_only",
      "testHarness": "runs-with-mock-input"
    },
    "Agents::DatabaseQueryTool": {
      "rubyClass": "AgentStudioServer::Tools::DatabaseQueryTool",
      "implementation": "stub",
      "testHarness": "stub"
    },
    "Agents::GitWorkspaceTool": {
      "rubyClass": "AgentStudioServer::Tools::GitWorkspaceTool",
      "implementation": "git_workspace",
      "testHarness": "runs-with-mock-input",
      "category": "Artisan"
    },
    "Agents::SafeFileOperationsTool": {
      "rubyClass": "AgentStudioServer::Tools::SafeFileOperationsTool",
      "implementation": "safe_file_operations",
      "testHarness": "runs-with-mock-input",
      "category": "Artisan"
    },
    "Agents::GatedBashTool": {
      "rubyClass": "AgentStudioServer::Tools::GatedBashTool",
      "implementation": "gated_bash",
      "testHarness": "requires_env",
      "category": "Artisan"
    }
  },
  "toolInvocationParamSpecs": {
    "Agents::WebSearchTool": [
      { "key": "query", "label": "Query", "placeholder": "search query" }
    ],
    "Agents::BrowsePageTool": [
      { "key": "url", "label": "URL", "placeholder": "https://..." }
    ],
    "Agents::CurrentDateTimeTool": [],
    "Agents::CodeInterpreterTool": [
      { "key": "language", "label": "Language", "placeholder": "ruby or javascript" },
      { "key": "code", "label": "Code", "placeholder": "source code" }
    ],
    "Agents::CalculatorTool": [
      { "key": "expression", "label": "Expression", "placeholder": "2 + 2" }
    ],
    "Agents::WikipediaSearchTool": [
      { "key": "query", "label": "Query", "placeholder": "topic" }
    ],
    "Agents::GitHubCreateIssueTool": [
      { "key": "repo", "label": "Repo", "placeholder": "owner/name" },
      { "key": "title", "label": "Title", "placeholder": "issue title" },
      { "key": "body", "label": "Body", "placeholder": "markdown" }
    ],
    "Agents::GitHubSearchCodeTool": [
      { "key": "query", "label": "Query", "placeholder": "search string" },
      { "key": "repo", "label": "Repo (optional)", "placeholder": "owner/name" }
    ],
    "Agents::FileReadTool": [
      { "key": "path", "label": "Path", "placeholder": "relative to workspace" }
    ],
    "Agents::FileWriteTool": [
      { "key": "path", "label": "Path", "placeholder": "relative to workspace" },
      { "key": "content", "label": "Content", "placeholder": "file contents" }
    ],
    "Agents::APIRequestTool": [
      { "key": "method", "label": "Method", "placeholder": "GET" },
      { "key": "url", "label": "URL", "placeholder": "https://..." },
      { "key": "body", "label": "Body (optional)", "placeholder": "{}" }
    ],
    "Agents::EmailSendStubTool": [
      { "key": "to", "label": "To", "placeholder": "addr@example.com" },
      { "key": "subject", "label": "Subject", "placeholder": "" },
      { "key": "body", "label": "Body", "placeholder": "" }
    ],
    "Agents::DatabaseQueryTool": [
      { "key": "sql", "label": "SQL", "placeholder": "SELECT 1" }
    ],
    "Agents::GitWorkspaceTool": [
      { "key": "action", "label": "Action", "placeholder": "create_workspace | commit | revert | partial_revert | history" },
      { "key": "message", "label": "Message (optional)", "placeholder": "commit message" },
      { "key": "commit_sha", "label": "Commit SHA (optional)", "placeholder": "abc123" },
      { "key": "file_path", "label": "File path (optional)", "placeholder": "src/app.js" }
    ],
    "Agents::SafeFileOperationsTool": [
      { "key": "operation", "label": "Operation", "placeholder": "read_file | write_file | list_dir | delete_file" },
      { "key": "path", "label": "Path", "placeholder": "relative to workspace" },
      { "key": "content", "label": "Content (optional)", "placeholder": "file contents" }
    ],
    "Agents::GatedBashTool": [
      { "key": "command", "label": "Command", "placeholder": "bash -lc command" }
    ]
  },
  "toolInvocationOutputSpecs": {
    "Agents::WebSearchTool": [
      { "key": "results", "label": "Results" }
    ],
    "Agents::BrowsePageTool": [
      { "key": "text", "label": "Extracted text" },
      { "key": "title", "label": "Title" }
    ],
    "Agents::CurrentDateTimeTool": [
      { "key": "local_date", "label": "Local date" },
      { "key": "local_time", "label": "Local time" },
      { "key": "utc_date", "label": "UTC date" },
      { "key": "utc_time", "label": "UTC time" }
    ],
    "Agents::CodeInterpreterTool": [
      { "key": "stdout", "label": "Stdout" },
      { "key": "stderr", "label": "Stderr" }
    ],
    "Agents::CalculatorTool": [
      { "key": "result", "label": "Result" }
    ],
    "Agents::WikipediaSearchTool": [
      { "key": "summary", "label": "Summary" },
      { "key": "url", "label": "URL" }
    ],
    "Agents::GitHubCreateIssueTool": [
      { "key": "html_url", "label": "Issue URL" },
      { "key": "number", "label": "Number" }
    ],
    "Agents::GitHubSearchCodeTool": [
      { "key": "items", "label": "Matches" }
    ],
    "Agents::FileReadTool": [
      { "key": "content", "label": "Content" }
    ],
    "Agents::FileWriteTool": [
      { "key": "path", "label": "Path written" },
      { "key": "bytes", "label": "Bytes" }
    ],
    "Agents::APIRequestTool": [
      { "key": "status", "label": "Status" },
      { "key": "body", "label": "Body" }
    ],
    "Agents::EmailSendStubTool": [
      { "key": "logged", "label": "Logged" }
    ],
    "Agents::DatabaseQueryTool": [
      { "key": "message", "label": "Status" }
    ]
  },
  "knowledgeSkillLabels": {
    "agent_studio_system": "Agent Studio system guide",
    "research": "Research",
    "summarize": "Summarize",
    "code_review": "Code review",
    "citations": "Citations"
  },
  "knowledgeFacetLabels": {
    "agent_studio_system": "Agent Studio system guide",
    "research": "Research",
    "summarize": "Summarize",
    "code_review": "Code review",
    "citations": "Citations"
  }
}
