cai/tools/index.html

3361 lines
87 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="prev" href="../agents/">
<link rel="next" href="../handoffs/">
<link rel="icon" href="../assets/imago.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.11">
<title>Tools - CAI</title>
<link rel="stylesheet" href="../assets/stylesheets/main.4af4bdda.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../assets/_mkdocstrings.css">
<link rel="stylesheet" href="../stylesheets/extra.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="custom" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#tools" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="CAI" class="md-header__button md-logo" aria-label="CAI" data-md-component="logo">
<img src="../assets/imago.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
CAI
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Tools
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/aliasrobotics/cai" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</div>
<div class="md-source__repository">
aliasrobotics/cai
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="CAI" class="md-nav__button md-logo" aria-label="CAI" data-md-component="logo">
<img src="../assets/imago.png" alt="logo">
</a>
CAI
</label>
<div class="md-nav__source">
<a href="https://github.com/aliasrobotics/cai" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</div>
<div class="md-source__repository">
aliasrobotics/cai
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_1" >
<label class="md-nav__link" for="__nav_1" id="__nav_1_label" tabindex="">
<span class="md-ellipsis">
Getting Started
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_1">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Welcome
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai_installation/" class="md-nav__link">
<span class="md-ellipsis">
Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai_quickstart/" class="md-nav__link">
<span class="md-ellipsis">
Quickstart
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai_list_of_models/" class="md-nav__link">
<span class="md-ellipsis">
Available Models
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_1_5" >
<label class="md-nav__link" for="__nav_1_5" id="__nav_1_5_label" tabindex="0">
<span class="md-ellipsis">
Model Providers
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_1_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_1_5">
<span class="md-nav__icon md-icon"></span>
Model Providers
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../providers/openrouter.md" class="md-nav__link">
<span class="md-ellipsis">
OpenRouter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../providers/ollama/" class="md-nav__link">
<span class="md-ellipsis">
Ollama
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../providers/azure.md" class="md-nav__link">
<span class="md-ellipsis">
Azure OpenAI
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../cai_pro/" class="md-nav__link">
<span class="md-ellipsis">
🚀 CAI PRO
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-ellipsis">
Core Concepts
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Core Concepts
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../cai_architecture/" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../agents/" class="md-nav__link">
<span class="md-ellipsis">
Agents
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Tools
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Tools
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#hosted-tools" class="md-nav__link">
<span class="md-ellipsis">
Hosted tools
</span>
</a>
<nav class="md-nav" aria-label="Hosted tools">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#c99-tool" class="md-nav__link">
<span class="md-ellipsis">
C99 Tool
</span>
</a>
<nav class="md-nav" aria-label="C99 Tool">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#configuration" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#usage-example" class="md-nav__link">
<span class="md-ellipsis">
Usage Example
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#function-tools" class="md-nav__link">
<span class="md-ellipsis">
Function tools
</span>
</a>
<nav class="md-nav" aria-label="Function tools">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#custom-function-tools" class="md-nav__link">
<span class="md-ellipsis">
Custom function tools
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#automatic-argument-and-docstring-parsing" class="md-nav__link">
<span class="md-ellipsis">
Automatic argument and docstring parsing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#agents-as-tools" class="md-nav__link">
<span class="md-ellipsis">
Agents as tools
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#handling-errors-in-function-tools" class="md-nav__link">
<span class="md-ellipsis">
Handling errors in function tools
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../handoffs/" class="md-nav__link">
<span class="md-ellipsis">
Handoffs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../multi_agent/" class="md-nav__link">
<span class="md-ellipsis">
Multi-Agent Systems
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="">
<span class="md-ellipsis">
Benchmarking
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Benchmarking
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../benchmarking/overview/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/running_benchmarks/" class="md-nav__link">
<span class="md-ellipsis">
Running Benchmarks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/attack_defense/" class="md-nav__link">
<span class="md-ellipsis">
Attack & Defense CTFs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/jeopardy_ctfs/" class="md-nav__link">
<span class="md-ellipsis">
Jeopardy CTFs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/cyber_ranges/" class="md-nav__link">
<span class="md-ellipsis">
Cyber Ranges
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/knowledge_benchmarks/" class="md-nav__link">
<span class="md-ellipsis">
Knowledge Benchmarks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/privacy_benchmarks/" class="md-nav__link">
<span class="md-ellipsis">
Privacy Benchmarks
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="">
<span class="md-ellipsis">
Guides
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Guides
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../running_agents/" class="md-nav__link">
<span class="md-ellipsis">
Running Agents
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../continue_mode/" class="md-nav__link">
<span class="md-ellipsis">
Continue Mode
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../results/" class="md-nav__link">
<span class="md-ellipsis">
Working with Results
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../streaming/" class="md-nav__link">
<span class="md-ellipsis">
Streaming
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tracing/" class="md-nav__link">
<span class="md-ellipsis">
Tracing & Debugging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../context/" class="md-nav__link">
<span class="md-ellipsis">
Context Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../guardrails/" class="md-nav__link">
<span class="md-ellipsis">
Guardrails & Security
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../environment_variables/" class="md-nav__link">
<span class="md-ellipsis">
Environment Variables
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai/getting-started/packet_capture_wsl/" class="md-nav__link">
<span class="md-ellipsis">
Packet Capture on WSL2
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="">
<span class="md-ellipsis">
Troubleshooting
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Troubleshooting
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../cai/troubleshooting/operator_feedback_reproduction/" class="md-nav__link">
<span class="md-ellipsis">
Operator Feedback Reproduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai/troubleshooting/platform_limitations/" class="md-nav__link">
<span class="md-ellipsis">
Platform Limitations
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="">
<span class="md-ellipsis">
Case Studies
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Case Studies
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../cai/case-studies/operator-artifact-evidence/" class="md-nav__link">
<span class="md-ellipsis">
Operator Artifact Evidence
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_8" >
<label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="">
<span class="md-ellipsis">
Mobile UI (iOS)
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
Mobile UI (iOS)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../mui/mui_index/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mui/getting_started/" class="md-nav__link">
<span class="md-ellipsis">
Getting Started
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mui/user_interface/" class="md-nav__link">
<span class="md-ellipsis">
User Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mui/gestures_shortcuts/" class="md-nav__link">
<span class="md-ellipsis">
Gestures & Shortcuts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mui/chat_features/" class="md-nav__link">
<span class="md-ellipsis">
Chat Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_9" >
<label class="md-nav__link" for="__nav_9" id="__nav_9_label" tabindex="">
<span class="md-ellipsis">
Terminal UI (TUI) - Deprecated
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_9">
<span class="md-nav__icon md-icon"></span>
Terminal UI (TUI) - Deprecated
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../tui/tui_index/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/getting_started/" class="md-nav__link">
<span class="md-ellipsis">
Getting Started
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/user_interface/" class="md-nav__link">
<span class="md-ellipsis">
User Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/terminals_management/" class="md-nav__link">
<span class="md-ellipsis">
Terminals Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/teams_and_parallel_execution/" class="md-nav__link">
<span class="md-ellipsis">
Teams & Parallel Execution
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/sidebar_features/" class="md-nav__link">
<span class="md-ellipsis">
Sidebar Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/keyboard_shortcuts/" class="md-nav__link">
<span class="md-ellipsis">
Keyboard Shortcuts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/commands_reference/" class="md-nav__link">
<span class="md-ellipsis">
Commands Reference
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/advanced_features/" class="md-nav__link">
<span class="md-ellipsis">
Advanced Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tui/troubleshooting/" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_10" >
<label class="md-nav__link" for="__nav_10" id="__nav_10_label" tabindex="">
<span class="md-ellipsis">
API Reference
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10">
<span class="md-nav__icon md-icon"></span>
API Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_10_1" >
<label class="md-nav__link" for="__nav_10_1" id="__nav_10_1_label" tabindex="0">
<span class="md-ellipsis">
Agents
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_10_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10_1">
<span class="md-nav__icon md-icon"></span>
Agents
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../ref/agent/" class="md-nav__link">
<span class="md-ellipsis">
Agent
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/run/" class="md-nav__link">
<span class="md-ellipsis">
Runner
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/tool/" class="md-nav__link">
<span class="md-ellipsis">
Tool
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/result/" class="md-nav__link">
<span class="md-ellipsis">
Result
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/stream_events/" class="md-nav__link">
<span class="md-ellipsis">
Stream Events
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/handoffs/" class="md-nav__link">
<span class="md-ellipsis">
Handoffs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/lifecycle/" class="md-nav__link">
<span class="md-ellipsis">
Lifecycle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/items/" class="md-nav__link">
<span class="md-ellipsis">
Items
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/run_context/" class="md-nav__link">
<span class="md-ellipsis">
Run Context
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/usage/" class="md-nav__link">
<span class="md-ellipsis">
Usage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/exceptions/" class="md-nav__link">
<span class="md-ellipsis">
Exceptions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/guardrail/" class="md-nav__link">
<span class="md-ellipsis">
Guardrail
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/model_settings/" class="md-nav__link">
<span class="md-ellipsis">
Model Settings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/agent_output/" class="md-nav__link">
<span class="md-ellipsis">
Agent Output
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/function_schema/" class="md-nav__link">
<span class="md-ellipsis">
Function Schema
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_10_2" >
<label class="md-nav__link" for="__nav_10_2" id="__nav_10_2_label" tabindex="0">
<span class="md-ellipsis">
Models
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_10_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10_2">
<span class="md-nav__icon md-icon"></span>
Models
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../ref/models/interface/" class="md-nav__link">
<span class="md-ellipsis">
Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/models/openai_chatcompletions/" class="md-nav__link">
<span class="md-ellipsis">
OpenAI Chat Completions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/models/openai_responses/" class="md-nav__link">
<span class="md-ellipsis">
OpenAI Responses
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_10_3" >
<label class="md-nav__link" for="__nav_10_3" id="__nav_10_3_label" tabindex="0">
<span class="md-ellipsis">
Extensions
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_10_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_10_3">
<span class="md-nav__icon md-icon"></span>
Extensions
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../ref/extensions/handoff_filters/" class="md-nav__link">
<span class="md-ellipsis">
Handoff Filters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ref/extensions/handoff_prompt/" class="md-nav__link">
<span class="md-ellipsis">
Handoff Prompt
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_11" >
<label class="md-nav__link" for="__nav_11" id="__nav_11_label" tabindex="">
<span class="md-ellipsis">
Advanced
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_11">
<span class="md-nav__icon md-icon"></span>
Advanced
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../cai_development/" class="md-nav__link">
<span class="md-ellipsis">
Development
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_12" >
<label class="md-nav__link" for="__nav_12" id="__nav_12_label" tabindex="">
<span class="md-ellipsis">
Research
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_12_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_12">
<span class="md-nav__icon md-icon"></span>
Research
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../research/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_13" >
<label class="md-nav__link" for="__nav_13" id="__nav_13_label" tabindex="">
<span class="md-ellipsis">
Resources
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_13">
<span class="md-nav__icon md-icon"></span>
Resources
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../cai_faq/" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai_find_us/" class="md-nav__link">
<span class="md-ellipsis">
Find Us
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cai_citation_and_acknowledgments/" class="md-nav__link">
<span class="md-ellipsis">
Citation & Acknowledgments
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#hosted-tools" class="md-nav__link">
<span class="md-ellipsis">
Hosted tools
</span>
</a>
<nav class="md-nav" aria-label="Hosted tools">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#c99-tool" class="md-nav__link">
<span class="md-ellipsis">
C99 Tool
</span>
</a>
<nav class="md-nav" aria-label="C99 Tool">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#configuration" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#usage-example" class="md-nav__link">
<span class="md-ellipsis">
Usage Example
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#function-tools" class="md-nav__link">
<span class="md-ellipsis">
Function tools
</span>
</a>
<nav class="md-nav" aria-label="Function tools">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#custom-function-tools" class="md-nav__link">
<span class="md-ellipsis">
Custom function tools
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#automatic-argument-and-docstring-parsing" class="md-nav__link">
<span class="md-ellipsis">
Automatic argument and docstring parsing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#agents-as-tools" class="md-nav__link">
<span class="md-ellipsis">
Agents as tools
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#handling-errors-in-function-tools" class="md-nav__link">
<span class="md-ellipsis">
Handling errors in function tools
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="tools">Tools</h1>
<p>Tools let agents take actions: things like fetching data, running code, calling external APIs, and even using a computer. There are three classes of tools in the CAI Agents</p>
<ul>
<li>Hosted tools: these run on LLM servers alongside the AI models. CAI offers some <a href="src/cai/tools">tools</a></li>
<li>Function calling: these allow you to use any Python function as a tool.</li>
<li>Agents as tools: this allows you to use an agent as a tool, allowing Agents to call other agents without handing off to them.</li>
</ul>
<h2 id="hosted-tools">Hosted tools</h2>
<p>CAI offers a few built-in tools when using the <a class="autorefs autorefs-internal" title="OpenAIResponsesModel" href="../ref/models/openai_responses/#cai.sdk.agents.models.openai_responses.OpenAIResponsesModel"><code>OpenAIResponsesModel</code></a>. They are in <a href="src/cai/tools">tools</a> and grouped in 6 major categories inspired by the security kill chain[2]:</p>
<ol>
<li>Reconnaissance and weaponization - <em>reconnaissance</em> (crypto, listing, etc)</li>
<li>Exploitation - <em>exploitation</em></li>
<li>Privilege escalation - <em>escalation</em></li>
<li>Lateral movement - <em>lateral</em></li>
<li>Data exfiltration - <em>exfiltration</em></li>
<li>Command and control - <em>control</em></li>
</ol>
<h3 id="c99-tool">C99 Tool</h3>
<p>CAI includes integration with the C99.nl API for subdomain discovery and DNS enumeration. This tool is particularly useful for reconnaissance during security assessments.</p>
<h4 id="configuration">Configuration</h4>
<p>To use the C99 tool, you need to set up your API key:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-0-1"><span class="c1"># In your .env file</span>
</span><span id="__span-0-2"><span class="nv">C99_API_KEY</span><span class="o">=</span><span class="s2">&quot;your-c99-api-key-here&quot;</span>
</span></code></pre></div>
<p>You can obtain an API key by registering at <a href="https://c99.nl">C99.nl</a>.</p>
<h4 id="usage-example">Usage Example</h4>
<div class="language-python highlight"><pre><span></span><code><span id="__span-1-1"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.sdk.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Agent</span><span class="p">,</span> <span class="n">Runner</span><span class="p">,</span> <span class="n">OpenAIChatCompletionsModel</span>
</span><span id="__span-1-2"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.tools.reconnaissance.c99_tool</span><span class="w"> </span><span class="kn">import</span> <span class="n">c99_subdomain_finder</span>
</span><span id="__span-1-3"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">AsyncOpenAI</span>
</span><span id="__span-1-4">
</span><span id="__span-1-5"><span class="n">recon_agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
</span><span id="__span-1-6"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;Recon Agent&quot;</span><span class="p">,</span>
</span><span id="__span-1-7"> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Agent specialized in subdomain discovery&quot;</span><span class="p">,</span>
</span><span id="__span-1-8"> <span class="n">instructions</span><span class="o">=</span><span class="s2">&quot;You are a reconnaissance expert focused on DNS enumeration.&quot;</span><span class="p">,</span>
</span><span id="__span-1-9"> <span class="n">tools</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-1-10"> <span class="n">c99_subdomain_finder</span><span class="p">,</span>
</span><span id="__span-1-11"> <span class="p">],</span>
</span><span id="__span-1-12"> <span class="n">model</span><span class="o">=</span><span class="n">OpenAIChatCompletionsModel</span><span class="p">(</span>
</span><span id="__span-1-13"> <span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:14b&quot;</span><span class="p">,</span>
</span><span id="__span-1-14"> <span class="n">openai_client</span><span class="o">=</span><span class="n">AsyncOpenAI</span><span class="p">(),</span>
</span><span id="__span-1-15"> <span class="p">)</span>
</span><span id="__span-1-16"><span class="p">)</span>
</span><span id="__span-1-17">
</span><span id="__span-1-18"><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
</span><span id="__span-1-19"> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">Runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">recon_agent</span><span class="p">,</span> <span class="s2">&quot;Find all subdomains for example.com&quot;</span><span class="p">)</span>
</span><span id="__span-1-20"> <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">final_output</span><span class="p">)</span>
</span></code></pre></div>
<p>The C99 tool provides comprehensive subdomain enumeration capabilities, making it valuable for the reconnaissance phase of security assessments.</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-2-1"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.sdk.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Agent</span><span class="p">,</span> <span class="n">Runner</span><span class="p">,</span> <span class="n">OpenAIChatCompletionsModel</span>
</span><span id="__span-2-2"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.tools.reconnaissance.generic_linux_command</span><span class="w"> </span><span class="kn">import</span> <span class="n">generic_linux_command</span>
</span><span id="__span-2-3"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">AsyncOpenAI</span>
</span><span id="__span-2-4">
</span><span id="__span-2-5"><span class="n">one_tool_agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
</span><span id="__span-2-6"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;CTF agent&quot;</span><span class="p">,</span>
</span><span id="__span-2-7"> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Agent focused on listing directories&quot;</span><span class="p">,</span>
</span><span id="__span-2-8"> <span class="n">instructions</span><span class="o">=</span><span class="s2">&quot;You are a Cybersecurity expert Leader facing a CTF challenge.&quot;</span><span class="p">,</span>
</span><span id="__span-2-9"> <span class="n">tools</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-2-10"> <span class="n">generic_linux_command</span><span class="p">,</span>
</span><span id="__span-2-11"> <span class="p">],</span>
</span><span id="__span-2-12"> <span class="n">model</span><span class="o">=</span><span class="n">OpenAIChatCompletionsModel</span><span class="p">(</span>
</span><span id="__span-2-13"> <span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:14b&quot;</span><span class="p">,</span>
</span><span id="__span-2-14"> <span class="n">openai_client</span><span class="o">=</span><span class="n">AsyncOpenAI</span><span class="p">(),</span>
</span><span id="__span-2-15"> <span class="p">)</span>
</span><span id="__span-2-16"><span class="p">)</span>
</span><span id="__span-2-17"><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
</span><span id="__span-2-18"> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">Runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">one_tool_agent</span><span class="p">,</span> <span class="s2">&quot;List all directories&quot;</span><span class="p">)</span>
</span><span id="__span-2-19"> <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">final_output</span><span class="p">)</span>
</span></code></pre></div>
<h2 id="function-tools">Function tools</h2>
<p>You can use any Python function as a tool. The CAI will setup the tool automatically:</p>
<ul>
<li>The name of the tool will be the name of the Python function (or you can provide a name)</li>
<li>Tool description will be taken from the docstring of the function (or you can provide a description)</li>
<li>The schema for the function inputs is automatically created from the function's arguments</li>
<li>Descriptions for each input are taken from the docstring of the function, unless disabled</li>
</ul>
<p>We use Python's <code>inspect</code> module to extract the function signature, along with <a href="https://mkdocstrings.github.io/griffe/"><code>griffe</code></a> to parse docstrings and <code>pydantic</code> for schema creation.</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-3-1"><span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
</span><span id="__span-3-2"><span class="kn">from</span><span class="w"> </span><span class="nn">typing_extensions</span><span class="w"> </span><span class="kn">import</span> <span class="n">TypedDict</span><span class="p">,</span> <span class="n">Any</span>
</span><span id="__span-3-3"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.sdk.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Agent</span><span class="p">,</span> <span class="n">FunctionTool</span><span class="p">,</span> <span class="n">RunContextWrapper</span><span class="p">,</span> <span class="n">function_tool</span><span class="p">,</span> <span class="n">OpenAIChatCompletionsModel</span>
</span><span id="__span-3-4"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">AsyncOpenAI</span>
</span><span id="__span-3-5">
</span><span id="__span-3-6"><span class="k">class</span><span class="w"> </span><span class="nc">IPAddress</span><span class="p">(</span><span class="n">TypedDict</span><span class="p">):</span>
</span><span id="__span-3-7"> <span class="n">ip</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-3-8">
</span><span id="__span-3-9">
</span><span id="__span-3-10"><span class="nd">@function_tool</span>
</span><span id="__span-3-11"><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">check_ip_reputation</span><span class="p">(</span><span class="n">ip_data</span><span class="p">:</span> <span class="n">IPAddress</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-3-12"><span class="w"> </span><span class="sd">&quot;&quot;&quot;Check if an IP address has a bad reputation.</span>
</span><span id="__span-3-13">
</span><span id="__span-3-14"><span class="sd"> Args:</span>
</span><span id="__span-3-15"><span class="sd"> ip_data: A dictionary with the IP address to check.</span>
</span><span id="__span-3-16"><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="__span-3-17"> <span class="c1"># In a real system, this would query an IP reputation API</span>
</span><span id="__span-3-18"> <span class="k">return</span> <span class="s2">&quot;malicious&quot;</span> <span class="k">if</span> <span class="n">ip_data</span><span class="p">[</span><span class="s2">&quot;ip&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;192.168&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot;clean&quot;</span>
</span><span id="__span-3-19">
</span><span id="__span-3-20">
</span><span id="__span-3-21"><span class="nd">@function_tool</span><span class="p">(</span><span class="n">name_override</span><span class="o">=</span><span class="s2">&quot;read_log_file&quot;</span><span class="p">)</span>
</span><span id="__span-3-22"><span class="k">def</span><span class="w"> </span><span class="nf">read_log_file</span><span class="p">(</span><span class="n">ctx</span><span class="p">:</span> <span class="n">RunContextWrapper</span><span class="p">[</span><span class="n">Any</span><span class="p">],</span> <span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">directory</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-3-23"><span class="w"> </span><span class="sd">&quot;&quot;&quot;Read the contents of a log file.</span>
</span><span id="__span-3-24">
</span><span id="__span-3-25"><span class="sd"> Args:</span>
</span><span id="__span-3-26"><span class="sd"> path: The path to the log file.</span>
</span><span id="__span-3-27"><span class="sd"> directory: The optional directory to search in.</span>
</span><span id="__span-3-28"><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="__span-3-29"> <span class="c1"># In a real system, this would read from the filesystem logs</span>
</span><span id="__span-3-30"> <span class="k">return</span> <span class="s2">&quot;&lt;log file contents: suspicious activity found&gt;&quot;</span>
</span><span id="__span-3-31">
</span><span id="__span-3-32">
</span><span id="__span-3-33"><span class="c1"># Create the cybersecurity agent</span>
</span><span id="__span-3-34"><span class="n">agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
</span><span id="__span-3-35"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;CyberSecBot&quot;</span><span class="p">,</span>
</span><span id="__span-3-36"> <span class="n">tools</span><span class="o">=</span><span class="p">[</span><span class="n">check_ip_reputation</span><span class="p">,</span> <span class="n">read_log_file</span><span class="p">],</span>
</span><span id="__span-3-37"> <span class="n">model</span><span class="o">=</span><span class="n">OpenAIChatCompletionsModel</span><span class="p">(</span>
</span><span id="__span-3-38"> <span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:14b&quot;</span><span class="p">,</span>
</span><span id="__span-3-39"> <span class="n">openai_client</span><span class="o">=</span><span class="n">AsyncOpenAI</span><span class="p">(),</span>
</span><span id="__span-3-40"> <span class="p">)</span>
</span><span id="__span-3-41"><span class="p">)</span>
</span><span id="__span-3-42">
</span><span id="__span-3-43"><span class="c1"># Display metadata for each available tool</span>
</span><span id="__span-3-44"><span class="k">for</span> <span class="n">tool</span> <span class="ow">in</span> <span class="n">agent</span><span class="o">.</span><span class="n">tools</span><span class="p">:</span>
</span><span id="__span-3-45"> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">tool</span><span class="p">,</span> <span class="n">FunctionTool</span><span class="p">):</span>
</span><span id="__span-3-46"> <span class="nb">print</span><span class="p">(</span><span class="n">tool</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
</span><span id="__span-3-47"> <span class="nb">print</span><span class="p">(</span><span class="n">tool</span><span class="o">.</span><span class="n">description</span><span class="p">)</span>
</span><span id="__span-3-48"> <span class="nb">print</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">tool</span><span class="o">.</span><span class="n">params_json_schema</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">))</span>
</span><span id="__span-3-49"> <span class="nb">print</span><span class="p">()</span>
</span></code></pre></div>
<ol>
<li>You can use any Python types as arguments to your functions, and the function can be sync or async.</li>
<li>Docstrings, if present, are used to capture descriptions and argument descriptions</li>
<li>Functions can optionally take the <code>context</code> (must be the first argument). You can also set overrides, like the name of the tool, description, which docstring style to use, etc.</li>
<li>You can pass the decorated functions to the list of tools.</li>
</ol>
<details class="note">
<summary>Expand to see output</summary>
<div class="language-text highlight"><pre><span></span><code><span id="__span-4-1">check_ip_reputation
</span><span id="__span-4-2">Check if an IP address has a bad reputation.
</span><span id="__span-4-3">{
</span><span id="__span-4-4"> &quot;$defs&quot;: {
</span><span id="__span-4-5"> &quot;IPAddress&quot;: {
</span><span id="__span-4-6"> &quot;properties&quot;: {
</span><span id="__span-4-7"> &quot;ip&quot;: {
</span><span id="__span-4-8"> &quot;title&quot;: &quot;Ip&quot;,
</span><span id="__span-4-9"> &quot;type&quot;: &quot;string&quot;
</span><span id="__span-4-10"> }
</span><span id="__span-4-11"> },
</span><span id="__span-4-12"> &quot;required&quot;: [
</span><span id="__span-4-13"> &quot;ip&quot;
</span><span id="__span-4-14"> ],
</span><span id="__span-4-15"> &quot;title&quot;: &quot;IPAddress&quot;,
</span><span id="__span-4-16"> &quot;type&quot;: &quot;object&quot;,
</span><span id="__span-4-17"> &quot;additionalProperties&quot;: false
</span><span id="__span-4-18"> }
</span><span id="__span-4-19"> },
</span><span id="__span-4-20"> &quot;properties&quot;: {
</span><span id="__span-4-21"> &quot;ip_data&quot;: {
</span><span id="__span-4-22"> &quot;description&quot;: &quot;A dictionary with the IP address to check.&quot;,
</span><span id="__span-4-23"> &quot;properties&quot;: {
</span><span id="__span-4-24"> &quot;ip&quot;: {
</span><span id="__span-4-25"> &quot;title&quot;: &quot;Ip&quot;,
</span><span id="__span-4-26"> &quot;type&quot;: &quot;string&quot;
</span><span id="__span-4-27"> }
</span><span id="__span-4-28"> },
</span><span id="__span-4-29"> &quot;required&quot;: [
</span><span id="__span-4-30"> &quot;ip&quot;
</span><span id="__span-4-31"> ],
</span><span id="__span-4-32"> &quot;title&quot;: &quot;IPAddress&quot;,
</span><span id="__span-4-33"> &quot;type&quot;: &quot;object&quot;,
</span><span id="__span-4-34"> &quot;additionalProperties&quot;: false
</span><span id="__span-4-35"> }
</span><span id="__span-4-36"> },
</span><span id="__span-4-37"> &quot;required&quot;: [
</span><span id="__span-4-38"> &quot;ip_data&quot;
</span><span id="__span-4-39"> ],
</span><span id="__span-4-40"> &quot;title&quot;: &quot;check_ip_reputation_args&quot;,
</span><span id="__span-4-41"> &quot;type&quot;: &quot;object&quot;,
</span><span id="__span-4-42"> &quot;additionalProperties&quot;: false
</span><span id="__span-4-43">}
</span><span id="__span-4-44">
</span><span id="__span-4-45">read_log_file
</span><span id="__span-4-46">Read the contents of a log file.
</span><span id="__span-4-47">{
</span><span id="__span-4-48"> &quot;properties&quot;: {
</span><span id="__span-4-49"> &quot;path&quot;: {
</span><span id="__span-4-50"> &quot;description&quot;: &quot;The path to the log file.&quot;,
</span><span id="__span-4-51"> &quot;title&quot;: &quot;Path&quot;,
</span><span id="__span-4-52"> &quot;type&quot;: &quot;string&quot;
</span><span id="__span-4-53"> },
</span><span id="__span-4-54"> &quot;directory&quot;: {
</span><span id="__span-4-55"> &quot;anyOf&quot;: [
</span><span id="__span-4-56"> {
</span><span id="__span-4-57"> &quot;type&quot;: &quot;string&quot;
</span><span id="__span-4-58"> },
</span><span id="__span-4-59"> {
</span><span id="__span-4-60"> &quot;type&quot;: &quot;null&quot;
</span><span id="__span-4-61"> }
</span><span id="__span-4-62"> ],
</span><span id="__span-4-63"> &quot;description&quot;: &quot;The optional directory to search in.&quot;,
</span><span id="__span-4-64"> &quot;title&quot;: &quot;Directory&quot;
</span><span id="__span-4-65"> }
</span><span id="__span-4-66"> },
</span><span id="__span-4-67"> &quot;required&quot;: [
</span><span id="__span-4-68"> &quot;path&quot;,
</span><span id="__span-4-69"> &quot;directory&quot;
</span><span id="__span-4-70"> ],
</span><span id="__span-4-71"> &quot;title&quot;: &quot;read_log_file_args&quot;,
</span><span id="__span-4-72"> &quot;type&quot;: &quot;object&quot;,
</span><span id="__span-4-73"> &quot;additionalProperties&quot;: false
</span><span id="__span-4-74">}
</span></code></pre></div>
</details>
<h3 id="custom-function-tools">Custom function tools</h3>
<p>Sometimes, you don't want to use a Python function as a tool. You can directly create a <a class="autorefs autorefs-internal" title="FunctionTool
dataclass
" href="../ref/tool/#cai.sdk.agents.tool.FunctionTool"><code>FunctionTool</code></a> if you prefer. You'll need to provide:</p>
<ul>
<li><code>name</code></li>
<li><code>description</code></li>
<li><code>params_json_schema</code>, which is the JSON schema for the arguments</li>
<li><code>on_invoke_tool</code>, which is an async function that receives the context and the arguments as a JSON string, and must return the tool output as a string.</li>
</ul>
<div class="language-python highlight"><pre><span></span><code><span id="__span-5-1"><span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Any</span>
</span><span id="__span-5-2"><span class="kn">from</span><span class="w"> </span><span class="nn">pydantic</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseModel</span>
</span><span id="__span-5-3"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.sdk.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">RunContextWrapper</span><span class="p">,</span> <span class="n">FunctionTool</span>
</span><span id="__span-5-4">
</span><span id="__span-5-5">
</span><span id="__span-5-6"><span class="k">def</span><span class="w"> </span><span class="nf">do_some_work</span><span class="p">(</span><span class="n">data</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-5-7"> <span class="k">return</span> <span class="s2">&quot;done&quot;</span>
</span><span id="__span-5-8">
</span><span id="__span-5-9"><span class="k">class</span><span class="w"> </span><span class="nc">FunctionArgs</span><span class="p">(</span><span class="n">BaseModel</span><span class="p">):</span>
</span><span id="__span-5-10"> <span class="n">username</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="__span-5-11"> <span class="n">age</span><span class="p">:</span> <span class="nb">int</span>
</span><span id="__span-5-12">
</span><span id="__span-5-13">
</span><span id="__span-5-14"><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_function</span><span class="p">(</span><span class="n">ctx</span><span class="p">:</span> <span class="n">RunContextWrapper</span><span class="p">[</span><span class="n">Any</span><span class="p">],</span> <span class="n">args</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="__span-5-15"> <span class="n">parsed</span> <span class="o">=</span> <span class="n">FunctionArgs</span><span class="o">.</span><span class="n">model_validate_json</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
</span><span id="__span-5-16"> <span class="k">return</span> <span class="n">do_some_work</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">parsed</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2"> is </span><span class="si">{</span><span class="n">parsed</span><span class="o">.</span><span class="n">age</span><span class="si">}</span><span class="s2"> years old&quot;</span><span class="p">)</span>
</span><span id="__span-5-17">
</span><span id="__span-5-18">
</span><span id="__span-5-19"><span class="n">tool</span> <span class="o">=</span> <span class="n">FunctionTool</span><span class="p">(</span>
</span><span id="__span-5-20"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;process_user&quot;</span><span class="p">,</span>
</span><span id="__span-5-21"> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Processes extracted user data&quot;</span><span class="p">,</span>
</span><span id="__span-5-22"> <span class="n">params_json_schema</span><span class="o">=</span><span class="n">FunctionArgs</span><span class="o">.</span><span class="n">model_json_schema</span><span class="p">(),</span>
</span><span id="__span-5-23"> <span class="n">on_invoke_tool</span><span class="o">=</span><span class="n">run_function</span><span class="p">,</span>
</span><span id="__span-5-24"><span class="p">)</span>
</span></code></pre></div>
<h3 id="automatic-argument-and-docstring-parsing">Automatic argument and docstring parsing</h3>
<p>As mentioned before, we automatically parse the function signature to extract the schema for the tool, and we parse the docstring to extract descriptions for the tool and for individual arguments. Some notes on that:</p>
<ol>
<li>The signature parsing is done via the <code>inspect</code> module. We use type annotations to understand the types for the arguments, and dynamically build a Pydantic model to represent the overall schema. It supports most types, including Python primitives, Pydantic models, TypedDicts, and more.</li>
<li>We use <code>griffe</code> to parse docstrings. Supported docstring formats are <code>google</code>, <code>sphinx</code> and <code>numpy</code>. We attempt to automatically detect the docstring format, but this is best-effort and you can explicitly set it when calling <code>function_tool</code>. You can also disable docstring parsing by setting <code>use_docstring_info</code> to <code>False</code>.</li>
</ol>
<p>The code for the schema extraction lives in <a class="autorefs autorefs-internal" href="../ref/function_schema/#cai.sdk.agents.function_schema"><code>cai.sdk.agents.function_schema</code></a>.</p>
<h2 id="agents-as-tools">Agents as tools</h2>
<p>In some workflows, you may want a central agent to orchestrate a network of specialized agents, instead of handing off control. You can do this by modeling agents as tools.</p>
<div class="language-python highlight"><pre><span></span><code><span id="__span-6-1"><span class="kn">from</span><span class="w"> </span><span class="nn">cai.sdk.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Agent</span><span class="p">,</span> <span class="n">Runner</span><span class="p">,</span> <span class="n">OpenAIChatCompletionsModel</span>
</span><span id="__span-6-2"><span class="kn">from</span><span class="w"> </span><span class="nn">openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">AsyncOpenAI</span>
</span><span id="__span-6-3"><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span>
</span><span id="__span-6-4">
</span><span id="__span-6-5"><span class="c1"># Agent that simulates scanning an IP for threats</span>
</span><span id="__span-6-6"><span class="n">ip_scanner_agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
</span><span id="__span-6-7"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;IP Scanner&quot;</span><span class="p">,</span>
</span><span id="__span-6-8"> <span class="n">instructions</span><span class="o">=</span><span class="s2">&quot;You receive an IP address and respond with its threat status (e.g., malicious or clean).&quot;</span><span class="p">,</span>
</span><span id="__span-6-9"><span class="p">)</span>
</span><span id="__span-6-10">
</span><span id="__span-6-11"><span class="c1"># Agent that simulates analyzing a log file</span>
</span><span id="__span-6-12"><span class="n">log_analyzer_agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
</span><span id="__span-6-13"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;Log Analyzer&quot;</span><span class="p">,</span>
</span><span id="__span-6-14"> <span class="n">instructions</span><span class="o">=</span><span class="s2">&quot;You receive a log file path and respond with any suspicious findings from the logs.&quot;</span><span class="p">,</span>
</span><span id="__span-6-15"> <span class="n">model</span><span class="o">=</span><span class="n">OpenAIChatCompletionsModel</span><span class="p">(</span>
</span><span id="__span-6-16"> <span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:14b&quot;</span><span class="p">,</span>
</span><span id="__span-6-17"> <span class="n">openai_client</span><span class="o">=</span><span class="n">AsyncOpenAI</span><span class="p">(),</span>
</span><span id="__span-6-18"> <span class="p">)</span>
</span><span id="__span-6-19"><span class="p">)</span>
</span><span id="__span-6-20">
</span><span id="__span-6-21"><span class="c1"># Orchestrator agent that routes cybersecurity tasks to the correct tool</span>
</span><span id="__span-6-22"><span class="n">cyber_orchestrator_agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
</span><span id="__span-6-23"> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;Cyber Orchestrator&quot;</span><span class="p">,</span>
</span><span id="__span-6-24"> <span class="n">instructions</span><span class="o">=</span><span class="p">(</span>
</span><span id="__span-6-25"> <span class="s2">&quot;You are a cybersecurity assistant. Based on the user&#39;s request, you decide whether to scan an IP or analyze a log. &quot;</span>
</span><span id="__span-6-26"> <span class="s2">&quot;Use the appropriate tool for each task.&quot;</span>
</span><span id="__span-6-27"> <span class="p">),</span>
</span><span id="__span-6-28"> <span class="n">tools</span><span class="o">=</span><span class="p">[</span>
</span><span id="__span-6-29"> <span class="n">ip_scanner_agent</span><span class="o">.</span><span class="n">as_tool</span><span class="p">(</span>
</span><span id="__span-6-30"> <span class="n">tool_name</span><span class="o">=</span><span class="s2">&quot;scan_ip&quot;</span><span class="p">,</span>
</span><span id="__span-6-31"> <span class="n">tool_description</span><span class="o">=</span><span class="s2">&quot;Scan an IP address for possible threats&quot;</span><span class="p">,</span>
</span><span id="__span-6-32"> <span class="p">),</span>
</span><span id="__span-6-33"> <span class="n">log_analyzer_agent</span><span class="o">.</span><span class="n">as_tool</span><span class="p">(</span>
</span><span id="__span-6-34"> <span class="n">tool_name</span><span class="o">=</span><span class="s2">&quot;analyze_log&quot;</span><span class="p">,</span>
</span><span id="__span-6-35"> <span class="n">tool_description</span><span class="o">=</span><span class="s2">&quot;Analyze a system log file for suspicious activity&quot;</span><span class="p">,</span>
</span><span id="__span-6-36"> <span class="p">),</span>
</span><span id="__span-6-37"> <span class="p">],</span>
</span><span id="__span-6-38"> <span class="n">model</span><span class="o">=</span><span class="n">OpenAIChatCompletionsModel</span><span class="p">(</span>
</span><span id="__span-6-39"> <span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:14b&quot;</span><span class="p">,</span>
</span><span id="__span-6-40"> <span class="n">openai_client</span><span class="o">=</span><span class="n">AsyncOpenAI</span><span class="p">(),</span>
</span><span id="__span-6-41"> <span class="p">)</span>
</span><span id="__span-6-42"><span class="p">)</span>
</span><span id="__span-6-43">
</span><span id="__span-6-44"><span class="c1"># Main function that asks the orchestrator to scan an IP</span>
</span><span id="__span-6-45"><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>
</span><span id="__span-6-46"> <span class="c1"># Example input to scan an IP</span>
</span><span id="__span-6-47"> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">Runner</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">cyber_orchestrator_agent</span><span class="p">,</span> <span class="nb">input</span><span class="o">=</span><span class="s2">&quot;Scan the IP address 192.168.0.10 for threats.&quot;</span><span class="p">)</span>
</span><span id="__span-6-48"> <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">final_output</span><span class="p">)</span>
</span><span id="__span-6-49">
</span><span id="__span-6-50"><span class="c1"># Run the asynchronous main function</span>
</span><span id="__span-6-51"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
</span><span id="__span-6-52"> <span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</span></code></pre></div>
<h2 id="handling-errors-in-function-tools">Handling errors in function tools</h2>
<p>When you create a function tool via <code>@function_tool</code>, you can pass a <code>failure_error_function</code>. This is a function that provides an error response to the LLM in case the tool call crashes.</p>
<ul>
<li>By default (i.e. if you don't pass anything), it runs a <code>default_tool_error_function</code> which tells the LLM an error occurred.</li>
<li>If you pass your own error function, it runs that instead, and sends the response to the LLM.</li>
<li>If you explicitly pass <code>None</code>, then any tool call errors will be re-raised for you to handle. This could be a <code>ModelBehaviorError</code> if the model produced invalid JSON, or a <code>UserError</code> if your code crashed, etc.</li>
</ul>
<p>If you are manually creating a <code>FunctionTool</code> object, then you must handle errors inside the <code>on_invoke_tool</code> function.</p>
<hr />
<p>[1] Arguably, the Chain-of-Thought agentic pattern is a special case of the Hierarchical agentic pattern.
[2] Kamhoua, C. A., Leslie, N. O., &amp; Weisman, M. J. (2018). Game theoretic modeling of advanced persistent threat in internet of things. Journal of Cyber Security and Information Systems.
[3] Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K., &amp; Cao, Y. (2023, January). React: Synergizing reasoning and acting in language models. In International Conference on Learning Representations (ICLR).</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["content.code.copy", "content.code.select", "navigation.path", "navigation.sections", "navigation.expand", "content.code.annotate"], "search": "../assets/javascripts/workers/search.f8cc74c7.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.c8b220af.min.js"></script>
</body>
</html>