[{"data":1,"prerenderedAt":1405},["ShallowReactive",2],{"docs:/docs/agents/composition":3},{"id":4,"title":5,"body":6,"description":1398,"extension":1399,"meta":1400,"navigation":174,"path":1401,"seo":1402,"stem":1403,"__hash__":1404},"docs/docs/agents/composition.md","Blueprint Composition for Agents",{"type":7,"value":8,"toc":1383},"minimark",[9,14,18,23,31,43,48,90,94,103,653,657,715,719,732,1277,1281,1285,1288,1292,1295,1299,1321,1325,1379],[10,11,13],"h1",{"id":12},"blueprint-composition","Blueprint Composition",[15,16,17],"p",{},"Combine the agents Blueprint with other Blueprints to build powerful real-time applications.",[19,20,22],"h2",{"id":21},"how-composition-works","How Composition Works",[15,24,25,26,30],{},"NoLag Blueprints are independent apps within the same project. Each Blueprint manages its own rooms and topics. Composition happens through ",[27,28,29],"strong",{},"cross-app actor access",": one actor, with one token and one connection, can use several apps at the same time.",[15,32,33,34,38,39,42],{},"For example, an actor representing a chatbot can attach a ",[35,36,37],"code",{},"@nolag/chat"," wrapper (for user-facing messaging) and a ",[35,40,41],{},"@nolag/agents"," wrapper (for AI coordination) to the same client. The actor bridges the two apps, forwarding user messages to the agent workflow and sending agent responses back to the chat.",[44,45,47],"h3",{"id":46},"key-concepts","Key concepts",[49,50,51,66,84,87],"ul",{},[52,53,54,57,58,61,62,65],"li",{},[27,55,56],{},"Actors are created at the project level."," An app in its default ",[35,59,60],{},"open"," access mode admits every active actor in the project; a ",[35,63,64],{},"restricted"," app admits only actors granted access to it.",[52,67,68,71,72,75,76,79,80,83],{},[27,69,70],{},"One token, one client."," The actor connects once with ",[35,73,74],{},"NoLag(token)","; every wrapper takes that ",[35,77,78],{},"client"," in its options and names its own app with ",[35,81,82],{},"appName",".",[52,85,86],{},"Each wrapper keeps its own rooms and topics on the shared connection.",[52,88,89],{},"The bridge code listens on one wrapper and publishes on the other.",[19,91,93],{"id":92},"example-agentic-chatbot","Example: Agentic Chatbot",[15,95,96,97,99,100,102],{},"A customer support chatbot that uses ",[35,98,37],{}," for the user-facing interface and ",[35,101,41],{}," for the AI backend. When a user sends a message, the bot dispatches it as a task to a customer-support agent, waits for the result, and posts the response back to the chat room.",[104,105,106],"code-tabs",{},[107,108,114],"pre",{"className":109,"code":110,"filename":111,"language":112,"meta":113,"style":113},"language-typescript shiki shiki-themes github-light github-dark","import { NoLag } from \"@nolag/js-sdk\";\nimport { NoLagChat } from \"@nolag/chat\";\nimport { NoLagAgents, Handoff } from \"@nolag/agents\";\n\n// One actor, one connection, two apps\nconst client = NoLag(BOT_TOKEN);\nconst chat = new NoLagChat({ client, appName: CHAT_APP_SLUG, username: \"support-bot\" });\nconst agents = new NoLagAgents({\n  client,\n  appName: AGENTS_APP_SLUG,\n  agentId: \"support-bridge\",\n  presence: { name: \"support-bridge\", role: \"orchestrator\" },\n});\n\nawait client.connect();\nawait Promise.all([chat.ready(), agents.ready()]);\n\n// User-facing chat room (seeded by the chat blueprint)\nconst chatRoom = chat.joinRoom(\"general\");\n\n// Agent coordination room (seeded by the agents blueprint)\nconst agentRoom = agents.room(\"default-workflow\");\nconst handoff = new Handoff(agentRoom);\n\n// Publishers never receive their own messages, so this fires only for other users\nchatRoom.on(\"message\", async (msg) => {\n  const result = await handoff.dispatch(\n    \"customer-support\",\n    {\n      userId: msg.userId,\n      text: msg.text,\n      history: chatRoom.getMessages().map((m) => ({ from: m.username, text: m.text })),\n    },\n    { waitForResult: true, timeout: 30000 },\n  );\n\n  if (result && result.status === \"success\") {\n    chatRoom.sendMessage(String(result.payload.response));\n  }\n});\n","TypeScript","typescript","",[35,115,116,139,154,169,176,183,209,240,258,264,276,287,304,310,315,330,357,362,368,391,396,402,425,443,448,454,490,513,521,527,533,539,567,573,590,596,601,625,642,648],{"__ignoreMap":113},[117,118,121,125,129,132,136],"span",{"class":119,"line":120},"line",1,[117,122,124],{"class":123},"szBVR","import",[117,126,128],{"class":127},"sVt8B"," { NoLag } ",[117,130,131],{"class":123},"from",[117,133,135],{"class":134},"sZZnC"," \"@nolag/js-sdk\"",[117,137,138],{"class":127},";\n",[117,140,142,144,147,149,152],{"class":119,"line":141},2,[117,143,124],{"class":123},[117,145,146],{"class":127}," { NoLagChat } ",[117,148,131],{"class":123},[117,150,151],{"class":134}," \"@nolag/chat\"",[117,153,138],{"class":127},[117,155,157,159,162,164,167],{"class":119,"line":156},3,[117,158,124],{"class":123},[117,160,161],{"class":127}," { NoLagAgents, Handoff } ",[117,163,131],{"class":123},[117,165,166],{"class":134}," \"@nolag/agents\"",[117,168,138],{"class":127},[117,170,172],{"class":119,"line":171},4,[117,173,175],{"emptyLinePlaceholder":174},true,"\n",[117,177,179],{"class":119,"line":178},5,[117,180,182],{"class":181},"sJ8bj","// One actor, one connection, two apps\n",[117,184,186,189,193,196,200,203,206],{"class":119,"line":185},6,[117,187,188],{"class":123},"const",[117,190,192],{"class":191},"sj4cs"," client",[117,194,195],{"class":123}," =",[117,197,199],{"class":198},"sScJk"," NoLag",[117,201,202],{"class":127},"(",[117,204,205],{"class":191},"BOT_TOKEN",[117,207,208],{"class":127},");\n",[117,210,212,214,217,219,222,225,228,231,234,237],{"class":119,"line":211},7,[117,213,188],{"class":123},[117,215,216],{"class":191}," chat",[117,218,195],{"class":123},[117,220,221],{"class":123}," new",[117,223,224],{"class":198}," NoLagChat",[117,226,227],{"class":127},"({ client, appName: ",[117,229,230],{"class":191},"CHAT_APP_SLUG",[117,232,233],{"class":127},", username: ",[117,235,236],{"class":134},"\"support-bot\"",[117,238,239],{"class":127}," });\n",[117,241,243,245,248,250,252,255],{"class":119,"line":242},8,[117,244,188],{"class":123},[117,246,247],{"class":191}," agents",[117,249,195],{"class":123},[117,251,221],{"class":123},[117,253,254],{"class":198}," NoLagAgents",[117,256,257],{"class":127},"({\n",[117,259,261],{"class":119,"line":260},9,[117,262,263],{"class":127},"  client,\n",[117,265,267,270,273],{"class":119,"line":266},10,[117,268,269],{"class":127},"  appName: ",[117,271,272],{"class":191},"AGENTS_APP_SLUG",[117,274,275],{"class":127},",\n",[117,277,279,282,285],{"class":119,"line":278},11,[117,280,281],{"class":127},"  agentId: ",[117,283,284],{"class":134},"\"support-bridge\"",[117,286,275],{"class":127},[117,288,290,293,295,298,301],{"class":119,"line":289},12,[117,291,292],{"class":127},"  presence: { name: ",[117,294,284],{"class":134},[117,296,297],{"class":127},", role: ",[117,299,300],{"class":134},"\"orchestrator\"",[117,302,303],{"class":127}," },\n",[117,305,307],{"class":119,"line":306},13,[117,308,309],{"class":127},"});\n",[117,311,313],{"class":119,"line":312},14,[117,314,175],{"emptyLinePlaceholder":174},[117,316,318,321,324,327],{"class":119,"line":317},15,[117,319,320],{"class":123},"await",[117,322,323],{"class":127}," client.",[117,325,326],{"class":198},"connect",[117,328,329],{"class":127},"();\n",[117,331,333,335,338,340,343,346,349,352,354],{"class":119,"line":332},16,[117,334,320],{"class":123},[117,336,337],{"class":191}," Promise",[117,339,83],{"class":127},[117,341,342],{"class":198},"all",[117,344,345],{"class":127},"([chat.",[117,347,348],{"class":198},"ready",[117,350,351],{"class":127},"(), agents.",[117,353,348],{"class":198},[117,355,356],{"class":127},"()]);\n",[117,358,360],{"class":119,"line":359},17,[117,361,175],{"emptyLinePlaceholder":174},[117,363,365],{"class":119,"line":364},18,[117,366,367],{"class":181},"// User-facing chat room (seeded by the chat blueprint)\n",[117,369,371,373,376,378,381,384,386,389],{"class":119,"line":370},19,[117,372,188],{"class":123},[117,374,375],{"class":191}," chatRoom",[117,377,195],{"class":123},[117,379,380],{"class":127}," chat.",[117,382,383],{"class":198},"joinRoom",[117,385,202],{"class":127},[117,387,388],{"class":134},"\"general\"",[117,390,208],{"class":127},[117,392,394],{"class":119,"line":393},20,[117,395,175],{"emptyLinePlaceholder":174},[117,397,399],{"class":119,"line":398},21,[117,400,401],{"class":181},"// Agent coordination room (seeded by the agents blueprint)\n",[117,403,405,407,410,412,415,418,420,423],{"class":119,"line":404},22,[117,406,188],{"class":123},[117,408,409],{"class":191}," agentRoom",[117,411,195],{"class":123},[117,413,414],{"class":127}," agents.",[117,416,417],{"class":198},"room",[117,419,202],{"class":127},[117,421,422],{"class":134},"\"default-workflow\"",[117,424,208],{"class":127},[117,426,428,430,433,435,437,440],{"class":119,"line":427},23,[117,429,188],{"class":123},[117,431,432],{"class":191}," handoff",[117,434,195],{"class":123},[117,436,221],{"class":123},[117,438,439],{"class":198}," Handoff",[117,441,442],{"class":127},"(agentRoom);\n",[117,444,446],{"class":119,"line":445},24,[117,447,175],{"emptyLinePlaceholder":174},[117,449,451],{"class":119,"line":450},25,[117,452,453],{"class":181},"// Publishers never receive their own messages, so this fires only for other users\n",[117,455,457,460,463,465,468,471,474,477,481,484,487],{"class":119,"line":456},26,[117,458,459],{"class":127},"chatRoom.",[117,461,462],{"class":198},"on",[117,464,202],{"class":127},[117,466,467],{"class":134},"\"message\"",[117,469,470],{"class":127},", ",[117,472,473],{"class":123},"async",[117,475,476],{"class":127}," (",[117,478,480],{"class":479},"s4XuR","msg",[117,482,483],{"class":127},") ",[117,485,486],{"class":123},"=>",[117,488,489],{"class":127}," {\n",[117,491,493,496,499,501,504,507,510],{"class":119,"line":492},27,[117,494,495],{"class":123},"  const",[117,497,498],{"class":191}," result",[117,500,195],{"class":123},[117,502,503],{"class":123}," await",[117,505,506],{"class":127}," handoff.",[117,508,509],{"class":198},"dispatch",[117,511,512],{"class":127},"(\n",[117,514,516,519],{"class":119,"line":515},28,[117,517,518],{"class":134},"    \"customer-support\"",[117,520,275],{"class":127},[117,522,524],{"class":119,"line":523},29,[117,525,526],{"class":127},"    {\n",[117,528,530],{"class":119,"line":529},30,[117,531,532],{"class":127},"      userId: msg.userId,\n",[117,534,536],{"class":119,"line":535},31,[117,537,538],{"class":127},"      text: msg.text,\n",[117,540,542,545,548,551,554,557,560,562,564],{"class":119,"line":541},32,[117,543,544],{"class":127},"      history: chatRoom.",[117,546,547],{"class":198},"getMessages",[117,549,550],{"class":127},"().",[117,552,553],{"class":198},"map",[117,555,556],{"class":127},"((",[117,558,559],{"class":479},"m",[117,561,483],{"class":127},[117,563,486],{"class":123},[117,565,566],{"class":127}," ({ from: m.username, text: m.text })),\n",[117,568,570],{"class":119,"line":569},33,[117,571,572],{"class":127},"    },\n",[117,574,576,579,582,585,588],{"class":119,"line":575},34,[117,577,578],{"class":127},"    { waitForResult: ",[117,580,581],{"class":191},"true",[117,583,584],{"class":127},", timeout: ",[117,586,587],{"class":191},"30000",[117,589,303],{"class":127},[117,591,593],{"class":119,"line":592},35,[117,594,595],{"class":127},"  );\n",[117,597,599],{"class":119,"line":598},36,[117,600,175],{"emptyLinePlaceholder":174},[117,602,604,607,610,613,616,619,622],{"class":119,"line":603},37,[117,605,606],{"class":123},"  if",[117,608,609],{"class":127}," (result ",[117,611,612],{"class":123},"&&",[117,614,615],{"class":127}," result.status ",[117,617,618],{"class":123},"===",[117,620,621],{"class":134}," \"success\"",[117,623,624],{"class":127},") {\n",[117,626,628,631,634,636,639],{"class":119,"line":627},38,[117,629,630],{"class":127},"    chatRoom.",[117,632,633],{"class":198},"sendMessage",[117,635,202],{"class":127},[117,637,638],{"class":198},"String",[117,640,641],{"class":127},"(result.payload.response));\n",[117,643,645],{"class":119,"line":644},39,[117,646,647],{"class":127},"  }\n",[117,649,651],{"class":119,"line":650},40,[117,652,309],{"class":127},[44,654,656],{"id":655},"architecture","Architecture",[658,659,660,676],"table",{},[661,662,663],"thead",{},[664,665,666,670,673],"tr",{},[667,668,669],"th",{},"Component",[667,671,672],{},"Blueprint",[667,674,675],{},"Role",[677,678,679,692,703],"tbody",{},[664,680,681,685,689],{},[682,683,684],"td",{},"Chat UI",[682,686,687],{},[35,688,37],{},[682,690,691],{},"User-facing chat rooms with presence and typing",[664,693,694,697,700],{},[682,695,696],{},"Bot bridge",[682,698,699],{},"Both",[682,701,702],{},"Listens to chat, dispatches to agents, sends responses",[664,704,705,708,712],{},[682,706,707],{},"AI workers",[682,709,710],{},[35,711,41],{},[682,713,714],{},"Process user queries with an LLM, return responses",[19,716,718],{"id":717},"example-monitored-delivery-fleet","Example: Monitored Delivery Fleet",[15,720,721,722,725,726,728,729,731],{},"A delivery fleet that uses ",[35,723,724],{},"@nolag/track"," for real-time GPS tracking and ",[35,727,41],{}," for intelligent monitoring. ",[35,730,724],{}," evaluates geofences on the client for every location update it receives, so when a vehicle enters one, the monitor dispatches an analysis task and records the outcome on the Blackboard.",[104,733,734],{},[107,735,737],{"className":109,"code":736,"filename":111,"language":112,"meta":113,"style":113},"import { NoLag } from \"@nolag/js-sdk\";\nimport { NoLagTrack } from \"@nolag/track\";\nimport { NoLagAgents, Handoff, Blackboard } from \"@nolag/agents\";\n\nconst client = NoLag(MONITOR_TOKEN);\nconst track = new NoLagTrack({ client, appName: TRACK_APP_SLUG, assetId: \"fleet-monitor\" });\nconst agents = new NoLagAgents({\n  client,\n  appName: AGENTS_APP_SLUG,\n  agentId: \"fleet-monitor\",\n  presence: { name: \"fleet-monitor\", role: \"orchestrator\" },\n});\n\nawait client.connect();\nawait Promise.all([track.ready(), agents.ready()]);\n\n// Tracking zone (seeded by the track blueprint) with a client-side geofence\nconst fleet = track.joinZone(\"fleet-zone\");\nfleet.addGeofence({\n  id: \"depot\",\n  shape: \"circle\",\n  center: { lat: -37.8136, lng: 144.9631 },\n  radiusMeters: 250,\n});\n\nconst agentRoom = agents.room(\"default-workflow\");\nconst handoff = new Handoff(agentRoom);\nconst blackboard = new Blackboard(agentRoom, agents.agentId);\n\n// When a vehicle enters the geofence, trigger agent analysis\nfleet.on(\"geofenceTriggered\", async (event) => {\n  if (event.type !== \"enter\") return;\n\n  const result = await handoff.dispatch(\n    \"logistics\",\n    { assetId: event.assetId, geofenceId: event.geofenceId, point: event.point },\n    { waitForResult: true, timeout: 30000 },\n  );\n\n  // Record the outcome on shared state (read-modify-write, last writer wins)\n  if (result && result.status === \"success\") {\n    const status = (blackboard.get(\"fleet-status\") as Record\u003Cstring, unknown> | undefined) ?? {};\n    blackboard.set(\"fleet-status\", { ...status, [event.assetId]: result.payload.status });\n  }\n});\n",[35,738,739,751,765,778,782,799,826,840,844,852,860,872,876,880,890,911,915,920,942,952,962,972,991,1001,1005,1009,1027,1041,1058,1062,1067,1093,1113,1117,1133,1140,1145,1157,1161,1165,1170,1187,1245,1267,1272],{"__ignoreMap":113},[117,740,741,743,745,747,749],{"class":119,"line":120},[117,742,124],{"class":123},[117,744,128],{"class":127},[117,746,131],{"class":123},[117,748,135],{"class":134},[117,750,138],{"class":127},[117,752,753,755,758,760,763],{"class":119,"line":141},[117,754,124],{"class":123},[117,756,757],{"class":127}," { NoLagTrack } ",[117,759,131],{"class":123},[117,761,762],{"class":134}," \"@nolag/track\"",[117,764,138],{"class":127},[117,766,767,769,772,774,776],{"class":119,"line":156},[117,768,124],{"class":123},[117,770,771],{"class":127}," { NoLagAgents, Handoff, Blackboard } ",[117,773,131],{"class":123},[117,775,166],{"class":134},[117,777,138],{"class":127},[117,779,780],{"class":119,"line":171},[117,781,175],{"emptyLinePlaceholder":174},[117,783,784,786,788,790,792,794,797],{"class":119,"line":178},[117,785,188],{"class":123},[117,787,192],{"class":191},[117,789,195],{"class":123},[117,791,199],{"class":198},[117,793,202],{"class":127},[117,795,796],{"class":191},"MONITOR_TOKEN",[117,798,208],{"class":127},[117,800,801,803,806,808,810,813,815,818,821,824],{"class":119,"line":185},[117,802,188],{"class":123},[117,804,805],{"class":191}," track",[117,807,195],{"class":123},[117,809,221],{"class":123},[117,811,812],{"class":198}," NoLagTrack",[117,814,227],{"class":127},[117,816,817],{"class":191},"TRACK_APP_SLUG",[117,819,820],{"class":127},", assetId: ",[117,822,823],{"class":134},"\"fleet-monitor\"",[117,825,239],{"class":127},[117,827,828,830,832,834,836,838],{"class":119,"line":211},[117,829,188],{"class":123},[117,831,247],{"class":191},[117,833,195],{"class":123},[117,835,221],{"class":123},[117,837,254],{"class":198},[117,839,257],{"class":127},[117,841,842],{"class":119,"line":242},[117,843,263],{"class":127},[117,845,846,848,850],{"class":119,"line":260},[117,847,269],{"class":127},[117,849,272],{"class":191},[117,851,275],{"class":127},[117,853,854,856,858],{"class":119,"line":266},[117,855,281],{"class":127},[117,857,823],{"class":134},[117,859,275],{"class":127},[117,861,862,864,866,868,870],{"class":119,"line":278},[117,863,292],{"class":127},[117,865,823],{"class":134},[117,867,297],{"class":127},[117,869,300],{"class":134},[117,871,303],{"class":127},[117,873,874],{"class":119,"line":289},[117,875,309],{"class":127},[117,877,878],{"class":119,"line":306},[117,879,175],{"emptyLinePlaceholder":174},[117,881,882,884,886,888],{"class":119,"line":312},[117,883,320],{"class":123},[117,885,323],{"class":127},[117,887,326],{"class":198},[117,889,329],{"class":127},[117,891,892,894,896,898,900,903,905,907,909],{"class":119,"line":317},[117,893,320],{"class":123},[117,895,337],{"class":191},[117,897,83],{"class":127},[117,899,342],{"class":198},[117,901,902],{"class":127},"([track.",[117,904,348],{"class":198},[117,906,351],{"class":127},[117,908,348],{"class":198},[117,910,356],{"class":127},[117,912,913],{"class":119,"line":332},[117,914,175],{"emptyLinePlaceholder":174},[117,916,917],{"class":119,"line":359},[117,918,919],{"class":181},"// Tracking zone (seeded by the track blueprint) with a client-side geofence\n",[117,921,922,924,927,929,932,935,937,940],{"class":119,"line":364},[117,923,188],{"class":123},[117,925,926],{"class":191}," fleet",[117,928,195],{"class":123},[117,930,931],{"class":127}," track.",[117,933,934],{"class":198},"joinZone",[117,936,202],{"class":127},[117,938,939],{"class":134},"\"fleet-zone\"",[117,941,208],{"class":127},[117,943,944,947,950],{"class":119,"line":370},[117,945,946],{"class":127},"fleet.",[117,948,949],{"class":198},"addGeofence",[117,951,257],{"class":127},[117,953,954,957,960],{"class":119,"line":393},[117,955,956],{"class":127},"  id: ",[117,958,959],{"class":134},"\"depot\"",[117,961,275],{"class":127},[117,963,964,967,970],{"class":119,"line":398},[117,965,966],{"class":127},"  shape: ",[117,968,969],{"class":134},"\"circle\"",[117,971,275],{"class":127},[117,973,974,977,980,983,986,989],{"class":119,"line":404},[117,975,976],{"class":127},"  center: { lat: ",[117,978,979],{"class":123},"-",[117,981,982],{"class":191},"37.8136",[117,984,985],{"class":127},", lng: ",[117,987,988],{"class":191},"144.9631",[117,990,303],{"class":127},[117,992,993,996,999],{"class":119,"line":427},[117,994,995],{"class":127},"  radiusMeters: ",[117,997,998],{"class":191},"250",[117,1000,275],{"class":127},[117,1002,1003],{"class":119,"line":445},[117,1004,309],{"class":127},[117,1006,1007],{"class":119,"line":450},[117,1008,175],{"emptyLinePlaceholder":174},[117,1010,1011,1013,1015,1017,1019,1021,1023,1025],{"class":119,"line":456},[117,1012,188],{"class":123},[117,1014,409],{"class":191},[117,1016,195],{"class":123},[117,1018,414],{"class":127},[117,1020,417],{"class":198},[117,1022,202],{"class":127},[117,1024,422],{"class":134},[117,1026,208],{"class":127},[117,1028,1029,1031,1033,1035,1037,1039],{"class":119,"line":492},[117,1030,188],{"class":123},[117,1032,432],{"class":191},[117,1034,195],{"class":123},[117,1036,221],{"class":123},[117,1038,439],{"class":198},[117,1040,442],{"class":127},[117,1042,1043,1045,1048,1050,1052,1055],{"class":119,"line":515},[117,1044,188],{"class":123},[117,1046,1047],{"class":191}," blackboard",[117,1049,195],{"class":123},[117,1051,221],{"class":123},[117,1053,1054],{"class":198}," Blackboard",[117,1056,1057],{"class":127},"(agentRoom, agents.agentId);\n",[117,1059,1060],{"class":119,"line":523},[117,1061,175],{"emptyLinePlaceholder":174},[117,1063,1064],{"class":119,"line":529},[117,1065,1066],{"class":181},"// When a vehicle enters the geofence, trigger agent analysis\n",[117,1068,1069,1071,1073,1075,1078,1080,1082,1084,1087,1089,1091],{"class":119,"line":535},[117,1070,946],{"class":127},[117,1072,462],{"class":198},[117,1074,202],{"class":127},[117,1076,1077],{"class":134},"\"geofenceTriggered\"",[117,1079,470],{"class":127},[117,1081,473],{"class":123},[117,1083,476],{"class":127},[117,1085,1086],{"class":479},"event",[117,1088,483],{"class":127},[117,1090,486],{"class":123},[117,1092,489],{"class":127},[117,1094,1095,1097,1100,1103,1106,1108,1111],{"class":119,"line":541},[117,1096,606],{"class":123},[117,1098,1099],{"class":127}," (event.type ",[117,1101,1102],{"class":123},"!==",[117,1104,1105],{"class":134}," \"enter\"",[117,1107,483],{"class":127},[117,1109,1110],{"class":123},"return",[117,1112,138],{"class":127},[117,1114,1115],{"class":119,"line":569},[117,1116,175],{"emptyLinePlaceholder":174},[117,1118,1119,1121,1123,1125,1127,1129,1131],{"class":119,"line":575},[117,1120,495],{"class":123},[117,1122,498],{"class":191},[117,1124,195],{"class":123},[117,1126,503],{"class":123},[117,1128,506],{"class":127},[117,1130,509],{"class":198},[117,1132,512],{"class":127},[117,1134,1135,1138],{"class":119,"line":592},[117,1136,1137],{"class":134},"    \"logistics\"",[117,1139,275],{"class":127},[117,1141,1142],{"class":119,"line":598},[117,1143,1144],{"class":127},"    { assetId: event.assetId, geofenceId: event.geofenceId, point: event.point },\n",[117,1146,1147,1149,1151,1153,1155],{"class":119,"line":603},[117,1148,578],{"class":127},[117,1150,581],{"class":191},[117,1152,584],{"class":127},[117,1154,587],{"class":191},[117,1156,303],{"class":127},[117,1158,1159],{"class":119,"line":627},[117,1160,595],{"class":127},[117,1162,1163],{"class":119,"line":644},[117,1164,175],{"emptyLinePlaceholder":174},[117,1166,1167],{"class":119,"line":650},[117,1168,1169],{"class":181},"  // Record the outcome on shared state (read-modify-write, last writer wins)\n",[117,1171,1173,1175,1177,1179,1181,1183,1185],{"class":119,"line":1172},41,[117,1174,606],{"class":123},[117,1176,609],{"class":127},[117,1178,612],{"class":123},[117,1180,615],{"class":127},[117,1182,618],{"class":123},[117,1184,621],{"class":134},[117,1186,624],{"class":127},[117,1188,1190,1193,1196,1198,1201,1204,1206,1209,1211,1214,1217,1220,1223,1225,1228,1231,1234,1237,1239,1242],{"class":119,"line":1189},42,[117,1191,1192],{"class":123},"    const",[117,1194,1195],{"class":191}," status",[117,1197,195],{"class":123},[117,1199,1200],{"class":127}," (blackboard.",[117,1202,1203],{"class":198},"get",[117,1205,202],{"class":127},[117,1207,1208],{"class":134},"\"fleet-status\"",[117,1210,483],{"class":127},[117,1212,1213],{"class":123},"as",[117,1215,1216],{"class":198}," Record",[117,1218,1219],{"class":127},"\u003C",[117,1221,1222],{"class":191},"string",[117,1224,470],{"class":127},[117,1226,1227],{"class":191},"unknown",[117,1229,1230],{"class":127},"> ",[117,1232,1233],{"class":123},"|",[117,1235,1236],{"class":191}," undefined",[117,1238,483],{"class":127},[117,1240,1241],{"class":123},"??",[117,1243,1244],{"class":127}," {};\n",[117,1246,1248,1251,1254,1256,1258,1261,1264],{"class":119,"line":1247},43,[117,1249,1250],{"class":127},"    blackboard.",[117,1252,1253],{"class":198},"set",[117,1255,202],{"class":127},[117,1257,1208],{"class":134},[117,1259,1260],{"class":127},", { ",[117,1262,1263],{"class":123},"...",[117,1265,1266],{"class":127},"status, [event.assetId]: result.payload.status });\n",[117,1268,1270],{"class":119,"line":1269},44,[117,1271,647],{"class":127},[117,1273,1275],{"class":119,"line":1274},45,[117,1276,309],{"class":127},[19,1278,1280],{"id":1279},"composition-patterns","Composition Patterns",[44,1282,1284],{"id":1283},"event-bridge","Event bridge",[15,1286,1287],{},"The simplest pattern: listen for events on one Blueprint and trigger actions on another. The chatbot example above uses this: chat messages trigger agent tasks.",[44,1289,1291],{"id":1290},"shared-state-sync","Shared state sync",[15,1293,1294],{},"Use the Blackboard pattern to maintain state that is derived from events in other Blueprints. The fleet example writes fleet status from tracking events.",[44,1296,1298],{"id":1297},"approval-pipeline","Approval pipeline",[15,1300,1301,1302,1304,1305,1308,1309,1312,1313,1316,1317,1320],{},"Combine ",[35,1303,41],{}," (Approve pattern) with ",[35,1306,1307],{},"@nolag/notify",". A bridge handles ",[35,1310,1311],{},"approve.onRequest()"," by sending the request as a notification; when a human answers it, the bridge calls ",[35,1314,1315],{},"respond(\"approved\")"," or ",[35,1318,1319],{},"respond(\"rejected\", reason)"," and the agent workflow continues.",[19,1322,1324],{"id":1323},"which-blueprints-compose-well","Which Blueprints compose well?",[658,1326,1327,1337],{},[661,1328,1329],{},[664,1330,1331,1334],{},[667,1332,1333],{},"Combination",[667,1335,1336],{},"Use case",[677,1338,1339,1347,1355,1363,1371],{},[664,1340,1341,1344],{},[682,1342,1343],{},"Agents + Chat",[682,1345,1346],{},"Agentic chatbots, AI-assisted customer support",[664,1348,1349,1352],{},[682,1350,1351],{},"Agents + Notify",[682,1353,1354],{},"Agent-triggered notifications, approval requests",[664,1356,1357,1360],{},[682,1358,1359],{},"Agents + Track",[682,1361,1362],{},"Intelligent fleet monitoring, autonomous logistics",[664,1364,1365,1368],{},[682,1366,1367],{},"Agents + Dash",[682,1369,1370],{},"AI-powered dashboards, automated reporting",[664,1372,1373,1376],{},[682,1374,1375],{},"Agents + IoT",[682,1377,1378],{},"Autonomous device management, predictive maintenance",[1380,1381,1382],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":113,"searchDepth":141,"depth":141,"links":1384},[1385,1388,1391,1392,1397],{"id":21,"depth":141,"text":22,"children":1386},[1387],{"id":46,"depth":156,"text":47},{"id":92,"depth":141,"text":93,"children":1389},[1390],{"id":655,"depth":156,"text":656},{"id":717,"depth":141,"text":718},{"id":1279,"depth":141,"text":1280,"children":1393},[1394,1395,1396],{"id":1283,"depth":156,"text":1284},{"id":1290,"depth":156,"text":1291},{"id":1297,"depth":156,"text":1298},{"id":1323,"depth":141,"text":1324},"How to compose the agents Blueprint with chat, notify, track, and other Blueprints on one shared client.","md",{},"/docs/agents/composition",{"title":5,"description":1398},"docs/agents/composition","wodKCc3QWJNq8pQsOdSRoC-zmRlOM-I5GjJDJ2gzzI8",1789869418246]