[{"data":1,"prerenderedAt":983},["ShallowReactive",2],{"navigation_docs":3,"-build-plugins-example-support-triage":320,"-build-plugins-example-support-triage-surround":978},[4,35,69,109,133,193,228,262,305],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-ph-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-ph-rocket-launch",{"title":21,"path":22,"stem":23,"icon":24},"Concepts","\u002Fgetting-started\u002Fconcepts","1.getting-started\u002F3.concepts","i-ph-book-open",{"title":26,"path":27,"stem":28,"icon":29},"Install","\u002Fgetting-started\u002Finstall","1.getting-started\u002F4.install","i-ph-download-simple",{"title":31,"path":32,"stem":33,"icon":34},"What works today","\u002Fgetting-started\u002Fstatus","1.getting-started\u002F5.status","i-ph-list-checks",{"title":21,"icon":6,"path":36,"stem":37,"children":38,"page":6},"\u002Fconcepts","2.concepts",[39,44,49,54,59,64],{"title":40,"path":41,"stem":42,"icon":43},"Architecture","\u002Fconcepts\u002Farchitecture","2.concepts\u002F1.architecture","i-ph-planet",{"title":45,"path":46,"stem":47,"icon":48},"Jobs and durability","\u002Fconcepts\u002Fjobs","2.concepts\u002F2.jobs","i-ph-infinity",{"title":50,"path":51,"stem":52,"icon":53},"Routing","\u002Fconcepts\u002Frouting","2.concepts\u002F3.routing","i-ph-path",{"title":55,"path":56,"stem":57,"icon":58},"Security model","\u002Fconcepts\u002Fsecurity","2.concepts\u002F4.security","i-ph-shield-check",{"title":60,"path":61,"stem":62,"icon":63},"Tenants","\u002Fconcepts\u002Ftenants","2.concepts\u002F5.tenants","i-ph-buildings",{"title":65,"path":66,"stem":67,"icon":68},"Temporal","\u002Fconcepts\u002Ftemporal","2.concepts\u002F6.temporal","i-ph-clock",{"title":70,"icon":6,"path":71,"stem":72,"children":73,"page":6},"Run a fleet","\u002Ffleet","3.fleet",[74,79,84,89,94,99,104],{"title":75,"path":76,"stem":77,"icon":78},"Dev mode","\u002Ffleet\u002Fdev-mode","3.fleet\u002F1.dev-mode","i-ph-laptop",{"title":80,"path":81,"stem":82,"icon":83},"Run a cluster","\u002Ffleet\u002Fcluster","3.fleet\u002F2.cluster","i-ph-hard-drives",{"title":85,"path":86,"stem":87,"icon":88},"Join nodes","\u002Ffleet\u002Fjoin-nodes","3.fleet\u002F3.join-nodes","i-ph-plugs-connected",{"title":90,"path":91,"stem":92,"icon":93},"Manage nodes","\u002Ffleet\u002Fmanage-nodes","3.fleet\u002F4.manage-nodes","i-ph-list-bullets",{"title":95,"path":96,"stem":97,"icon":98},"Secrets","\u002Ffleet\u002Fsecrets","3.fleet\u002F5.secrets","i-ph-key",{"title":100,"path":101,"stem":102,"icon":103},"High availability","\u002Ffleet\u002Fhigh-availability","3.fleet\u002F6.high-availability","i-ph-copy",{"title":105,"path":106,"stem":107,"icon":108},"Upgrades, backups and restores","\u002Ffleet\u002Fupgrades","3.fleet\u002F7.upgrades","i-ph-arrows-clockwise",{"title":110,"icon":6,"path":111,"stem":112,"children":113,"page":6},"Use plugins","\u002Fplugins","4.plugins",[114,119,124,128],{"title":115,"path":116,"stem":117,"icon":118},"What a plugin is","\u002Fplugins\u002Foverview","4.plugins\u002F1.overview","i-ph-puzzle-piece",{"title":120,"path":121,"stem":122,"icon":123},"Install and update","\u002Fplugins\u002Finstall","4.plugins\u002F2.install","i-ph-package",{"title":125,"path":126,"stem":127,"icon":123},"Existing MCP packages","\u002Fplugins\u002Fpackages","4.plugins\u002F3.packages",{"title":129,"path":130,"stem":131,"icon":132},"The catalog","\u002Fplugins\u002Fcatalog","4.plugins\u002F4.catalog","i-ph-books",{"title":134,"icon":6,"path":135,"stem":136,"children":137,"page":6},"Build plugins","\u002Fbuild-plugins","5.build-plugins",[138,143,148,153,158,163,168,173,178,183,188],{"title":139,"path":140,"stem":141,"icon":142},"Your first plugin","\u002Fbuild-plugins\u002Ffirst-plugin","5.build-plugins\u002F1.first-plugin","i-ph-hammer",{"title":144,"path":145,"stem":146,"icon":147},"Harnesses","\u002Fbuild-plugins\u002Fharnesses","5.build-plugins\u002F10.harnesses","i-ph-cpu",{"title":149,"path":150,"stem":151,"icon":152},"Example: support triage","\u002Fbuild-plugins\u002Fexample-support-triage","5.build-plugins\u002F11.example-support-triage","i-ph-lifebuoy",{"title":154,"path":155,"stem":156,"icon":157},"Tools","\u002Fbuild-plugins\u002Ftools","5.build-plugins\u002F2.tools","i-ph-wrench",{"title":159,"path":160,"stem":161,"icon":162},"Agents","\u002Fbuild-plugins\u002Fagents","5.build-plugins\u002F3.agents","i-ph-robot",{"title":164,"path":165,"stem":166,"icon":167},"Skills","\u002Fbuild-plugins\u002Fskills","5.build-plugins\u002F4.skills","i-ph-graduation-cap",{"title":169,"path":170,"stem":171,"icon":172},"Develop and test","\u002Fbuild-plugins\u002Fdevelop-and-test","5.build-plugins\u002F5.develop-and-test","i-ph-flask",{"title":174,"path":175,"stem":176,"icon":177},"Publish and version","\u002Fbuild-plugins\u002Fpublish","5.build-plugins\u002F6.publish","i-ph-tag",{"title":179,"path":180,"stem":181,"icon":182},"Hooks","\u002Fbuild-plugins\u002Fhooks","5.build-plugins\u002F7.hooks","i-ph-anchor",{"title":184,"path":185,"stem":186,"icon":187},"Flows","\u002Fbuild-plugins\u002Fflows","5.build-plugins\u002F8.flows","i-ph-flow-arrow",{"title":189,"path":190,"stem":191,"icon":192},"Evals and quality gates","\u002Fbuild-plugins\u002Fevals","5.build-plugins\u002F9.evals","i-ph-seal-check",{"title":194,"icon":6,"path":195,"stem":196,"children":197,"page":6},"Run agents","\u002Fagents","6.agents",[198,203,208,213,218,223],{"title":199,"path":200,"stem":201,"icon":202},"Run jobs","\u002Fagents\u002Frun-jobs","6.agents\u002F1.run-jobs","i-ph-play",{"title":204,"path":205,"stem":206,"icon":207},"Models and keys","\u002Fagents\u002Fmodels-and-keys","6.agents\u002F2.models-and-keys","i-ph-sparkle",{"title":209,"path":210,"stem":211,"icon":212},"Delegation","\u002Fagents\u002Fdelegation","6.agents\u002F3.delegation","i-ph-git-fork",{"title":214,"path":215,"stem":216,"icon":217},"Contracts and limits","\u002Fagents\u002Fcontracts-and-limits","6.agents\u002F4.contracts-and-limits","i-ph-ruler",{"title":219,"path":220,"stem":221,"icon":222},"Runtime API","\u002Fagents\u002Fruntime-api","6.agents\u002F5.runtime-api","i-ph-plug",{"title":224,"path":225,"stem":226,"icon":227},"Approvals","\u002Fagents\u002Fapprovals","6.agents\u002F6.approvals","i-ph-hand-palm",{"title":229,"icon":6,"path":230,"stem":231,"children":232,"page":6},"Monitor","\u002Fmonitor","7.monitor",[233,238,243,248,253,258],{"title":234,"path":235,"stem":236,"icon":237},"Web UI","\u002Fmonitor\u002Fweb-ui","7.monitor\u002F0.web-ui","i-ph-monitor",{"title":239,"path":240,"stem":241,"icon":242},"Cost and usage","\u002Fmonitor\u002Fcost-and-usage","7.monitor\u002F1.cost-and-usage","i-ph-coins",{"title":244,"path":245,"stem":246,"icon":247},"Node health","\u002Fmonitor\u002Fnodes","7.monitor\u002F2.nodes","i-ph-heartbeat",{"title":249,"path":250,"stem":251,"icon":252},"Job history","\u002Fmonitor\u002Fhistory","7.monitor\u002F3.history","i-ph-clock-counter-clockwise",{"title":254,"path":255,"stem":256,"icon":257},"Tracing and metrics","\u002Fmonitor\u002Fobservability","7.monitor\u002F4.observability","i-ph-chart-line",{"title":259,"path":260,"stem":261,"icon":152},"Troubleshooting","\u002Fmonitor\u002Ftroubleshooting","7.monitor\u002F5.troubleshooting",{"title":263,"icon":6,"path":264,"stem":265,"children":266,"page":6},"Reference","\u002Freference","8.reference",[267,281,286,290,295,300],{"title":268,"icon":269,"path":270,"stem":271,"children":272,"page":6},"CLI","i-ph-terminal-window","\u002Freference\u002Fcli","8.reference\u002F1.cli",[273,277],{"title":274,"path":275,"stem":276},"orchestrator-zero","\u002Freference\u002Fcli\u002Forchestrator-zero","8.reference\u002F1.cli\u002F1.orchestrator-zero",{"title":278,"path":279,"stem":280},"orchestrator-zero-node","\u002Freference\u002Fcli\u002Forchestrator-zero-node","8.reference\u002F1.cli\u002F2.orchestrator-zero-node",{"title":282,"path":283,"stem":284,"icon":285},"oz0-plugin.yaml","\u002Freference\u002Fplugin-manifest","8.reference\u002F2.plugin-manifest","i-ph-file-code",{"title":287,"path":288,"stem":289,"icon":162},"Agent definition","\u002Freference\u002Fagent-definition","8.reference\u002F3.agent-definition",{"title":291,"path":292,"stem":293,"icon":294},"Ports","\u002Freference\u002Fports","8.reference\u002F4.ports","i-ph-network",{"title":296,"path":297,"stem":298,"icon":299},"Environment variables","\u002Freference\u002Fenvironment","8.reference\u002F5.environment","i-ph-brackets-curly",{"title":301,"path":302,"stem":303,"icon":304},"Files and directories","\u002Freference\u002Ffiles","8.reference\u002F6.files","i-ph-tree-structure",{"title":306,"icon":6,"path":307,"stem":308,"children":309,"page":6},"About","\u002Fabout","9.about",[310,315],{"title":311,"path":312,"stem":313,"icon":314},"Licensing","\u002Fabout\u002Flicensing","9.about\u002F1.licensing","i-ph-scales",{"title":316,"path":317,"stem":318,"icon":319},"About these docs","\u002Fabout\u002Fcontributing-docs","9.about\u002F2.contributing-docs","i-ph-pencil-simple",{"id":321,"title":149,"body":322,"description":971,"extension":972,"links":973,"meta":974,"navigation":975,"path":150,"seo":976,"stem":151,"__hash__":977},"docs\u002F5.build-plugins\u002F11.example-support-triage.md",{"type":323,"value":324,"toc":964},"minimark",[325,344,354,359,706,712,716,729,761,764,770,782,786,793,850,856,861,865,884,890,896,899,903,944,960],[326,327,328,329,339,340,343],"p",{},"This example puts every building block in one plugin, the way a team would build it. A service that answers typed questions with a confidence (Jev, from TypeSafe AI) decides which team a support ticket goes to and whether a refund is risky. The plugin is in the repository as ",[330,331,335],"a",{"href":332,"rel":333},"https:\u002F\u002Fgithub.com\u002Fmoon-ventures-se\u002Forchestrator-zero\u002Ftree\u002Fdevelop\u002Fexamples\u002Fjev-tools",[334],"nofollow",[336,337,338],"code",{},"examples\u002Fjev-tools",", and ",[336,341,342],{},"make demo-m5"," runs all of it.",[345,346,352],"pre",{"className":347,"code":349,"language":350,"meta":351},[348],"language-text","jev-tools\u002F\n├── oz0-plugin.yaml             # tools, the hook, requires.secrets: [JEV_API_KEY]\n├── src\u002Fjev_tools\u002F\n│   ├── jev_mcp.py              # jev.decide: typed questions in, answers with a confidence out\n│   ├── hooks.py                # guard.check_refund: is this refund risky?\n│   └── support_mcp.py          # support.lookup_order, support.refund\n├── agents\u002F                     # support-billing, support-technical, support-sales\n├── flows\u002Fsupport-triage.yaml   # started by Zendesk's webhook\n└── evals\u002F                      # billing.yaml, triage.yaml\n","text","",[336,353,349],{"__ignoreMap":351},[355,356,358],"h2",{"id":357},"the-flow","The flow",[345,360,365],{"className":361,"code":362,"filename":363,"language":364,"meta":351,"style":351},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: support-triage\ninput_schema: schemas\u002Fticket.json\ntrigger:\n  webhook: { secret: ZENDESK_WEBHOOK }\nsteps:\n  - id: decide\n    tool: jev.decide\n    input:\n      state: ${{ input.ticket }}\n      questions:\n        team: { choice: [billing, technical, sales] }\n        urgent: { yes_no: \"The customer needs an answer within an hour\" }\n  - id: route\n    when: steps.decide.team.confidence >= 0.8\n    agent: support-${{ steps.decide.team.choice }}\n    input: ${{ input.ticket }}\n  - id: ask_human\n    when: steps.decide.team.confidence \u003C 0.8\n    approval:\n      details: 'Jev is not sure where \"${{ input.ticket.subject }}\" goes. Send it to ${{ steps.decide.team.choice }}?'\n      timeout: 4h\n  - id: route_checked\n    when: has(steps.ask_human)\n    agent: support-${{ steps.decide.team.choice }}\n    input: ${{ input.ticket }}\noutput: \"${{ has(steps.route) ? steps.route : steps.route_checked }}\"\n","flows\u002Fsupport-triage.yaml","yaml",[336,366,367,384,395,404,426,434,448,459,467,478,486,523,549,561,572,583,592,604,614,622,639,650,662,672,681,690],{"__ignoreMap":351},[368,369,372,376,380],"span",{"class":370,"line":371},"line",1,[368,373,375],{"class":374},"swJcz","name",[368,377,379],{"class":378},"sMK4o",":",[368,381,383],{"class":382},"sfazB"," support-triage\n",[368,385,387,390,392],{"class":370,"line":386},2,[368,388,389],{"class":374},"input_schema",[368,391,379],{"class":378},[368,393,394],{"class":382}," schemas\u002Fticket.json\n",[368,396,398,401],{"class":370,"line":397},3,[368,399,400],{"class":374},"trigger",[368,402,403],{"class":378},":\n",[368,405,407,410,412,415,418,420,423],{"class":370,"line":406},4,[368,408,409],{"class":374},"  webhook",[368,411,379],{"class":378},[368,413,414],{"class":378}," {",[368,416,417],{"class":374}," secret",[368,419,379],{"class":378},[368,421,422],{"class":382}," ZENDESK_WEBHOOK",[368,424,425],{"class":378}," }\n",[368,427,429,432],{"class":370,"line":428},5,[368,430,431],{"class":374},"steps",[368,433,403],{"class":378},[368,435,437,440,443,445],{"class":370,"line":436},6,[368,438,439],{"class":378},"  -",[368,441,442],{"class":374}," id",[368,444,379],{"class":378},[368,446,447],{"class":382}," decide\n",[368,449,451,454,456],{"class":370,"line":450},7,[368,452,453],{"class":374},"    tool",[368,455,379],{"class":378},[368,457,458],{"class":382}," jev.decide\n",[368,460,462,465],{"class":370,"line":461},8,[368,463,464],{"class":374},"    input",[368,466,403],{"class":378},[368,468,470,473,475],{"class":370,"line":469},9,[368,471,472],{"class":374},"      state",[368,474,379],{"class":378},[368,476,477],{"class":382}," ${{ input.ticket }}\n",[368,479,481,484],{"class":370,"line":480},10,[368,482,483],{"class":374},"      questions",[368,485,403],{"class":378},[368,487,489,492,494,496,499,501,504,507,510,513,515,518,521],{"class":370,"line":488},11,[368,490,491],{"class":374},"        team",[368,493,379],{"class":378},[368,495,414],{"class":378},[368,497,498],{"class":374}," choice",[368,500,379],{"class":378},[368,502,503],{"class":378}," [",[368,505,506],{"class":382},"billing",[368,508,509],{"class":378},",",[368,511,512],{"class":382}," technical",[368,514,509],{"class":378},[368,516,517],{"class":382}," sales",[368,519,520],{"class":378},"]",[368,522,425],{"class":378},[368,524,526,529,531,533,536,538,541,544,547],{"class":370,"line":525},12,[368,527,528],{"class":374},"        urgent",[368,530,379],{"class":378},[368,532,414],{"class":378},[368,534,535],{"class":374}," yes_no",[368,537,379],{"class":378},[368,539,540],{"class":378}," \"",[368,542,543],{"class":382},"The customer needs an answer within an hour",[368,545,546],{"class":378},"\"",[368,548,425],{"class":378},[368,550,552,554,556,558],{"class":370,"line":551},13,[368,553,439],{"class":378},[368,555,442],{"class":374},[368,557,379],{"class":378},[368,559,560],{"class":382}," route\n",[368,562,564,567,569],{"class":370,"line":563},14,[368,565,566],{"class":374},"    when",[368,568,379],{"class":378},[368,570,571],{"class":382}," steps.decide.team.confidence >= 0.8\n",[368,573,575,578,580],{"class":370,"line":574},15,[368,576,577],{"class":374},"    agent",[368,579,379],{"class":378},[368,581,582],{"class":382}," support-${{ steps.decide.team.choice }}\n",[368,584,586,588,590],{"class":370,"line":585},16,[368,587,464],{"class":374},[368,589,379],{"class":378},[368,591,477],{"class":382},[368,593,595,597,599,601],{"class":370,"line":594},17,[368,596,439],{"class":378},[368,598,442],{"class":374},[368,600,379],{"class":378},[368,602,603],{"class":382}," ask_human\n",[368,605,607,609,611],{"class":370,"line":606},18,[368,608,566],{"class":374},[368,610,379],{"class":378},[368,612,613],{"class":382}," steps.decide.team.confidence \u003C 0.8\n",[368,615,617,620],{"class":370,"line":616},19,[368,618,619],{"class":374},"    approval",[368,621,403],{"class":378},[368,623,625,628,630,633,636],{"class":370,"line":624},20,[368,626,627],{"class":374},"      details",[368,629,379],{"class":378},[368,631,632],{"class":378}," '",[368,634,635],{"class":382},"Jev is not sure where \"${{ input.ticket.subject }}\" goes. Send it to ${{ steps.decide.team.choice }}?",[368,637,638],{"class":378},"'\n",[368,640,642,645,647],{"class":370,"line":641},21,[368,643,644],{"class":374},"      timeout",[368,646,379],{"class":378},[368,648,649],{"class":382}," 4h\n",[368,651,653,655,657,659],{"class":370,"line":652},22,[368,654,439],{"class":378},[368,656,442],{"class":374},[368,658,379],{"class":378},[368,660,661],{"class":382}," route_checked\n",[368,663,665,667,669],{"class":370,"line":664},23,[368,666,566],{"class":374},[368,668,379],{"class":378},[368,670,671],{"class":382}," has(steps.ask_human)\n",[368,673,675,677,679],{"class":370,"line":674},24,[368,676,577],{"class":374},[368,678,379],{"class":378},[368,680,582],{"class":382},[368,682,684,686,688],{"class":370,"line":683},25,[368,685,464],{"class":374},[368,687,379],{"class":378},[368,689,477],{"class":382},[368,691,693,696,698,700,703],{"class":370,"line":692},26,[368,694,695],{"class":374},"output",[368,697,379],{"class":378},[368,699,540],{"class":378},[368,701,702],{"class":382},"${{ has(steps.route) ? steps.route : steps.route_checked }}",[368,704,705],{"class":378},"\"\n",[326,707,708,709,711],{},"A ticket Jev is sure about goes straight to that team's agent; one it is unsure about waits until a person approves its guess. See ",[330,710,184],{"href":185},".",[355,713,715],{"id":714},"the-tool-its-key-and-its-cost","The tool, its key and its cost",[326,717,718,721,722,725,726,379],{},[336,719,720],{},"jev.decide"," reads the service's key from the environment: the plugin declares ",[336,723,724],{},"requires.secrets: [JEV_API_KEY]",", so every process of the plugin gets the tenant secret, and the key never goes into the repository. It returns the answers as structured content and reports what the service charged in the result's ",[336,727,728],{},"_meta",[345,730,734],{"className":731,"code":732,"language":733,"meta":351,"style":351},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","return CallToolResult(\n    content=[TextContent(type=\"text\", text=json.dumps(answers))],\n    structured_content=answers,\n    _meta={\"oz0\u002Fusage\": {\"service\": \"jev\", \"unit\": \"question\", \"units\": len(questions), \"cost_usd\": cost}},\n)\n","python",[336,735,736,741,746,751,756],{"__ignoreMap":351},[368,737,738],{"class":370,"line":371},[368,739,740],{},"return CallToolResult(\n",[368,742,743],{"class":370,"line":386},[368,744,745],{},"    content=[TextContent(type=\"text\", text=json.dumps(answers))],\n",[368,747,748],{"class":370,"line":397},[368,749,750],{},"    structured_content=answers,\n",[368,752,753],{"class":370,"line":406},[368,754,755],{},"    _meta={\"oz0\u002Fusage\": {\"service\": \"jev\", \"unit\": \"question\", \"units\": len(questions), \"cost_usd\": cost}},\n",[368,757,758],{"class":370,"line":428},[368,759,760],{},")\n",[326,762,763],{},"That cost lands on the job next to the model calls, and counts toward the job's budget:",[345,765,768],{"className":766,"code":767,"language":350,"meta":351},[348],"JOB                                      AGENT            NODES              MODELS                      CALLS  INPUT  CACHED  OUTPUT  COST\nhook-support-triage-zendesk-ticket-1001  support-triage   node-be9581dcfec6                              0      0      0       0       $0.0004\n└ support-billing-2227b26b               support-billing  node-be9581dcfec6  anthropic\u002Fclaude-haiku-4-5  3      1211   0       73      $0.0018\nReported by plugins:\n  hook-support-triage-zendesk-ticket-1001 (support-triage): jev, 2 questions, $0.0004, by jev-tools\n  support-billing-2227b26b (support-billing): jev, 1 question, $0.0002, by jev-tools\n",[336,769,767],{"__ignoreMap":351},[326,771,772,773,777,778,711],{},"See ",[330,774,776],{"href":775},"\u002Ffleet\u002Fsecrets#secrets-for-plugins","Secrets for plugins"," and ",[330,779,781],{"href":780},"\u002Fbuild-plugins\u002Ftools#report-what-your-own-services-cost","Report what your own services cost",[355,783,785],{"id":784},"the-hook","The hook",[326,787,788,789,792],{},"Before every refund, ",[336,790,791],{},"guard.check_refund"," asks Jev whether the refund is risky. A risky one (here: over $100) is escalated, so the call waits for a person:",[345,794,796],{"className":361,"code":795,"filename":282,"language":364,"meta":351,"style":351},"hooks:\n  - on: pre_tool_call\n    call: guard.check_refund\n    match: {tools: [support.refund]}\n",[336,797,798,805,818,828],{"__ignoreMap":351},[368,799,800,803],{"class":370,"line":371},[368,801,802],{"class":374},"hooks",[368,804,403],{"class":378},[368,806,807,809,813,815],{"class":370,"line":386},[368,808,439],{"class":378},[368,810,812],{"class":811},"sfNiH"," on",[368,814,379],{"class":378},[368,816,817],{"class":382}," pre_tool_call\n",[368,819,820,823,825],{"class":370,"line":397},[368,821,822],{"class":374},"    call",[368,824,379],{"class":378},[368,826,827],{"class":382}," guard.check_refund\n",[368,829,830,833,835,837,840,842,844,847],{"class":370,"line":406},[368,831,832],{"class":374},"    match",[368,834,379],{"class":378},[368,836,414],{"class":378},[368,838,839],{"class":374},"tools",[368,841,379],{"class":378},[368,843,503],{"class":378},[368,845,846],{"class":382},"support.refund",[368,848,849],{"class":378},"]}\n",[345,851,854],{"className":852,"code":853,"language":350,"meta":351},[348],"support-billing → support.refund {\"amount_usd\":400,\"order_id\":\"5678\",\"reason\":\"double charge\"}\nsupport-billing ⏸ support.refund waits for approval a-86f882b36825: {\"hook\": \"guard.check_refund\", \"reason\": \"Jev thinks this refund is risky (0.90)\", ...}\nsupport-billing ▶ support.refund approved by operator:admin: checked the bank statement\nsupport-billing ← support.refund Refunded $400.00 for order 5678 (double charge).\n",[336,855,853],{"__ignoreMap":351},[326,857,858,859,711],{},"When Jev cannot be reached, the hook escalates too, so a person decides rather than nobody. See ",[330,860,179],{"href":180},[355,862,864],{"id":863},"the-evals-and-a-version-that-does-worse","The evals, and a version that does worse",[326,866,867,870,871,874,875,878,879,883],{},[336,868,869],{},"evals\u002Fbilling.yaml"," wants a double charge refunded and a single charge left alone; ",[336,872,873],{},"evals\u002Ftriage.yaml"," sends a ticket through the whole flow. ",[336,876,877],{},"plugin test"," runs them while the team works, and the ",[330,880,882],{"href":881},"\u002Fbuild-plugins\u002Fevals#quality-gates","quality gate"," runs them again at every install.",[326,885,886,887,889],{},"In the demo, a teammate's version 1.1.0 drops ",[336,888,846],{}," from the billing agent's tools. Its evals get worse, and the gate stops it before the fleet gets it:",[345,891,894],{"className":892,"code":893,"language":350,"meta":351},[348],"Gate of jev-tools 1.1.0: stopped: eval billing: 1 of 2 cases passed (50%), below its threshold of 100%\n",[336,895,893],{"__ignoreMap":351},[326,897,898],{},"The fleet keeps answering tickets with 1.0.0.",[355,900,902],{"id":901},"run-it","Run it",[345,904,909],{"className":905,"code":906,"filename":907,"language":908,"meta":351,"style":351},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","make demo-m5                                  # stand-ins for Jev and Claude, no keys needed\nANTHROPIC_API_KEY=sk-ant-... make demo-m5     # the agents on Claude (claude-haiku-4-5)\n","Terminal","bash",[336,910,911,924],{"__ignoreMap":351},[368,912,913,917,920],{"class":370,"line":371},[368,914,916],{"class":915},"sBMFI","make",[368,918,919],{"class":382}," demo-m5",[368,921,923],{"class":922},"sHwdD","                                  # stand-ins for Jev and Claude, no keys needed\n",[368,925,926,930,933,936,939,941],{"class":370,"line":386},[368,927,929],{"class":928},"sTEyZ","ANTHROPIC_API_KEY",[368,931,932],{"class":378},"=",[368,934,935],{"class":382},"sk-ant-...",[368,937,938],{"class":915}," make",[368,940,919],{"class":382},[368,942,943],{"class":922},"     # the agents on Claude (claude-haiku-4-5)\n",[945,946,947,948,951,952,955,956,959],"note",{},"Jev is a hosted service with a waiting list, and its SDK is not public. The example therefore speaks a request of its own shape, and ",[336,949,950],{},"scripts\u002Ffakejev"," answers it in the demo. With access to Jev, replace ",[336,953,954],{},"ask()"," in ",[336,957,958],{},"jev.py"," with a call to TypeSafe's SDK; the same pattern works with a classifier of your own or a small LLM.",[961,962,963],"style",{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":351,"searchDepth":386,"depth":386,"links":965},[966,967,968,969,970],{"id":357,"depth":386,"text":358},{"id":714,"depth":386,"text":715},{"id":784,"depth":386,"text":785},{"id":863,"depth":386,"text":864},{"id":901,"depth":386,"text":902},"A plugin that routes support tickets with typed decisions, a hook that holds risky refunds, and a gate that stops a worse version.","md",null,{},{"icon":152},{"title":149,"description":971},"0znDPDunxjHPNr-p6bx0IErx-y7OfBcLapUESN7DFjY",[979,981],{"title":144,"path":145,"stem":146,"description":980,"icon":147,"children":-1},"Run a whole session of an existing agent harness, such as the Claude Agent SDK, as a job.",{"title":154,"path":155,"stem":156,"description":982,"icon":157,"children":-1},"Tools are MCP servers. Write your own in Python, or use any existing server.",1791135410661]