[{"data":1,"prerenderedAt":919},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Fconcepts\u002Fagents-world":3},{"id":4,"title":5,"body":6,"description":912,"extension":913,"meta":914,"navigation":249,"path":915,"seo":916,"stem":917,"__hash__":918},"docs\u002Fdocs\u002Fv2\u002Fconcepts\u002Fagents-world.md","The Agent's World",{"type":7,"value":8,"toc":904},"minimark",[9,14,27,41,46,56,64,79,86,98,113,117,120,420,423,426,430,438,532,538,542,548,584,587,673,676,682,686,689,787,866,869,873,884,891,900],[10,11,13],"h1",{"id":12},"the-agents-world-is-the-capsule","The agent's world is the capsule",[15,16,17,18,22,23,26],"p",{},"The agent has one way to interact with the world: a ",[19,20,21],"code",{},"\u003Ctypescript>"," block that executes in\nthe capsule. Everything it can read, write, run, or delegate flows through that boundary.\n",[19,24,25],{},"\u003Ctext>"," communicates with the user. Everything else is code.",[15,28,29,30,33,34,33,37,40],{},"That boundary is not a limitation — it's a complete runtime. The capsule runs on the\nuser's machine, in a full Bun process, with access to the filesystem, the shell, and the\nnetwork. The tool namespaces (",[19,31,32],{},"fs",", ",[19,35,36],{},"process",[19,38,39],{},"subagent",") are the common-case surface.\nBelow them is the full TypeScript language.",[42,43,45],"h2",{"id":44},"the-tool-namespaces","The tool namespaces",[15,47,48,49,51,52,55],{},"Every ",[19,50,21],{}," block executes with these namespaces in scope, declared in the\n",[19,53,54],{},"\u003Cenv>"," block of the AIR context:",[15,57,58,63],{},[59,60,61],"strong",{},[19,62,32],{}," — filesystem operations. Read, write, list, edit, search. The edit operations\nare typed and atomic — multiple ops applied in one call, each reporting success or failure\nindividually.",[15,65,66,70,71,74,75,78],{},[59,67,68],{},[19,69,36],{}," — shell execution. ",[19,72,73],{},"process.run()"," for blocking commands, ",[19,76,77],{},"process.spawn()","\nfor long-lived processes. Both run real OS processes on the user's machine with real\nstdout, stderr, and exit codes.",[15,80,81,85],{},[59,82,83],{},[19,84,39],{}," — agent delegation. Spawn another agent instance with a focused prompt.\nWait for its result or run it in the background.",[15,87,88,93,94,97],{},[59,89,90],{},[19,91,92],{},"axon"," — the agent's own API. The agent can call ",[19,95,96],{},"axon.request()"," from within a\ntool execution, spinning up a full cognitive loop mid-task — load a prompt, delegate to\nthe loop, get the result back as a string. Scripts, events, and prompts are all reachable\nthe same way.",[15,99,100,101,104,105,108,109,112],{},"These are conveniences, not constraints. The agent can ",[19,102,103],{},"await fetch()",", use\n",[19,106,107],{},"Promise.all",", import from ",[19,110,111],{},"node:crypto",", write a stream to disk, or do anything else\nBun supports. The namespaces exist because reading a file or running a command should be\na one-liner — not because they're the only things available.",[42,114,116],{"id":115},"full-language-composition","Full-language composition",[15,118,119],{},"Because the output is TypeScript, not a function call, the agent composes freely within a\nsingle block:",[121,122,127],"pre",{"className":123,"code":124,"language":125,"meta":126,"style":126},"language-ts shiki shiki-themes dark-plus","\u002F\u002F Read three files in parallel, process the results, write once\nconst [src, tests, config] = await Promise.all([\n    fs.read(\"src\u002Findex.ts\"),\n    fs.read(\"src\u002Findex.test.ts\"),\n    fs.read(\"axon.config.ts\"),\n])\n\nconst issues = src.split(\"\\n\")\n    .map((line, i) => ({ line: i + 1, content: line }))\n    .filter(({ content }) => content.includes(\"TODO\"))\n\nawait fs.write(\"issues.json\", JSON.stringify(issues, null, 2))\n","ts","",[19,128,129,138,184,206,222,238,244,251,283,335,370,375],{"__ignoreMap":126},[130,131,134],"span",{"class":132,"line":133},"line",1,[130,135,137],{"class":136},"sOLPB","\u002F\u002F Read three files in parallel, process the results, write once\n",[130,139,141,145,149,153,155,158,160,163,166,170,174,177,181],{"class":132,"line":140},2,[130,142,144],{"class":143},"scz_3","const",[130,146,148],{"class":147},"sTNBD"," [",[130,150,152],{"class":151},"s9McN","src",[130,154,33],{"class":147},[130,156,157],{"class":151},"tests",[130,159,33],{"class":147},[130,161,162],{"class":151},"config",[130,164,165],{"class":147},"] = ",[130,167,169],{"class":168},"sYbnZ","await",[130,171,173],{"class":172},"sNl3T"," Promise",[130,175,176],{"class":147},".",[130,178,180],{"class":179},"sCudf","all",[130,182,183],{"class":147},"([\n",[130,185,187,191,193,196,199,203],{"class":132,"line":186},3,[130,188,190],{"class":189},"s3F5K","    fs",[130,192,176],{"class":147},[130,194,195],{"class":179},"read",[130,197,198],{"class":147},"(",[130,200,202],{"class":201},"sKc5r","\"src\u002Findex.ts\"",[130,204,205],{"class":147},"),\n",[130,207,209,211,213,215,217,220],{"class":132,"line":208},4,[130,210,190],{"class":189},[130,212,176],{"class":147},[130,214,195],{"class":179},[130,216,198],{"class":147},[130,218,219],{"class":201},"\"src\u002Findex.test.ts\"",[130,221,205],{"class":147},[130,223,225,227,229,231,233,236],{"class":132,"line":224},5,[130,226,190],{"class":189},[130,228,176],{"class":147},[130,230,195],{"class":179},[130,232,198],{"class":147},[130,234,235],{"class":201},"\"axon.config.ts\"",[130,237,205],{"class":147},[130,239,241],{"class":132,"line":240},6,[130,242,243],{"class":147},"])\n",[130,245,247],{"class":132,"line":246},7,[130,248,250],{"emptyLinePlaceholder":249},true,"\n",[130,252,254,256,259,262,264,266,269,271,274,278,280],{"class":132,"line":253},8,[130,255,144],{"class":143},[130,257,258],{"class":151}," issues",[130,260,261],{"class":147}," = ",[130,263,152],{"class":189},[130,265,176],{"class":147},[130,267,268],{"class":179},"split",[130,270,198],{"class":147},[130,272,273],{"class":201},"\"",[130,275,277],{"class":276},"svVle","\\n",[130,279,273],{"class":201},[130,281,282],{"class":147},")\n",[130,284,286,289,292,295,297,299,302,305,308,311,314,317,320,324,326,329,332],{"class":132,"line":285},9,[130,287,288],{"class":147},"    .",[130,290,291],{"class":179},"map",[130,293,294],{"class":147},"((",[130,296,132],{"class":189},[130,298,33],{"class":147},[130,300,301],{"class":189},"i",[130,303,304],{"class":147},") ",[130,306,307],{"class":143},"=>",[130,309,310],{"class":147}," ({ ",[130,312,313],{"class":189},"line:",[130,315,316],{"class":189}," i",[130,318,319],{"class":147}," + ",[130,321,323],{"class":322},"sDGX8","1",[130,325,33],{"class":147},[130,327,328],{"class":189},"content:",[130,330,331],{"class":189}," line",[130,333,334],{"class":147}," }))\n",[130,336,338,340,343,346,349,352,354,357,359,362,364,367],{"class":132,"line":337},10,[130,339,288],{"class":147},[130,341,342],{"class":179},"filter",[130,344,345],{"class":147},"(({ ",[130,347,348],{"class":189},"content",[130,350,351],{"class":147}," }) ",[130,353,307],{"class":143},[130,355,356],{"class":189}," content",[130,358,176],{"class":147},[130,360,361],{"class":179},"includes",[130,363,198],{"class":147},[130,365,366],{"class":201},"\"TODO\"",[130,368,369],{"class":147},"))\n",[130,371,373],{"class":132,"line":372},11,[130,374,250],{"emptyLinePlaceholder":249},[130,376,378,380,383,385,388,390,393,395,398,400,403,405,408,410,413,415,418],{"class":132,"line":377},12,[130,379,169],{"class":168},[130,381,382],{"class":189}," fs",[130,384,176],{"class":147},[130,386,387],{"class":179},"write",[130,389,198],{"class":147},[130,391,392],{"class":201},"\"issues.json\"",[130,394,33],{"class":147},[130,396,397],{"class":151},"JSON",[130,399,176],{"class":147},[130,401,402],{"class":179},"stringify",[130,404,198],{"class":147},[130,406,407],{"class":189},"issues",[130,409,33],{"class":147},[130,411,412],{"class":143},"null",[130,414,33],{"class":147},[130,416,417],{"class":322},"2",[130,419,369],{"class":147},[15,421,422],{},"No round-trips. No separate tool calls for each file. One block, one stdout, one tick.",[15,424,425],{},"The agent splits into a new turn only when it genuinely needs to observe a result before\nknowing what to do next. Everything that can be determined ahead of time runs together.",[42,427,429],{"id":428},"subprocesses","Subprocesses",[15,431,432,434,435,437],{},[19,433,73],{}," blocks until the command exits and returns stdout, stderr, and exit code.\nFor anything that needs to stay alive — a dev server, a watcher, a build process —\n",[19,436,77],{}," returns a handle:",[121,439,441],{"className":123,"code":440,"language":125,"meta":126,"style":126},"const server = process.spawn(\"bun run dev\", { cwd: \".\" })\n\n\u002F\u002F Wait for it to be ready\nawait server.waitFor(\"ready in\")\n\n\u002F\u002F Check on it later\nconst output = server.stdout()\n",[19,442,443,476,480,485,503,507,512],{"__ignoreMap":126},[130,444,445,447,450,452,454,456,459,461,464,467,470,473],{"class":132,"line":133},[130,446,144],{"class":143},[130,448,449],{"class":151}," server",[130,451,261],{"class":147},[130,453,36],{"class":189},[130,455,176],{"class":147},[130,457,458],{"class":179},"spawn",[130,460,198],{"class":147},[130,462,463],{"class":201},"\"bun run dev\"",[130,465,466],{"class":147},", { ",[130,468,469],{"class":189},"cwd:",[130,471,472],{"class":201}," \".\"",[130,474,475],{"class":147}," })\n",[130,477,478],{"class":132,"line":140},[130,479,250],{"emptyLinePlaceholder":249},[130,481,482],{"class":132,"line":186},[130,483,484],{"class":136},"\u002F\u002F Wait for it to be ready\n",[130,486,487,489,491,493,496,498,501],{"class":132,"line":208},[130,488,169],{"class":168},[130,490,449],{"class":189},[130,492,176],{"class":147},[130,494,495],{"class":179},"waitFor",[130,497,198],{"class":147},[130,499,500],{"class":201},"\"ready in\"",[130,502,282],{"class":147},[130,504,505],{"class":132,"line":224},[130,506,250],{"emptyLinePlaceholder":249},[130,508,509],{"class":132,"line":240},[130,510,511],{"class":136},"\u002F\u002F Check on it later\n",[130,513,514,516,519,521,524,526,529],{"class":132,"line":246},[130,515,144],{"class":143},[130,517,518],{"class":151}," output",[130,520,261],{"class":147},[130,522,523],{"class":189},"server",[130,525,176],{"class":147},[130,527,528],{"class":179},"stdout",[130,530,531],{"class":147},"()\n",[15,533,534,535,537],{},"Spawned processes appear in the ",[19,536,54],{}," block on subsequent ticks. The agent can see\ntheir current output and status without querying — they're part of the context it\nreceives.",[42,539,541],{"id":540},"subagents","Subagents",[15,543,544,547],{},[19,545,546],{},"subagent.request()"," spawns another agent instance with a focused task and waits for the\nresult. The spawned agent runs its own full cognitive loop — tools, context assembly, stop\nconditions — and returns when it's done.",[121,549,551],{"className":123,"code":550,"language":125,"meta":126,"style":126},"const analysis = await subagent.request(\n    \"Read the test coverage report and list every module below 80% coverage.\"\n)\n",[19,552,553,575,580],{"__ignoreMap":126},[130,554,555,557,560,562,564,567,569,572],{"class":132,"line":133},[130,556,144],{"class":143},[130,558,559],{"class":151}," analysis",[130,561,261],{"class":147},[130,563,169],{"class":168},[130,565,566],{"class":189}," subagent",[130,568,176],{"class":147},[130,570,571],{"class":179},"request",[130,573,574],{"class":147},"(\n",[130,576,577],{"class":132,"line":140},[130,578,579],{"class":201},"    \"Read the test coverage report and list every module below 80% coverage.\"\n",[130,581,582],{"class":132,"line":186},[130,583,282],{"class":147},[15,585,586],{},"For tasks that can run in parallel:",[121,588,590],{"className":123,"code":589,"language":125,"meta":126,"style":126},"const [coverage, deps, types] = await Promise.all([\n    subagent.request(\"Summarise test coverage gaps\"),\n    subagent.request(\"Check for outdated dependencies\"),\n    subagent.request(\"Find any type errors in src\u002F\"),\n])\n",[19,591,592,623,639,654,669],{"__ignoreMap":126},[130,593,594,596,598,601,603,606,608,611,613,615,617,619,621],{"class":132,"line":133},[130,595,144],{"class":143},[130,597,148],{"class":147},[130,599,600],{"class":151},"coverage",[130,602,33],{"class":147},[130,604,605],{"class":151},"deps",[130,607,33],{"class":147},[130,609,610],{"class":151},"types",[130,612,165],{"class":147},[130,614,169],{"class":168},[130,616,173],{"class":172},[130,618,176],{"class":147},[130,620,180],{"class":179},[130,622,183],{"class":147},[130,624,625,628,630,632,634,637],{"class":132,"line":140},[130,626,627],{"class":189},"    subagent",[130,629,176],{"class":147},[130,631,571],{"class":179},[130,633,198],{"class":147},[130,635,636],{"class":201},"\"Summarise test coverage gaps\"",[130,638,205],{"class":147},[130,640,641,643,645,647,649,652],{"class":132,"line":186},[130,642,627],{"class":189},[130,644,176],{"class":147},[130,646,571],{"class":179},[130,648,198],{"class":147},[130,650,651],{"class":201},"\"Check for outdated dependencies\"",[130,653,205],{"class":147},[130,655,656,658,660,662,664,667],{"class":132,"line":208},[130,657,627],{"class":189},[130,659,176],{"class":147},[130,661,571],{"class":179},[130,663,198],{"class":147},[130,665,666],{"class":201},"\"Find any type errors in src\u002F\"",[130,668,205],{"class":147},[130,670,671],{"class":132,"line":224},[130,672,243],{"class":147},[15,674,675],{},"Each subagent runs independently. They don't share state, don't see each other's\ntimelines, and don't coordinate. The parent agent receives their text output and decides\nwhat to do with it.",[15,677,678,679,681],{},"A running subagent appears in the parent's ",[19,680,54],{}," block with its current status and\npartial output. The parent can see work in progress without waiting for it to finish.",[42,683,685],{"id":684},"what-this-means-in-practice","What this means in practice",[15,687,688],{},"The agent doesn't call a limited set of functions from a registry. It writes code. The\ndistinction matters when the task doesn't fit neatly into any predefined tool:",[121,690,692],{"className":123,"code":691,"language":125,"meta":126,"style":126},"\u002F\u002F No \"files changed in last commit\" tool needed\nconst result = await process.run(\"git diff --name-only HEAD~1\")\nconst changedFiles = result.stdout.trim().split(\"\\n\").filter(f => f.endsWith(\".ts\"))\n",[19,693,694,699,725],{"__ignoreMap":126},[130,695,696],{"class":132,"line":133},[130,697,698],{"class":136},"\u002F\u002F No \"files changed in last commit\" tool needed\n",[130,700,701,703,706,708,710,713,715,718,720,723],{"class":132,"line":140},[130,702,144],{"class":143},[130,704,705],{"class":151}," result",[130,707,261],{"class":147},[130,709,169],{"class":168},[130,711,712],{"class":189}," process",[130,714,176],{"class":147},[130,716,717],{"class":179},"run",[130,719,198],{"class":147},[130,721,722],{"class":201},"\"git diff --name-only HEAD~1\"",[130,724,282],{"class":147},[130,726,727,729,732,734,737,739,741,743,746,749,751,753,755,757,759,762,764,766,769,772,775,777,780,782,785],{"class":132,"line":186},[130,728,144],{"class":143},[130,730,731],{"class":151}," changedFiles",[130,733,261],{"class":147},[130,735,736],{"class":189},"result",[130,738,176],{"class":147},[130,740,528],{"class":189},[130,742,176],{"class":147},[130,744,745],{"class":179},"trim",[130,747,748],{"class":147},"().",[130,750,268],{"class":179},[130,752,198],{"class":147},[130,754,273],{"class":201},[130,756,277],{"class":276},[130,758,273],{"class":201},[130,760,761],{"class":147},").",[130,763,342],{"class":179},[130,765,198],{"class":147},[130,767,768],{"class":189},"f",[130,770,771],{"class":143}," =>",[130,773,774],{"class":189}," f",[130,776,176],{"class":147},[130,778,779],{"class":179},"endsWith",[130,781,198],{"class":147},[130,783,784],{"class":201},"\".ts\"",[130,786,369],{"class":147},[121,788,790],{"className":123,"code":789,"language":125,"meta":126,"style":126},"\u002F\u002F No \"watch for test failure\" tool needed\nconst runner = process.spawn(\"bun test --watch\")\nconst { line } = await runner.waitFor(\u002FFAIL|error\u002F)\nawait runner.kill()\n",[19,791,792,797,819,853],{"__ignoreMap":126},[130,793,794],{"class":132,"line":133},[130,795,796],{"class":136},"\u002F\u002F No \"watch for test failure\" tool needed\n",[130,798,799,801,804,806,808,810,812,814,817],{"class":132,"line":140},[130,800,144],{"class":143},[130,802,803],{"class":151}," runner",[130,805,261],{"class":147},[130,807,36],{"class":189},[130,809,176],{"class":147},[130,811,458],{"class":179},[130,813,198],{"class":147},[130,815,816],{"class":201},"\"bun test --watch\"",[130,818,282],{"class":147},[130,820,821,823,826,828,831,833,835,837,839,841,845,848,851],{"class":132,"line":186},[130,822,144],{"class":143},[130,824,825],{"class":147}," { ",[130,827,132],{"class":151},[130,829,830],{"class":147}," } = ",[130,832,169],{"class":168},[130,834,803],{"class":189},[130,836,176],{"class":147},[130,838,495],{"class":179},[130,840,198],{"class":147},[130,842,844],{"class":843},"sxaxS","\u002FFAIL",[130,846,847],{"class":179},"|",[130,849,850],{"class":843},"error\u002F",[130,852,282],{"class":147},[130,854,855,857,859,861,864],{"class":132,"line":208},[130,856,169],{"class":168},[130,858,803],{"class":189},[130,860,176],{"class":147},[130,862,863],{"class":179},"kill",[130,865,531],{"class":147},[15,867,868],{},"The tool namespaces cover the common patterns. The language covers everything else.",[42,870,872],{"id":871},"policy-as-the-real-boundary","Policy as the real boundary",[15,874,875,876,879,880,176],{},"All of this — filesystem access, subprocess execution, network calls, subagent spawning —\nruns through the policy gate declared in ",[19,877,878],{},"axon.config.ts",". The capsule enforces it before\nany function executes. The breadth of what's available doesn't mean the agent can do\nanything; it means the agent can do anything ",[881,882,883],"em",{},"you've allowed",[15,885,886,887,890],{},"An agent with ",[19,888,889],{},"fs: { read: [\".\u002Fsrc\u002F**\"] }"," can read source files and nothing else. The\nfull runtime is present. The policy decides how much of it the agent can reach.",[15,892,893,894,899],{},"See ",[895,896,898],"a",{"href":897},"\u002Fdocs\u002Fv2\u002Fconcepts\u002Fkernel-and-policy","Kernel & Policy"," for the enforcement model\nand what it does and does not protect against.",[901,902,903],"style",{},"html pre.shiki code .sOLPB, html code.shiki .sOLPB{--shiki-default:#6A9955}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 .s9McN, html code.shiki .s9McN{--shiki-default:#4FC1FF}html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}html pre.shiki code .sNl3T, html code.shiki .sNl3T{--shiki-default:#4EC9B0}html pre.shiki code .sCudf, html code.shiki .sCudf{--shiki-default:#DCDCAA}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}html pre.shiki code .sKc5r, html code.shiki .sKc5r{--shiki-default:#CE9178}html pre.shiki code .svVle, html code.shiki .svVle{--shiki-default:#D7BA7D}html pre.shiki code .sDGX8, html code.shiki .sDGX8{--shiki-default:#B5CEA8}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 .sxaxS, html code.shiki .sxaxS{--shiki-default:#D16969}",{"title":126,"searchDepth":140,"depth":140,"links":905},[906,907,908,909,910,911],{"id":44,"depth":140,"text":45},{"id":115,"depth":140,"text":116},{"id":428,"depth":140,"text":429},{"id":540,"depth":140,"text":541},{"id":684,"depth":140,"text":685},{"id":871,"depth":140,"text":872},"The agent has one way to interact with the world: a \u003Ctypescript> block that executes in\nthe capsule. Everything it can read, write, run, or delegate flows through that boundary.\n\u003Ctext> communicates with the user. Everything else is code.","md",{},"\u002Fdocs\u002Fv2\u002Fconcepts\u002Fagents-world",{"title":5,"description":912},"docs\u002Fv2\u002Fconcepts\u002Fagents-world","ZktEGGLNeDRmIx48jndVfXnm3FVtbJxzDd3emDQmNxc",1785671807762]