[{"data":1,"prerenderedAt":1847},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Fagent\u002Fsrc\u002Ftools":3},{"id":4,"title":5,"body":6,"description":1839,"extension":1840,"meta":1841,"navigation":173,"path":1843,"seo":1844,"stem":1845,"__hash__":1846},"docs\u002Fdocs\u002Fv2\u002Fagent\u002Fsrc\u002Ftools\u002Findex.md","tools\u002F",{"type":7,"value":8,"toc":1827},"minimark",[9,13,30,93,96,101,104,111,259,273,279,442,451,455,458,537,550,554,561,617,652,664,681,769,776,784,788,795,1128,1133,1136,1222,1232,1243,1412,1419,1422,1426,1432,1517,1520,1524,1530,1589,1690,1693,1696,1743,1746,1780,1790,1800,1804,1814,1823],[10,11,5],"h1",{"id":12},"tools",[14,15,16,17,21,22,25,26,29],"p",{},"Export anything from ",[18,19,20],"code",{},".ts"," files in ",[18,23,24],{},"src\u002Ftools\u002F"," and it becomes a global in the agent's execution scope. No registration, no schema definition, no ",[18,27,28],{},"defineTool",".",[31,32,37],"pre",{"className":33,"code":34,"language":35,"meta":36,"style":36},"language-bash shiki shiki-themes dark-plus","my-agent\u002F\n└── src\u002F\n    └── tools\u002F\n        ├── github.ts\n        ├── kanban.ts\n        └── time.ts\n","bash","",[18,38,39,48,58,67,76,84],{"__ignoreMap":36},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sCudf","my-agent\u002F\n",[40,49,51,54],{"class":42,"line":50},2,[40,52,53],{"class":46},"└──",[40,55,57],{"class":56},"sKc5r"," src\u002F\n",[40,59,61,64],{"class":42,"line":60},3,[40,62,63],{"class":46},"    └──",[40,65,66],{"class":56}," tools\u002F\n",[40,68,70,73],{"class":42,"line":69},4,[40,71,72],{"class":46},"        ├──",[40,74,75],{"class":56}," github.ts\n",[40,77,79,81],{"class":42,"line":78},5,[40,80,72],{"class":46},[40,82,83],{"class":56}," kanban.ts\n",[40,85,87,90],{"class":42,"line":86},6,[40,88,89],{"class":46},"        └──",[40,91,92],{"class":56}," time.ts\n",[14,94,95],{},"Each file's exports land directly on the global scope. The filename groups the file; it is\nnot a prefix. What you export is what the agent calls.",[97,98,100],"h2",{"id":99},"export-shapes","Export shapes",[14,102,103],{},"Any export form works.",[14,105,106,110],{},[107,108,109],"strong",{},"Named functions"," — each function becomes its own global:",[31,112,116],{"className":113,"code":114,"language":115,"meta":36,"style":36},"language-ts shiki shiki-themes dark-plus","\u002F\u002F src\u002Ftools\u002Ftime.ts\nexport async function now() {\n    return new Date().toISOString()\n}\n\nexport async function format(date: string, locale = \"en-GB\") {\n    return new Intl.DateTimeFormat(locale).format(new Date(date))\n}\n","ts",[18,117,118,124,144,164,169,175,215,254],{"__ignoreMap":36},[40,119,120],{"class":42,"line":43},[40,121,123],{"class":122},"sOLPB","\u002F\u002F src\u002Ftools\u002Ftime.ts\n",[40,125,126,130,134,137,140],{"class":42,"line":50},[40,127,129],{"class":128},"sYbnZ","export",[40,131,133],{"class":132},"scz_3"," async",[40,135,136],{"class":132}," function",[40,138,139],{"class":46}," now",[40,141,143],{"class":142},"sTNBD","() {\n",[40,145,146,149,152,155,158,161],{"class":42,"line":60},[40,147,148],{"class":128},"    return",[40,150,151],{"class":132}," new",[40,153,154],{"class":46}," Date",[40,156,157],{"class":142},"().",[40,159,160],{"class":46},"toISOString",[40,162,163],{"class":142},"()\n",[40,165,166],{"class":42,"line":69},[40,167,168],{"class":142},"}\n",[40,170,171],{"class":42,"line":78},[40,172,174],{"emptyLinePlaceholder":173},true,"\n",[40,176,177,179,181,183,186,189,193,196,200,203,206,209,212],{"class":42,"line":86},[40,178,129],{"class":128},[40,180,133],{"class":132},[40,182,136],{"class":132},[40,184,185],{"class":46}," format",[40,187,188],{"class":142},"(",[40,190,192],{"class":191},"s3F5K","date",[40,194,195],{"class":142},": ",[40,197,199],{"class":198},"sNl3T","string",[40,201,202],{"class":142},", ",[40,204,205],{"class":191},"locale",[40,207,208],{"class":142}," = ",[40,210,211],{"class":56},"\"en-GB\"",[40,213,214],{"class":142},") {\n",[40,216,218,220,222,225,227,230,232,234,237,240,242,245,247,249,251],{"class":42,"line":217},7,[40,219,148],{"class":128},[40,221,151],{"class":132},[40,223,224],{"class":191}," Intl",[40,226,29],{"class":142},[40,228,229],{"class":46},"DateTimeFormat",[40,231,188],{"class":142},[40,233,205],{"class":191},[40,235,236],{"class":142},").",[40,238,239],{"class":46},"format",[40,241,188],{"class":142},[40,243,244],{"class":132},"new",[40,246,154],{"class":46},[40,248,188],{"class":142},[40,250,192],{"class":191},[40,252,253],{"class":142},"))\n",[40,255,257],{"class":42,"line":256},8,[40,258,168],{"class":142},[14,260,261,262,265,266,268,269,272],{},"The agent gets ",[18,263,264],{},"now"," and ",[18,267,239],{}," as top-level globals. Not ",[18,270,271],{},"time.now"," — the file is a\ngrouping for you, not a namespace for the agent.",[14,274,275,278],{},[107,276,277],{},"Named object"," — the object itself becomes a global:",[31,280,282],{"className":113,"code":281,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Fkanban.ts\nexport const kanban = {\n    list: async (status?: string) => db.tasks.findAll({ status }),\n    add: async (title: string) => db.tasks.create({ title }),\n    close: async (id: string) => db.tasks.update(id, { status: \"done\" }),\n}\n",[18,283,284,289,303,351,390,438],{"__ignoreMap":36},[40,285,286],{"class":42,"line":43},[40,287,288],{"class":122},"\u002F\u002F src\u002Ftools\u002Fkanban.ts\n",[40,290,291,293,296,300],{"class":42,"line":50},[40,292,129],{"class":128},[40,294,295],{"class":132}," const",[40,297,299],{"class":298},"s9McN"," kanban",[40,301,302],{"class":142}," = {\n",[40,304,305,308,311,313,316,319,322,324,327,330,333,335,338,340,343,346,348],{"class":42,"line":60},[40,306,307],{"class":46},"    list",[40,309,310],{"class":191},":",[40,312,133],{"class":132},[40,314,315],{"class":142}," (",[40,317,318],{"class":191},"status",[40,320,321],{"class":142},"?: ",[40,323,199],{"class":198},[40,325,326],{"class":142},") ",[40,328,329],{"class":132},"=>",[40,331,332],{"class":191}," db",[40,334,29],{"class":142},[40,336,337],{"class":191},"tasks",[40,339,29],{"class":142},[40,341,342],{"class":46},"findAll",[40,344,345],{"class":142},"({ ",[40,347,318],{"class":191},[40,349,350],{"class":142}," }),\n",[40,352,353,356,358,360,362,365,367,369,371,373,375,377,379,381,384,386,388],{"class":42,"line":69},[40,354,355],{"class":46},"    add",[40,357,310],{"class":191},[40,359,133],{"class":132},[40,361,315],{"class":142},[40,363,364],{"class":191},"title",[40,366,195],{"class":142},[40,368,199],{"class":198},[40,370,326],{"class":142},[40,372,329],{"class":132},[40,374,332],{"class":191},[40,376,29],{"class":142},[40,378,337],{"class":191},[40,380,29],{"class":142},[40,382,383],{"class":46},"create",[40,385,345],{"class":142},[40,387,364],{"class":191},[40,389,350],{"class":142},[40,391,392,395,397,399,401,404,406,408,410,412,414,416,418,420,423,425,427,430,433,436],{"class":42,"line":78},[40,393,394],{"class":46},"    close",[40,396,310],{"class":191},[40,398,133],{"class":132},[40,400,315],{"class":142},[40,402,403],{"class":191},"id",[40,405,195],{"class":142},[40,407,199],{"class":198},[40,409,326],{"class":142},[40,411,329],{"class":132},[40,413,332],{"class":191},[40,415,29],{"class":142},[40,417,337],{"class":191},[40,419,29],{"class":142},[40,421,422],{"class":46},"update",[40,424,188],{"class":142},[40,426,403],{"class":191},[40,428,429],{"class":142},", { ",[40,431,432],{"class":191},"status:",[40,434,435],{"class":56}," \"done\"",[40,437,350],{"class":142},[40,439,440],{"class":42,"line":86},[40,441,168],{"class":142},[14,443,261,444,447,448,29],{},[18,445,446],{},"kanban"," as a global. Calls it as ",[18,449,450],{},"kanban.add(\"task\")",[97,452,454],{"id":453},"calling-tools","Calling tools",[14,456,457],{},"The agent calls tools like any other code — the export name is the call name, with no\nprefix:",[31,459,461],{"className":113,"code":460,"language":115,"meta":36,"style":36},"const tasks = await kanban.list(\"open\")\nconst pr = await openPr(\"fix: auth\", body, \"feat\u002Fauth\")\nconst ts = await now()\n",[18,462,463,491,522],{"__ignoreMap":36},[40,464,465,468,471,473,476,478,480,483,485,488],{"class":42,"line":43},[40,466,467],{"class":132},"const",[40,469,470],{"class":298}," tasks",[40,472,208],{"class":142},[40,474,475],{"class":128},"await",[40,477,299],{"class":191},[40,479,29],{"class":142},[40,481,482],{"class":46},"list",[40,484,188],{"class":142},[40,486,487],{"class":56},"\"open\"",[40,489,490],{"class":142},")\n",[40,492,493,495,498,500,502,505,507,510,512,515,517,520],{"class":42,"line":50},[40,494,467],{"class":132},[40,496,497],{"class":298}," pr",[40,499,208],{"class":142},[40,501,475],{"class":128},[40,503,504],{"class":46}," openPr",[40,506,188],{"class":142},[40,508,509],{"class":56},"\"fix: auth\"",[40,511,202],{"class":142},[40,513,514],{"class":191},"body",[40,516,202],{"class":142},[40,518,519],{"class":56},"\"feat\u002Fauth\"",[40,521,490],{"class":142},[40,523,524,526,529,531,533,535],{"class":42,"line":60},[40,525,467],{"class":132},[40,527,528],{"class":298}," ts",[40,530,208],{"class":142},[40,532,475],{"class":128},[40,534,139],{"class":46},[40,536,163],{"class":142},[14,538,539,540,543,544,549],{},"(From a script or route you reach the same functions through ",[18,541,542],{},"axon.tools.*"," instead — see\n",[545,546,548],"a",{"href":547},"#calling-tools-from-your-own-code","Calling tools from your own code",".)",[97,551,553],{"id":552},"every-tool-is-async-at-the-call-site","Every tool is async at the call site",[14,555,556],{},[107,557,558,559,29],{},"Write your tool sync or async — both work. It is always called with ",[18,560,475],{},[31,562,564],{"className":113,"code":563,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Fmath.ts — a perfectly valid tool\nexport function add(a: number, b: number) {\n    return a + b\n}\n",[18,565,566,571,600,613],{"__ignoreMap":36},[40,567,568],{"class":42,"line":43},[40,569,570],{"class":122},"\u002F\u002F src\u002Ftools\u002Fmath.ts — a perfectly valid tool\n",[40,572,573,575,577,580,582,584,586,589,591,594,596,598],{"class":42,"line":50},[40,574,129],{"class":128},[40,576,136],{"class":132},[40,578,579],{"class":46}," add",[40,581,188],{"class":142},[40,583,545],{"class":191},[40,585,195],{"class":142},[40,587,588],{"class":198},"number",[40,590,202],{"class":142},[40,592,593],{"class":191},"b",[40,595,195],{"class":142},[40,597,588],{"class":198},[40,599,214],{"class":142},[40,601,602,604,607,610],{"class":42,"line":60},[40,603,148],{"class":128},[40,605,606],{"class":191}," a",[40,608,609],{"class":142}," + ",[40,611,612],{"class":191},"b\n",[40,614,615],{"class":42,"line":69},[40,616,168],{"class":142},[31,618,620],{"className":113,"code":619,"language":115,"meta":36,"style":36},"const sum = await add(2, 3)   \u002F\u002F 5\n",[18,621,622],{"__ignoreMap":36},[40,623,624,626,629,631,633,635,637,641,643,646,649],{"class":42,"line":43},[40,625,467],{"class":132},[40,627,628],{"class":298}," sum",[40,630,208],{"class":142},[40,632,475],{"class":128},[40,634,579],{"class":46},[40,636,188],{"class":142},[40,638,640],{"class":639},"sDGX8","2",[40,642,202],{"class":142},[40,644,645],{"class":639},"3",[40,647,648],{"class":142},")   ",[40,650,651],{"class":122},"\u002F\u002F 5\n",[14,653,654,655,658,659,663],{},"This is not a style preference; it is structural. Every tool call is policy-mediated\nbefore the function body runs, and a policy rule can be ",[18,656,657],{},"escalate"," — which asks the user\nto approve the call and waits for the answer. That round trip cannot happen synchronously,\nso the function Axon installs in the agent's scope is always an async wrapper around\nyours. A sync tool body is fine. A sync ",[660,661,662],"em",{},"call"," is not available, for any tool.",[14,665,666,667,670,671,673,674,677,678,29],{},"The practical consequence: ",[18,668,669],{},"add(2, 3)"," without ",[18,672,475],{}," gives you a ",[18,675,676],{},"Promise",", not ",[18,679,680],{},"5",[31,682,684],{"className":113,"code":683,"language":115,"meta":36,"style":36},"const wrong = add(2, 3)          \u002F\u002F Promise\u003Cnumber>\nconst wrong2 = add(2, 3) * 2     \u002F\u002F NaN — no error, just wrong\n\nconst right = await add(2, 3)    \u002F\u002F 5\n",[18,685,686,712,739,743],{"__ignoreMap":36},[40,687,688,690,693,695,698,700,702,704,706,709],{"class":42,"line":43},[40,689,467],{"class":132},[40,691,692],{"class":298}," wrong",[40,694,208],{"class":142},[40,696,697],{"class":46},"add",[40,699,188],{"class":142},[40,701,640],{"class":639},[40,703,202],{"class":142},[40,705,645],{"class":639},[40,707,708],{"class":142},")          ",[40,710,711],{"class":122},"\u002F\u002F Promise\u003Cnumber>\n",[40,713,714,716,719,721,723,725,727,729,731,734,736],{"class":42,"line":50},[40,715,467],{"class":132},[40,717,718],{"class":298}," wrong2",[40,720,208],{"class":142},[40,722,697],{"class":46},[40,724,188],{"class":142},[40,726,640],{"class":639},[40,728,202],{"class":142},[40,730,645],{"class":639},[40,732,733],{"class":142},") * ",[40,735,640],{"class":639},[40,737,738],{"class":122},"     \u002F\u002F NaN — no error, just wrong\n",[40,740,741],{"class":42,"line":60},[40,742,174],{"emptyLinePlaceholder":173},[40,744,745,747,750,752,754,756,758,760,762,764,767],{"class":42,"line":69},[40,746,467],{"class":132},[40,748,749],{"class":298}," right",[40,751,208],{"class":142},[40,753,475],{"class":128},[40,755,579],{"class":46},[40,757,188],{"class":142},[40,759,640],{"class":639},[40,761,202],{"class":142},[40,763,645],{"class":639},[40,765,766],{"class":142},")    ",[40,768,651],{"class":122},[14,770,771,772,775],{},"If you don't need a sync body for anything, writing ",[18,773,774],{},"async function"," makes the call site\nand the signature agree, and is the easier habit.",[14,777,778,779,783],{},"See ",[545,780,782],{"href":781},"\u002Fdocs\u002Fv2\u002Fagent\u002Fpolicy","Policy"," for what mediation checks and how escalation is\nconfigured.",[97,785,787],{"id":786},"what-the-agent-sees","What the agent sees",[14,789,790,791,794],{},"Tool types come from your TypeScript signatures directly — run through real TypeScript\ndeclaration emission, so inferred return types are the compiler's actual inference, not\n",[18,792,793],{},"unknown",". Write JSDoc as if explaining to someone who has never seen your codebase —\nthat's the model deciding when and how to call the function.",[31,796,798],{"className":113,"code":797,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Fgithub.ts\n\n\u002F** List all open pull requests for the configured repository. *\u002F\nexport async function listOpenPrs(): Promise\u003C{ number: number; title: string }[]> {\n    const { data } = await octokit.pulls.list({ state: \"open\", ...repo() })\n    return data.map(pr => ({ number: pr.number, title: pr.title }))\n}\n\n\u002F** Open a pull request. Returns the PR number and URL. *\u002F\nexport async function openPr(\n    title: string,\n    body: string,\n    head: string,\n    base = \"main\"\n): Promise\u003C{ number: number; url: string }> {\n    const { data } = await octokit.pulls.create({ title, body, head, base, ...repo() })\n    return { number: data.number, url: data.html_url }\n}\n",[18,799,800,805,809,814,851,896,942,946,950,956,970,983,995,1007,1018,1046,1093,1123],{"__ignoreMap":36},[40,801,802],{"class":42,"line":43},[40,803,804],{"class":122},"\u002F\u002F src\u002Ftools\u002Fgithub.ts\n",[40,806,807],{"class":42,"line":50},[40,808,174],{"emptyLinePlaceholder":173},[40,810,811],{"class":42,"line":60},[40,812,813],{"class":122},"\u002F** List all open pull requests for the configured repository. *\u002F\n",[40,815,816,818,820,822,825,828,830,833,835,837,839,842,844,846,848],{"class":42,"line":69},[40,817,129],{"class":128},[40,819,133],{"class":132},[40,821,136],{"class":132},[40,823,824],{"class":46}," listOpenPrs",[40,826,827],{"class":142},"(): ",[40,829,676],{"class":198},[40,831,832],{"class":142},"\u003C{ ",[40,834,588],{"class":191},[40,836,195],{"class":142},[40,838,588],{"class":198},[40,840,841],{"class":142},"; ",[40,843,364],{"class":191},[40,845,195],{"class":142},[40,847,199],{"class":198},[40,849,850],{"class":142}," }[]> {\n",[40,852,853,856,859,862,865,867,870,872,875,877,879,881,884,887,890,893],{"class":42,"line":78},[40,854,855],{"class":132},"    const",[40,857,858],{"class":142}," { ",[40,860,861],{"class":298},"data",[40,863,864],{"class":142}," } = ",[40,866,475],{"class":128},[40,868,869],{"class":191}," octokit",[40,871,29],{"class":142},[40,873,874],{"class":191},"pulls",[40,876,29],{"class":142},[40,878,482],{"class":46},[40,880,345],{"class":142},[40,882,883],{"class":191},"state:",[40,885,886],{"class":56}," \"open\"",[40,888,889],{"class":142},", ...",[40,891,892],{"class":46},"repo",[40,894,895],{"class":142},"() })\n",[40,897,898,900,903,905,908,910,913,916,919,922,924,926,928,930,933,935,937,939],{"class":42,"line":86},[40,899,148],{"class":128},[40,901,902],{"class":191}," data",[40,904,29],{"class":142},[40,906,907],{"class":46},"map",[40,909,188],{"class":142},[40,911,912],{"class":191},"pr",[40,914,915],{"class":132}," =>",[40,917,918],{"class":142}," ({ ",[40,920,921],{"class":191},"number:",[40,923,497],{"class":191},[40,925,29],{"class":142},[40,927,588],{"class":191},[40,929,202],{"class":142},[40,931,932],{"class":191},"title:",[40,934,497],{"class":191},[40,936,29],{"class":142},[40,938,364],{"class":191},[40,940,941],{"class":142}," }))\n",[40,943,944],{"class":42,"line":217},[40,945,168],{"class":142},[40,947,948],{"class":42,"line":256},[40,949,174],{"emptyLinePlaceholder":173},[40,951,953],{"class":42,"line":952},9,[40,954,955],{"class":122},"\u002F** Open a pull request. Returns the PR number and URL. *\u002F\n",[40,957,959,961,963,965,967],{"class":42,"line":958},10,[40,960,129],{"class":128},[40,962,133],{"class":132},[40,964,136],{"class":132},[40,966,504],{"class":46},[40,968,969],{"class":142},"(\n",[40,971,973,976,978,980],{"class":42,"line":972},11,[40,974,975],{"class":191},"    title",[40,977,195],{"class":142},[40,979,199],{"class":198},[40,981,982],{"class":142},",\n",[40,984,986,989,991,993],{"class":42,"line":985},12,[40,987,988],{"class":191},"    body",[40,990,195],{"class":142},[40,992,199],{"class":198},[40,994,982],{"class":142},[40,996,998,1001,1003,1005],{"class":42,"line":997},13,[40,999,1000],{"class":191},"    head",[40,1002,195],{"class":142},[40,1004,199],{"class":198},[40,1006,982],{"class":142},[40,1008,1010,1013,1015],{"class":42,"line":1009},14,[40,1011,1012],{"class":191},"    base",[40,1014,208],{"class":142},[40,1016,1017],{"class":56},"\"main\"\n",[40,1019,1021,1024,1026,1028,1030,1032,1034,1036,1039,1041,1043],{"class":42,"line":1020},15,[40,1022,1023],{"class":142},"): ",[40,1025,676],{"class":198},[40,1027,832],{"class":142},[40,1029,588],{"class":191},[40,1031,195],{"class":142},[40,1033,588],{"class":198},[40,1035,841],{"class":142},[40,1037,1038],{"class":191},"url",[40,1040,195],{"class":142},[40,1042,199],{"class":198},[40,1044,1045],{"class":142}," }> {\n",[40,1047,1049,1051,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075,1077,1079,1082,1084,1087,1089,1091],{"class":42,"line":1048},16,[40,1050,855],{"class":132},[40,1052,858],{"class":142},[40,1054,861],{"class":298},[40,1056,864],{"class":142},[40,1058,475],{"class":128},[40,1060,869],{"class":191},[40,1062,29],{"class":142},[40,1064,874],{"class":191},[40,1066,29],{"class":142},[40,1068,383],{"class":46},[40,1070,345],{"class":142},[40,1072,364],{"class":191},[40,1074,202],{"class":142},[40,1076,514],{"class":191},[40,1078,202],{"class":142},[40,1080,1081],{"class":191},"head",[40,1083,202],{"class":142},[40,1085,1086],{"class":191},"base",[40,1088,889],{"class":142},[40,1090,892],{"class":46},[40,1092,895],{"class":142},[40,1094,1096,1098,1100,1102,1104,1106,1108,1110,1113,1115,1117,1120],{"class":42,"line":1095},17,[40,1097,148],{"class":128},[40,1099,858],{"class":142},[40,1101,921],{"class":191},[40,1103,902],{"class":191},[40,1105,29],{"class":142},[40,1107,588],{"class":191},[40,1109,202],{"class":142},[40,1111,1112],{"class":191},"url:",[40,1114,902],{"class":191},[40,1116,29],{"class":142},[40,1118,1119],{"class":191},"html_url",[40,1121,1122],{"class":142}," }\n",[40,1124,1126],{"class":42,"line":1125},18,[40,1127,168],{"class":142},[1129,1130,1132],"h3",{"id":1131},"types-your-signature-references","Types your signature references",[14,1134,1135],{},"When a signature mentions a type you declared elsewhere — an interface, a type alias — that\ndeclaration is followed and carried alongside the tool, so the agent sees the full shape\nrather than a bare name:",[31,1137,1139],{"className":113,"code":1138,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Ftasks.ts\ntype Task = { id: string; title: string; done: boolean }\n\n\u002F** Fetch the next unfinished task. *\u002F\nexport async function next(): Promise\u003CTask | null> { ... }\n",[18,1140,1141,1146,1183,1187,1192],{"__ignoreMap":36},[40,1142,1143],{"class":42,"line":43},[40,1144,1145],{"class":122},"\u002F\u002F src\u002Ftools\u002Ftasks.ts\n",[40,1147,1148,1151,1154,1157,1159,1161,1163,1165,1167,1169,1171,1173,1176,1178,1181],{"class":42,"line":50},[40,1149,1150],{"class":132},"type",[40,1152,1153],{"class":198}," Task",[40,1155,1156],{"class":142}," = { ",[40,1158,403],{"class":191},[40,1160,195],{"class":142},[40,1162,199],{"class":198},[40,1164,841],{"class":142},[40,1166,364],{"class":191},[40,1168,195],{"class":142},[40,1170,199],{"class":198},[40,1172,841],{"class":142},[40,1174,1175],{"class":191},"done",[40,1177,195],{"class":142},[40,1179,1180],{"class":198},"boolean",[40,1182,1122],{"class":142},[40,1184,1185],{"class":42,"line":60},[40,1186,174],{"emptyLinePlaceholder":173},[40,1188,1189],{"class":42,"line":69},[40,1190,1191],{"class":122},"\u002F** Fetch the next unfinished task. *\u002F\n",[40,1193,1194,1196,1198,1200,1203,1205,1207,1210,1213,1216,1219],{"class":42,"line":78},[40,1195,129],{"class":128},[40,1197,133],{"class":132},[40,1199,136],{"class":132},[40,1201,1202],{"class":46}," next",[40,1204,827],{"class":142},[40,1206,676],{"class":198},[40,1208,1209],{"class":142},"\u003C",[40,1211,1212],{"class":198},"Task",[40,1214,1215],{"class":142}," | ",[40,1217,1218],{"class":198},"null",[40,1220,1221],{"class":142},"> { ... }\n",[14,1223,1224,1225,1228,1229,1231],{},"The agent receives both the ",[18,1226,1227],{},"next()"," signature and the ",[18,1230,1212],{}," definition.",[14,1233,1234,1235,1238,1239,1242],{},"Prefer plain data — interfaces, type aliases, object shapes — for anything a tool returns.\nThe agent only ever receives the serialized ",[660,1236,1237],{},"value"," of a return, so a returned class\ninstance arrives as its plain fields: methods are not callable across the capsule boundary,\nand ",[18,1240,1241],{},"instanceof"," means nothing on the other side. A tool returning a rich class is usually\nbetter expressed as one returning a plain object, with the class kept internal:",[31,1244,1246],{"className":113,"code":1245,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Fdice.ts\nimport { Roll } from \"..\u002Flib\u002Froll\"\n\ntype RollResult = { spec: string; dice: number[]; total: number }\n\n\u002F** Roll dice from a spec like \"2d6+3\". Returns the individual dice and the total. *\u002F\nexport async function roll(spec: string): Promise\u003CRollResult> {\n    const r = new Roll(spec)          \u002F\u002F class stays internal\n    return { spec, dice: r.dice, total: r.total }\n}\n",[18,1247,1248,1253,1272,1276,1313,1317,1322,1353,1376,1408],{"__ignoreMap":36},[40,1249,1250],{"class":42,"line":43},[40,1251,1252],{"class":122},"\u002F\u002F src\u002Ftools\u002Fdice.ts\n",[40,1254,1255,1258,1260,1263,1266,1269],{"class":42,"line":50},[40,1256,1257],{"class":128},"import",[40,1259,858],{"class":142},[40,1261,1262],{"class":191},"Roll",[40,1264,1265],{"class":142}," } ",[40,1267,1268],{"class":128},"from",[40,1270,1271],{"class":56}," \"..\u002Flib\u002Froll\"\n",[40,1273,1274],{"class":42,"line":60},[40,1275,174],{"emptyLinePlaceholder":173},[40,1277,1278,1280,1283,1285,1288,1290,1292,1294,1297,1299,1301,1304,1307,1309,1311],{"class":42,"line":69},[40,1279,1150],{"class":132},[40,1281,1282],{"class":198}," RollResult",[40,1284,1156],{"class":142},[40,1286,1287],{"class":191},"spec",[40,1289,195],{"class":142},[40,1291,199],{"class":198},[40,1293,841],{"class":142},[40,1295,1296],{"class":191},"dice",[40,1298,195],{"class":142},[40,1300,588],{"class":198},[40,1302,1303],{"class":142},"[]; ",[40,1305,1306],{"class":191},"total",[40,1308,195],{"class":142},[40,1310,588],{"class":198},[40,1312,1122],{"class":142},[40,1314,1315],{"class":42,"line":78},[40,1316,174],{"emptyLinePlaceholder":173},[40,1318,1319],{"class":42,"line":86},[40,1320,1321],{"class":122},"\u002F** Roll dice from a spec like \"2d6+3\". Returns the individual dice and the total. *\u002F\n",[40,1323,1324,1326,1328,1330,1333,1335,1337,1339,1341,1343,1345,1347,1350],{"class":42,"line":217},[40,1325,129],{"class":128},[40,1327,133],{"class":132},[40,1329,136],{"class":132},[40,1331,1332],{"class":46}," roll",[40,1334,188],{"class":142},[40,1336,1287],{"class":191},[40,1338,195],{"class":142},[40,1340,199],{"class":198},[40,1342,1023],{"class":142},[40,1344,676],{"class":198},[40,1346,1209],{"class":142},[40,1348,1349],{"class":198},"RollResult",[40,1351,1352],{"class":142},"> {\n",[40,1354,1355,1357,1360,1362,1364,1367,1369,1371,1373],{"class":42,"line":256},[40,1356,855],{"class":132},[40,1358,1359],{"class":298}," r",[40,1361,208],{"class":142},[40,1363,244],{"class":132},[40,1365,1366],{"class":46}," Roll",[40,1368,188],{"class":142},[40,1370,1287],{"class":191},[40,1372,708],{"class":142},[40,1374,1375],{"class":122},"\u002F\u002F class stays internal\n",[40,1377,1378,1380,1382,1384,1386,1389,1391,1393,1395,1397,1400,1402,1404,1406],{"class":42,"line":952},[40,1379,148],{"class":128},[40,1381,858],{"class":142},[40,1383,1287],{"class":191},[40,1385,202],{"class":142},[40,1387,1388],{"class":191},"dice:",[40,1390,1359],{"class":191},[40,1392,29],{"class":142},[40,1394,1296],{"class":191},[40,1396,202],{"class":142},[40,1398,1399],{"class":191},"total:",[40,1401,1359],{"class":191},[40,1403,29],{"class":142},[40,1405,1306],{"class":191},[40,1407,1122],{"class":142},[40,1409,1410],{"class":42,"line":958},[40,1411,168],{"class":142},[14,1413,1414,1415,1418],{},"A class named in a signature ",[660,1416,1417],{},"is"," carried across — the model sees its declared shape, not\na bare name. What it does not get is behavior: the agent receives the serialized value, so\nreturning a plain object is still the clearer contract.",[14,1420,1421],{},"Two tool files declaring the same type name with different shapes is an error, not a\nsilent pick. Rename one, or move the shared definition into a file both import.",[97,1423,1425],{"id":1424},"module-scope-is-persistent","Module scope is persistent",[14,1427,1428,1429,1431],{},"The capsule process starts at boot and stays alive for the session. Module-level code in ",[18,1430,5],{}," runs once and persists for the entire session. Use this for clients, connections, and caches.",[31,1433,1435],{"className":113,"code":1434,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Fgithub.ts\nimport { Octokit } from \"@octokit\u002Frest\"\n\n\u002F\u002F Instantiated once at boot — reused across every call\nconst octokit = new Octokit({ auth: process.env.GITHUB_TOKEN })\n\nexport async function listOpenPrs() { ... }\n",[18,1436,1437,1441,1457,1461,1466,1500,1504],{"__ignoreMap":36},[40,1438,1439],{"class":42,"line":43},[40,1440,804],{"class":122},[40,1442,1443,1445,1447,1450,1452,1454],{"class":42,"line":50},[40,1444,1257],{"class":128},[40,1446,858],{"class":142},[40,1448,1449],{"class":191},"Octokit",[40,1451,1265],{"class":142},[40,1453,1268],{"class":128},[40,1455,1456],{"class":56}," \"@octokit\u002Frest\"\n",[40,1458,1459],{"class":42,"line":60},[40,1460,174],{"emptyLinePlaceholder":173},[40,1462,1463],{"class":42,"line":69},[40,1464,1465],{"class":122},"\u002F\u002F Instantiated once at boot — reused across every call\n",[40,1467,1468,1470,1472,1474,1476,1479,1481,1484,1487,1489,1492,1494,1497],{"class":42,"line":78},[40,1469,467],{"class":132},[40,1471,869],{"class":298},[40,1473,208],{"class":142},[40,1475,244],{"class":132},[40,1477,1478],{"class":46}," Octokit",[40,1480,345],{"class":142},[40,1482,1483],{"class":191},"auth:",[40,1485,1486],{"class":191}," process",[40,1488,29],{"class":142},[40,1490,1491],{"class":191},"env",[40,1493,29],{"class":142},[40,1495,1496],{"class":298},"GITHUB_TOKEN",[40,1498,1499],{"class":142}," })\n",[40,1501,1502],{"class":42,"line":86},[40,1503,174],{"emptyLinePlaceholder":173},[40,1505,1506,1508,1510,1512,1514],{"class":42,"line":217},[40,1507,129],{"class":128},[40,1509,133],{"class":132},[40,1511,136],{"class":132},[40,1513,824],{"class":46},[40,1515,1516],{"class":142},"() { ... }\n",[14,1518,1519],{},"No re-authentication per call. No cold-start latency per invocation.",[97,1521,1523],{"id":1522},"sharing-code-between-files","Sharing code between files",[14,1525,1526,1527,1529],{},"Files in ",[18,1528,5],{}," can import from each other. A file with no exports contributes nothing to the global scope — use it as a shared internal module.",[31,1531,1533],{"className":113,"code":1532,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002F_http.ts — underscore prefix, nothing exported to global scope\nexport function buildHeaders(token: string) {\n    return { Authorization: `Bearer ${token}` }\n}\n",[18,1534,1535,1540,1560,1585],{"__ignoreMap":36},[40,1536,1537],{"class":42,"line":43},[40,1538,1539],{"class":122},"\u002F\u002F src\u002Ftools\u002F_http.ts — underscore prefix, nothing exported to global scope\n",[40,1541,1542,1544,1546,1549,1551,1554,1556,1558],{"class":42,"line":50},[40,1543,129],{"class":128},[40,1545,136],{"class":132},[40,1547,1548],{"class":46}," buildHeaders",[40,1550,188],{"class":142},[40,1552,1553],{"class":191},"token",[40,1555,195],{"class":142},[40,1557,199],{"class":198},[40,1559,214],{"class":142},[40,1561,1562,1564,1566,1569,1572,1575,1577,1580,1583],{"class":42,"line":60},[40,1563,148],{"class":128},[40,1565,858],{"class":142},[40,1567,1568],{"class":191},"Authorization:",[40,1570,1571],{"class":56}," `Bearer ",[40,1573,1574],{"class":132},"${",[40,1576,1553],{"class":191},[40,1578,1579],{"class":132},"}",[40,1581,1582],{"class":56},"`",[40,1584,1122],{"class":142},[40,1586,1587],{"class":42,"line":69},[40,1588,168],{"class":142},[31,1590,1592],{"className":113,"code":1591,"language":115,"meta":36,"style":36},"\u002F\u002F src\u002Ftools\u002Fgithub.ts\nimport { buildHeaders } from \".\u002F_http\"\n\nexport async function openPr(title: string, body: string, head: string) {\n    const headers = buildHeaders(process.env.GITHUB_TOKEN!)\n    \u002F\u002F ...\n}\n",[18,1593,1594,1598,1614,1618,1654,1681,1686],{"__ignoreMap":36},[40,1595,1596],{"class":42,"line":43},[40,1597,804],{"class":122},[40,1599,1600,1602,1604,1607,1609,1611],{"class":42,"line":50},[40,1601,1257],{"class":128},[40,1603,858],{"class":142},[40,1605,1606],{"class":191},"buildHeaders",[40,1608,1265],{"class":142},[40,1610,1268],{"class":128},[40,1612,1613],{"class":56}," \".\u002F_http\"\n",[40,1615,1616],{"class":42,"line":60},[40,1617,174],{"emptyLinePlaceholder":173},[40,1619,1620,1622,1624,1626,1628,1630,1632,1634,1636,1638,1640,1642,1644,1646,1648,1650,1652],{"class":42,"line":69},[40,1621,129],{"class":128},[40,1623,133],{"class":132},[40,1625,136],{"class":132},[40,1627,504],{"class":46},[40,1629,188],{"class":142},[40,1631,364],{"class":191},[40,1633,195],{"class":142},[40,1635,199],{"class":198},[40,1637,202],{"class":142},[40,1639,514],{"class":191},[40,1641,195],{"class":142},[40,1643,199],{"class":198},[40,1645,202],{"class":142},[40,1647,1081],{"class":191},[40,1649,195],{"class":142},[40,1651,199],{"class":198},[40,1653,214],{"class":142},[40,1655,1656,1658,1661,1663,1665,1667,1670,1672,1674,1676,1678],{"class":42,"line":78},[40,1657,855],{"class":132},[40,1659,1660],{"class":298}," headers",[40,1662,208],{"class":142},[40,1664,1606],{"class":46},[40,1666,188],{"class":142},[40,1668,1669],{"class":191},"process",[40,1671,29],{"class":142},[40,1673,1491],{"class":191},[40,1675,29],{"class":142},[40,1677,1496],{"class":298},[40,1679,1680],{"class":142},"!)\n",[40,1682,1683],{"class":42,"line":86},[40,1684,1685],{"class":122},"    \u002F\u002F ...\n",[40,1687,1688],{"class":42,"line":217},[40,1689,168],{"class":142},[97,1691,548],{"id":1692},"calling-tools-from-your-own-code",[14,1694,1695],{},"Tools aren't only for the model. Scripts, routes and hooks call them the same way the\nagent does — by name, no prefix:",[31,1697,1699],{"className":113,"code":1698,"language":115,"meta":36,"style":36},"\u002F\u002F In a script or route handler\nconst prs = await listOpenPrs()\nconst sum = await add(2, 3)\n",[18,1700,1701,1706,1721],{"__ignoreMap":36},[40,1702,1703],{"class":42,"line":43},[40,1704,1705],{"class":122},"\u002F\u002F In a script or route handler\n",[40,1707,1708,1710,1713,1715,1717,1719],{"class":42,"line":50},[40,1709,467],{"class":132},[40,1711,1712],{"class":298}," prs",[40,1714,208],{"class":142},[40,1716,475],{"class":128},[40,1718,824],{"class":46},[40,1720,163],{"class":142},[40,1722,1723,1725,1727,1729,1731,1733,1735,1737,1739,1741],{"class":42,"line":60},[40,1724,467],{"class":132},[40,1726,628],{"class":298},[40,1728,208],{"class":142},[40,1730,475],{"class":128},[40,1732,579],{"class":46},[40,1734,188],{"class":142},[40,1736,640],{"class":639},[40,1738,202],{"class":142},[40,1740,645],{"class":639},[40,1742,490],{"class":142},[14,1744,1745],{},"The same functions are always also reachable explicitly:",[31,1747,1749],{"className":113,"code":1748,"language":115,"meta":36,"style":36},"const prs = await axon.tools.github.listOpenPrs()\n",[18,1750,1751],{"__ignoreMap":36},[40,1752,1753,1755,1757,1759,1761,1764,1766,1768,1770,1773,1775,1778],{"class":42,"line":43},[40,1754,467],{"class":132},[40,1756,1712],{"class":298},[40,1758,208],{"class":142},[40,1760,475],{"class":128},[40,1762,1763],{"class":191}," axon",[40,1765,29],{"class":142},[40,1767,12],{"class":191},[40,1769,29],{"class":142},[40,1771,1772],{"class":191},"github",[40,1774,29],{"class":142},[40,1776,1777],{"class":46},"listOpenPrs",[40,1779,163],{"class":142},[14,1781,1782,1783,1786,1787,29],{},"Identical behaviour — same capsule, same policy, same tracing; the globals are bindings\nonto that surface. Use the explicit form when a bare name would be ambiguous: a tool whose\nname collides with a host builtin is not installed as a global (a tool called ",[18,1784,1785],{},"fetch"," will\nnot shadow the real one) and stays callable as ",[18,1788,1789],{},"axon.tools.\u003Cfile>.fetch",[14,1791,1792,1793,1795,1796,29],{},"Both are ",[18,1794,475],{},"ed — see ",[545,1797,1799],{"href":1798},"#every-tool-is-async-at-the-call-site","above",[97,1801,1803],{"id":1802},"ide-support","IDE support",[14,1805,1806,1809,1810,1813],{},[18,1807,1808],{},"axon prepare"," generates ",[18,1811,1812],{},".agent\u002Ftool-globals.d.ts",", which declares each export as a typed global. Full autocomplete in scripts, routes, and hooks without any imports.",[14,1815,1816,1817,1819,1820,1822],{},"Run ",[18,1818,1808],{}," after adding or changing files in ",[18,1821,5],{}," to refresh types.",[1824,1825,1826],"style",{},"html pre.shiki code .sCudf, html code.shiki .sCudf{--shiki-default:#DCDCAA}html pre.shiki code .sKc5r, html code.shiki .sKc5r{--shiki-default:#CE9178}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 pre.shiki code .sOLPB, html code.shiki .sOLPB{--shiki-default:#6A9955}html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}html pre.shiki code .scz_3, html code.shiki .scz_3{--shiki-default:#569CD6}html pre.shiki code .sTNBD, html code.shiki .sTNBD{--shiki-default:#D4D4D4}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}html pre.shiki code .sNl3T, html code.shiki .sNl3T{--shiki-default:#4EC9B0}html pre.shiki code .s9McN, html code.shiki .s9McN{--shiki-default:#4FC1FF}html pre.shiki code .sDGX8, html code.shiki .sDGX8{--shiki-default:#B5CEA8}",{"title":36,"searchDepth":50,"depth":50,"links":1828},[1829,1830,1831,1832,1835,1836,1837,1838],{"id":99,"depth":50,"text":100},{"id":453,"depth":50,"text":454},{"id":552,"depth":50,"text":553},{"id":786,"depth":50,"text":787,"children":1833},[1834],{"id":1131,"depth":60,"text":1132},{"id":1424,"depth":50,"text":1425},{"id":1522,"depth":50,"text":1523},{"id":1692,"depth":50,"text":548},{"id":1802,"depth":50,"text":1803},"Export anything from .ts files in src\u002Ftools\u002F and it becomes a global in the agent's execution scope. No registration, no schema definition, no defineTool.","md",{"icon":1842},"vscode-icons:folder-type-tools","\u002Fdocs\u002Fv2\u002Fagent\u002Fsrc\u002Ftools",{"title":5,"description":1839},"docs\u002Fv2\u002Fagent\u002Fsrc\u002Ftools\u002Findex","Za2q-ciizlwkE8VZmxOK1_W-qvqazvJ1fFtjGxJwguc",1785671806092]