reflex-agent 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +111 -98
- package/.next/app-path-routes-manifest.json +9 -9
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +4 -54
- package/.next/react-loadable-manifest.json +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/agents/[agentId]/page.js +3 -3
- package/.next/server/app/agents/[agentId]/page.js.nft.json +1 -1
- package/.next/server/app/agents/[agentId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/[agentId]/respond/route.js +2 -2
- package/.next/server/app/api/agents/[agentId]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/[agentId]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/images/[rootId]/[file]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/oauth/callback/route.js +3 -3
- package/.next/server/app/api/oauth/callback/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/oauth/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/roots/[id]/attachments/route.js +0 -0
- package/.next/server/app/api/roots/[id]/attachments/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/roots/[id]/chat/[topicId]/send/route.js +2 -2
- package/.next/server/app/api/roots/[id]/chat/[topicId]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/roots/[id]/chat/[topicId]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/roots/[id]/chat/[topicId]/stop/route.js +2 -2
- package/.next/server/app/api/roots/[id]/chat/[topicId]/stop/route.js.nft.json +1 -1
- package/.next/server/app/api/roots/[id]/chat/[topicId]/stop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/roots/[id]/chat/[topicId]/stream/route.js +2 -2
- package/.next/server/app/api/roots/[id]/chat/[topicId]/stream/route.js.nft.json +1 -1
- package/.next/server/app/api/roots/[id]/chat/[topicId]/stream/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/roots/[id]/dashboard/route.js +1 -1
- package/.next/server/app/api/roots/[id]/dashboard/route.js.nft.json +1 -1
- package/.next/server/app/api/roots/[id]/dashboard/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/roots/[id]/suggestions/route.js +1 -1
- package/.next/server/app/api/roots/[id]/suggestions/route.js.nft.json +1 -1
- package/.next/server/app/api/roots/[id]/suggestions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/bundle.js/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/host/route.js +2 -2
- package/.next/server/app/api/utilities/[scope]/[id]/host/route.js.nft.json +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/host/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/host-api.mjs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/host-ui.mjs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/iframe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/utilities/[scope]/[id]/style.css/route_client-reference-manifest.js +1 -1
- package/.next/server/app/audit/page.js +2 -2
- package/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/server/app/onboarding/page.js +4 -4
- package/.next/server/app/onboarding/page.js.nft.json +1 -1
- package/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/roots/[id]/chat/[topicId]/page.js +2 -6
- package/.next/server/app/roots/[id]/chat/[topicId]/page.js.nft.json +1 -1
- package/.next/server/app/roots/[id]/chat/[topicId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/roots/[id]/kb/[...slug]/page.js +2 -6
- package/.next/server/app/roots/[id]/kb/[...slug]/page.js.nft.json +1 -1
- package/.next/server/app/roots/[id]/kb/[...slug]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/roots/[id]/page.js +3 -3
- package/.next/server/app/roots/[id]/page.js.nft.json +1 -1
- package/.next/server/app/roots/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/roots/[id]/workflows/[wfId]/page.js +2 -2
- package/.next/server/app/roots/[id]/workflows/[wfId]/page.js.nft.json +1 -1
- package/.next/server/app/roots/[id]/workflows/[wfId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/roots/[id]/workflows/page.js +2 -2
- package/.next/server/app/roots/[id]/workflows/page.js.nft.json +1 -1
- package/.next/server/app/roots/[id]/workflows/page_client-reference-manifest.js +1 -1
- package/.next/server/app/roots/new/page.js +4 -2
- package/.next/server/app/roots/new/page.js.nft.json +1 -1
- package/.next/server/app/roots/new/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/page.js +6 -6
- package/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/share/[id]/file/page.js +2 -2
- package/.next/server/app/share/[id]/file/page.js.nft.json +1 -1
- package/.next/server/app/share/[id]/file/page_client-reference-manifest.js +1 -1
- package/.next/server/app/share/[id]/page.js +2 -2
- package/.next/server/app/share/[id]/page.js.nft.json +1 -1
- package/.next/server/app/share/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/utilities/[scope]/[id]/page.js +2 -2
- package/.next/server/app/utilities/[scope]/[id]/page.js.nft.json +1 -1
- package/.next/server/app/utilities/[scope]/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/utilities/page.js +2 -17
- package/.next/server/app/utilities/page.js.nft.json +1 -1
- package/.next/server/app/utilities/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +9 -9
- package/.next/server/chunks/1223.js +1 -1
- package/.next/server/chunks/133.js +1 -490
- package/.next/server/chunks/1888.js +1 -1
- package/.next/server/chunks/{9739.js → 1988.js} +13 -9
- package/.next/server/chunks/2433.js +1 -1
- package/.next/server/chunks/2503.js +1 -1
- package/.next/server/chunks/285.js +471 -0
- package/.next/server/chunks/2959.js +1 -0
- package/.next/server/chunks/2995.js +1 -0
- package/.next/server/chunks/3240.js +1 -1
- package/.next/server/chunks/3332.js +1 -1
- package/.next/server/chunks/3657.js +1 -1
- package/.next/server/chunks/4066.js +1 -1
- package/.next/server/chunks/4438.js +1 -0
- package/.next/server/chunks/4514.js +3 -0
- package/.next/server/chunks/4553.js +1 -1
- package/.next/server/chunks/4812.js +179 -0
- package/.next/server/chunks/4925.js +1 -1
- package/.next/server/chunks/{3953.js → 5068.js} +2 -2
- package/.next/server/chunks/5319.js +1 -1
- package/.next/server/chunks/569.js +1 -1
- package/.next/server/chunks/6730.js +1 -1
- package/.next/server/chunks/6909.js +142 -161
- package/.next/server/chunks/8262.js +1 -1
- package/.next/server/chunks/9098.js +1 -1
- package/.next/server/chunks/94.js +1 -1
- package/.next/server/chunks/9427.js +1 -0
- package/.next/server/chunks/9538.js +1 -0
- package/.next/server/chunks/963.js +1 -0
- package/.next/server/chunks/9835.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +1 -2
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/2865-134f546f21ca4330.js +1 -0
- package/.next/static/chunks/4108.5abdb7812a13eafd.js +1 -0
- package/.next/static/chunks/5254-4196f25e56270de5.js +1 -0
- package/.next/static/chunks/5521-cbc665104c7e59d3.js +1 -0
- package/.next/static/chunks/6445-99824866a51b582a.js +1 -0
- package/.next/static/chunks/8855-9b941d2b78f398ce.js +1 -0
- package/.next/static/chunks/8871-2948840b33c0863d.js +1 -0
- package/.next/static/chunks/9411-af5f758c57741929.js +3 -0
- package/.next/static/chunks/app/agents/[agentId]/page-5d6f4cb16b42d02b.js +1 -0
- package/.next/static/chunks/app/layout-d4cf24375db6d793.js +1 -0
- package/.next/static/chunks/app/onboarding/page-7303664b62ccc24a.js +1 -0
- package/.next/static/chunks/app/page-97d312db91d569f7.js +1 -0
- package/.next/static/chunks/app/roots/[id]/chat/[topicId]/page-123f60a544619a3c.js +1 -0
- package/.next/static/chunks/app/roots/[id]/kb/[...slug]/page-e253597edb1b2440.js +1 -0
- package/.next/static/chunks/app/roots/[id]/page-91a8de6a1c79f8a3.js +1 -0
- package/.next/static/chunks/app/roots/[id]/workflows/[wfId]/page-4300a52e163883df.js +1 -0
- package/.next/static/chunks/app/roots/new/page-6b104aad46a38173.js +1 -0
- package/.next/static/chunks/app/settings/page-afe1b80f7f45c5eb.js +1 -0
- package/.next/static/chunks/app/share/[id]/page-a5fb565bd892d4df.js +1 -0
- package/.next/static/chunks/app/utilities/[scope]/[id]/page-eb713a2b5209942c.js +1 -0
- package/.next/static/chunks/app/utilities/page-b7f30c151c42a27c.js +1 -0
- package/.next/static/chunks/{webpack-5fca180586957874.js → webpack-bddc3babcbc30dd7.js} +1 -1
- package/.next/static/css/60e9b6cdf1283e83.css +1 -0
- package/.next/trace +47 -46
- package/dist/lib/reflex/agents/prompts.js +46 -46
- package/dist/lib/reflex/agents/prompts.js.map +1 -1
- package/dist/lib/reflex/prompts/defaults.js +102 -102
- package/next.config.ts +4 -1
- package/package.json +2 -2
- package/.next/server/app/_not-found.html +0 -1
- package/.next/server/app/_not-found.meta +0 -8
- package/.next/server/app/_not-found.rsc +0 -18
- package/.next/server/app/index.html +0 -1
- package/.next/server/app/index.meta +0 -9
- package/.next/server/app/index.rsc +0 -19
- package/.next/server/chunks/1410.js +0 -1
- package/.next/server/chunks/1986.js +0 -1
- package/.next/server/chunks/2448.js +0 -3
- package/.next/server/chunks/5754.js +0 -3
- package/.next/server/chunks/7097.js +0 -1
- package/.next/server/chunks/7782.js +0 -1
- package/.next/server/chunks/7987.js +0 -1
- package/.next/server/chunks/810.js +0 -1
- package/.next/server/chunks/8843.js +0 -1
- package/.next/server/chunks/9328.js +0 -179
- package/.next/server/pages/404.html +0 -1
- package/.next/static/chunks/2488-c9590facb4b9f184.js +0 -1
- package/.next/static/chunks/2684-257d38989ef53935.js +0 -1
- package/.next/static/chunks/4108.fb9f99a9c899ef54.js +0 -1
- package/.next/static/chunks/6231-d83c1544bbea8424.js +0 -1
- package/.next/static/chunks/9045-731ff0865352dd95.js +0 -1
- package/.next/static/chunks/9496-75ccd3fadb294fba.js +0 -1
- package/.next/static/chunks/992-4e7b7f722c629e21.js +0 -1
- package/.next/static/chunks/app/agents/[agentId]/page-0b5c2838354d0eba.js +0 -1
- package/.next/static/chunks/app/layout-9a59ed07c18cb786.js +0 -1
- package/.next/static/chunks/app/onboarding/page-79f07a813ea2abfe.js +0 -1
- package/.next/static/chunks/app/page-27f4b98b02ac4f79.js +0 -1
- package/.next/static/chunks/app/roots/[id]/chat/[topicId]/page-8db2d0b75cd333c8.js +0 -1
- package/.next/static/chunks/app/roots/[id]/kb/[...slug]/page-873b131eec3a2f30.js +0 -1
- package/.next/static/chunks/app/roots/[id]/page-270d0d49eb668784.js +0 -1
- package/.next/static/chunks/app/roots/[id]/workflows/[wfId]/page-7c1f10dbe0bcb9ad.js +0 -1
- package/.next/static/chunks/app/roots/new/page-ac1a9f6379710ca2.js +0 -1
- package/.next/static/chunks/app/settings/page-81cb1393e817dfc3.js +0 -1
- package/.next/static/chunks/app/share/[id]/page-2d123f0a99e1606f.js +0 -1
- package/.next/static/chunks/app/utilities/[scope]/[id]/page-0bbb8d17af80c1da.js +0 -1
- package/.next/static/chunks/app/utilities/page-e6ce673b9357bf1f.js +0 -1
- package/.next/static/css/87e01f779d555d04.css +0 -1
- package/packages/utilities/learn-anything/README.md +0 -41
- package/packages/utilities/learn-anything/actions/_json.ts +0 -191
- package/packages/utilities/learn-anything/actions/_store.ts +0 -248
- package/packages/utilities/learn-anything/actions/buildModule.ts +0 -487
- package/packages/utilities/learn-anything/actions/explainSelection.ts +0 -64
- package/packages/utilities/learn-anything/actions/generateOutline.ts +0 -170
- package/packages/utilities/learn-anything/actions/generateQuiz.ts +0 -72
- package/packages/utilities/learn-anything/actions/generateTrainer.ts +0 -106
- package/packages/utilities/learn-anything/actions/refreshCourseCard.ts +0 -76
- package/packages/utilities/learn-anything/actions/tutorAsk.ts +0 -93
- package/packages/utilities/learn-anything/article-view.tsx +0 -464
- package/packages/utilities/learn-anything/manifest.json +0 -42
- package/packages/utilities/learn-anything/ui.tsx +0 -1589
- /package/.next/static/{og_wC7UPkGtJDiapaTgBr → IGuuMcet1qtGZQCP2MEn4}/_buildManifest.js +0 -0
- /package/.next/static/{og_wC7UPkGtJDiapaTgBr → IGuuMcet1qtGZQCP2MEn4}/_ssgManifest.js +0 -0
|
@@ -4,7 +4,7 @@ Auto-generated index. Edit freely — Reflex only appends new entries below.
|
|
|
4
4
|
|
|
5
5
|
## Files
|
|
6
6
|
|
|
7
|
-
`}m+=l+"\n",await d.promises.writeFile(g,m,"utf8"),e.add(g)}}return[...e]}async function n(a,b,c){let e;try{e=await d.promises.readdir(b,{withFileTypes:!0})}catch{return}for(let g of e){if(g.isDirectory()){if(b===a&&j.has(g.name)||"utilities"===g.name)continue;await n(a,f().join(b,g.name),c);continue}if(!g.name.toLowerCase().endsWith(".md"))continue;let e=f().join(b,g.name);try{let a=await d.promises.stat(e);c.set(e,a.mtimeMs)}catch{}}}async function o(a){try{let b=await d.promises.readFile(a,"utf8");if(!b.startsWith("---"))return{};let c=h()(b).data,e={};return"string"==typeof c.title&&(e.title=c.title),"string"==typeof c.kind&&(e.kind=c.kind),e}catch{return{}}}async function p(a){try{return await d.promises.access(a),!0}catch{return!1}}},1701:(a,b,c)=>{c.d(b,{GC:()=>l,Mn:()=>m,az:()=>n});var d=c(73024),e=c(76760),f=c.n(e),g=c(29163);let h=f().join((0,g._)(),"pending-mcp-adds.json");async function i(){try{let a=await d.promises.readFile(h,"utf8"),b=JSON.parse(a);if(1!==b.version||!Array.isArray(b.entries))return{version:1,entries:[]};return b}catch{return{version:1,entries:[]}}}async function j(a){await d.promises.mkdir(f().dirname(h),{recursive:!0}),await d.promises.writeFile(h,JSON.stringify(a,null,2)+"\n",{encoding:"utf8",mode:384});try{await d.promises.chmod(h,384)}catch{}}function k(a){let b=Date.now()-2592e6;return{version:1,entries:a.entries.filter(a=>{let c=Date.parse(a.createdAt);return Number.isFinite(c)&&c>b})}}async function l(a){let b=k(await i());b.entries=b.entries.filter(b=>b.requestId!==a.requestId),b.entries.push({...a,createdAt:new Date().toISOString()}),await j(b)}async function m(){return k(await i()).entries}async function n(a){let b=k(await i()),c=b.entries.findIndex(b=>b.requestId===a);if(c<0)return null;let d=b.entries[c];return b.entries.splice(c,1),await j(b),d}},3613:(a,b,c)=>{c.d(b,{k:()=>m});var d=c(73024),e=c(76760),f=c.n(e),g=c(30192),h=c.n(g),i=c(29163);let j=f().join((0,i._)(),"skills"),k=[{id:"deep-research",title:"Deep research",description:"
|
|
7
|
+
`}m+=l+"\n",await d.promises.writeFile(g,m,"utf8"),e.add(g)}}return[...e]}async function n(a,b,c){let e;try{e=await d.promises.readdir(b,{withFileTypes:!0})}catch{return}for(let g of e){if(g.isDirectory()){if(b===a&&j.has(g.name)||"utilities"===g.name)continue;await n(a,f().join(b,g.name),c);continue}if(!g.name.toLowerCase().endsWith(".md"))continue;let e=f().join(b,g.name);try{let a=await d.promises.stat(e);c.set(e,a.mtimeMs)}catch{}}}async function o(a){try{let b=await d.promises.readFile(a,"utf8");if(!b.startsWith("---"))return{};let c=h()(b).data,e={};return"string"==typeof c.title&&(e.title=c.title),"string"==typeof c.kind&&(e.kind=c.kind),e}catch{return{}}}async function p(a){try{return await d.promises.access(a),!0}catch{return!1}}},1701:(a,b,c)=>{c.d(b,{GC:()=>l,Mn:()=>m,az:()=>n});var d=c(73024),e=c(76760),f=c.n(e),g=c(29163);let h=f().join((0,g._)(),"pending-mcp-adds.json");async function i(){try{let a=await d.promises.readFile(h,"utf8"),b=JSON.parse(a);if(1!==b.version||!Array.isArray(b.entries))return{version:1,entries:[]};return b}catch{return{version:1,entries:[]}}}async function j(a){await d.promises.mkdir(f().dirname(h),{recursive:!0}),await d.promises.writeFile(h,JSON.stringify(a,null,2)+"\n",{encoding:"utf8",mode:384});try{await d.promises.chmod(h,384)}catch{}}function k(a){let b=Date.now()-2592e6;return{version:1,entries:a.entries.filter(a=>{let c=Date.parse(a.createdAt);return Number.isFinite(c)&&c>b})}}async function l(a){let b=k(await i());b.entries=b.entries.filter(b=>b.requestId!==a.requestId),b.entries.push({...a,createdAt:new Date().toISOString()}),await j(b)}async function m(){return k(await i()).entries}async function n(a){let b=k(await i()),c=b.entries.findIndex(b=>b.requestId===a);if(c<0)return null;let d=b.entries[c];return b.entries.splice(c,1),await j(b),d}},3613:(a,b,c)=>{c.d(b,{k:()=>m});var d=c(73024),e=c(76760),f=c.n(e),g=c(30192),h=c.n(g),i=c(29163);let j=f().join((0,i._)(),"skills"),k=[{id:"deep-research",title:"Deep research",description:"Deep research with citations - web + KB, synthesis via researcher sub-agents.",author:"builtin",instructions:'## Skill: deep-research\n\nRun the investigation like a professional analyst:\n 1. First draft a short search plan: 3-5 key questions around the topic.\n 2. For each key question, dispatch a researcher sub-agent with a concrete brief and the expected output shape.\n 3. Once results come back, synthesize: what is confirmed, what conflicts, where the gaps are.\n 4. Cite sources with URL and date (when available). Never invent links.\n 5. At the end propose: (a) saving the key facts into KB (`<<reflex:kb>>` kind="research-note"), (b) assembling a news-list/link-list widget.\n 6. If data is thin - say so openly and suggest next steps.'},{id:"widget-builder",title:"Widget builder",description:"Widget-creation helper - suggests the kind and data format.",author:"builtin",instructions:"## Skill: widget-builder\n\nYou help design and assemble a widget:\n 1. Clarify via `<<reflex:question>>` the widget's purpose and audience (for me alone / for the team / a report).\n 2. Pick the optimal `kind` - justify the choice out loud (one line).\n 3. If the widget needs data, gather it via WebFetch/WebSearch/Read before emitting.\n 4. Emit exactly one `<<reflex:widget-create>>` marker, with a thoughtful `id` and `refresh` cadence.\n 5. Tell the user how to edit the widget (pencil icon -> this same topic)."},{id:"kb-curator",title:"KB curator",description:"Turns raw content into clean KB notes with the right kind and meta.",author:"builtin",instructions:"## Skill: kb-curator\n\nYou are the knowledge-base curator. Every input - note, fact, or link - becomes a tidy KB entry:\n 1. Determine the `kind` (fact | task | meeting | product | person | place | event | ...). If ambiguous - ask.\n 2. Title: 4-9 words, no quotes, no trailing period.\n 3. `meta`: put structured fields here (ISO dates, links, tags). Do NOT duplicate them in the body.\n 4. `body`: anything that didn't fit in meta - context, nuance, quotes with sources.\n 5. Emit a `<<reflex:kb>>` marker; do not write via Write - the manager places it in the correct folder.\n 6. If the entry adds to an existing topic - mention sibling files via @-mentions in chat (for context, not for the agent)."}];async function l(){let a;try{a=await d.promises.readdir(j,{withFileTypes:!0})}catch{return[]}let b=[];for(let c of a)if(c.isFile()&&c.name.toLowerCase().endsWith(".md"))try{let a=await d.promises.readFile(f().join(j,c.name),"utf8"),e=h()(a),g=e.data,i="string"==typeof g.id?g.id:null;if(!i)continue;b.push({id:i,title:"string"==typeof g.title?g.title:i,description:"string"==typeof g.description?g.description:"",author:"user",instructions:e.content.trim()})}catch{}return b}async function m(a){let b=(await l()).find(b=>b.id===a);return b||(k.find(b=>b.id===a)??null)}},5243:(a,b,c)=>{c.d(b,{addMcpServer:()=>r,getMcpServer:()=>q,listMcpServers:()=>p,updateMcpServer:()=>s});var d=c(73024),e=c(76760),f=c.n(e),g=c(14126),h=c(88124),i=c(29163);let j=f().join((0,i._)(),"mcp"),k=f().join(j,"servers.json"),l=g.Ik({id:g.Yj().min(1).max(64).regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/,"id must start with a letter; letters, digits, '_' and '-' allowed"),label:g.Yj().min(1).max(120),description:g.Yj().max(2e3).default(""),config:h.McpConfigSchema,addedAt:g.Yj(),lastVerifiedAt:g.Yj().optional()}),m=g.Ik({version:g.eu(1),servers:g.YO(l)});async function n(){try{let a=await d.promises.readFile(k,"utf8"),b=m.safeParse(JSON.parse(a));if(!b.success)return{version:1,servers:[]};return b.data}catch{return{version:1,servers:[]}}}async function o(a){await d.promises.mkdir(j,{recursive:!0}),await d.promises.writeFile(k,JSON.stringify(a,null,2)+"\n",{encoding:"utf8",mode:384});try{await d.promises.chmod(k,384)}catch{}}async function p(){return[...(await n()).servers].sort((a,b)=>a.id.localeCompare(b.id))}async function q(a){return(await n()).servers.find(b=>b.id===a)??null}async function r(a){let b=l.parse({id:a.id,label:a.label,description:a.description??"",config:a.config,addedAt:new Date().toISOString()}),c=await n();if(c.servers.some(a=>a.id===b.id))throw Error(`MCP server "${b.id}" already exists`);return c.servers.push(b),await o(c),b}async function s(a,b){let c=await n(),d=c.servers.findIndex(b=>b.id===a);if(d<0)throw Error(`MCP server "${a}" not found`);let e=l.parse({...c.servers[d],...b});return c.servers[d]=e,await o(c),e}},7188:(a,b,c)=>{c.d(b,{buildRecord:()=>w,iq:()=>p,listWidgets:()=>m,readLayout:()=>s,readWidget:()=>n,reconcileLayout:()=>u,writeLayout:()=>t,writeWidget:()=>o});var d=c(73024),e=c(76760),f=c.n(e),g=c(13474),h=c(11244);function i(a){return f().join((0,g.FF)(a),"widgets")}function j(a,b){return f().join(i(a),`${l(b)}.json`)}function k(a){return f().join((0,g.FF)(a),"dashboard-layout.json")}function l(a){return a.replace(/[^A-Za-z0-9_-]/g,"-").slice(0,80)}async function m(a){let b,c=i(a);try{b=await d.promises.readdir(c,{withFileTypes:!0})}catch{return[]}let e=[];for(let a of b)if(a.isFile()&&a.name.toLowerCase().endsWith(".json"))try{let b=await d.promises.readFile(f().join(c,a.name),"utf8"),g=JSON.parse(b);v(g)&&e.push(g)}catch{}return e}async function n(a,b){try{let c=await d.promises.readFile(j(a,b),"utf8"),e=JSON.parse(c);return v(e)?e:null}catch{return null}}async function o(a,b){if(!v(b))throw Error(`Invalid widget record (id=${b.id}, kind=${b.kind})`);await d.promises.mkdir(i(a),{recursive:!0}),await d.promises.writeFile(j(a,b.id),JSON.stringify(b,null,2)+"\n","utf8")}async function p(a,b){try{let c=(0,g.FF)(a),e=f().resolve(c,b),h=f().relative(c,e);if(h.startsWith("..")||f().isAbsolute(h))return null;return await d.promises.readFile(e,"utf8")}catch{return null}}let q={order:["sys:active-goals","sys:pending","sys:recent-kb","sys:ai-suggestions"],hidden:[],sizes:{}},r=new Set(["sm","md","wide"]);async function s(a){try{let b=await d.promises.readFile(k(a),"utf8"),c=JSON.parse(b);if(!Array.isArray(c.order)||!Array.isArray(c.hidden))return q;let e={};if(c.sizes&&"object"==typeof c.sizes)for(let[a,b]of Object.entries(c.sizes))"string"==typeof b&&r.has(b)&&(e[a]=b);return{order:c.order.filter(a=>"string"==typeof a),hidden:c.hidden.filter(a=>"string"==typeof a),sizes:e}}catch{return q}}async function t(a,b){await d.promises.mkdir((0,g.FF)(a),{recursive:!0}),await d.promises.writeFile(k(a),JSON.stringify(b,null,2)+"\n","utf8")}function u(a,b,c){let d=new Set([...b,...c]),e=a.order.filter(a=>d.has(a)),f=a.hidden.filter(a=>d.has(a)),g=new Set([...e,...f]);for(let a of[...c,...b])g.has(a)||e.push(a);let h={};if(a.sizes)for(let[b,c]of Object.entries(a.sizes))d.has(b)&&(h[b]=c);return{order:e,hidden:f,sizes:h}}function v(a){return!!a&&"object"==typeof a&&"string"==typeof a.id&&!!a.id&&"string"==typeof a.title&&"string"==typeof a.kind&&!!h.hU.includes(a.kind)&&!!a.data&&"object"==typeof a.data&&"string"==typeof a.createdAt&&"string"==typeof a.updatedAt&&!0}function w(a){let b=new Date().toISOString(),c=l(a.id);if(!c)throw Error("Widget id is empty after sanitization");if(!h.hU.includes(a.payload.kind))throw Error(`Unknown widget kind: ${a.payload.kind}`);let d=a.refresh??a.existing?.refresh,e=a.memory??a.existing?.memory,f=a.memoryFile??a.existing?.memoryFile,g=a.lastRefreshAt??a.existing?.lastRefreshAt;return{id:c,title:a.title||c,...a.description?{description:a.description}:{},...a.sourceTopicId?{sourceTopicId:a.sourceTopicId}:{},kind:a.payload.kind,data:a.payload.data,createdAt:a.existing?.createdAt??b,updatedAt:b,...a.size?{size:a.size}:a.existing?.size?{size:a.existing.size}:{},...d?{refresh:d}:{},...void 0!==e?{memory:e}:{},...f?{memoryFile:f}:{},...g?{lastRefreshAt:g}:{}}}},8734:(a,b,c)=>{c.d(b,{$4:()=>f,FB:()=>g,GX:()=>l,YE:()=>k,dA:()=>h,vl:()=>j,wr:()=>e,wt:()=>i});var d=c(25608);function e(a){let b=(0,d.dr)(a);return b&&("plan"===b.def.id||"goal"===b.def.id)?{kind:b.def.id,text:b.payload}:null}function f(a){return`## /plan — Plan-first mode
|
|
8
8
|
|
|
9
9
|
Reply in ${a}. **Before doing anything**, lay out a clear, numbered step-by-step plan. Each step should be concrete and verifiable.
|
|
10
10
|
|
|
@@ -35,7 +35,7 @@ Workflow each turn:
|
|
|
35
35
|
|
|
36
36
|
GOAL ACHIEVED
|
|
37
37
|
|
|
38
|
-
If you genuinely need user input mid-flight (clarification, permission for a risky action, missing data), pause via <<reflex:question>> or <<reflex:permission>>. Those markers stop auto-continuation; everything else keeps the loop going.`}function h(a,b){return["## /research — Deep research mode (this turn)","",`Reply in ${b}.`,a?`Тема: ${a}`:"","","Подход:"," 1. Делегируй основной поиск sub-агенту с ролью `researcher` через `<<reflex:dispatch>>` (одним маркером — он сам пройдётся по web + KB)."," 2. Если возможно — несколько researcher'ов параллельно с разными углами (например: \xabистория\xbb, \xabтекущее состояние\xbb, \xabкритика\xbb)."," 3. Дождись результатов, **компонуй синтез**: сходства, разногласия, белые пятна. Цитируй источники со ссылками.",' 4. В конце предложи сохранить ключевые факты в KB маркером `<<reflex:kb>>` (kind="research-note") — но дождись подтверждения.'," 5. Если тема глубокая — предложи виджет `news-list` или `link-list` через `<<reflex:widget-create>>`.","","Не отвечай из памяти модели — гони через WebSearch/WebFetch."].filter(Boolean).join("\n")}function i(a,b){return["## /widget — Создание виджета на дашборде","",`Reply in ${b}.`,a?`Запрос пользователя: ${a}`:"","","Правила:"," 1. Выбери подходящий `kind` (см. блок про widgets в системном промпте). Если запрос неоднозначный — спроси через `<<reflex:question>>`."," 2. Подбери стабильный kebab-case `id`, который потом можно будет переиспользовать для widget-update."," 3. Если нужны актуальные данные (новости, цены, статусы) — собери через WebSearch/WebFetch перед эмитом."," 4. Эмить **один** `<<reflex:widget-create>>` маркер в этом ходе, потом коротко расскажи пользователю что появилось на дашборде.",' 5. Если виджет имеет смысл авто-обновлять — поставь `refresh: "hourly"|"daily"|"weekly"` и опиши `memory` для дедупа/истории.'].filter(Boolean).join("\n")}function j(a,b){return["## /workflow — Сборка workflow (n8n-style линейный рецепт)","",`Reply in ${b}.`,a?`Запрос пользователя: ${a}`:"","","Правила:"," 1. Если задача неоднозначная (что входит, куда писать, как часто) — задай 1-3 уточняющих вопроса через `<<reflex:question>>` ОДНИМ блоком. Не угадывай."," 2. Шаги КОРОТКИЕ (3-5). Поддерживаемые типы: `text-template`, `http-request`, `web-fetch`, `ask-agent`, `kb-write`. Если задача шире — разбей на несколько workflows."," 3. `id` каждого шага — стабильный kebab-case (его используют шаблоны: `{{steps.<id>.output}}`)."," 4. Trigger по умолчанию `manual`. `hourly/daily/weekly` ставь, только если пользователь явно попросил периодичность."," 5. Эмить **один** `<<reflex:workflow-create>>` маркер в этом ходе. Не дублируй JSON в текст — карточка превью отрендерится в чате автоматически."," 6. После маркера — короткий план словами: что workflow делает по шагам, как запустить, что появится в результате."].filter(Boolean).join("\n")}function k(a,b){return["## /mcp — Подключение MCP-сервера","",`Reply in ${b}.`,a?`Запрос: ${a}`:"Пользователь хочет подключить MCP-сервер, но не уточнил какой.","","Действуй как MCP-визард:"," 1. Если запрос конкретный (например \xabgithub mcp\xbb, \xabnotion\xbb) — сразу подбери конфиг и предложи через `<<reflex:mcp-add>>`. Не забудь про secrets-слоты с описанием где взять токен."," 2. Если запрос абстрактный — спроси через `<<reflex:question>>` что нужно подключить (Notion / Slack / GitHub / Linear / другое)."," 3. Если речь о существующем сервере — попроси использовать его инструменты, не предлагай add-карточку повторно."].filter(Boolean).join("\n")}let l=15},11244:(a,b,c)=>{c.d(b,{SYSTEM_WIDGET_IDS:()=>e,VQ:()=>d,hU:()=>f});let d={hourly:36e5,daily:864e5,weekly:6048e5},e=["sys:active-goals","sys:pending","sys:recent-kb","sys:ai-suggestions"],f=["markdown","news-list","link-list","kpi","checklist","quote","kb-pinned","progress","image","stat-table","map","utility-card"]},13295:(a,b,c)=>{c.d(b,{bp:()=>o,listWorkflows:()=>l,lq:()=>q,ni:()=>k,r$:()=>n,readWorkflow:()=>m,v:()=>p});var d=c(73024),e=c(76760),f=c.n(e),g=c(13474);function h(a){return f().join((0,g.FF)(a),"workflows")}function i(a,b){return f().join(h(a),`${k(b)}.json`)}function j(a,b){return f().join(h(a),"runs",k(b))}function k(a){return a.replace(/[^A-Za-z0-9_-]/g,"-").slice(0,80)}async function l(a){let b,c=h(a);try{b=await d.promises.readdir(c,{withFileTypes:!0})}catch{return[]}let e=[];for(let a of b)if(a.isFile()&&a.name.toLowerCase().endsWith(".json"))try{let b=await d.promises.readFile(f().join(c,a.name),"utf8"),g=JSON.parse(b);r(g)&&e.push(g)}catch{}return e.sort((a,b)=>a.updatedAt<b.updatedAt?1:-1),e}async function m(a,b){try{let c=await d.promises.readFile(i(a,b),"utf8"),e=JSON.parse(c);return r(e)?e:null}catch{return null}}async function n(a,b){if(!r(b))throw Error(`Invalid workflow (id=${b.id})`);await d.promises.mkdir(h(a),{recursive:!0}),await d.promises.writeFile(i(a,b.id),JSON.stringify(b,null,2)+"\n","utf8")}async function o(a,b){var c,e;await d.promises.mkdir(j(a,b.workflowId),{recursive:!0}),await d.promises.writeFile((c=b.workflowId,e=b.id,f().join(j(a,c),`${k(e)}.json`)),JSON.stringify(b,null,2)+"\n","utf8")}async function p(a,b,c=20){let e,g=j(a,b);try{e=await d.promises.readdir(g,{withFileTypes:!0})}catch{return[]}let h=(await Promise.all(e.filter(a=>a.isFile()&&a.name.toLowerCase().endsWith(".json")).map(async a=>{let b=f().join(g,a.name);try{let a=await d.promises.stat(b);return{abs:b,mtime:a.mtimeMs}}catch{return null}}))).filter(a=>null!==a).sort((a,b)=>b.mtime-a.mtime).slice(0,c),i=[];for(let a of h)try{let b=await d.promises.readFile(a.abs,"utf8");i.push(JSON.parse(b))}catch{}return i}async function q(a,b){let c,e=j(a,b);try{c=await d.promises.readdir(e,{withFileTypes:!0})}catch{return}for(let a of(await Promise.all(c.filter(a=>a.isFile()&&a.name.toLowerCase().endsWith(".json")).map(async a=>{let b=f().join(e,a.name);try{let a=await d.promises.stat(b);return{abs:b,mtime:a.mtimeMs}}catch{return null}}))).filter(a=>null!==a).sort((a,b)=>b.mtime-a.mtime).slice(50))await d.promises.unlink(a.abs).catch(()=>void 0)}function r(a){return!!a&&"object"==typeof a&&"string"==typeof a.id&&!!a.id&&"string"==typeof a.label&&!!Array.isArray(a.steps)&&"string"==typeof a.createdAt&&"string"==typeof a.updatedAt}},16909:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{z:()=>G});var e=c(78474),f=c(77598),g=c(74342),h=c(25713),i=c(22830),j=c(47423),k=c(96931),l=c(23956),m=c(59835),n=c(7188),o=c(13295),p=c(24058),q=c(49353),r=c(911),s=c(1701),t=c(35053),u=c(61105),v=c(17640),w=c(56843),x=c(8734),y=c(24776),z=a([h,p]);[h,p]=z.then?(await z)():z;class E{async ensureAgent(a){let b=this.byTopicRole.get(a.topicId)?.get(a.role);if(b){let a=this.agents.get(b);if(a)return{...a.meta}}return this.createAgent(a)}async createAgent(a){let b=C(),c={id:b,topicId:a.topicId,rootId:a.rootId,role:a.role,task:a.task,harness:a.harness,model:a.model,label:a.label,status:"idle",startedAt:A(),...a.parentId?{parentId:a.parentId}:{}};this.agents.set(b,{meta:c,rootPath:a.rootPath,reflexScope:a.reflexScope});let d=this.byTopicRole.get(a.topicId);return d||(d=new Map,this.byTopicRole.set(a.topicId,d)),d.set(a.role,b),await this.emit({type:"agent-start",meta:c,agentId:b,ts:c.startedAt,seq:0}),c}async invoke(a){let b=this.agents.get(a.agentId);if(!b)throw Error(`Agent not found: ${a.agentId}`);if("running"===b.meta.status)throw Error(`Agent ${a.agentId} is already running`);b.meta.status="running",this.lastInvoke.set(a.agentId,{systemPrompt:a.systemPrompt,rootPath:b.rootPath}),this.turnText.set(a.agentId,"");let c=C();a.userMessage&&await this.emit({type:"user-message",text:a.userMessage,agentId:a.agentId,ts:A(),seq:0}),await this.emit({type:"turn-start",turnId:c,agentId:a.agentId,ts:A(),seq:0});let d=null;try{d=await (0,r.Qr)(b.rootPath)}catch{}try{let e={meta:{id:b.meta.id},args:{rootPath:b.rootPath,reflexScope:b.reflexScope,systemPrompt:a.systemPrompt,prompt:a.prompt,model:b.meta.model,allowedTools:a.allowedTools??[]},manager:this};if("claude-code"===b.meta.harness)await (0,h.Z)(e);else if("codex"===b.meta.harness)await (0,i.H)(e);else if("ollama"===b.meta.harness)await (0,j.E)(e);else if("image-gen"===b.meta.harness)await (0,k.R)({meta:e.meta,args:{rootPath:e.args.rootPath,prompt:e.args.prompt},manager:e.manager});else throw Error(`Unsupported harness: ${String(b.meta.harness)}`);await this.applyImageGenDirectives(a.agentId);let f=await this.evaluateGoalContinuation(a.agentId);b.meta.status="idle",await this.emit({type:"turn-end",turnId:c,status:"completed",agentId:a.agentId,ts:A(),seq:0});let{writtenViaKb:g,dispatches:l,youtubeSummaries:m}=await this.detectInteractionDirectives(a.agentId);d&&await this.reindexAfterTurn(a.agentId,d,g),l.length>0&&"orchestrator"===b.meta.role?this.dispatchSubAgents(a.agentId,l).catch(b=>{this.emit({type:"error",message:"sub-agent dispatch failed: "+(b instanceof Error?b.message:String(b)),agentId:a.agentId,ts:A(),seq:0})}):m.length>0&&"orchestrator"===b.meta.role?this.runYoutubeSummaries(a.agentId,m).catch(b=>{this.emit({type:"error",message:"youtube-summary failed: "+(b instanceof Error?b.message:String(b)),agentId:a.agentId,ts:A(),seq:0})}):f&&setTimeout(()=>{this.continueTurn(a.agentId,`[Reflex /goal] Продолжай выполнение. Активная цель: ${f.goal}. Итерация ${f.iteration}/${x.GX}. Если задача завершена И проверена — закончи маркером \`GOAL ACHIEVED\` и kb-записью kind:"goal-completion".`)},50)}catch(e){let d=e instanceof Error?e.message:String(e);b.meta.status="idle",b.meta.error=d,await this.emit({type:"error",message:d,agentId:a.agentId,ts:A(),seq:0}),await this.emit({type:"turn-end",turnId:c,status:"failed",error:d,agentId:a.agentId,ts:A(),seq:0})}finally{this.turnText.delete(a.agentId)}}async respondPermission(a,b){let c,d=this.agents.get(a);if(!d)throw Error("Agent not found");let e="running"===d.meta.status;try{let a=(await (0,g.wj)(d.rootPath,d.meta.topicId)).find(a=>"permission-request"===a.type&&a.requestId===b.requestId);c=a?.action}catch{}await this.emit({type:"permission-response",requestId:b.requestId,decision:b.decision,...b.scope?{scope:b.scope}:{},agentId:a,ts:A(),seq:0});let f="";if("tool-policy"===c&&"allow"===b.decision&&b.tool)try{let a=await (0,v.M)(),c=d.meta.task,e=a.assignments[c];e&&!e.allowedTools.includes(b.tool)&&(e.allowedTools=[...e.allowedTools,b.tool],await (0,v.D)(a),f=` Инструмент ${b.tool} добавлен в settings.assignments.${c}.allowedTools.`)}catch(b){await this.emit({type:"error",message:"Не удалось сохранить разрешённый инструмент: "+(b instanceof Error?b.message:String(b)),agentId:a,ts:A(),seq:0})}let h=`[Reflex] Permission for ${b.tool??"action"} (${b.requestId}): ${b.decision}${b.scope?` (${b.scope})`:""}.${f} Continue.`;e||await this.continueTurn(a,h)}async respondQuestion(a,b){let c=this.agents.get(a);if(!c)throw Error("Agent not found");let d="running"===c.meta.status;await this.emit({type:"answer",questionId:b.questionId,answer:b.answer,agentId:a,ts:A(),seq:0});let e=`[Reflex] Answer for question ${b.questionId}: ${b.answer}. Continue.`;d||await this.continueTurn(a,e)}async respondMcpAdd(a,b){let d,e=this.agents.get(a),f=!!(e&&"running"===e.meta.status),h=null,i=e?.meta.topicId??null,j=e?.rootPath??null,k=this.pendingMcpAdds.get(b.requestId);if(k&&k.agentId===a)h=k.directive,this.pendingMcpAdds.delete(b.requestId);else{let a=await (0,s.az)(b.requestId);a&&(h=a.directive,i=i??a.topicId,j=j??a.rootPath)}if(!h)throw Error(`Unknown mcp-add request: ${b.requestId}`);let l=async a=>{if(e)return void await this.emit(a);if(i&&j){let b=await (0,g.v)(j,i);await (0,g.Zn)(j,i,{...a,seq:b})}};if("reject"===b.decision){await l({type:"mcp-add-response",requestId:b.requestId,decision:"reject",agentId:a,ts:A(),seq:0}),d=`[Reflex] User rejected adding MCP server "${h.server}". Don't re-propose the same server — either pick a different approach or ask the user what they prefer.`,e&&!f&&await this.continueTurn(a,d);return}try{let e=await B(h.config,h.secrets??[],b.secretValues??{}),{McpConfigSchema:f}=await Promise.resolve().then(c.bind(c,88124)),g=f.parse(e),{addMcpServer:i,updateMcpServer:j,getMcpServer:k}=await Promise.resolve().then(c.bind(c,5243));await k(h.server)?await j(h.server,{label:h.label,...void 0!==h.description?{description:h.description}:{},config:g}):await i({id:h.server,label:h.label,...void 0!==h.description?{description:h.description}:{},config:g}),await l({type:"mcp-add-response",requestId:b.requestId,decision:"approve",server:h.server,agentId:a,ts:A(),seq:0}),d=`[Reflex] MCP server "${h.server}" registered. You can now call its tools via \`mcp__${h.server}__<tool>\` (chat) or \`reflex.mcp.call({server:"${h.server}",tool,args})\` (from a utility that declared it in manifest.mcpServers). Continue.`}catch(e){let c=e instanceof Error?e.message:String(e);await l({type:"error",message:"mcp-add failed: "+c,agentId:a,ts:A(),seq:0}),await l({type:"mcp-add-response",requestId:b.requestId,decision:"reject",agentId:a,ts:A(),seq:0}),d=`[Reflex] Failed to register MCP server "${h.server}": ${c}. Don't retry the exact same config; either fix the issue or ask the user.`}e&&!f&&await this.continueTurn(a,d)}async continueTurn(a,b){let c=this.agents.get(a);if(!c)return;let d=this.lastInvoke.get(a);if(!d)return void await this.emit({type:"error",message:"Cannot continue turn: no cached system prompt. Send another message manually.",agentId:a,ts:A(),seq:0});let e=[];try{let a=await (0,v.M)();e=a.assignments[c.meta.task]?.allowedTools??[]}catch{}let f=await D(d.rootPath,c.meta.topicId),g=`Prior conversation:
|
|
38
|
+
If you genuinely need user input mid-flight (clarification, permission for a risky action, missing data), pause via <<reflex:question>> or <<reflex:permission>>. Those markers stop auto-continuation; everything else keeps the loop going.`}function h(a,b){return["## /research — Deep research mode (this turn)","",`Reply in ${b}.`,a?`Topic: ${a}`:"","","Approach:"," 1. Delegate the main search to a sub-agent with role `researcher` via `<<reflex:dispatch>>` (one marker — it will sweep web + KB on its own).",' 2. If possible — multiple researchers in parallel with different angles (e.g. "history", "current state", "criticism").'," 3. Wait for results, **compose a synthesis**: similarities, disagreements, blind spots. Cite sources with links.",' 4. At the end, propose saving key facts to the KB via the `<<reflex:kb>>` marker (kind="research-note") — but wait for confirmation.'," 5. If the topic is deep — propose a `news-list` or `link-list` widget via `<<reflex:widget-create>>`.","","Don't answer from model memory — drive everything through WebSearch/WebFetch."].filter(Boolean).join("\n")}function i(a,b){return["## /widget — Create a dashboard widget","",`Reply in ${b}.`,a?`User request: ${a}`:"","","Rules:"," 1. Pick the appropriate `kind` (see the widgets block in the system prompt). If the request is ambiguous — ask via `<<reflex:question>>`."," 2. Pick a stable kebab-case `id` that can later be reused for widget-update."," 3. If you need fresh data (news, prices, statuses) — gather it via WebSearch/WebFetch before emitting."," 4. Emit **one** `<<reflex:widget-create>>` marker in this turn, then briefly tell the user what appeared on the dashboard.",' 5. If the widget makes sense to auto-refresh — set `refresh: "hourly"|"daily"|"weekly"` and describe `memory` for dedup/history.'].filter(Boolean).join("\n")}function j(a,b){return["## /workflow — Build a workflow (n8n-style linear recipe)","",`Reply in ${b}.`,a?`User request: ${a}`:"","","Rules:"," 1. If the task is ambiguous (what's included, where to write, how often) — ask 1-3 clarifying questions via `<<reflex:question>>` in a SINGLE block. Don't guess."," 2. Steps are SHORT (3-5). Supported kinds: `text-template`, `http-request`, `web-fetch`, `ask-agent`, `kb-write`. If the task is broader — split it into multiple workflows."," 3. Each step's `id` is stable kebab-case (templates use it: `{{steps.<id>.output}}`)."," 4. Trigger defaults to `manual`. Set `hourly/daily/weekly` only if the user explicitly asked for a schedule."," 5. Emit **one** `<<reflex:workflow-create>>` marker in this turn. Don't duplicate the JSON in text — the preview card renders in chat automatically."," 6. After the marker — a short plan in words: what the workflow does step by step, how to run it, what appears as the result."].filter(Boolean).join("\n")}function k(a,b){return["## /mcp — Connect an MCP server","",`Reply in ${b}.`,a?`Request: ${a}`:"The user wants to connect an MCP server but didn't specify which one.","","Act as an MCP wizard:",' 1. If the request is concrete (e.g. "github mcp", "notion") — pick a config right away and propose it via `<<reflex:mcp-add>>`. Don\'t forget secrets slots with a description of where to get the token.'," 2. If the request is abstract — ask via `<<reflex:question>>` what to connect (Notion / Slack / GitHub / Linear / other)."," 3. If it's about an existing server — ask the user to use its tools; don't propose the add card again."].filter(Boolean).join("\n")}let l=15},11244:(a,b,c)=>{c.d(b,{SYSTEM_WIDGET_IDS:()=>e,VQ:()=>d,hU:()=>f});let d={hourly:36e5,daily:864e5,weekly:6048e5},e=["sys:active-goals","sys:pending","sys:recent-kb","sys:ai-suggestions"],f=["markdown","news-list","link-list","kpi","checklist","quote","kb-pinned","progress","image","stat-table","map","utility-card"]},13295:(a,b,c)=>{c.d(b,{bp:()=>o,listWorkflows:()=>l,lq:()=>q,ni:()=>k,r$:()=>n,readWorkflow:()=>m,v:()=>p});var d=c(73024),e=c(76760),f=c.n(e),g=c(13474);function h(a){return f().join((0,g.FF)(a),"workflows")}function i(a,b){return f().join(h(a),`${k(b)}.json`)}function j(a,b){return f().join(h(a),"runs",k(b))}function k(a){return a.replace(/[^A-Za-z0-9_-]/g,"-").slice(0,80)}async function l(a){let b,c=h(a);try{b=await d.promises.readdir(c,{withFileTypes:!0})}catch{return[]}let e=[];for(let a of b)if(a.isFile()&&a.name.toLowerCase().endsWith(".json"))try{let b=await d.promises.readFile(f().join(c,a.name),"utf8"),g=JSON.parse(b);r(g)&&e.push(g)}catch{}return e.sort((a,b)=>a.updatedAt<b.updatedAt?1:-1),e}async function m(a,b){try{let c=await d.promises.readFile(i(a,b),"utf8"),e=JSON.parse(c);return r(e)?e:null}catch{return null}}async function n(a,b){if(!r(b))throw Error(`Invalid workflow (id=${b.id})`);await d.promises.mkdir(h(a),{recursive:!0}),await d.promises.writeFile(i(a,b.id),JSON.stringify(b,null,2)+"\n","utf8")}async function o(a,b){var c,e;await d.promises.mkdir(j(a,b.workflowId),{recursive:!0}),await d.promises.writeFile((c=b.workflowId,e=b.id,f().join(j(a,c),`${k(e)}.json`)),JSON.stringify(b,null,2)+"\n","utf8")}async function p(a,b,c=20){let e,g=j(a,b);try{e=await d.promises.readdir(g,{withFileTypes:!0})}catch{return[]}let h=(await Promise.all(e.filter(a=>a.isFile()&&a.name.toLowerCase().endsWith(".json")).map(async a=>{let b=f().join(g,a.name);try{let a=await d.promises.stat(b);return{abs:b,mtime:a.mtimeMs}}catch{return null}}))).filter(a=>null!==a).sort((a,b)=>b.mtime-a.mtime).slice(0,c),i=[];for(let a of h)try{let b=await d.promises.readFile(a.abs,"utf8");i.push(JSON.parse(b))}catch{}return i}async function q(a,b){let c,e=j(a,b);try{c=await d.promises.readdir(e,{withFileTypes:!0})}catch{return}for(let a of(await Promise.all(c.filter(a=>a.isFile()&&a.name.toLowerCase().endsWith(".json")).map(async a=>{let b=f().join(e,a.name);try{let a=await d.promises.stat(b);return{abs:b,mtime:a.mtimeMs}}catch{return null}}))).filter(a=>null!==a).sort((a,b)=>b.mtime-a.mtime).slice(50))await d.promises.unlink(a.abs).catch(()=>void 0)}function r(a){return!!a&&"object"==typeof a&&"string"==typeof a.id&&!!a.id&&"string"==typeof a.label&&!!Array.isArray(a.steps)&&"string"==typeof a.createdAt&&"string"==typeof a.updatedAt}},16909:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{z:()=>G});var e=c(78474),f=c(77598),g=c(74342),h=c(25713),i=c(22830),j=c(47423),k=c(96931),l=c(23956),m=c(59835),n=c(7188),o=c(13295),p=c(24058),q=c(49353),r=c(911),s=c(1701),t=c(35053),u=c(61105),v=c(17640),w=c(56843),x=c(8734),y=c(24776),z=a([h,p]);[h,p]=z.then?(await z)():z;class E{async ensureAgent(a){let b=this.byTopicRole.get(a.topicId)?.get(a.role);if(b){let a=this.agents.get(b);if(a)return{...a.meta}}return this.createAgent(a)}async createAgent(a){let b=C(),c={id:b,topicId:a.topicId,rootId:a.rootId,role:a.role,task:a.task,harness:a.harness,model:a.model,label:a.label,status:"idle",startedAt:A(),...a.parentId?{parentId:a.parentId}:{}};this.agents.set(b,{meta:c,rootPath:a.rootPath,reflexScope:a.reflexScope});let d=this.byTopicRole.get(a.topicId);return d||(d=new Map,this.byTopicRole.set(a.topicId,d)),d.set(a.role,b),await this.emit({type:"agent-start",meta:c,agentId:b,ts:c.startedAt,seq:0}),c}async invoke(a){let b=this.agents.get(a.agentId);if(!b)throw Error(`Agent not found: ${a.agentId}`);if("running"===b.meta.status)throw Error(`Agent ${a.agentId} is already running`);b.meta.status="running",this.lastInvoke.set(a.agentId,{systemPrompt:a.systemPrompt,rootPath:b.rootPath}),this.turnText.set(a.agentId,"");let c=C();a.userMessage&&await this.emit({type:"user-message",text:a.userMessage,agentId:a.agentId,ts:A(),seq:0}),await this.emit({type:"turn-start",turnId:c,agentId:a.agentId,ts:A(),seq:0});let d=null;try{d=await (0,r.Qr)(b.rootPath)}catch{}try{let e={meta:{id:b.meta.id},args:{rootPath:b.rootPath,reflexScope:b.reflexScope,systemPrompt:a.systemPrompt,prompt:a.prompt,model:b.meta.model,allowedTools:a.allowedTools??[]},manager:this};if("claude-code"===b.meta.harness)await (0,h.Z)(e);else if("codex"===b.meta.harness)await (0,i.H)(e);else if("ollama"===b.meta.harness)await (0,j.E)(e);else if("image-gen"===b.meta.harness)await (0,k.R)({meta:e.meta,args:{rootPath:e.args.rootPath,prompt:e.args.prompt},manager:e.manager});else throw Error(`Unsupported harness: ${String(b.meta.harness)}`);await this.applyImageGenDirectives(a.agentId);let f=await this.evaluateGoalContinuation(a.agentId);b.meta.status="idle",await this.emit({type:"turn-end",turnId:c,status:"completed",agentId:a.agentId,ts:A(),seq:0});let{writtenViaKb:g,dispatches:l,youtubeSummaries:m}=await this.detectInteractionDirectives(a.agentId);d&&await this.reindexAfterTurn(a.agentId,d,g),l.length>0&&"orchestrator"===b.meta.role?this.dispatchSubAgents(a.agentId,l).catch(b=>{this.emit({type:"error",message:"sub-agent dispatch failed: "+(b instanceof Error?b.message:String(b)),agentId:a.agentId,ts:A(),seq:0})}):m.length>0&&"orchestrator"===b.meta.role?this.runYoutubeSummaries(a.agentId,m).catch(b=>{this.emit({type:"error",message:"youtube-summary failed: "+(b instanceof Error?b.message:String(b)),agentId:a.agentId,ts:A(),seq:0})}):f&&setTimeout(()=>{this.continueTurn(a.agentId,`[Reflex /goal] Continue execution. Active goal: ${f.goal}. Iteration ${f.iteration}/${x.GX}. If the task is done AND verified, finish with the marker \`GOAL ACHIEVED\` and a kb-entry kind:"goal-completion".`)},50)}catch(e){let d=e instanceof Error?e.message:String(e);b.meta.status="idle",b.meta.error=d,await this.emit({type:"error",message:d,agentId:a.agentId,ts:A(),seq:0}),await this.emit({type:"turn-end",turnId:c,status:"failed",error:d,agentId:a.agentId,ts:A(),seq:0})}finally{this.turnText.delete(a.agentId)}}async respondPermission(a,b){let c,d=this.agents.get(a);if(!d)throw Error("Agent not found");let e="running"===d.meta.status;try{let a=(await (0,g.wj)(d.rootPath,d.meta.topicId)).find(a=>"permission-request"===a.type&&a.requestId===b.requestId);c=a?.action}catch{}await this.emit({type:"permission-response",requestId:b.requestId,decision:b.decision,...b.scope?{scope:b.scope}:{},agentId:a,ts:A(),seq:0});let f="";if("tool-policy"===c&&"allow"===b.decision&&b.tool)try{let a=await (0,v.M)(),c=d.meta.task,e=a.assignments[c];e&&!e.allowedTools.includes(b.tool)&&(e.allowedTools=[...e.allowedTools,b.tool],await (0,v.D)(a),f=` Tool ${b.tool} added to settings.assignments.${c}.allowedTools.`)}catch(b){await this.emit({type:"error",message:"Failed to save allowed tool: "+(b instanceof Error?b.message:String(b)),agentId:a,ts:A(),seq:0})}let h=`[Reflex] Permission for ${b.tool??"action"} (${b.requestId}): ${b.decision}${b.scope?` (${b.scope})`:""}.${f} Continue.`;e||await this.continueTurn(a,h)}async respondQuestion(a,b){let c=this.agents.get(a);if(!c)throw Error("Agent not found");let d="running"===c.meta.status;await this.emit({type:"answer",questionId:b.questionId,answer:b.answer,agentId:a,ts:A(),seq:0});let e=`[Reflex] Answer for question ${b.questionId}: ${b.answer}. Continue.`;d||await this.continueTurn(a,e)}async respondMcpAdd(a,b){let d,e=this.agents.get(a),f=!!(e&&"running"===e.meta.status),h=null,i=e?.meta.topicId??null,j=e?.rootPath??null,k=this.pendingMcpAdds.get(b.requestId);if(k&&k.agentId===a)h=k.directive,this.pendingMcpAdds.delete(b.requestId);else{let a=await (0,s.az)(b.requestId);a&&(h=a.directive,i=i??a.topicId,j=j??a.rootPath)}if(!h)throw Error(`Unknown mcp-add request: ${b.requestId}`);let l=async a=>{if(e)return void await this.emit(a);if(i&&j){let b=await (0,g.v)(j,i);await (0,g.Zn)(j,i,{...a,seq:b})}};if("reject"===b.decision){await l({type:"mcp-add-response",requestId:b.requestId,decision:"reject",agentId:a,ts:A(),seq:0}),d=`[Reflex] User rejected adding MCP server "${h.server}". Don't re-propose the same server — either pick a different approach or ask the user what they prefer.`,e&&!f&&await this.continueTurn(a,d);return}try{let e=await B(h.config,h.secrets??[],b.secretValues??{}),{McpConfigSchema:f}=await Promise.resolve().then(c.bind(c,88124)),g=f.parse(e),{addMcpServer:i,updateMcpServer:j,getMcpServer:k}=await Promise.resolve().then(c.bind(c,5243));await k(h.server)?await j(h.server,{label:h.label,...void 0!==h.description?{description:h.description}:{},config:g}):await i({id:h.server,label:h.label,...void 0!==h.description?{description:h.description}:{},config:g}),await l({type:"mcp-add-response",requestId:b.requestId,decision:"approve",server:h.server,agentId:a,ts:A(),seq:0}),d=`[Reflex] MCP server "${h.server}" registered. You can now call its tools via \`mcp__${h.server}__<tool>\` (chat) or \`reflex.mcp.call({server:"${h.server}",tool,args})\` (from a utility that declared it in manifest.mcpServers). Continue.`}catch(e){let c=e instanceof Error?e.message:String(e);await l({type:"error",message:"mcp-add failed: "+c,agentId:a,ts:A(),seq:0}),await l({type:"mcp-add-response",requestId:b.requestId,decision:"reject",agentId:a,ts:A(),seq:0}),d=`[Reflex] Failed to register MCP server "${h.server}": ${c}. Don't retry the exact same config; either fix the issue or ask the user.`}e&&!f&&await this.continueTurn(a,d)}async continueTurn(a,b){let c=this.agents.get(a);if(!c)return;let d=this.lastInvoke.get(a);if(!d)return void await this.emit({type:"error",message:"Cannot continue turn: no cached system prompt. Send another message manually.",agentId:a,ts:A(),seq:0});let e=[];try{let a=await (0,v.M)();e=a.assignments[c.meta.task]?.allowedTools??[]}catch{}let f=await D(d.rootPath,c.meta.topicId),g=`Prior conversation:
|
|
39
39
|
|
|
40
40
|
${f}
|
|
41
41
|
|
|
@@ -51,27 +51,27 @@ ${b}
|
|
|
51
51
|

|
|
52
52
|
`,agentId:a,ts:A(),seq:0}),c.attachToKb)try{let f=await (0,q.j)({rootPath:b.rootPath,directive:{kind:"image",title:c.caption||c.prompt.slice(0,80),body:``,meta:{provider:d.provider,prompt:c.prompt,sha:d.sha,...c.aspectRatio?{aspectRatio:c.aspectRatio}:{}}}});await this.emit({type:"kb-write",kind:f.kind,title:f.title,relPath:f.relPath,absPath:f.absPath,agentId:a,ts:A(),seq:0})}catch(b){await this.emit({type:"error",message:"image-gen kb attach failed: "+(b instanceof Error?b.message:String(b)),agentId:a,ts:A(),seq:0})}}catch(b){await this.emit({type:"assistant-delta",text:`
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
`,agentId:a,ts:A(),seq:0})}}async applyWorkflowDirectives(a,b,c,d){for(let e of d)try{let d=(0,o.ni)(e.id);if(!d)throw Error("Workflow id
|
|
56
|
-
${b.map(a=>`• ${a.url}`).join("\n")}`,subtype:"reflex.preflight",agentId:a,ts:A(),seq:0});let{summarizeYoutubeAction:d}=await Promise.resolve().then(c.bind(c,18746)),e=await Promise.all(b.map(async a=>{let b=await d({url:a.url,...a.prompt?{prompt:a.prompt}:{}});return b.ok?{url:a.url,text:b.text,model:b.model}:{url:a.url,error:b.error}})),f=e.map(a=>"text"in a?[`### youtube-summary ${a.url}`,`_(Gemini ${a.model} —
|
|
57
|
-
_(Gemini failed: ${a.error}.
|
|
54
|
+
_Failed to generate image: ${b instanceof Error?b.message:String(b)}_
|
|
55
|
+
`,agentId:a,ts:A(),seq:0})}}async applyWorkflowDirectives(a,b,c,d){for(let e of d)try{let d=(0,o.ni)(e.id);if(!d)throw Error("Workflow id is empty");let f=new Date().toISOString(),g=e.steps.map((a,b)=>({id:(0,o.ni)(a.id??`step-${b+1}`),kind:a.kind,label:a.label,params:a.params??{}})),h={id:d,label:e.label,...e.description?{description:e.description}:{},trigger:e.trigger??"manual",steps:g,createdAt:f,updatedAt:f,sourceTopicId:b},i=(0,p.n)(h);if(i)throw Error(i);await (0,o.r$)(a,h),await this.emit({type:"workflow-event",workflowId:h.id,label:h.label,...h.description?{description:h.description}:{},trigger:h.trigger,stepCount:h.steps.length,sourceTopicId:b,agentId:c,ts:f,seq:0})}catch(a){await this.emit({type:"workflow-error",workflowId:e.id,message:"workflow-create failed: "+(a instanceof Error?a.message:String(a)),agentId:c,ts:A(),seq:0})}}async applyWidgetDirectives(a,b,c,d,e){let f=await (0,n.readLayout)(a),g=[...f.order],h=[...f.hidden];for(let f of[...d,...e]){let d=e.includes(f);try{let e={kind:f.kind,data:f.data},i=d?await (0,n.readWidget)(a,f.id):null,j=(0,n.buildRecord)({id:f.id,title:f.title,...f.description?{description:f.description}:{},sourceTopicId:b,payload:e,existing:i,...f.size?{size:f.size}:{},...f.refresh?{refresh:f.refresh}:{},...void 0!==f.memory?{memory:f.memory}:{},...f.memoryFile?{memoryFile:f.memoryFile}:{}});await (0,n.writeWidget)(a,j),i||h.includes(j.id)||g.includes(j.id)||h.push(j.id),await this.emit({type:"widget-event",op:d&&i?"update":"create",widgetId:j.id,title:j.title,...j.description?{description:j.description}:{},kind:j.kind,data:j.data,sourceTopicId:b,agentId:c,ts:A(),seq:0})}catch(a){await this.emit({type:"widget-error",widgetId:f.id,message:(d?"widget-update":"widget-create")+" failed: "+(a instanceof Error?a.message:String(a)),agentId:c,ts:A(),seq:0})}}await (0,n.writeLayout)(a,{order:g,hidden:h})}async runYoutubeSummaries(a,b){if(!this.agents.get(a))return;await this.emit({type:"system",text:`Starting Gemini YouTube summary (${b.length}):
|
|
56
|
+
${b.map(a=>`• ${a.url}`).join("\n")}`,subtype:"reflex.preflight",agentId:a,ts:A(),seq:0});let{summarizeYoutubeAction:d}=await Promise.resolve().then(c.bind(c,18746)),e=await Promise.all(b.map(async a=>{let b=await d({url:a.url,...a.prompt?{prompt:a.prompt}:{}});return b.ok?{url:a.url,text:b.text,model:b.model}:{url:a.url,error:b.error}})),f=e.map(a=>"text"in a?[`### youtube-summary ${a.url}`,`_(Gemini ${a.model} — use as primary source; do not WebFetch the same URL.)_`,"",a.text].join("\n"):`### youtube-summary ${a.url}
|
|
57
|
+
_(Gemini failed: ${a.error}. Notify the user and suggest saving the key in Settings -> Gemini, or answer without the summary.)_`);await this.emit({type:"system",text:e.every(a=>"text"in a)?"Summaries received, passing to the agent.":"Some summaries failed — details are in the context.",subtype:"reflex.preflight",agentId:a,ts:A(),seq:0});let g=`[Reflex] Gemini YouTube summaries you requested:
|
|
58
58
|
|
|
59
59
|
${f.join("\n\n")}
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
Now answer the user based on this context. Do not repeat the summaries verbatim — compose a human-readable response.`;await this.continueTurn(a,g)}async destroy(a,b="completed"){let c=this.agents.get(a);if(!c)return;c.meta.status=b,c.meta.endedAt=A(),await this.emit({type:"agent-end",status:b,agentId:a,ts:c.meta.endedAt,seq:0}),this.agents.delete(a),this.turnText.delete(a),this.lastInvoke.delete(a);let d=this.byTopicRole.get(c.meta.topicId);if(d){for(let[b,c]of d)c===a&&d.delete(b);0===d.size&&this.byTopicRole.delete(c.meta.topicId)}}async emit(a){let b=this.agents.get(a.agentId);if(!b)return;let c=await (0,g.v)(b.rootPath,b.meta.topicId),d={...a,seq:c};if(await (0,g.Zn)(b.rootPath,b.meta.topicId,d),"assistant-delta"===a.type){let b=this.turnText.get(a.agentId)??"";this.turnText.set(a.agentId,b+a.text)}this.emitter.emit(`topic:${b.meta.topicId}`,d),this.emitter.emit(`agent:${a.agentId}`,d)}subscribeTopic(a,b){let c=`topic:${a}`;return this.emitter.on(c,b),()=>this.emitter.off(c,b)}subscribeAgent(a,b){let c=`agent:${a}`;return this.emitter.on(c,b),()=>this.emitter.off(c,b)}list(a){let b=[];for(let c of this.agents.values())(!a?.topicId||c.meta.topicId===a.topicId)&&(a?.rootId&&c.meta.rootId!==a.rootId||b.push({...c.meta}));return b.sort((a,b)=>Date.parse(b.startedAt)-Date.parse(a.startedAt)),b}get(a){let b=this.agents.get(a);return b?{...b.meta}:null}isActive(a){let b=this.byTopicRole.get(a);if(!b)return!1;for(let a of b.values()){let b=this.agents.get(a);if(b?.meta.status==="running")return!0}return!1}listRunningTopicsForRoot(a){let b=new Set;for(let c of this.agents.values())c.meta.rootId===a&&"running"===c.meta.status&&b.add(c.meta.topicId);return[...b]}async stopTopic(a){let b=[];for(let[c,d]of this.agents)d.meta.topicId===a&&b.push(c);let c=0;for(let a of b){let b=this.agents.get(a);b&&"running"===b.meta.status&&(await this.destroy(a,"cancelled"),c+=1)}return{stopped:c}}constructor(){this.agents=new Map,this.byTopicRole=new Map,this.emitter=new e.EventEmitter,this.turnText=new Map,this.lastInvoke=new Map,this.pendingMcpAdds=new Map}}function A(){return new Date().toISOString()}let F=new Set(["claude-code","codex","ollama","image-gen"]);async function B(a,b,d){if(!a||"object"!=typeof a)return a;let e={...a},f=e.transport,g="stdio"===f?"env":"http"===f||"sse"===f?"headers":null;if(!g)return e;let h=e[g]??{},i={};for(let[a,b]of Object.entries(h))i[a]=String(b);for(let a of b){if(a.oauth){let{getOAuthTokens:b}=await c.e(6730).then(c.bind(c,96730)),{isOAuthProviderId:d}=await c.e(3657).then(c.bind(c,63657));if(!d(a.oauth))throw Error(`unknown OAuth provider: ${a.oauth}`);if(!await b(a.oauth))throw Error(`provider "${a.oauth}" not authorized — open Settings → OAuth and Authorize first`);i[a.envKey]=`$oauth:${a.oauth}`;continue}let b=d[a.envKey];if(void 0!==b&&""!==b)i[a.envKey]=b;else if(a.required)throw Error(`secret "${a.envKey}" is required`);else delete i[a.envKey]}return e[g]=i,e}function C(){return(0,f.randomUUID)().replace(/-/g,"").slice(0,12)}async function D(a,b){let c=await (0,g.wj)(a,b),d=[],e=null,f=()=>{e&&(d.push(`### ${e.role}
|
|
62
62
|
${e.text.trim()}`),e=null)};for(let a of c)"user-message"===a.type?(f(),e={role:"user",text:a.text},f()):"assistant-delta"===a.type?(e&&"assistant"===e.role||(f(),e={role:"assistant",text:""}),e.text+=a.text):("turn-end"===a.type||"agent-end"===a.type)&&f();return f(),d.join("\n\n")}let G=globalThis.__reflexAgentManager??new E;globalThis.__reflexAgentManager=G,c.e(3240).then(c.bind(c,93240)).then(a=>a.startWidgetScheduler()).catch(a=>{console.error("[widget-scheduler] failed to start:",a)}),d()}catch(a){d(a)}})},19219:(a,b,c)=>{c.d(b,{YN:()=>p,cC:()=>r,fH:()=>q,tf:()=>m});var d=c(73024),e=c(76760),f=c.n(e),g=c(77598),h=c.n(g),i=c(24576);let j=f().join(".reflex","assets","images"),k={"image/png":"png","image/jpeg":"jpg","image/jpg":"jpg","image/webp":"webp","image/gif":"gif","image/svg+xml":"svg","image/avif":"avif"},l={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp",gif:"image/gif",svg:"image/svg+xml",avif:"image/avif"};function m(a){return l[a.toLowerCase()]??"application/octet-stream"}async function n(a){let b=await (0,i.Zn)(a);if(!b)throw Error(`unknown root: ${a}`);return b.path}async function o(a){let b=f().join(await n(a),j);return await d.promises.mkdir(b,{recursive:!0}),b}async function p(a,b,c){let e=Buffer.isBuffer(b)?b:Buffer.from(b),g=h().createHash("sha256").update(e).digest("hex"),i=k[c.toLowerCase()]??"bin",l=await o(a),m=f().join(l,`${g}.${i}`);try{await d.promises.access(m)}catch{await d.promises.writeFile(m,e)}return{sha:g,ext:i,mime:c,absPath:m,relPath:f().posix.join(j.split(f().sep).join("/"),`${g}.${i}`),urlPath:`/api/images/${encodeURIComponent(a)}/${g}.${i}`,size:e.byteLength}}async function q(a,b){let c=await fetch(b,{redirect:"follow",signal:AbortSignal.timeout(3e4)});if(!c.ok)throw Error(`fetch ${b} -> ${c.status} ${c.statusText}`);let d=c.headers.get("content-type")?.split(";")[0]?.trim()??"";if(!d.startsWith("image/"))throw Error(`not an image: content-type=${d||"(none)"}`);let e=Number(c.headers.get("content-length")??"0");if(e>0x1400000)throw Error(`image too large: ${e} bytes (cap 20971520)`);let f=await c.arrayBuffer();if(f.byteLength>0x1400000)throw Error(`image too large after download: ${f.byteLength} bytes (cap 20971520)`);return p(a,Buffer.from(f),d)}async function r(a,b){if(!/^[a-f0-9]{8,64}\.[a-z0-9]{2,5}$/i.test(b))return null;let c=await o(a),e=f().resolve(c,b);if(!e.startsWith(c+f().sep)&&e!==c)return null;try{let a=await d.promises.stat(e);if(!a.isFile())return null;let c=f().extname(b).slice(1);return{absPath:e,mime:m(c),size:a.size}}catch{return null}}},22830:(a,b,c)=>{c.d(b,{H:()=>e});var d=c(61088);async function e(a){let b=(0,d.Tf)().startThread({model:a.args.model,workingDirectory:a.args.rootPath,sandboxMode:"read-only",additionalDirectories:[a.args.reflexScope],approvalPolicy:"never",skipGitRepoCheck:!0}),c=a.args.systemPrompt.trim().length>0?`${a.args.systemPrompt}
|
|
63
63
|
|
|
64
|
-
${a.args.prompt}`:a.args.prompt,e=await b.runStreamed(c),f=new Map;try{for await(let b of e.events)if("item.started"!==b.type){if("item.updated"===b.type||"item.completed"===b.type){let c=b.item;if("agent_message"===c.type){let b=f.get(c.id)??"",d=c.text.slice(b.length);d.length>0&&(f.set(c.id,c.text),await a.manager.emit({type:"assistant-delta",text:d,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}));continue}if("command_execution"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:"Bash",input:{command:c.command},agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),await a.manager.emit({type:"tool-result",toolUseId:c.id,content:c.aggregated_output??"",...0!==c.exit_code?{isError:!0}:{},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("file_change"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:"FileChange",input:{changes:c.changes},agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),await a.manager.emit({type:"tool-result",toolUseId:c.id,content:`${c.status}: ${c.changes.map(a=>`${a.kind} ${a.path}`).join(", ")}`,..."failed"===c.status?{isError:!0}:{},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("mcp_tool_call"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:`mcp:${c.server}:${c.tool}`,input:c.arguments,agentId:a.meta.id,ts:new Date().toISOString(),seq:0});let b=c.error?c.error.message:JSON.stringify(c.result?.content??[]).slice(0,4e3);await a.manager.emit({type:"tool-result",toolUseId:c.id,content:b,...c.error?{isError:!0}:{},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("web_search"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:"WebSearch",input:{query:c.query},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}"error"===c.type&&"item.completed"===b.type&&await a.manager.emit({type:"error",message:c.message,agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("turn.failed"===b.type)throw await a.manager.emit({type:"error",message:`codex turn failed: ${b.error.message}`,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),Error(b.error.message);if("error"===b.type)throw await a.manager.emit({type:"error",message:b.message,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),Error(b.message)}}finally{await (0,d.Nb)(b.id)}}},23956:(a,b,c)=>{function d(a){return p(a,"<<reflex:permission>>","<</reflex:permission>>")}function e(a){let b=p(a,"<<reflex:question>>","<</reflex:question>>"),c=[];for(let a of b)if(a&&"object"==typeof a){if("questions"in a&&Array.isArray(a.questions)){for(let b of a.questions)b&&"object"==typeof b&&"string"==typeof b.prompt&&c.push(b);continue}"string"==typeof a.prompt&&c.push(a)}return c}function f(a){return p(a,"<<reflex:kb>>","<</reflex:kb>>").filter(a=>"string"==typeof a?.kind&&"string"==typeof a?.title)}function g(a){return p(a,"<<reflex:mcp-add>>","<</reflex:mcp-add>>").filter(a=>null!==a&&"object"==typeof a&&"string"==typeof a.server&&"string"==typeof a.label&&"object"==typeof a.config&&null!==a.config)}function h(a){return p(a,"<<reflex:dispatch>>","<</reflex:dispatch>>").filter(a=>null!==a&&"object"==typeof a&&"string"==typeof a.role&&"string"==typeof a.brief&&a.brief.trim().length>0)}function i(a){return p(a,"<<reflex:youtube-summary>>","<</reflex:youtube-summary>>").filter(a=>null!==a&&"object"==typeof a&&"string"==typeof a.url)}function j(a){return p(a,"<<reflex:workflow-create>>","<</reflex:workflow-create>>").filter(a=>!!a&&"object"==typeof a&&"string"==typeof a.id&&"string"==typeof a.label&&Array.isArray(a.steps)&&a.steps.length>0)}function k(a){return p(a,"<<reflex:widget-create>>","<</reflex:widget-create>>").filter(m)}function l(a){return p(a,"<<reflex:widget-update>>","<</reflex:widget-update>>").filter(m)}function m(a){return!!a&&"object"==typeof a&&"string"==typeof a.id&&a.id.length>0&&"string"==typeof a.title&&"string"==typeof a.kind&&!!a.data&&"object"==typeof a.data}function n(a){return p(a,"<<reflex:image-gen>>","<</reflex:image-gen>>").filter(a=>!!a&&"object"==typeof a&&"string"==typeof a.prompt&&a.prompt.trim().length>0)}function o(a){return p(a,"<<reflex:utility>>","<</reflex:utility>>").filter(a=>null!==a&&"object"==typeof a&&("global"===a.scope||"project"===a.scope)&&"object"==typeof a.files&&null!==a.files)}function p(a,b,c){let d=b.replace(/^<+/,"").replace(/>+$/,""),e=c.replace(/^<+/,"").replace(/>+$/,""),f=RegExp(`<{1,2}${q(d)}>{1,2}`,"g"),g=RegExp(`<{1,2}${q(e)}>{1,2}`,"g"),h=[],i=0;for(;i<a.length;){f.lastIndex=i;let b=f.exec(a);if(!b)break;let c=b.index+b[0].length;g.lastIndex=c;let d=g.exec(a);if(!d)break;let e=a.slice(c,d.index).trim();i=d.index+d[0].length;try{h.push(JSON.parse(e))}catch{}}return h}function q(a){return a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}c.d(b,{Bc:()=>f,Dq:()=>k,Eb:()=>h,Oo:()=>o,QN:()=>j,Up:()=>l,XZ:()=>i,dJ:()=>e,eD:()=>g,gQ:()=>d,qk:()=>n})},24058:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n,runWorkflow:()=>m});var e=c(77598),f=c.n(e),g=c(24576),h=c(13295),i=c(64011),j=c(79178),k=c(72440),l=a([k]);async function m(a,b,c){let d=await (0,g.Zn)(a);if(!d)return{ok:!1,error:"Root not found"};let e=await (0,h.readWorkflow)(d.path,b);if(!e)return{ok:!1,error:"Workflow not found"};let l={id:function(){let a=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),b=f().randomBytes(3).toString("hex");return`${a}-${b}`}(),workflowId:e.id,workflowLabel:e.label,status:"running",startedAt:new Date().toISOString(),steps:e.steps.map(a=>({stepId:a.id,status:"pending"})),...void 0!==c?{initialInput:c}:{}};await (0,h.bp)(d.path,l);let m={},n=c,o={rootId:a,rootPath:d.path,workflow:{id:e.id,label:e.label}};for(let a=0;a<e.steps.length;a++){let b=e.steps[a],f=l.steps[a];f.status="running",f.startedAt=new Date().toISOString(),await (0,h.bp)(d.path,l);try{let a=k.L[b.kind];if(!a)throw Error(`Unknown node kind: ${b.kind}`);let d=(0,j.V)(b.params,{prev:n,steps:m,input:c,workflow:{id:e.id,label:e.label}}),g=(0,i.P)(b.kind,d);f.renderedParams=g;let h=await a(g,o);f.output=h,f.status="completed",f.finishedAt=new Date().toISOString(),m[b.id]={output:h},n=h}catch(a){return f.status="failed",f.error=a instanceof Error?a.message:String(a),f.finishedAt=new Date().toISOString(),l.status="failed",l.finishedAt=new Date().toISOString(),await (0,h.bp)(d.path,l),(0,h.lq)(d.path,e.id),{ok:!0,run:l}}await (0,h.bp)(d.path,l)}return l.status="completed",l.finishedAt=new Date().toISOString(),await (0,h.bp)(d.path,l),(0,h.lq)(d.path,e.id),{ok:!0,run:l}}function n(a){if(!a.id||"string"!=typeof a.id)return"id обязателен";if(!a.label||"string"!=typeof a.label)return"label обязателен";if(!Array.isArray(a.steps)||0===a.steps.length)return"steps[] не может быть пустым";let b=new Set;for(let c of a.steps){if(!c.id)return"Каждый step должен иметь id";if(b.has(c.id))return`Дублирующийся step id: ${c.id}`;if(b.add(c.id),!k.L[c.kind])return`Неизвестный тип step'а: ${c.kind}`}return null}k=(l.then?(await l)():l)[0],d()}catch(a){d(a)}})},24776:(a,b,c)=>{c.d(b,{Aq:()=>i,pO:()=>h});let d=["Read","Glob","Grep","WebFetch","WebSearch"],e=[...d,"Write","Edit","MultiEdit"];function f(a,b,c){return[`## Specialist role: ${a}`,"",`Reply in ${b}. You are a focused specialist, not a general assistant. Do exactly the task in the brief — no more.`,"\n## Brief from the orchestrator",c.trim(),""].join("\n")}function g(a){return["\n## Rules",a,"\n- Don't ask clarifying questions to the user — you don't have a chat surface. If the brief is ambiguous, do your best with stated assumptions and note them in your output.\n- Don't emit `<<reflex:kb>>`, `<<reflex:utility>>`, `<<reflex:permission>>`, `<<reflex:question>>`, `<<reflex:dispatch>>` markers — those are for the orchestrator only. Just write your answer as plain text/markdown.\n- End with a tight summary the orchestrator can quote verbatim if the user asks for the result."].join("\n")}let h={researcher:{id:"researcher",label:"Researcher",description:"Глубокое чтение KB / поиск по проекту / web research. Read-only — не пишет файлы. Используй когда нужно найти/собрать факты.",allowedTools:d,systemPrompt:({language:a,root:b,reflexScope:c,brief:d})=>[f("researcher",a,d),`Project root: \`${b}\``,`Knowledge base scope: \`${c}\``,g("- You are READ-ONLY: never Write/Edit/MultiEdit. Use Read/Glob/Grep to scan the KB and WebFetch/WebSearch for external lookups.\n- Cite sources by rel-path inside the KB (or URL for web).\n- If the brief asks for something that requires a write, explicitly say `cannot complete — write required` instead of doing it.")].join("\n")},coder:{id:"coder",label:"Coder",description:"Пишет/редактирует исходный код, конфиги, схемы. Может создать утилиту. Используй когда нужны изменения файлов.",allowedTools:e,systemPrompt:({language:a,root:b,reflexScope:c,brief:d})=>[f("coder",a,d),`Project root: \`${b}\``,`Reflex scope (write here for KB files): \`${c}\``,g("- You may Write/Edit/MultiEdit files. Stay inside the project root.\n- Don't run shell or invoke other agents. If the brief implies installing a utility, write the utility files but do NOT emit `<<reflex:utility>>` — that's the orchestrator's job.\n- Report what you changed: list each touched file with a one-line summary.")].join("\n")},summarizer:{id:"summarizer",label:"Summarizer",description:"Сжимает большой текст / длинный transcript / список файлов в короткое summary. Без инструментов — только текст в брифе.",allowedTools:[],systemPrompt:({language:a,brief:b})=>[f("summarizer",a,b),g("- You have NO tools — work only from the text in the brief.\n- Compress aggressively: bullet points, ~10x reduction is the target unless the brief says otherwise.\n- Preserve names, numbers, dates, file paths verbatim. Drop filler.")].join("\n")},"kb-writer":{id:"kb-writer",label:"KB Writer",description:"Структурированная запись в базу знаний (kind/title/body/frontmatter). Используй когда orchestrator решил что-то сохранить.",allowedTools:d,systemPrompt:({language:a,root:b,reflexScope:c,brief:d})=>[f("kb-writer",a,d),`KB root: \`${c}\``,`Project: \`${b}\``,g('- You DO NOT write the file yourself. Output a JSON object the orchestrator will pass to <<reflex:kb>>:\n ```json\n {"kind":"<entity-type>","title":"…","body":"…markdown…","meta":{…optional frontmatter fields…}}\n ```\n- Pick a sensible `kind` (fact / task / meeting / product / decision / source / …).\n- `body` is full markdown. Frontmatter `meta` should hold structured fields the user might filter/group on.')].join("\n")},"utility-builder":{id:"utility-builder",label:"Utility Builder",description:"Спроектировать утилиту: manifest + ui.tsx + (опц.) server actions. Используй когда пользователь явно просит создать утилиту.",allowedTools:d,systemPrompt:({language:a,root:b,brief:c})=>[f("utility-builder",a,c),`Project: \`${b}\``,g("- Output the utility files inline in markdown code fences with file paths as headers:\n ### manifest.json\n ```json\n { … }\n ```\n ### ui.tsx\n ```tsx\n … React functional component, default-export …\n ```\n- Follow Reflex utility contract: imports only from `react`, `react-dom/client`, `react/jsx-runtime`, `@host/api`, `@host/ui`. Declare needed permissions and secrets in manifest.\n- Don't emit `<<reflex:utility>>` yourself — the orchestrator wraps your output and emits the marker.")].join("\n")}};function i(a){return a in h}},25608:(a,b,c)=>{c.d(b,{dr:()=>e});let d=[{id:"plan",trigger:"plan",label:"/plan",description:"Сначала покажи план — Reflex распишет шаги и подождёт одобрения.",kind:"agent-mode",usage:"/plan <задача>",icon:"ListChecks"},{id:"goal",trigger:"goal",label:"/goal",description:"Поставь цель — Reflex будет двигаться к ней сам, без напоминаний.",kind:"agent-mode",usage:"/goal <чего достичь>",icon:"Target"},{id:"research",trigger:"research",label:"/research",description:"Глубокое исследование темы — поиск в интернете + сводка с источниками.",kind:"agent-mode",usage:"/research <тема>",icon:"Telescope"},{id:"widget",trigger:"widget",label:"/widget",description:"Создать карточку на дашборде пространства.",kind:"agent-mode",usage:"/widget <что показать>",icon:"LayoutGrid"},{id:"workflow",trigger:"workflow",label:"/workflow",description:"Собрать рецепт — линейная автоматизация из шагов под задачу.",kind:"agent-mode",usage:"/workflow <что автоматизировать>",icon:"Workflow"},{id:"remember",trigger:"remember",label:"/remember",description:"Запомнить заметку — сразу в память, без обращения к AI.",kind:"direct",usage:"/remember <что запомнить>",icon:"BookmarkPlus"},{id:"mcp",trigger:"mcp",label:"/mcp",description:"Подключить внешний сервис (мастер настройки откроется в чате).",kind:"agent-mode",usage:"/mcp <что нужно>",icon:"PackagePlus"},{id:"skill",trigger:"skill",label:"/skill",description:"Подключить роль — готовый набор инструкций на этот разговор.",kind:"agent-mode",usage:"/skill <id-роли> [запрос]",icon:"Sparkles"},{id:"delete-topic",trigger:"delete-topic",label:"/delete-topic",description:"Удалить этот разговор (с подтверждением).",kind:"direct",usage:"/delete-topic",requiresConfirm:!0,allowEmpty:!0,icon:"Trash2"},{id:"clear-project",trigger:"clear-project",label:"/clear-project",description:"ОПАСНО: очистить пространство — все разговоры, карточки, память. Двойное подтверждение.",kind:"direct",usage:"/clear-project",requiresConfirm:!0,allowEmpty:!0,icon:"AlertOctagon"},{id:"util",trigger:"util",label:"/util",description:"Открыть мини-приложение (по части названия или из списка).",kind:"direct",usage:"/util <часть названия или id>",allowEmpty:!0,icon:"Boxes"},{id:"help",trigger:"help",label:"/help",description:"Список доступных команд.",kind:"direct",usage:"/help",allowEmpty:!0,icon:"HelpCircle"}];function e(a){var b;let c=a.trim();if(!c.startsWith("/"))return null;let e=/^\/([a-z][a-z0-9-]*)(?:\s+([\s\S]*))?$/.exec(c);if(!e)return null;let f=(b=e[1],d.find(a=>a.trigger===b)??null);return f?{def:f,payload:(e[2]??"").trim()}:null}},25713:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Z:()=>j});var e=c(7206),f=c(77598),g=c.n(f),h=c(91147),i=a([e]);e=(i.then?(await i)():i)[0];let l=["Read","LS","Glob","Grep","WebSearch","WebFetch"];async function j(a){let b=await (0,h._)(a.meta.id),c=a.args.allowedTools&&a.args.allowedTools.length>0?a.args.allowedTools:l,d=b?[...c,...b.serverIds.map(a=>`mcp__${a}__*`)]:c,f=["-p",a.args.prompt,"--append-system-prompt",a.args.systemPrompt,"--permission-mode","default","--allowedTools",d.join(","),"--add-dir",a.args.reflexScope,"--output-format","stream-json","--verbose","--model",a.args.model,...b?["--mcp-config",b.path]:[]],i=(0,e.execa)("claude",f,{cwd:a.args.rootPath,buffer:!1,stdin:"ignore"}),j=new Map;try{for await(let b of k(i.stdout)){let c=function(a){try{return JSON.parse(a)}catch{return null}}(b);if(c)for(let b of function(a,b,c){let d=new Date().toISOString();if("system"===a.type)return[{type:"system",text:a.subtype??"system",subtype:a.subtype,agentId:b,ts:d,seq:0}];if("assistant"===a.type){let e=[];for(let f of a.message?.content??[])"text"===f.type?e.push({type:"assistant-delta",text:f.text,agentId:b,ts:d,seq:0}):"tool_use"===f.type&&(c.set(f.id,f.name),e.push({type:"tool-use",toolUseId:f.id,name:f.name,input:f.input??{},agentId:b,ts:d,seq:0}));return e}if("user"===a.type){let h=[];for(let i of a.message?.content??[])if("tool_result"===i.type){var e,f;let a=(e=i.content)?"string"==typeof e?e:e.map(a=>"text"===a.type&&a.text?a.text:"").join(""):"";if(h.push({type:"tool-result",toolUseId:i.tool_use_id,content:a,...i.is_error?{isError:!0}:{},agentId:b,ts:d,seq:0}),i.is_error){let e=c.get(i.tool_use_id)??function(a){let b=/requested permissions to use\s+([A-Za-z_]\w*)/i.exec(a);if(b?.[1])return b[1];if(/requested permissions to write\b/i.test(a))return"Write";if(/requested permissions to edit\b/i.test(a))return"Edit";if(/requested permissions to run\b/i.test(a))return"Bash";if(/requested permissions to read\b/i.test(a))return"Read";let c=/permission .* tool[:\s]+([A-Za-z_]\w*)/i.exec(a);return c?.[1]??null}(a);if(e){let c=function(a){let b=/requested permissions to (?:write to|edit|read)\s+(\S+?)(?:,|\s+but\b|\s*$)/i.exec(a)??/requested permissions to run\s+(.+?)(?:,\s+but\b|\s*$)/i.exec(a);return b?.[1]?.trim()??null}(a);h.push({type:"permission-request",requestId:g().randomUUID().replace(/-/g,"").slice(0,12),tool:e,action:"tool-policy",...c?{input:{target:c}}:{},description:c?`Агент хочет ${f=e,"Write"===f?"записать в":"Edit"===f||"MultiEdit"===f?"отредактировать":"Read"===f?"прочитать":"Bash"===f?"выполнить команду":"NotebookEdit"===f?"отредактировать notebook":"WebFetch"===f?"запросить URL":"WebSearch"===f?"поискать в вебе":"использовать"} \`${c}\` через \xab${e}\xbb. Разрешить?`:`Агент попытался вызвать инструмент \xab${e}\xbb, но он не в списке разрешённых для этой задачи. Разрешить?`,agentId:b,ts:d,seq:0})}}}return h}return a.type,[]}(c,a.meta.id,j))await a.manager.emit(b)}await i}finally{b&&await b.cleanup()}}async function*k(a){if(!a)return;let b="";for await(let c of a){let a;for(b+="string"==typeof c?c:c.toString("utf8");(a=b.indexOf("\n"))>=0;){let c=b.slice(0,a);b=b.slice(a+1),c.trim()&&(yield c)}}b.trim()&&(yield b)}d()}catch(a){d(a)}})},31900:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{W:()=>r});var e=c(76760),f=c.n(e),g=c(13474),h=c(61992),i=c(17640),j=c(24576),k=c(16909),l=c(74342),m=c(8734),n=c(25608),o=c(56843),p=c(3613),q=a([k]);async function r(a){let b=await (0,j.Zn)(a.rootId);if(!b)return{error:"Root not found",status:404};if(k.z.isActive(a.topicId))return{error:"Topic already has a running agent",status:409};let c=await (0,i.M)(),d=c.assignments.chat,e=a.harness??d.harness,l=a.model??d.model,q=c.language,r=(0,g.FF)(b.path),u=(0,m.wr)(a.message),v=(0,n.dr)(a.message),w=a.message;u?"goal"===u.kind&&u.text?(await (0,o.PF)(b.path,a.topicId,u.text),w=u.text):"plan"===u.kind&&(w=u.text||a.message):v&&"agent-mode"===v.def.kind&&(w=v.payload||a.message);let x=null;if(v?.def.id==="skill"){let[a,...b]=v.payload.split(/\s+/);if(a){let c=await (0,p.k)(a);c&&(x=c.instructions,w=b.join(" ").trim()||w)}}let y=await (0,o.eF)(b.path,a.topicId),z=y?.meta.goal&&"active"===y.meta.goalStatus?y.meta.goal:void 0,A=await (0,h.M)({root:b.path,scope:b.path,reflexScope:r,language:q}),B=function(a){let b=[],c=new Set;for(let d of a.matchAll(/https?:\/\/[^\s)>'"]+/g)){let a=d[0];try{let d=new URL(a);if(!t.has(d.hostname.toLowerCase())||c.has(a))continue;c.add(a),b.push(a)}catch{}}return b}(w),C=[A,z?(0,m.FB)(z,q):"",u?.kind==="plan"?(0,m.$4)(q):"",v?.def.id==="research"?(0,m.dA)(v.payload,q):"",v?.def.id==="widget"?(0,m.wt)(v.payload,q):"",v?.def.id==="mcp"?(0,m.YE)(v.payload,q):"",v?.def.id==="workflow"?(0,m.vl)(v.payload,q):"",x??"",a.focusFile?function(a,b,c){let d=f().join(b,a);return/russ/i.test(c)||/рус/i.test(c)?`## Открытый документ — приоритетный контекст
|
|
64
|
+
${a.args.prompt}`:a.args.prompt,e=await b.runStreamed(c),f=new Map;try{for await(let b of e.events)if("item.started"!==b.type){if("item.updated"===b.type||"item.completed"===b.type){let c=b.item;if("agent_message"===c.type){let b=f.get(c.id)??"",d=c.text.slice(b.length);d.length>0&&(f.set(c.id,c.text),await a.manager.emit({type:"assistant-delta",text:d,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}));continue}if("command_execution"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:"Bash",input:{command:c.command},agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),await a.manager.emit({type:"tool-result",toolUseId:c.id,content:c.aggregated_output??"",...0!==c.exit_code?{isError:!0}:{},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("file_change"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:"FileChange",input:{changes:c.changes},agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),await a.manager.emit({type:"tool-result",toolUseId:c.id,content:`${c.status}: ${c.changes.map(a=>`${a.kind} ${a.path}`).join(", ")}`,..."failed"===c.status?{isError:!0}:{},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("mcp_tool_call"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:`mcp:${c.server}:${c.tool}`,input:c.arguments,agentId:a.meta.id,ts:new Date().toISOString(),seq:0});let b=c.error?c.error.message:JSON.stringify(c.result?.content??[]).slice(0,4e3);await a.manager.emit({type:"tool-result",toolUseId:c.id,content:b,...c.error?{isError:!0}:{},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("web_search"===c.type&&"item.completed"===b.type){await a.manager.emit({type:"tool-use",toolUseId:c.id,name:"WebSearch",input:{query:c.query},agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}"error"===c.type&&"item.completed"===b.type&&await a.manager.emit({type:"error",message:c.message,agentId:a.meta.id,ts:new Date().toISOString(),seq:0});continue}if("turn.failed"===b.type)throw await a.manager.emit({type:"error",message:`codex turn failed: ${b.error.message}`,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),Error(b.error.message);if("error"===b.type)throw await a.manager.emit({type:"error",message:b.message,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),Error(b.message)}}finally{await (0,d.Nb)(b.id)}}},23956:(a,b,c)=>{function d(a){return p(a,"<<reflex:permission>>","<</reflex:permission>>")}function e(a){let b=p(a,"<<reflex:question>>","<</reflex:question>>"),c=[];for(let a of b)if(a&&"object"==typeof a){if("questions"in a&&Array.isArray(a.questions)){for(let b of a.questions)b&&"object"==typeof b&&"string"==typeof b.prompt&&c.push(b);continue}"string"==typeof a.prompt&&c.push(a)}return c}function f(a){return p(a,"<<reflex:kb>>","<</reflex:kb>>").filter(a=>"string"==typeof a?.kind&&"string"==typeof a?.title)}function g(a){return p(a,"<<reflex:mcp-add>>","<</reflex:mcp-add>>").filter(a=>null!==a&&"object"==typeof a&&"string"==typeof a.server&&"string"==typeof a.label&&"object"==typeof a.config&&null!==a.config)}function h(a){return p(a,"<<reflex:dispatch>>","<</reflex:dispatch>>").filter(a=>null!==a&&"object"==typeof a&&"string"==typeof a.role&&"string"==typeof a.brief&&a.brief.trim().length>0)}function i(a){return p(a,"<<reflex:youtube-summary>>","<</reflex:youtube-summary>>").filter(a=>null!==a&&"object"==typeof a&&"string"==typeof a.url)}function j(a){return p(a,"<<reflex:workflow-create>>","<</reflex:workflow-create>>").filter(a=>!!a&&"object"==typeof a&&"string"==typeof a.id&&"string"==typeof a.label&&Array.isArray(a.steps)&&a.steps.length>0)}function k(a){return p(a,"<<reflex:widget-create>>","<</reflex:widget-create>>").filter(m)}function l(a){return p(a,"<<reflex:widget-update>>","<</reflex:widget-update>>").filter(m)}function m(a){return!!a&&"object"==typeof a&&"string"==typeof a.id&&a.id.length>0&&"string"==typeof a.title&&"string"==typeof a.kind&&!!a.data&&"object"==typeof a.data}function n(a){return p(a,"<<reflex:image-gen>>","<</reflex:image-gen>>").filter(a=>!!a&&"object"==typeof a&&"string"==typeof a.prompt&&a.prompt.trim().length>0)}function o(a){return p(a,"<<reflex:utility>>","<</reflex:utility>>").filter(a=>null!==a&&"object"==typeof a&&("global"===a.scope||"project"===a.scope)&&"object"==typeof a.files&&null!==a.files)}function p(a,b,c){let d=b.replace(/^<+/,"").replace(/>+$/,""),e=c.replace(/^<+/,"").replace(/>+$/,""),f=RegExp(`<{1,2}${q(d)}>{1,2}`,"g"),g=RegExp(`<{1,2}${q(e)}>{1,2}`,"g"),h=[],i=0;for(;i<a.length;){f.lastIndex=i;let b=f.exec(a);if(!b)break;let c=b.index+b[0].length;g.lastIndex=c;let d=g.exec(a);if(!d)break;let e=a.slice(c,d.index).trim();i=d.index+d[0].length;try{h.push(JSON.parse(e))}catch{}}return h}function q(a){return a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}c.d(b,{Bc:()=>f,Dq:()=>k,Eb:()=>h,Oo:()=>o,QN:()=>j,Up:()=>l,XZ:()=>i,dJ:()=>e,eD:()=>g,gQ:()=>d,qk:()=>n})},24058:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n,runWorkflow:()=>m});var e=c(77598),f=c.n(e),g=c(24576),h=c(13295),i=c(64011),j=c(79178),k=c(72440),l=a([k]);async function m(a,b,c){let d=await (0,g.Zn)(a);if(!d)return{ok:!1,error:"Root not found"};let e=await (0,h.readWorkflow)(d.path,b);if(!e)return{ok:!1,error:"Workflow not found"};let l={id:function(){let a=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),b=f().randomBytes(3).toString("hex");return`${a}-${b}`}(),workflowId:e.id,workflowLabel:e.label,status:"running",startedAt:new Date().toISOString(),steps:e.steps.map(a=>({stepId:a.id,status:"pending"})),...void 0!==c?{initialInput:c}:{}};await (0,h.bp)(d.path,l);let m={},n=c,o={rootId:a,rootPath:d.path,workflow:{id:e.id,label:e.label}};for(let a=0;a<e.steps.length;a++){let b=e.steps[a],f=l.steps[a];f.status="running",f.startedAt=new Date().toISOString(),await (0,h.bp)(d.path,l);try{let a=k.L[b.kind];if(!a)throw Error(`Unknown node kind: ${b.kind}`);let d=(0,j.V)(b.params,{prev:n,steps:m,input:c,workflow:{id:e.id,label:e.label}}),g=(0,i.P)(b.kind,d);f.renderedParams=g;let h=await a(g,o);f.output=h,f.status="completed",f.finishedAt=new Date().toISOString(),m[b.id]={output:h},n=h}catch(a){return f.status="failed",f.error=a instanceof Error?a.message:String(a),f.finishedAt=new Date().toISOString(),l.status="failed",l.finishedAt=new Date().toISOString(),await (0,h.bp)(d.path,l),(0,h.lq)(d.path,e.id),{ok:!0,run:l}}await (0,h.bp)(d.path,l)}return l.status="completed",l.finishedAt=new Date().toISOString(),await (0,h.bp)(d.path,l),(0,h.lq)(d.path,e.id),{ok:!0,run:l}}function n(a){if(!a.id||"string"!=typeof a.id)return"id is required";if(!a.label||"string"!=typeof a.label)return"label is required";if(!Array.isArray(a.steps)||0===a.steps.length)return"steps[] cannot be empty";let b=new Set;for(let c of a.steps){if(!c.id)return"every step must have an id";if(b.has(c.id))return`Duplicate step id: ${c.id}`;if(b.add(c.id),!k.L[c.kind])return`Unknown step kind: ${c.kind}`}return null}k=(l.then?(await l)():l)[0],d()}catch(a){d(a)}})},24776:(a,b,c)=>{c.d(b,{Aq:()=>i,pO:()=>h});let d=["Read","Glob","Grep","WebFetch","WebSearch"],e=[...d,"Write","Edit","MultiEdit"];function f(a,b,c){return[`## Specialist role: ${a}`,"",`Reply in ${b}. You are a focused specialist, not a general assistant. Do exactly the task in the brief — no more.`,"\n## Brief from the orchestrator",c.trim(),""].join("\n")}function g(a){return["\n## Rules",a,"\n- Don't ask clarifying questions to the user — you don't have a chat surface. If the brief is ambiguous, do your best with stated assumptions and note them in your output.\n- Don't emit `<<reflex:kb>>`, `<<reflex:utility>>`, `<<reflex:permission>>`, `<<reflex:question>>`, `<<reflex:dispatch>>` markers — those are for the orchestrator only. Just write your answer as plain text/markdown.\n- End with a tight summary the orchestrator can quote verbatim if the user asks for the result."].join("\n")}let h={researcher:{id:"researcher",label:"Researcher",description:"Deep KB reading / project search / web research. Read-only — never writes files. Use when you need to find or gather facts.",allowedTools:d,systemPrompt:({language:a,root:b,reflexScope:c,brief:d})=>[f("researcher",a,d),`Project root: \`${b}\``,`Knowledge base scope: \`${c}\``,g("- You are READ-ONLY: never Write/Edit/MultiEdit. Use Read/Glob/Grep to scan the KB and WebFetch/WebSearch for external lookups.\n- Cite sources by rel-path inside the KB (or URL for web).\n- If the brief asks for something that requires a write, explicitly say `cannot complete — write required` instead of doing it.")].join("\n")},coder:{id:"coder",label:"Coder",description:"Writes/edits source code, configs, schemas. Can create a utility. Use when file changes are required.",allowedTools:e,systemPrompt:({language:a,root:b,reflexScope:c,brief:d})=>[f("coder",a,d),`Project root: \`${b}\``,`Reflex scope (write here for KB files): \`${c}\``,g("- You may Write/Edit/MultiEdit files. Stay inside the project root.\n- Don't run shell or invoke other agents. If the brief implies installing a utility, write the utility files but do NOT emit `<<reflex:utility>>` — that's the orchestrator's job.\n- Report what you changed: list each touched file with a one-line summary.")].join("\n")},summarizer:{id:"summarizer",label:"Summarizer",description:"Compresses a large text / long transcript / file list into a short summary. No tools — only the text in the brief.",allowedTools:[],systemPrompt:({language:a,brief:b})=>[f("summarizer",a,b),g("- You have NO tools — work only from the text in the brief.\n- Compress aggressively: bullet points, ~10x reduction is the target unless the brief says otherwise.\n- Preserve names, numbers, dates, file paths verbatim. Drop filler.")].join("\n")},"kb-writer":{id:"kb-writer",label:"KB Writer",description:"Structured knowledge-base entry (kind/title/body/frontmatter). Use when the orchestrator decides to save something.",allowedTools:d,systemPrompt:({language:a,root:b,reflexScope:c,brief:d})=>[f("kb-writer",a,d),`KB root: \`${c}\``,`Project: \`${b}\``,g('- You DO NOT write the file yourself. Output a JSON object the orchestrator will pass to <<reflex:kb>>:\n ```json\n {"kind":"<entity-type>","title":"…","body":"…markdown…","meta":{…optional frontmatter fields…}}\n ```\n- Pick a sensible `kind` (fact / task / meeting / product / decision / source / …).\n- `body` is full markdown. Frontmatter `meta` should hold structured fields the user might filter/group on.')].join("\n")},"utility-builder":{id:"utility-builder",label:"Utility Builder",description:"Design a utility: manifest + ui.tsx + (optional) server actions. Use when the user explicitly asks to create a utility.",allowedTools:d,systemPrompt:({language:a,root:b,brief:c})=>[f("utility-builder",a,c),`Project: \`${b}\``,g("- Output the utility files inline in markdown code fences with file paths as headers:\n ### manifest.json\n ```json\n { … }\n ```\n ### ui.tsx\n ```tsx\n … React functional component, default-export …\n ```\n- Follow Reflex utility contract: imports only from `react`, `react-dom/client`, `react/jsx-runtime`, `@host/api`, `@host/ui`. Declare needed permissions and secrets in manifest.\n- Don't emit `<<reflex:utility>>` yourself — the orchestrator wraps your output and emits the marker.")].join("\n")}};function i(a){return a in h}},25608:(a,b,c)=>{c.d(b,{dr:()=>e});let d=[{id:"plan",trigger:"plan",label:"/plan",description:"Show the plan first — Reflex lays out the steps and waits for approval.",kind:"agent-mode",usage:"/plan <task>",icon:"ListChecks"},{id:"goal",trigger:"goal",label:"/goal",description:"Set a goal — Reflex will work toward it on its own, without reminders.",kind:"agent-mode",usage:"/goal <what to achieve>",icon:"Target"},{id:"research",trigger:"research",label:"/research",description:"Deep research on a topic — web search + summary with sources.",kind:"agent-mode",usage:"/research <topic>",icon:"Telescope"},{id:"widget",trigger:"widget",label:"/widget",description:"Create a card on the space dashboard.",kind:"agent-mode",usage:"/widget <what to show>",icon:"LayoutGrid"},{id:"workflow",trigger:"workflow",label:"/workflow",description:"Build a recipe — linear step-based automation for the task.",kind:"agent-mode",usage:"/workflow <what to automate>",icon:"Workflow"},{id:"remember",trigger:"remember",label:"/remember",description:"Save a note — straight into memory, no AI involved.",kind:"direct",usage:"/remember <what to remember>",icon:"BookmarkPlus"},{id:"mcp",trigger:"mcp",label:"/mcp",description:"Connect an external service (setup wizard opens in chat).",kind:"agent-mode",usage:"/mcp <what you need>",icon:"PackagePlus"},{id:"skill",trigger:"skill",label:"/skill",description:"Attach a role — a ready-made instruction set for this conversation.",kind:"agent-mode",usage:"/skill <role-id> [prompt]",icon:"Sparkles"},{id:"delete-topic",trigger:"delete-topic",label:"/delete-topic",description:"Delete this conversation (with confirmation).",kind:"direct",usage:"/delete-topic",requiresConfirm:!0,allowEmpty:!0,icon:"Trash2"},{id:"clear-project",trigger:"clear-project",label:"/clear-project",description:"DANGER: clear the space — all conversations, cards, memory. Double confirmation.",kind:"direct",usage:"/clear-project",requiresConfirm:!0,allowEmpty:!0,icon:"AlertOctagon"},{id:"util",trigger:"util",label:"/util",description:"Open a mini-app (by partial name or from the list).",kind:"direct",usage:"/util <partial name or id>",allowEmpty:!0,icon:"Boxes"},{id:"help",trigger:"help",label:"/help",description:"List available commands.",kind:"direct",usage:"/help",allowEmpty:!0,icon:"HelpCircle"}];function e(a){var b;let c=a.trim();if(!c.startsWith("/"))return null;let e=/^\/([a-z][a-z0-9-]*)(?:\s+([\s\S]*))?$/.exec(c);if(!e)return null;let f=(b=e[1],d.find(a=>a.trigger===b)??null);return f?{def:f,payload:(e[2]??"").trim()}:null}},25713:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Z:()=>j});var e=c(7206),f=c(77598),g=c.n(f),h=c(91147),i=a([e]);e=(i.then?(await i)():i)[0];let l=["Read","LS","Glob","Grep","WebSearch","WebFetch"];async function j(a){let b=await (0,h._)(a.meta.id),c=a.args.allowedTools&&a.args.allowedTools.length>0?a.args.allowedTools:l,d=b?[...c,...b.serverIds.map(a=>`mcp__${a}__*`)]:c,f=["-p",a.args.prompt,"--append-system-prompt",a.args.systemPrompt,"--permission-mode","default","--allowedTools",d.join(","),"--add-dir",a.args.reflexScope,"--output-format","stream-json","--verbose","--model",a.args.model,...b?["--mcp-config",b.path]:[]],i=(0,e.execa)("claude",f,{cwd:a.args.rootPath,buffer:!1,stdin:"ignore"}),j=new Map;try{for await(let b of k(i.stdout)){let c=function(a){try{return JSON.parse(a)}catch{return null}}(b);if(c)for(let b of function(a,b,c){let d=new Date().toISOString();if("system"===a.type)return[{type:"system",text:a.subtype??"system",subtype:a.subtype,agentId:b,ts:d,seq:0}];if("assistant"===a.type){let e=[];for(let f of a.message?.content??[])"text"===f.type?e.push({type:"assistant-delta",text:f.text,agentId:b,ts:d,seq:0}):"tool_use"===f.type&&(c.set(f.id,f.name),e.push({type:"tool-use",toolUseId:f.id,name:f.name,input:f.input??{},agentId:b,ts:d,seq:0}));return e}if("user"===a.type){let h=[];for(let i of a.message?.content??[])if("tool_result"===i.type){var e,f;let a=(e=i.content)?"string"==typeof e?e:e.map(a=>"text"===a.type&&a.text?a.text:"").join(""):"";if(h.push({type:"tool-result",toolUseId:i.tool_use_id,content:a,...i.is_error?{isError:!0}:{},agentId:b,ts:d,seq:0}),i.is_error){let e=c.get(i.tool_use_id)??function(a){let b=/requested permissions to use\s+([A-Za-z_]\w*)/i.exec(a);if(b?.[1])return b[1];if(/requested permissions to write\b/i.test(a))return"Write";if(/requested permissions to edit\b/i.test(a))return"Edit";if(/requested permissions to run\b/i.test(a))return"Bash";if(/requested permissions to read\b/i.test(a))return"Read";let c=/permission .* tool[:\s]+([A-Za-z_]\w*)/i.exec(a);return c?.[1]??null}(a);if(e){let c=function(a){let b=/requested permissions to (?:write to|edit|read)\s+(\S+?)(?:,|\s+but\b|\s*$)/i.exec(a)??/requested permissions to run\s+(.+?)(?:,\s+but\b|\s*$)/i.exec(a);return b?.[1]?.trim()??null}(a);h.push({type:"permission-request",requestId:g().randomUUID().replace(/-/g,"").slice(0,12),tool:e,action:"tool-policy",...c?{input:{target:c}}:{},description:c?`The agent wants to ${f=e,"Write"===f?"write to":"Edit"===f||"MultiEdit"===f?"edit":"Read"===f?"read":"Bash"===f?"run a command":"NotebookEdit"===f?"edit a notebook":"WebFetch"===f?"fetch a URL":"WebSearch"===f?"search the web":"use"} \`${c}\` via "${e}". Allow?`:`The agent tried to call the "${e}" tool, but it is not in the allowed list for this task. Allow?`,agentId:b,ts:d,seq:0})}}}return h}return a.type,[]}(c,a.meta.id,j))await a.manager.emit(b)}await i}finally{b&&await b.cleanup()}}async function*k(a){if(!a)return;let b="";for await(let c of a){let a;for(b+="string"==typeof c?c:c.toString("utf8");(a=b.indexOf("\n"))>=0;){let c=b.slice(0,a);b=b.slice(a+1),c.trim()&&(yield c)}}b.trim()&&(yield b)}d()}catch(a){d(a)}})},31900:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{W:()=>r});var e=c(76760),f=c.n(e),g=c(13474),h=c(61992),i=c(17640),j=c(24576),k=c(16909),l=c(74342),m=c(8734),n=c(25608),o=c(56843),p=c(3613),q=a([k]);k=(q.then?(await q)():q)[0];let t="рус";async function r(a){let b=await (0,j.Zn)(a.rootId);if(!b)return{error:"Root not found",status:404};if(k.z.isActive(a.topicId))return{error:"Topic already has a running agent",status:409};let c=await (0,i.M)(),d=c.assignments.chat,e=a.harness??d.harness,l=a.model??d.model,q=c.language,r=(0,g.FF)(b.path),v=(0,m.wr)(a.message),w=(0,n.dr)(a.message),x=a.message;v?"goal"===v.kind&&v.text?(await (0,o.PF)(b.path,a.topicId,v.text),x=v.text):"plan"===v.kind&&(x=v.text||a.message):w&&"agent-mode"===w.def.kind&&(x=w.payload||a.message);let y=null;if(w?.def.id==="skill"){let[a,...b]=w.payload.split(/\s+/);if(a){let c=await (0,p.k)(a);c&&(y=c.instructions,x=b.join(" ").trim()||x)}}let z=await (0,o.eF)(b.path,a.topicId),A=z?.meta.goal&&"active"===z.meta.goalStatus?z.meta.goal:void 0,B=await (0,h.M)({root:b.path,scope:b.path,reflexScope:r,language:q}),C=function(a){let b=[],c=new Set;for(let d of a.matchAll(/https?:\/\/[^\s)>'"]+/g)){let a=d[0];try{let d=new URL(a);if(!u.has(d.hostname.toLowerCase())||c.has(a))continue;c.add(a),b.push(a)}catch{}}return b}(x),D=[B,A?(0,m.FB)(A,q):"",v?.kind==="plan"?(0,m.$4)(q):"",w?.def.id==="research"?(0,m.dA)(w.payload,q):"",w?.def.id==="widget"?(0,m.wt)(w.payload,q):"",w?.def.id==="mcp"?(0,m.YE)(w.payload,q):"",w?.def.id==="workflow"?(0,m.vl)(w.payload,q):"",y??"",a.focusFile?function(a,b,c){let d=f().join(b,a);return/russ/i.test(c)||RegExp(t,"i").test(c)?`## Open document — primary context
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
The user is currently reading this KB file: \`${a}\`
|
|
67
|
+
Absolute path: \`${d}\`
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
1.
|
|
71
|
-
2.
|
|
72
|
-
3.
|
|
73
|
-
4.
|
|
74
|
-
5.
|
|
69
|
+
Rules for this turn (respond in Russian):
|
|
70
|
+
1. **Read this file in full via the Read tool first** — it is the primary source of context.
|
|
71
|
+
2. Base your answer primarily on its contents.
|
|
72
|
+
3. Only fall back to neighbouring files (same directory, sibling INDEX.md, parent dir) if the open file lacks the needed info.
|
|
73
|
+
4. Don't guess: if neither the open file nor its neighbours contain the answer, say so explicitly and suggest where to look.
|
|
74
|
+
5. When linking in your reply, use paths relative to the KB root (matching the open file).`:`## Open document — primary context
|
|
75
75
|
|
|
76
76
|
The user is currently reading this KB file: \`${a}\`
|
|
77
77
|
Absolute path: \`${d}\`
|
|
@@ -81,9 +81,9 @@ Rules for this turn:
|
|
|
81
81
|
2. Base your answer primarily on its contents.
|
|
82
82
|
3. Only fall back to neighbouring files (same directory, sibling INDEX.md, parent dir) if the open file lacks the needed info.
|
|
83
83
|
4. Don't guess: if neither the open file nor its neighbours contain the answer, say so explicitly and suggest where to look.
|
|
84
|
-
5. When citing, use rel-paths from the KB root (same convention as the open file).`}(a.focusFile,r,q):"",
|
|
84
|
+
5. When citing, use rel-paths from the KB root (same convention as the open file).`}(a.focusFile,r,q):"",C.length>0?function(a,b){let c=/russ/i.test(b)||RegExp(t,"i").test(b),d=a.map(a=>`- ${a}`).join("\n");return c?["## YouTube video in the message\n\nThe user's message contains YouTube URL(s):",d,'\n**Decide whether you actually need the video\'s content to answer.**\n\n- If the user wants to know **what the video is about** / **what\'s said in it** / a description / summary / quotes / facts — ask Reflex to run a Gemini summary:\n\n```\n<<reflex:youtube-summary>>{"url":"<URL>"}<</reflex:youtube-summary>>\n```\n\n One marker per video, all in the same turn. After emitting markers **STOP** — do not try to answer in this same turn. Reflex will wait for Gemini and re-invoke you with the summary in context.\n\n- If the request **doesn\'t need** the video\'s content (for example "which player is better", "fix this link", "add another video to this") — answer directly, no directive.\n\n- **Do not use WebFetch** for YouTube URLs — it returns neither captions nor video. Only the directive above.\n\n- If the Gemini summary fails (Reflex will return an error message), apologise and suggest saving a key in Settings -> Gemini. Respond in Russian.'].join("\n"):["## YouTube video in the message\n\nThe user's message contains YouTube URL(s):",d,'\n**Decide whether you actually need the video\'s content to answer.**\n\n- If the user wants to know **what the video is about** / **what\'s said in it** / a description / summary / quotes / facts — ask Reflex to run Gemini-summary:\n\n```\n<<reflex:youtube-summary>>{"url":"<URL>"}<</reflex:youtube-summary>>\n```\n\n One marker per video, all in the same turn. After emitting markers **STOP** — don\'t try to answer in this same turn. Reflex will wait for Gemini and re-invoke you with the summary in context.\n\n- If the request **doesn\'t need** the video\'s content ("which player is best", "fix this URL", "add another video") — answer directly, no directive.\n\n- **Don\'t use WebFetch** for YouTube URLs — it gets neither captions nor video. Only the directive above.\n\n- If the Gemini summary fails (Reflex will return an error message), apologise and suggest saving a key in Settings → Gemini.'].join("\n")}(C,q):""].filter(Boolean).join("\n\n"),E=await k.z.ensureAgent({topicId:a.topicId,rootId:a.rootId,rootPath:b.path,reflexScope:r,role:"orchestrator",task:"chat",harness:e,model:l,language:q,label:"Orchestrator"}),F=function(a,b){let c=a.trim();if(!b||0===b.length)return c;let d=b.map(a=>`📎 ${a.name} (${a.absPath})`).join("\n");return c?`${c}
|
|
85
85
|
|
|
86
|
-
${d}`:d}(a.message,a.attachments);return await k.z.emit({type:"user-message",text:
|
|
86
|
+
${d}`:d}(a.message,a.attachments);return await k.z.emit({type:"user-message",text:F,agentId:E.id,ts:new Date().toISOString(),seq:0}),(async()=>{try{let c=await s(b.path,a.topicId),e=function(a,b){let c=["### user",a.trim()||"(no text)"];if(b&&b.length>0)for(let a of(c.push(""),c.push("Attached files (use the Read tool to open them):"),b))c.push(` - ${a.absPath} (${a.mime}, ${a.size} bytes) — original: ${a.name}`);return c.join("\n")}(x,a.attachments),f=c?`Prior conversation:
|
|
87
87
|
|
|
88
88
|
${c}
|
|
89
89
|
|
|
@@ -93,8 +93,8 @@ ${e}
|
|
|
93
93
|
(Reply now.)`:`${e}
|
|
94
94
|
|
|
95
95
|
### assistant
|
|
96
|
-
(Reply now.)`;await k.z.invoke({agentId:
|
|
97
|
-
${e.text.trim()}`),e=null)};for(let a of c)"user-message"===a.type?(f(),e={role:"user",text:a.text},f()):"assistant-delta"===a.type?(e&&"assistant"===e.role||(f(),e={role:"assistant",text:""}),e.text+=a.text):("turn-end"===a.type||"agent-end"===a.type)&&f();return f(),d.join("\n\n")}d()}catch(a){d(a)}})},47423:(a,b,c)=>{c.d(b,{E:()=>e});var d=c(17640);async function e(a){let b=(await (0,d.M)()).harnesses.ollama.baseUrl.replace(/\/$/,""),c=await fetch(`${b}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:a.args.model,system:a.args.systemPrompt,prompt:a.args.prompt,stream:!0})});if(!c.ok||!c.body)throw Error(`Ollama /api/generate HTTP ${c.status}`);let e=c.body.getReader(),f=new TextDecoder,g="";for(;;){let b,{done:c,value:d}=await e.read();if(c)break;for(g+=f.decode(d,{stream:!0});(b=g.indexOf("\n"))>=0;){let c=g.slice(0,b).trim();if(g=g.slice(b+1),c)try{let b=JSON.parse(c);if(b.error)throw Error(b.error);b.response&&await a.manager.emit({type:"assistant-delta",text:b.response,agentId:a.meta.id,ts:new Date().toISOString(),seq:0})}catch{}}}}},56843:(a,b,c)=>{c.d(b,{OY:()=>u,PF:()=>r,_9:()=>t,do:()=>v,eF:()=>p,hk:()=>o,o0:()=>s});var d=c(73024),e=c(76760),f=c.n(e),g=c(77598),h=c.n(g),i=c(30192),j=c.n(i),k=c(13474);function l(a){return f().join((0,k.FF)(a),"topics")}function m(a,b){return f().join(l(a),`${n(b)}.md`)}function n(a){return a.replace(/[^A-Za-z0-9_-]/g,"")}async function o(a){let b,c=l(a);try{b=await d.promises.readdir(c,{withFileTypes:!0})}catch{return[]}let e=[];for(let a of b){if(!a.isFile()||!a.name.toLowerCase().endsWith(".md"))continue;let b=f().join(c,a.name);try{let a=await d.promises.readFile(b,"utf8"),c=j()(a),f=c.data;if(!f.id||!f.createdAt)continue;let g=c.content.replace(/^##\s+(user|assistant)\s*$/gim,"").trim().slice(0,160);e.push({meta:{id:f.id,title:f.title??"Untitled",createdAt:f.createdAt,updatedAt:f.updatedAt??f.createdAt,harness:f.harness,model:f.model,language:f.language,...f.goal?{goal:f.goal}:{},...f.goalStatus?{goalStatus:f.goalStatus}:{},..."number"==typeof f.goalIterations?{goalIterations:f.goalIterations}:{}},preview:g,abs:b})}catch{}}return e.sort((a,b)=>Date.parse(b.meta.updatedAt)-Date.parse(a.meta.updatedAt)),e}async function p(a,b){let c,e=m(a,b);try{c=await d.promises.readFile(e,"utf8")}catch{return null}let f=j()(c),g=f.data;return g.id?{meta:{id:g.id,title:g.title??"Untitled",createdAt:g.createdAt??new Date().toISOString(),updatedAt:g.updatedAt??g.createdAt??new Date().toISOString(),harness:g.harness,model:g.model,language:g.language,...g.goal?{goal:g.goal}:{},...g.goalStatus?{goalStatus:g.goalStatus}:{},..."number"==typeof g.goalIterations?{goalIterations:g.goalIterations}:{}},messages:function(a){let b=[],c=a.split(/\r?\n/),d=null;for(let a of c){let c=/^##\s+(user|assistant)\s*$/i.exec(a);if(c){d&&b.push({...d,body:d.body.trimEnd()}),d={role:c[1].toLowerCase(),body:""};continue}d&&(d.body+=a+"\n")}return d&&b.push({...d,body:d.body.trimEnd()}),b}(f.content),abs:e}:null}async function q(a,b,c){let e=m(a,b),f=await d.promises.readFile(e,"utf8"),g=j()(f),h={...g.data,...c,updatedAt:new Date().toISOString()};for(let a of Object.keys(h))void 0===h[a]&&delete h[a];await d.promises.writeFile(e,j().stringify(g.content,h),"utf8")}async function r(a,b,c){await q(a,b,{goal:c,goalStatus:"active",goalIterations:0})}async function s(a,b){let c=m(a,b),e=await d.promises.readFile(c,"utf8"),f=j()(e).data,g=("number"==typeof f.goalIterations?f.goalIterations:0)+1;return await q(a,b,{goalIterations:g}),g}async function t(a,b,c="abandoned"){await q(a,b,{goalStatus:c})}async function u(a){var b;let c=function(){let a=new Date().toISOString().slice(0,10),b=h().randomBytes(4).toString("hex");return`${a}-${b}`}(),e=new Date().toISOString(),f={id:c,title:function(a){let b=a.trim().split(/\r?\n/)[0]??"Untitled";return b.length>80?b.slice(0,77)+"…":b}(a.firstMessage),createdAt:e,updatedAt:e,...a.harness?{harness:a.harness}:{},...a.model?{model:a.model}:{},...a.language?{language:a.language}:{},...a.helperFor?{helperFor:a.helperFor}:{}};return await d.promises.mkdir(l(a.root),{recursive:!0}),await d.promises.writeFile(m(a.root,c),(b=f,j().stringify("",b)),"utf8"),{meta:f,messages:[],abs:m(a.root,c)}}async function v(a,b){let c=n(b);if(!c)throw Error(`Invalid topic id: ${b}`);let d=m(a,c),e=f().join(l(a),`${c}.events.jsonl`);return{removedMd:await w(d),removedEvents:await w(e)}}async function w(a){try{return await d.promises.unlink(a),!0}catch(a){if("object"==typeof a&&null!==a&&"code"in a&&"ENOENT"===a.code)return!1;throw a}}},59835:(a,b,c)=>{c.d(b,{attachRemote:()=>k,generateImage:()=>h,searchImages:()=>i});var d=c(19219),e=c(43180);async function f(a){let b=await (0,e.CG)("gemini");if(!b)throw Error("Gemini API key is not configured. Open Settings → Gemini.");let c=[{text:a.prompt}];for(let b of a.referenceImageUrls??[]){let a=await g(b);a&&c.push({inlineData:a})}let f={contents:[{role:"user",parts:c}]};a.aspectRatio&&(f.generationConfig={imageConfig:{aspectRatio:a.aspectRatio}});let h=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent?key=${encodeURIComponent(b)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f)});if(!h.ok){let a=await h.text().catch(()=>"");throw Error(`Gemini image API ${h.status}: ${a.slice(0,400)}`)}let i=await h.json(),j=function(a){for(let b of a.candidates??[])for(let a of b.content?.parts??[]){let b=a.inlineData;if(b?.data&&b.mimeType?.startsWith("image/"))return{data:b.data,mime:b.mimeType}}return null}(i);if(!j){let a=i?.candidates?.[0]?.finishReason??"no image returned",b=i?.candidates?.[0]?.content?.parts?.map(a=>a.text).filter(Boolean).join(" ")?.slice(0,300);throw Error(`Gemini вернул не-картинку (${a})${b?": "+b:""}`)}let k=Buffer.from(j.data,"base64");return(0,d.YN)(a.rootId,k,j.mime)}async function g(a){try{let b=await fetch(a,{redirect:"follow"});if(!b.ok)return null;let c=b.headers.get("content-type")?.split(";")[0]?.trim()??"";if(!c.startsWith("image/"))return null;let d=await b.arrayBuffer();return{data:Buffer.from(d).toString("base64"),mimeType:c}}catch{return null}}async function h(a){let b,d=a.provider??"gemini";if("gemini"===d)b=await f({rootId:a.rootId,prompt:a.prompt,...a.aspectRatio?{aspectRatio:a.aspectRatio}:{},...a.referenceImageUrls?{referenceImageUrls:a.referenceImageUrls}:{}});else if("codex"===d){let d=await c.e(6216).then(c.bind(c,76216));b=await d.generateWithCodex({rootId:a.rootId,prompt:a.prompt,...a.size?{size:a.size}:{}})}else throw Error(`unknown image provider: ${d}`);return{urlPath:b.urlPath,sha:b.sha,mime:b.mime,size:b.size,provider:d}}async function i(a){let b=Math.max(1,Math.min(24,a.count??12)),d=a.provider??await j();if("unsplash"===d)return(await c.e(9995).then(c.bind(c,99995))).searchUnsplash({query:a.query,count:b});if("pexels"===d)return(await c.e(9842).then(c.bind(c,39842))).searchPexels({query:a.query,count:b});if("brave"===d)return(await Promise.all([c.e(9631),c.e(2433)]).then(c.bind(c,42433))).searchBrave({query:a.query,count:b});throw Error(`unknown image search provider: ${d}`)}async function j(){let{hasApiKey:a}=await Promise.resolve().then(c.bind(c,43180)),{resolveBraveKey:b}=await Promise.all([c.e(9631),c.e(2433)]).then(c.bind(c,42433));return await b()?"brave":await a("unsplash")?"unsplash":await a("pexels")?"pexels":"brave"}async function k(a){return(0,d.fH)(a.rootId,a.sourceUrl)}},61088:(a,b,c)=>{c.d(b,{He:()=>o,Nb:()=>s,Tf:()=>l,dt:()=>n,listCodexModels:()=>q});var d=c(16435),e=c(73024),f=c(48161),g=c.n(f),h=c(76760),i=c.n(h),j=c(31421);let k=null;function l(){return k||(k=new d.U),k}let m=null;async function n(){return m||(m=(async()=>{let a=process.env.CODEX_HOME||i().join(g().homedir(),".codex"),b=i().join(a,"skills",".system","imagegen"),c=i().join(b,"SKILL.md");try{await e.promises.access(c);return}catch{}let d=i().join(process.cwd(),"lib","server","codex","skills","imagegen","SKILL.md");try{await e.promises.mkdir(b,{recursive:!0}),await e.promises.copyFile(d,c)}catch(a){console.warn("Failed to install Reflex imagegen skill into $CODEX_HOME:",a instanceof Error?a.message:a)}})())}function o(){let a=process.env.CODEX_HOME||i().join(g().homedir(),".codex");return i().join(a,"generated_images")}let p=null;async function q(a={}){if(!a.force&&p&&Date.now()-p.at<6e4)return p.models;let b=await r();return p={at:Date.now(),models:b},b}async function r(){return new Promise((a,b)=>{let c=(0,j.spawn)("codex",["app-server"],{stdio:["pipe","pipe","pipe"]}),d="",e=!1,f=()=>{try{c.kill("SIGTERM")}catch{}},g=setTimeout(()=>{e||(e=!0,f(),b(Error("codex app-server model/list timed out")))},1e4);c.on("error",a=>{e||(e=!0,clearTimeout(g),b(a))}),c.stdout.on("data",b=>{let c=(d+=b.toString("utf8")).indexOf("\n");for(;c>=0;){let b=d.slice(0,c).trim();if(d=d.slice(c+1),b.length>0)try{let c=JSON.parse(b);if(2===c.id&&c.result&&Array.isArray(c.result.data)){let b=[];for(let a of c.result.data)"string"==typeof a?.id&&b.push({id:a.id,displayName:"string"==typeof a.displayName?a.displayName:a.id,description:"string"==typeof a.description?a.description:"",hidden:!0===a.hidden,isDefault:!0===a.isDefault});if(!e){e=!0,clearTimeout(g),f(),a(b);return}}}catch{}c=d.indexOf("\n")}}),c.stderr.on("data",()=>{}),c.stdin.write(JSON.stringify({jsonrpc:"2.0",id:1,method:"initialize",params:{clientInfo:{name:"reflex",title:"Reflex",version:"0.0.0"},capabilities:{}}})+"\n"),c.stdin.write(JSON.stringify({jsonrpc:"2.0",method:"initialized",params:{}})+"\n"),c.stdin.write(JSON.stringify({jsonrpc:"2.0",id:2,method:"model/list",params:{}})+"\n"),c.stdin.end()})}async function s(a){if(!a)return;let b=process.env.CODEX_HOME||i().join(g().homedir(),".codex"),c=i().join(b,"sessions"),d=new Date;for(let b of[-1,0,1]){let f,g=new Date(d);g.setDate(g.getDate()+b);let h=i().join(c,String(g.getFullYear()),String(g.getMonth()+1).padStart(2,"0"),String(g.getDate()).padStart(2,"0"));try{f=await e.promises.readdir(h)}catch{continue}for(let b of f)b.includes(a)&&await e.promises.unlink(i().join(h,b)).catch(()=>{})}}},61992:(a,b,c)=>{c.d(b,{M:()=>k});var d=c(76760),e=c.n(d),f=c(73024),g=c(29163);let h={analyze:`You are populating a local knowledge base (KB) for the directory:
|
|
96
|
+
(Reply now.)`;await k.z.invoke({agentId:E.id,systemPrompt:D,prompt:f,allowedTools:d.allowedTools})}catch(a){await k.z.emit({type:"error",message:a instanceof Error?a.message:String(a),agentId:E.id,ts:new Date().toISOString(),seq:0})}})(),{agentId:E.id}}let u=new Set(["youtube.com","www.youtube.com","m.youtube.com","youtu.be","youtube-nocookie.com","www.youtube-nocookie.com"]);async function s(a,b){let c=await (0,l.wj)(a,b),d=[],e=null,f=()=>{e&&(d.push(`### ${e.role}
|
|
97
|
+
${e.text.trim()}`),e=null)};for(let a of c)"user-message"===a.type?(f(),e={role:"user",text:a.text},f()):"assistant-delta"===a.type?(e&&"assistant"===e.role||(f(),e={role:"assistant",text:""}),e.text+=a.text):("turn-end"===a.type||"agent-end"===a.type)&&f();return f(),d.join("\n\n")}d()}catch(a){d(a)}})},47423:(a,b,c)=>{c.d(b,{E:()=>e});var d=c(17640);async function e(a){let b=(await (0,d.M)()).harnesses.ollama.baseUrl.replace(/\/$/,""),c=await fetch(`${b}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:a.args.model,system:a.args.systemPrompt,prompt:a.args.prompt,stream:!0})});if(!c.ok||!c.body)throw Error(`Ollama /api/generate HTTP ${c.status}`);let e=c.body.getReader(),f=new TextDecoder,g="";for(;;){let b,{done:c,value:d}=await e.read();if(c)break;for(g+=f.decode(d,{stream:!0});(b=g.indexOf("\n"))>=0;){let c=g.slice(0,b).trim();if(g=g.slice(b+1),c)try{let b=JSON.parse(c);if(b.error)throw Error(b.error);b.response&&await a.manager.emit({type:"assistant-delta",text:b.response,agentId:a.meta.id,ts:new Date().toISOString(),seq:0})}catch{}}}}},56843:(a,b,c)=>{c.d(b,{OY:()=>u,PF:()=>r,_9:()=>t,do:()=>v,eF:()=>p,hk:()=>o,o0:()=>s});var d=c(73024),e=c(76760),f=c.n(e),g=c(77598),h=c.n(g),i=c(30192),j=c.n(i),k=c(13474);function l(a){return f().join((0,k.FF)(a),"topics")}function m(a,b){return f().join(l(a),`${n(b)}.md`)}function n(a){return a.replace(/[^A-Za-z0-9_-]/g,"")}async function o(a){let b,c=l(a);try{b=await d.promises.readdir(c,{withFileTypes:!0})}catch{return[]}let e=[];for(let a of b){if(!a.isFile()||!a.name.toLowerCase().endsWith(".md"))continue;let b=f().join(c,a.name);try{let a=await d.promises.readFile(b,"utf8"),c=j()(a),f=c.data;if(!f.id||!f.createdAt)continue;let g=c.content.replace(/^##\s+(user|assistant)\s*$/gim,"").trim().slice(0,160);e.push({meta:{id:f.id,title:f.title??"Untitled",createdAt:f.createdAt,updatedAt:f.updatedAt??f.createdAt,harness:f.harness,model:f.model,language:f.language,...f.goal?{goal:f.goal}:{},...f.goalStatus?{goalStatus:f.goalStatus}:{},..."number"==typeof f.goalIterations?{goalIterations:f.goalIterations}:{}},preview:g,abs:b})}catch{}}return e.sort((a,b)=>Date.parse(b.meta.updatedAt)-Date.parse(a.meta.updatedAt)),e}async function p(a,b){let c,e=m(a,b);try{c=await d.promises.readFile(e,"utf8")}catch{return null}let f=j()(c),g=f.data;return g.id?{meta:{id:g.id,title:g.title??"Untitled",createdAt:g.createdAt??new Date().toISOString(),updatedAt:g.updatedAt??g.createdAt??new Date().toISOString(),harness:g.harness,model:g.model,language:g.language,...g.goal?{goal:g.goal}:{},...g.goalStatus?{goalStatus:g.goalStatus}:{},..."number"==typeof g.goalIterations?{goalIterations:g.goalIterations}:{}},messages:function(a){let b=[],c=a.split(/\r?\n/),d=null;for(let a of c){let c=/^##\s+(user|assistant)\s*$/i.exec(a);if(c){d&&b.push({...d,body:d.body.trimEnd()}),d={role:c[1].toLowerCase(),body:""};continue}d&&(d.body+=a+"\n")}return d&&b.push({...d,body:d.body.trimEnd()}),b}(f.content),abs:e}:null}async function q(a,b,c){let e=m(a,b),f=await d.promises.readFile(e,"utf8"),g=j()(f),h={...g.data,...c,updatedAt:new Date().toISOString()};for(let a of Object.keys(h))void 0===h[a]&&delete h[a];await d.promises.writeFile(e,j().stringify(g.content,h),"utf8")}async function r(a,b,c){await q(a,b,{goal:c,goalStatus:"active",goalIterations:0})}async function s(a,b){let c=m(a,b),e=await d.promises.readFile(c,"utf8"),f=j()(e).data,g=("number"==typeof f.goalIterations?f.goalIterations:0)+1;return await q(a,b,{goalIterations:g}),g}async function t(a,b,c="abandoned"){await q(a,b,{goalStatus:c})}async function u(a){var b;let c=function(){let a=new Date().toISOString().slice(0,10),b=h().randomBytes(4).toString("hex");return`${a}-${b}`}(),e=new Date().toISOString(),f={id:c,title:function(a){let b=a.trim().split(/\r?\n/)[0]??"Untitled";return b.length>80?b.slice(0,77)+"…":b}(a.firstMessage),createdAt:e,updatedAt:e,...a.harness?{harness:a.harness}:{},...a.model?{model:a.model}:{},...a.language?{language:a.language}:{},...a.helperFor?{helperFor:a.helperFor}:{}};return await d.promises.mkdir(l(a.root),{recursive:!0}),await d.promises.writeFile(m(a.root,c),(b=f,j().stringify("",b)),"utf8"),{meta:f,messages:[],abs:m(a.root,c)}}async function v(a,b){let c=n(b);if(!c)throw Error(`Invalid topic id: ${b}`);let d=m(a,c),e=f().join(l(a),`${c}.events.jsonl`);return{removedMd:await w(d),removedEvents:await w(e)}}async function w(a){try{return await d.promises.unlink(a),!0}catch(a){if("object"==typeof a&&null!==a&&"code"in a&&"ENOENT"===a.code)return!1;throw a}}},59835:(a,b,c)=>{c.d(b,{attachRemote:()=>k,generateImage:()=>h,searchImages:()=>i});var d=c(19219),e=c(43180);async function f(a){let b=await (0,e.CG)("gemini");if(!b)throw Error("Gemini API key is not configured. Open Settings → Gemini.");let c=[{text:a.prompt}];for(let b of a.referenceImageUrls??[]){let a=await g(b);a&&c.push({inlineData:a})}let f={contents:[{role:"user",parts:c}]};a.aspectRatio&&(f.generationConfig={imageConfig:{aspectRatio:a.aspectRatio}});let h=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent?key=${encodeURIComponent(b)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f)});if(!h.ok){let a=await h.text().catch(()=>"");throw Error(`Gemini image API ${h.status}: ${a.slice(0,400)}`)}let i=await h.json(),j=function(a){for(let b of a.candidates??[])for(let a of b.content?.parts??[]){let b=a.inlineData;if(b?.data&&b.mimeType?.startsWith("image/"))return{data:b.data,mime:b.mimeType}}return null}(i);if(!j){let a=i?.candidates?.[0]?.finishReason??"no image returned",b=i?.candidates?.[0]?.content?.parts?.map(a=>a.text).filter(Boolean).join(" ")?.slice(0,300);throw Error(`Gemini returned a non-image response (${a})${b?": "+b:""}`)}let k=Buffer.from(j.data,"base64");return(0,d.YN)(a.rootId,k,j.mime)}async function g(a){try{let b=await fetch(a,{redirect:"follow"});if(!b.ok)return null;let c=b.headers.get("content-type")?.split(";")[0]?.trim()??"";if(!c.startsWith("image/"))return null;let d=await b.arrayBuffer();return{data:Buffer.from(d).toString("base64"),mimeType:c}}catch{return null}}async function h(a){let b,d=a.provider??"gemini";if("gemini"===d)b=await f({rootId:a.rootId,prompt:a.prompt,...a.aspectRatio?{aspectRatio:a.aspectRatio}:{},...a.referenceImageUrls?{referenceImageUrls:a.referenceImageUrls}:{}});else if("codex"===d){let d=await c.e(6216).then(c.bind(c,76216));b=await d.generateWithCodex({rootId:a.rootId,prompt:a.prompt,...a.size?{size:a.size}:{}})}else throw Error(`unknown image provider: ${d}`);return{urlPath:b.urlPath,sha:b.sha,mime:b.mime,size:b.size,provider:d}}async function i(a){let b=Math.max(1,Math.min(24,a.count??12)),d=a.provider??await j();if("unsplash"===d)return(await c.e(9995).then(c.bind(c,99995))).searchUnsplash({query:a.query,count:b});if("pexels"===d)return(await c.e(9842).then(c.bind(c,39842))).searchPexels({query:a.query,count:b});if("brave"===d)return(await Promise.all([c.e(9631),c.e(2433)]).then(c.bind(c,42433))).searchBrave({query:a.query,count:b});throw Error(`unknown image search provider: ${d}`)}async function j(){let{hasApiKey:a}=await Promise.resolve().then(c.bind(c,43180)),{resolveBraveKey:b}=await Promise.all([c.e(9631),c.e(2433)]).then(c.bind(c,42433));return await b()?"brave":await a("unsplash")?"unsplash":await a("pexels")?"pexels":"brave"}async function k(a){return(0,d.fH)(a.rootId,a.sourceUrl)}},61088:(a,b,c)=>{c.d(b,{He:()=>o,Nb:()=>s,Tf:()=>l,dt:()=>n,listCodexModels:()=>q});var d=c(16435),e=c(73024),f=c(48161),g=c.n(f),h=c(76760),i=c.n(h),j=c(31421);let k=null;function l(){return k||(k=new d.U),k}let m=null;async function n(){return m||(m=(async()=>{let a=process.env.CODEX_HOME||i().join(g().homedir(),".codex"),b=i().join(a,"skills",".system","imagegen"),c=i().join(b,"SKILL.md");try{await e.promises.access(c);return}catch{}let d=i().join(process.cwd(),"lib","server","codex","skills","imagegen","SKILL.md");try{await e.promises.mkdir(b,{recursive:!0}),await e.promises.copyFile(d,c)}catch(a){console.warn("Failed to install Reflex imagegen skill into $CODEX_HOME:",a instanceof Error?a.message:a)}})())}function o(){let a=process.env.CODEX_HOME||i().join(g().homedir(),".codex");return i().join(a,"generated_images")}let p=null;async function q(a={}){if(!a.force&&p&&Date.now()-p.at<6e4)return p.models;let b=await r();return p={at:Date.now(),models:b},b}async function r(){return new Promise((a,b)=>{let c=(0,j.spawn)("codex",["app-server"],{stdio:["pipe","pipe","pipe"]}),d="",e=!1,f=()=>{try{c.kill("SIGTERM")}catch{}},g=setTimeout(()=>{e||(e=!0,f(),b(Error("codex app-server model/list timed out")))},1e4);c.on("error",a=>{e||(e=!0,clearTimeout(g),b(a))}),c.stdout.on("data",b=>{let c=(d+=b.toString("utf8")).indexOf("\n");for(;c>=0;){let b=d.slice(0,c).trim();if(d=d.slice(c+1),b.length>0)try{let c=JSON.parse(b);if(2===c.id&&c.result&&Array.isArray(c.result.data)){let b=[];for(let a of c.result.data)"string"==typeof a?.id&&b.push({id:a.id,displayName:"string"==typeof a.displayName?a.displayName:a.id,description:"string"==typeof a.description?a.description:"",hidden:!0===a.hidden,isDefault:!0===a.isDefault});if(!e){e=!0,clearTimeout(g),f(),a(b);return}}}catch{}c=d.indexOf("\n")}}),c.stderr.on("data",()=>{}),c.stdin.write(JSON.stringify({jsonrpc:"2.0",id:1,method:"initialize",params:{clientInfo:{name:"reflex",title:"Reflex",version:"0.0.0"},capabilities:{}}})+"\n"),c.stdin.write(JSON.stringify({jsonrpc:"2.0",method:"initialized",params:{}})+"\n"),c.stdin.write(JSON.stringify({jsonrpc:"2.0",id:2,method:"model/list",params:{}})+"\n"),c.stdin.end()})}async function s(a){if(!a)return;let b=process.env.CODEX_HOME||i().join(g().homedir(),".codex"),c=i().join(b,"sessions"),d=new Date;for(let b of[-1,0,1]){let f,g=new Date(d);g.setDate(g.getDate()+b);let h=i().join(c,String(g.getFullYear()),String(g.getMonth()+1).padStart(2,"0"),String(g.getDate()).padStart(2,"0"));try{f=await e.promises.readdir(h)}catch{continue}for(let b of f)b.includes(a)&&await e.promises.unlink(i().join(h,b)).catch(()=>{})}}},61992:(a,b,c)=>{c.d(b,{M:()=>k});var d=c(76760),e=c.n(d),f=c(73024),g=c(29163);let h={analyze:`You are populating a local knowledge base (KB) for the directory:
|
|
98
98
|
{{scope}}
|
|
99
99
|
|
|
100
100
|
Project root: {{root}}
|
|
@@ -176,43 +176,43 @@ decision as your next user message.
|
|
|
176
176
|
|
|
177
177
|
<<reflex:permission>>{"tool":"Write","input":{"file_path":"…"},"description":"Why you need it"}<</reflex:permission>>
|
|
178
178
|
|
|
179
|
-
If you need a clarifying answer from the user, emit a question marker.
|
|
179
|
+
If you need a clarifying answer from the user, emit a question marker. **DO NOT use the native \`AskUserQuestion\` tool — it is not allowed in Reflex.** Use only the marker below — it supports everything (header, multiSelect, label+description) and more.
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
Simple variant with ready-made answers:
|
|
182
182
|
|
|
183
|
-
<<reflex:question>>{"prompt":"
|
|
183
|
+
<<reflex:question>>{"prompt":"Which language for the summary?","choices":["english","russian"]}<</reflex:question>>
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
Detailed variant with label+description (like AskUserQuestion):
|
|
186
186
|
|
|
187
187
|
<<reflex:question>>{
|
|
188
188
|
"id":"section",
|
|
189
|
-
"header":"
|
|
190
|
-
"prompt":"
|
|
189
|
+
"header":"Section",
|
|
190
|
+
"prompt":"Which section should we start with?",
|
|
191
191
|
"multiSelect":false,
|
|
192
192
|
"options":[
|
|
193
|
-
{"label":"
|
|
194
|
-
{"label":"
|
|
193
|
+
{"label":"History","description":"F1 timeline since 1950"},
|
|
194
|
+
{"label":"Season 2025","description":"Calendar and tables for the current season"}
|
|
195
195
|
]
|
|
196
196
|
}<</reflex:question>>
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
Multiple questions in one marker (batch — Reflex will show them as sequential cards):
|
|
199
199
|
|
|
200
200
|
<<reflex:question>>{
|
|
201
201
|
"questions":[
|
|
202
|
-
{"id":"section","header":"
|
|
203
|
-
{"id":"depth","header":"
|
|
202
|
+
{"id":"section","header":"Section","prompt":"Which section should we start with?","options":[…]},
|
|
203
|
+
{"id":"depth","header":"Depth","prompt":"How detailed should the articles be?","options":[…]}
|
|
204
204
|
]
|
|
205
205
|
}<</reflex:question>>
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
- \`prompt\` —
|
|
209
|
-
- \`header\` —
|
|
210
|
-
- \`multiSelect\` — \`true\`
|
|
211
|
-
- \`options\` —
|
|
212
|
-
- \`choices\` — legacy
|
|
213
|
-
- \`id\` —
|
|
207
|
+
Fields:
|
|
208
|
+
- \`prompt\` — required. The question itself, ~4-12 words.
|
|
209
|
+
- \`header\` — short tag label (≤12 chars): "Section", "Language", "Size". Optional.
|
|
210
|
+
- \`multiSelect\` — \`true\` if multiple options can be selected. Reflex returns the answer as a JSON array of strings.
|
|
211
|
+
- \`options\` — list of \`{label, description?}\`. Description — 1 line of context under the label.
|
|
212
|
+
- \`choices\` — legacy flat array of strings. For simple cases. Don't combine with \`options\`.
|
|
213
|
+
- \`id\` — stable id if you need to correlate the answer. Reflex generates one if omitted.
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
After emitting the marker(s) — STOP. Reflex will show the card, wait for the answer, and continue your turn.
|
|
216
216
|
|
|
217
217
|
## Routing: you are an orchestrator, not the worker
|
|
218
218
|
|
|
@@ -222,16 +222,16 @@ sub-agent instead of doing it yourself. Sub-agents run with a focused system
|
|
|
222
222
|
prompt and a constrained toolset, so they're faster and stay in their lane.
|
|
223
223
|
|
|
224
224
|
Available roles:
|
|
225
|
-
- **researcher** — read-only KB / web research (Read, Glob, Grep, WebFetch, WebSearch). Use for "
|
|
226
|
-
- **coder** — writes/edits files (Write, Edit, MultiEdit + read tools). Use for "
|
|
227
|
-
- **summarizer** — no tools; compresses long text passed in the brief. Use for "
|
|
225
|
+
- **researcher** — read-only KB / web research (Read, Glob, Grep, WebFetch, WebSearch). Use for "find / gather / quote".
|
|
226
|
+
- **coder** — writes/edits files (Write, Edit, MultiEdit + read tools). Use for "do / fix / create a file".
|
|
227
|
+
- **summarizer** — no tools; compresses long text passed in the brief. Use for "compress / extract the main points" from a large chunk.
|
|
228
228
|
- **kb-writer** — designs a structured KB entry (returns JSON for <<reflex:kb>>). Use when something is worth saving but the shape is non-trivial.
|
|
229
229
|
- **utility-builder** — designs a Reflex utility (manifest + ui.tsx). Use when the user asks to build a new utility.
|
|
230
230
|
|
|
231
231
|
To dispatch, emit one or more dispatch markers in a single turn and STOP:
|
|
232
232
|
|
|
233
|
-
<<reflex:dispatch>>{"id":"r1","role":"researcher","brief":"
|
|
234
|
-
<<reflex:dispatch>>{"id":"c1","role":"coder","brief":"
|
|
233
|
+
<<reflex:dispatch>>{"id":"r1","role":"researcher","brief":"Read {{reflexScope}}/INDEX.md and collect a list of all topics."}<</reflex:dispatch>>
|
|
234
|
+
<<reflex:dispatch>>{"id":"c1","role":"coder","brief":"Add a \`tags\` field to schema/note.md and update the examples."}<</reflex:dispatch>>
|
|
235
235
|
|
|
236
236
|
Rules:
|
|
237
237
|
- The \`brief\` must be self-contained. Sub-agents do NOT see the chat
|
|
@@ -248,11 +248,11 @@ Rules:
|
|
|
248
248
|
- Don't re-dispatch the same brief if a sub-agent returned an empty or
|
|
249
249
|
unhelpful result — either solve it yourself or ask the user.
|
|
250
250
|
|
|
251
|
-
## Knowledge-base writes —
|
|
251
|
+
## Knowledge-base writes — ONLY via the \`<<reflex:kb>>\` marker
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
**CRITICAL.** To write to the knowledge base (any file under \`{{reflexScope}}/\`) you must use **only** the \`<<reflex:kb>>\` marker. **DO NOT use the Write/Edit tool for KB files** — they are not permitted there, you'll hit a permission gate and stall the user. Reflex creates the file under \`{{reflexScope}}/<kind>/<date>-<slug>.md\` with the correct structure and frontmatter; no Write needed.
|
|
254
254
|
|
|
255
|
-
<<reflex:kb>>{"kind":"fact","title":"
|
|
255
|
+
<<reflex:kb>>{"kind":"fact","title":"Short title","body":"# H1\\n\\nDetailed description in Markdown","meta":{"tags":["finance"]}}<</reflex:kb>>
|
|
256
256
|
|
|
257
257
|
Fields:
|
|
258
258
|
- kind — \`fact\` | \`task\` | \`meeting\` | \`product\` | any kebab-case noun
|
|
@@ -269,39 +269,39 @@ Conventional \`meta\` shapes:
|
|
|
269
269
|
- fact → {"tags":["…"],"source":"…"}
|
|
270
270
|
|
|
271
271
|
Rules:
|
|
272
|
-
-
|
|
273
|
-
- Write/Edit
|
|
274
|
-
-
|
|
272
|
+
- Emit a marker for **each** entry, even if there are 50+. Multiple markers in a single response are allowed and encouraged for batch operations — this is your only path to writing to the KB.
|
|
273
|
+
- Write/Edit are allowed for **code and files outside \`.reflex/\`** (project sources). For anything that should land in the knowledge base — only \`<<reflex:kb>>\`.
|
|
274
|
+
- Don't duplicate the marker contents in the regular response text — the marker is canonical.
|
|
275
275
|
- The UI shows each saved entry as a card linking to the new file.
|
|
276
|
-
-
|
|
276
|
+
- If the user explicitly asks "do a Write" to a file under \`.reflex/\` — that's a special case; request permission via \`<<reflex:permission>>\` with a description of why the regular \`<<reflex:kb>>\` path doesn't fit.
|
|
277
277
|
|
|
278
|
-
## /reflex:utility —
|
|
278
|
+
## /reflex:utility — utility generation
|
|
279
279
|
|
|
280
|
-
Reflex
|
|
280
|
+
Reflex supports mini-applications ("utilities") that you can create right from chat. A utility lives in a separate directory (\`~/.reflex/utilities/<id>/\` for global or \`<root>/.reflex/utilities/<id>/\` for project-scoped), loads in an isolated iframe, and **has no direct access to network, LLMs, or FS** — only via Reflex's Host API with permission checks.
|
|
281
281
|
|
|
282
|
-
|
|
282
|
+
To create a utility, emit a marker:
|
|
283
283
|
|
|
284
284
|
<<reflex:utility>>{"scope":"global","manifest":{...},"files":{...}}<</reflex:utility>>
|
|
285
285
|
|
|
286
|
-
###
|
|
286
|
+
### Hard rules
|
|
287
287
|
|
|
288
|
-
1. **UI** —
|
|
289
|
-
2.
|
|
290
|
-
- \`"react"\`, \`"react-dom"\`, \`"react-dom/client"\` —
|
|
291
|
-
- \`"@host/api"\` —
|
|
292
|
-
- \`"@host/ui"\` —
|
|
293
|
-
-
|
|
294
|
-
3.
|
|
295
|
-
4.
|
|
296
|
-
5.
|
|
288
|
+
1. **UI** — a single React functional-component default-export, TypeScript. Put it in files["ui.tsx"].
|
|
289
|
+
2. **Imports ONLY**:
|
|
290
|
+
- \`"react"\`, \`"react-dom"\`, \`"react-dom/client"\` — resolved by the bundler.
|
|
291
|
+
- \`"@host/api"\` — gives the \`{ reflex }\` object (see below).
|
|
292
|
+
- \`"@host/ui"\` — gives primitives: Button, Input, Textarea, Label, Card, CardContent, CardHeader, CardTitle, Badge, ScrollArea.
|
|
293
|
+
- No other packages / node_modules / node:* modules. esbuild rejects any other import.
|
|
294
|
+
3. **No fetch/XHR/WebSocket/localStorage** inside the utility. Only \`reflex.web.fetch({url})\` with an explicitly whitelisted domain in the manifest.
|
|
295
|
+
4. **State** is persisted via \`reflex.fs.write({path, content})\` (in \`<utility>/data/\`) or \`reflex.kb.add({...})\`.
|
|
296
|
+
5. **Manifest** must list every required permission — the user sees this list at install time and can refuse.
|
|
297
297
|
|
|
298
|
-
###
|
|
298
|
+
### Manifest (JSON)
|
|
299
299
|
|
|
300
300
|
\`\`\`json
|
|
301
301
|
{
|
|
302
302
|
"id": "kebab-case-id",
|
|
303
|
-
"name": "
|
|
304
|
-
"description": "
|
|
303
|
+
"name": "Human-readable name",
|
|
304
|
+
"description": "What the utility does",
|
|
305
305
|
"version": "1.0.0",
|
|
306
306
|
"ui": "ui.tsx",
|
|
307
307
|
"permissions": {
|
|
@@ -316,111 +316,111 @@ Reflex поддерживает мини-приложения (\xabутилит
|
|
|
316
316
|
{"name": "summarize", "entry": "actions/summarize.ts", "timeoutMs": 30000}
|
|
317
317
|
],
|
|
318
318
|
"secrets": [
|
|
319
|
-
{"key": "OPENAI_API_KEY", "label": "OpenAI API key", "description": "
|
|
319
|
+
{"key": "OPENAI_API_KEY", "label": "OpenAI API key", "description": "Needed for calls to api.openai.com from this utility.", "required": true}
|
|
320
320
|
],
|
|
321
321
|
"mcpServers": ["github", "google-calendar"]
|
|
322
322
|
}
|
|
323
323
|
\`\`\`
|
|
324
324
|
|
|
325
|
-
### Host API (
|
|
325
|
+
### Host API (what's available on the \`reflex\` object)
|
|
326
326
|
|
|
327
|
-
- \`reflex.llm.complete({task, prompt, model?})\` → \`{text}\` — non-streaming LLM
|
|
327
|
+
- \`reflex.llm.complete({task, prompt, model?})\` → \`{text}\` — non-streaming LLM call. task ∈ {"chat","quick","rag","embed"}.
|
|
328
328
|
- \`reflex.kb.add({kind, title, body, meta?, rootId?})\` → \`{relPath, absPath}\`.
|
|
329
|
-
- \`reflex.kb.list({kind?, query?, rootId?})\` →
|
|
329
|
+
- \`reflex.kb.list({kind?, query?, rootId?})\` → array of summaries.
|
|
330
330
|
- \`reflex.kb.read({relPath, rootId?})\` → \`{content}\`.
|
|
331
|
-
- \`reflex.fs.read({path})\` / \`fs.write({path, content})\` / \`fs.list({path})\` —
|
|
332
|
-
- \`reflex.web.fetch({url, method?, headers?, body?})\` → \`{status, headers, body}\`. URL
|
|
331
|
+
- \`reflex.fs.read({path})\` / \`fs.write({path, content})\` / \`fs.list({path})\` — sandboxed to \`<utility>/data/\`.
|
|
332
|
+
- \`reflex.web.fetch({url, method?, headers?, body?})\` → \`{status, headers, body}\`. URL must be in \`permissions.web.fetch.domains\`.
|
|
333
333
|
- \`reflex.web.search({query})\` → \`{results: [{title, url, snippet}]}\`.
|
|
334
|
-
- \`reflex.audit.log({type, payload})\` —
|
|
335
|
-
- \`reflex.actions.invoke({name, args})\` —
|
|
336
|
-
- \`reflex.secrets.get({key})\` → \`{value}\` —
|
|
337
|
-
- \`reflex.secrets.list()\` → \`{secrets: [{key, label, description, required, set}]}\` — UI
|
|
338
|
-
- \`reflex.mcp.listServers()\` → \`{servers: [{id, label, description, registered}]}\` —
|
|
339
|
-
- \`reflex.mcp.listTools({server?})\` → \`{server, tools: [{name, description?, inputSchema?}]}\` —
|
|
340
|
-
- \`reflex.mcp.call({server?, tool, args})\` → \`{server, isError?, content}\` —
|
|
334
|
+
- \`reflex.audit.log({type, payload})\` — custom audit log entry.
|
|
335
|
+
- \`reflex.actions.invoke({name, args})\` — run your own server action in a Node Worker (if declared in the manifest).
|
|
336
|
+
- \`reflex.secrets.get({key})\` → \`{value}\` — reads a secret filled in by the user. \`key\` must be from \`manifest.secrets\`, otherwise error. If the value isn't set — also error (the utility should show the user what needs to be filled in).
|
|
337
|
+
- \`reflex.secrets.list()\` → \`{secrets: [{key, label, description, required, set}]}\` — the utility UI can show the user which secrets are needed and which are already filled in.
|
|
338
|
+
- \`reflex.mcp.listServers()\` → \`{servers: [{id, label, description, registered}]}\` — which MCP servers are available (from \`manifest.mcpServers\`) and which of them are actually registered in the system.
|
|
339
|
+
- \`reflex.mcp.listTools({server?})\` → \`{server, tools: [{name, description?, inputSchema?}]}\` — list of tools for a specific MCP server. If exactly one is declared in \`mcpServers\` — \`server\` can be omitted.
|
|
340
|
+
- \`reflex.mcp.call({server?, tool, args})\` → \`{server, isError?, content}\` — invoke an MCP tool. Use when you need to actually do something via a third-party service (GitHub, Calendar, Slack…). The server must be in \`manifest.mcpServers\` AND registered by the user in Settings → MCP.
|
|
341
341
|
|
|
342
|
-
###
|
|
342
|
+
### Secrets
|
|
343
343
|
|
|
344
|
-
|
|
344
|
+
If the utility needs confidential data (API keys, tokens, passwords) — **declare them in the manifest, don't bake them into code**:
|
|
345
345
|
|
|
346
346
|
\`\`\`json
|
|
347
347
|
"secrets": [
|
|
348
|
-
{"key": "OPENAI_API_KEY", "label": "OpenAI API key", "description": "
|
|
348
|
+
{"key": "OPENAI_API_KEY", "label": "OpenAI API key", "description": "What this is and why", "required": true}
|
|
349
349
|
]
|
|
350
350
|
\`\`\`
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
- \`key\` — UPPER_SNAKE_CASE (
|
|
354
|
-
-
|
|
355
|
-
-
|
|
356
|
-
-
|
|
352
|
+
Rules:
|
|
353
|
+
- \`key\` — UPPER_SNAKE_CASE (like env vars).
|
|
354
|
+
- The description (\`label\` + \`description\`) is **shown to the user** in the utility's right-hand panel, where they fill in the value themselves. Explain clearly: what it is, where to get it, what it affects.
|
|
355
|
+
- **You as the agent DO NOT SEE the secret values** — they're stored in \`~/.reflex/secrets/\` outside your sandbox. Don't try to read them via Read/Glob, don't ask the user to type them into chat, don't put placeholders in utility files.
|
|
356
|
+
- Inside the utility use it like this: \`const {value: apiKey} = await reflex.secrets.get({key: "OPENAI_API_KEY"});\`. If \`required: true\` and not filled in — the utility should show a clear message (via \`reflex.secrets.list()\` and a UI card "Fill in secrets", not crash in the console).
|
|
357
357
|
|
|
358
|
-
###
|
|
358
|
+
### Registering an MCP server from chat
|
|
359
359
|
|
|
360
|
-
|
|
360
|
+
If the answer requires an MCP server that isn't yet in the registry — **don't ask** the user to go to Settings manually. Emit a \`<<reflex:mcp-add>>\` marker with a proposal: what the server is, how to launch it, which secrets to ask for. Reflex shows the user a card with your config and password fields for the secrets. Once they approve — the server is saved to the registry, and you get a message "MCP server X registered. You can now call …", after which call \`mcp__<id>__<tool>\` immediately.
|
|
361
361
|
|
|
362
|
-
<<reflex:mcp-add>>{"id":"mcp1","server":"google-calendar","label":"Google Calendar","description":"
|
|
362
|
+
<<reflex:mcp-add>>{"id":"mcp1","server":"google-calendar","label":"Google Calendar","description":"Read/create events in Google Calendar.","config":{"transport":"stdio","command":"npx","args":["-y","@modelcontextprotocol/server-google-calendar"],"env":{}},"secrets":[{"envKey":"GOOGLE_OAUTH_TOKEN","label":"Access token","description":"Get one via https://developers.google.com/oauthplayground (scope https://www.googleapis.com/auth/calendar). Copy the access_token.","required":true}]}<</reflex:mcp-add>>
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
- \`server\` — kebab-case id
|
|
366
|
-
- \`config\` — McpConfig: stdio (command/args/env), http/sse (url/headers).
|
|
367
|
-
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
370
|
-
-
|
|
364
|
+
Rules:
|
|
365
|
+
- \`server\` — kebab-case id under which it will live in the registry (and from which the tool prefix \`mcp__<id>__\` is derived). Not to be confused with \`id\` (correlation id for you).
|
|
366
|
+
- \`config\` — McpConfig: stdio (command/args/env), http/sse (url/headers). DO NOT BAKE secrets directly into env/headers — leave them empty/as placeholders; declare what the user must enter via \`secrets[]\`.
|
|
367
|
+
- For stdio, secrets go into \`env\`; for http/sse — into \`headers\` (key name = \`envKey\`).
|
|
368
|
+
- In the secret's \`description\` you **must** tell the user where to get the token.
|
|
369
|
+
- Don't try to read the secret values yourself after registration — they're only for the server, you don't see them.
|
|
370
|
+
- If the user declined — DO NOT try the same configuration again. Ask what was wrong via \`<<reflex:question>>\` or pick an alternative.
|
|
371
371
|
|
|
372
|
-
####
|
|
372
|
+
#### Full OAuth (auto-refresh)
|
|
373
373
|
|
|
374
|
-
Reflex
|
|
374
|
+
Reflex supports a built-in OAuth flow with a local callback, persisted refresh tokens, and auto-renewal. Supported providers: \`google\`, \`github\`, \`notion\`, \`slack\`, \`linear\`. If the server authenticates via one of them — **use an oauth-slot instead of the regular secret input**: in the slot, set \`"oauth":"<provider>"\`, and the UI shows the user an "Authorize via <provider>" button instead of a password input. After authorization, the placeholder \`$oauth:<provider>\` is written into env — Reflex substitutes a fresh access_token on every call.
|
|
375
375
|
|
|
376
|
-
<<reflex:mcp-add>>{"id":"mcp1","server":"google-calendar","label":"Google Calendar","config":{"transport":"stdio","command":"npx","args":["-y","@modelcontextprotocol/server-google-calendar"],"env":{}},"secrets":[{"envKey":"GOOGLE_OAUTH_TOKEN","label":"Access token","oauth":"google","required":true,"description":"Reflex
|
|
376
|
+
<<reflex:mcp-add>>{"id":"mcp1","server":"google-calendar","label":"Google Calendar","config":{"transport":"stdio","command":"npx","args":["-y","@modelcontextprotocol/server-google-calendar"],"env":{}},"secrets":[{"envKey":"GOOGLE_OAUTH_TOKEN","label":"Access token","oauth":"google","required":true,"description":"Reflex will open a Google OAuth window and save the refresh token. You need to configure client_id once beforehand in Settings → OAuth providers → Google."}]}<</reflex:mcp-add>>
|
|
377
377
|
|
|
378
|
-
|
|
378
|
+
When to do this: for any wrapper server over a service from the list above (Google Calendar/Gmail/Drive, GitHub, Notion, Slack, Linear). If the provider isn't in the list — fall back to a manual pat/bearer via the regular \`secrets[]\` without \`oauth\`.
|
|
379
379
|
|
|
380
|
-
### MCP
|
|
380
|
+
### MCP servers (external services)
|
|
381
381
|
|
|
382
|
-
Reflex
|
|
382
|
+
Reflex stores a **global MCP server registry** (Settings → MCP) — Google Calendar, GitHub, Slack, any compatible server. A utility gets access to them by declaring their ids in the manifest:
|
|
383
383
|
|
|
384
384
|
\`\`\`json
|
|
385
385
|
"mcpServers": ["github", "google-calendar"]
|
|
386
386
|
\`\`\`
|
|
387
387
|
|
|
388
|
-
|
|
389
|
-
-
|
|
390
|
-
-
|
|
391
|
-
-
|
|
392
|
-
-
|
|
388
|
+
Rules:
|
|
389
|
+
- Server IDs are kebab-case and must match what's in the registry. If a server isn't in the registry — \`reflex.mcp.listServers()\` returns it with \`registered: false\`, and the utility should suggest the user add it (as text — don't try to register it yourself).
|
|
390
|
+
- DO NOT use \`reflex.llm.complete\` to "execute a tool call" — the LLM returns only text. To actually invoke a tool, call \`reflex.mcp.call({server, tool, args})\` directly.
|
|
391
|
+
- The server config (command/args/url/env) is stored centrally — don't duplicate it in the utility and don't ask the user for it; they already set it once in Settings.
|
|
392
|
+
- If \`mcpServers\` is empty or a declared server isn't registered — the utility should render a clear "Register server X in Settings → MCP" message rather than crash.
|
|
393
393
|
|
|
394
|
-
|
|
394
|
+
The chat agent (orchestrator) **also** has native MCP via \`--mcp-config\`, which Reflex automatically forwards to the claude-code CLI. Tools there are available as \`mcp__<server-id>__<tool-name>\` (e.g. \`mcp__github__list_repos\`). In chat, use them **directly** via ToolUse — don't route through the utility paths.
|
|
395
395
|
|
|
396
|
-
### Server actions (
|
|
396
|
+
### Server actions (heavy server-side logic)
|
|
397
397
|
|
|
398
|
-
|
|
398
|
+
If a utility needs to do something in Node, declare \`serverActions\` in the manifest. Each action is a .ts file in \`files["actions/<name>.ts"]\` with a default export:
|
|
399
399
|
|
|
400
400
|
\`\`\`ts
|
|
401
401
|
import { reflex } from "@host/api";
|
|
402
402
|
export default async function run(args, host) {
|
|
403
|
-
// host === reflex;
|
|
403
|
+
// host === reflex; use for llm/fs/kb/web calls
|
|
404
404
|
const data = await host.fs.read({path: args.path});
|
|
405
405
|
return {summary: data.content.slice(0, 200)};
|
|
406
406
|
}
|
|
407
407
|
\`\`\`
|
|
408
408
|
|
|
409
|
-
|
|
409
|
+
The action runs in a Worker thread with the same permissions as the UI. The Worker is terminated after a single invocation. Hard limits: 256MB heap, timeout per \`timeoutMs\`.
|
|
410
410
|
|
|
411
|
-
###
|
|
411
|
+
### Files
|
|
412
412
|
|
|
413
|
-
- \`ui.tsx\` — entry React component (
|
|
414
|
-
- \`README.md\` —
|
|
415
|
-
- \`actions/<name>.ts\` — server actions (
|
|
413
|
+
- \`ui.tsx\` — entry React component (required).
|
|
414
|
+
- \`README.md\` — description (recommended).
|
|
415
|
+
- \`actions/<name>.ts\` — server actions (if declared).
|
|
416
416
|
|
|
417
|
-
Tailwind
|
|
417
|
+
Tailwind classes are available via the standard sheet (cdn.jsdelivr.net/npm/tailwindcss).
|
|
418
418
|
|
|
419
|
-
###
|
|
419
|
+
### When to use
|
|
420
420
|
|
|
421
|
-
|
|
421
|
+
Emit \`<<reflex:utility>>\` only if the user explicitly asks to create a utility / mini-app / form / generator. For one-off tasks — a regular reply. If unsure — ask via \`<<reflex:question>>\`.
|
|
422
422
|
|
|
423
|
-
|
|
423
|
+
After the marker, the system shows a "Utility installed" card with a link; don't duplicate the name in prose.
|
|
424
424
|
|
|
425
425
|
## General rules
|
|
426
426
|
|
|
@@ -429,9 +429,9 @@ Tailwind-классы доступны через стандартную таб
|
|
|
429
429
|
- Markers must be valid JSON on a single block (whitespace inside is fine).
|
|
430
430
|
- You may proceed normally without any marker; only use them when blocked
|
|
431
431
|
or when there's knowledge worth persisting.
|
|
432
|
-
`},i=e().join((0,g._)(),"prompts");async function j(a){let b=e().join(i,`${a}.md`);try{return await f.promises.readFile(b,"utf8")}catch(a){var c;if(!("object"==typeof(c=a)&&null!==c&&"code"in c&&"ENOENT"===c.code))throw a}return await f.promises.mkdir(i,{recursive:!0}),await f.promises.writeFile(b,h[a],"utf8"),h[a]}async function k(a){var b,c;return[(b=await j("chat"),c={language:a.language??"english",root:a.root,scope:a.scope,reflexScope:a.reflexScope},b.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g,(a,b)=>{let d=c[b];return void 0===d?a:String(d)})),'## Routing: you are an orchestrator, not the worker\n\nFor anything non-trivial (deep KB reading, multi-file research, code writes, utility creation, summarization of large texts) — DELEGATE to a specialist sub-agent instead of doing it yourself. Sub-agents run with a focused system prompt and a constrained toolset.\n\nAvailable roles:\n - **researcher** — read-only KB / web research. Use for "
|
|
432
|
+
`},i=e().join((0,g._)(),"prompts");async function j(a){let b=e().join(i,`${a}.md`);try{return await f.promises.readFile(b,"utf8")}catch(a){var c;if(!("object"==typeof(c=a)&&null!==c&&"code"in c&&"ENOENT"===c.code))throw a}return await f.promises.mkdir(i,{recursive:!0}),await f.promises.writeFile(b,h[a],"utf8"),h[a]}async function k(a){var b,c;return[(b=await j("chat"),c={language:a.language??"english",root:a.root,scope:a.scope,reflexScope:a.reflexScope},b.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g,(a,b)=>{let d=c[b];return void 0===d?a:String(d)})),'## Routing: you are an orchestrator, not the worker\n\nFor anything non-trivial (deep KB reading, multi-file research, code writes, utility creation, summarization of large texts) — DELEGATE to a specialist sub-agent instead of doing it yourself. Sub-agents run with a focused system prompt and a constrained toolset.\n\nAvailable roles:\n - **researcher** — read-only KB / web research. Use for "find / gather / quote".\n - **coder** — writes/edits files (Write/Edit + read tools). Use for "do / fix / create a file".\n - **summarizer** — no tools; compresses long text from the brief. Use for "compress / extract the main points" from a large chunk.\n - **kb-writer** — designs a structured KB entry (returns JSON for <<reflex:kb>>). Use when something is worth saving but the shape is non-trivial.\n - **utility-builder** — designs a Reflex utility (manifest + ui.tsx). Use when the user asks to build a new utility.\n\nTo dispatch, emit one or more markers in a single turn and STOP:\n\n <<reflex:dispatch>>{"id":"r1","role":"researcher","brief":"Read INDEX.md and collect a list of topics."}<</reflex:dispatch>>\n\nRules:\n - `brief` must be self-contained — sub-agents do NOT see the chat transcript. Include all rel-paths, expected output shape, constraints.\n - Multiple dispatches in one turn run **concurrently**. Sequentially-dependent tasks → do them across multiple turns.\n - After dispatches Reflex re-invokes you with each sub-agent\'s output quoted. Compose the final user-facing reply from those results.\n - Do simple things yourself (one short answer, citing one file). Don\'t dispatch trivia.\n - Don\'t re-dispatch the same brief if a sub-agent returned empty — either solve it yourself or ask the user.\n\nOptional harness routing:\n - Add `"harness":"codex"` to the dispatch payload to run THAT sub-agent on Codex instead of inheriting yours. Useful when:\n – task is heavy code synthesis / refactor / type-fixing — Codex shines there.\n – task is short text classification / extraction — `"harness":"ollama"` is cheap and fast.\n - Without `harness`, the sub-agent inherits the orchestrator\'s runtime — usually fine. Override only when you have a concrete reason.\n - Example: `<<reflex:dispatch>>{"role":"coder","harness":"codex","brief":"Rewrite X in TypeScript strict mode"}<</reflex:dispatch>>`','## Widgets: putting results on the project dashboard\n\nWhen the user wants you to produce something durable — a news digest, a checklist, a KPI snapshot, a curated link list — DON\'T just answer in chat and forget. Materialize it as a **widget** on the project dashboard so the user sees it on every visit.\n\nEmit a marker on its own block:\n\n```\n<<reflex:widget-create>>{\n "id": "<kebab-case-id>",\n "title": "<short user-visible title>",\n "description": "<one-line subtitle, optional>",\n "kind": "<one of: markdown, news-list, link-list, kpi, checklist, quote, kb-pinned, progress, image, stat-table, map>",\n "data": { ...kind-specific payload... },\n "size": { "mode": "md" }\n}<</reflex:widget-create>>\n```\n\nUse `widget-update` (same shape, same id) when refreshing an existing widget — e.g. user asked for a weekly news digest, you regenerate the items.\n\n### Auto-refresh and memory\n\n- `refresh`: `"manual"` (default) | `"hourly"` | `"daily"` | `"weekly"`. When set to anything other than manual, Reflex\'s scheduler will periodically re-invoke you on the source topic with a synthetic `[Reflex] Refresh widget <id>` user-message — you respond by emitting a fresh `<<reflex:widget-update>>` with the same id.\n- `memory`: agent-managed inline state (markdown, <2KB). Use for **short** state that should persist across refreshes — e.g. "already-shown URLs to dedupe", "last 4 KPI snapshots", "running tally". On every refresh prompt you\'ll see the current `memory` value; emit an updated one inside the widget-update payload.\n- `memoryFile`: rel-path (inside `.reflex/`) for **long** memory — a journal-style markdown file you append to via the regular `<<reflex:kb>>` directive. Use for OKR-history-style widgets where the journal itself is worth keeping in the KB tree. Pick a path like `widgets/<widget-id>.memory.md`.\n- Pick ONE of `memory` or `memoryFile` per widget. Inline for compact structured deduping; file for narrative history.\n- When refreshing, prefer **incremental** updates: dedupe against memory, add new items at the top, drop very old ones — the user wants signal, not a snapshot reset.\n\n### Kinds and `data` shapes\n\n- `markdown` — `{body: string}`. Long-form notes, summaries, instructions.\n- `news-list` — `{items: [{title, url?, summary?, source?, date?}]}`. Headlines + 1-2 line summaries.\n- `link-list` — `{items: [{title, url, hint?}]}`. Curated resources, bookmarks.\n- `kpi` — `{items: [{label, value, hint?, delta?: "up"|"down"|"flat"}]}`. Big-number tiles.\n- `checklist` — `{items: [{text, done?: boolean}]}`. Action items / todo.\n- `quote` — `{text, attribution?}`. One memorable quote.\n- `kb-pinned` — `{items: [{rel, title?, snippet?}]}`. Pinned KB rel-paths.\n- `progress` — `{items: [{label, current, target, unit?}]}`. Goal-tracking bars.\n- `image` — `{url, alt?, caption?}`. Single image card.\n- `stat-table` — `{columns?: [string], rows: [[string, ...]]}`. Compact comparison table.\n- `map` — `{points: [{lat, lng, title, description?}], center?, zoom?, route?: {stops: number[], color?, mode?}}`. Map with points + an optional route (polyline + multi-waypoint deep-links: google/yandex/2gis/apple/osm/waze/organic). `route.stops` — array of indices in `points` in traversal order (minimum 2). Each point gets a popup with branded service buttons. By default the map auto-fits to the points. IMPORTANT: `lat`/`lng` are numbers in decimal degrees (lat=55.7558, lng=37.6173 — Moscow). NOT strings. If you have an address — find coordinates via WebSearch/WebFetch (geocoding); don\'t invent them. The user can search for places (Nominatim) and build a route right in the widget — the "Route" button switches to point-pick-by-click mode.\n\n### Interactivity\n\nDashboard widgets are interactive — the user can, right in the UI:\n - **checklist**: tick checkboxes (toggle done), delete items, add new ones.\n - **link-list**: delete links.\n - **news-list**: mark a news item as read (`read:true`), remove the card.\n - **kb-pinned**: unpin files.\n - **progress**: \xb1 buttons on `current`.\n\nThese changes are written straight to disk, bypassing you. On the next `widget-update` you\'ll see the current state. Strategy:\n - If the user deleted a checklist item — don\'t add it back (that\'s a signal).\n - If the user marked a news item as read — record its URL in `memory` for dedup.\n - If the user reset progress — apparently it\'s a new cycle; respect it.\n\n### Rules\n\n- Pick the SIMPLEST kind that fits — don\'t squeeze a news digest into `markdown` if `news-list` exists.\n- `id` is stable: same id across `widget-create` and `widget-update`. Pick a slug from the topic content (e.g. `tech-news-weekly`, `okrs-q2`).\n- `size.mode`: `"sm"` (3 per row, icons/KPI) | `"md"` (default, 2 per row) | `"wide"` (full row, for long tables/markdown). Match it to the content, but the user can override via the UI — your choice is only a hint.\n- After emitting the marker, briefly tell the user in plain text WHAT widget you assembled. IMPORTANT: a new widget does NOT appear on the dashboard automatically — it sits in the library as a draft. The user sees it right in the chat (preview) and can pin it with the "Pin to dashboard" button or via the library. Don\'t claim the widget is already on the dashboard.\n- Reflex automatically shows a live preview of the widget inside this chat turn — no need to re-render in markdown.',`## Workflows — built-in "n8n for non-techies"
|
|
433
433
|
|
|
434
|
-
|
|
434
|
+
When the user wants to automate something recurring (morning digest, page monitor, "fetch → process → save" routine), emit a \`<<reflex:workflow-create>>\` marker — Reflex will save the workflow to disk and show a preview with a link to the editor.
|
|
435
435
|
|
|
436
436
|
\`\`\`
|
|
437
437
|
<<reflex:workflow-create>>{
|
|
@@ -440,49 +440,30 @@ Tailwind-классы доступны через стандартную таб
|
|
|
440
440
|
"description": "<one line>",
|
|
441
441
|
"trigger": "manual" | "hourly" | "daily" | "weekly",
|
|
442
442
|
"steps": [
|
|
443
|
-
{"id": "fetch", "kind": "web-fetch", "label": "
|
|
444
|
-
{"id": "digest", "kind": "ask-agent", "label": "
|
|
445
|
-
{"id": "save", "kind": "kb-write", "label": "
|
|
443
|
+
{"id": "fetch", "kind": "web-fetch", "label": "Fetch HN", "params": {"url": "https://news.ycombinator.com/rss"}},
|
|
444
|
+
{"id": "digest", "kind": "ask-agent", "label": "Compress into digest", "params": {"prompt": "Summarize the top 5 headlines from the RSS:\\n{{prev}}"}},
|
|
445
|
+
{"id": "save", "kind": "kb-write", "label": "Write to KB", "params": {"kind": "digest", "title": "HN digest", "body": "{{prev}}"}}
|
|
446
446
|
]
|
|
447
447
|
}<</reflex:workflow-create>>
|
|
448
448
|
\`\`\`
|
|
449
449
|
|
|
450
|
-
###
|
|
451
|
-
|
|
452
|
-
- \`text-template\` — \`{template: string}\`. Подстановки: \`{{prev}}\`, \`{{steps.<id>.output}}\`, \`{{input.<field>}}\`, \`{{workflow.label}}\`.
|
|
453
|
-
- \`http-request\` — \`{url, method?, headers?: string-JSON, body?}\`. Output: текст или JSON (по content-type).
|
|
454
|
-
- \`web-fetch\` — \`{url}\`. Простой GET, output — текст ответа.
|
|
455
|
-
- \`ask-agent\` — \`{prompt}\`. Запускает headless orchestrator и возвращает текст ответа. Используй для суммаризации, перефразирования, классификации.
|
|
456
|
-
- \`kb-write\` — \`{kind, title, body}\`. Сохраняет в базу знаний как обычный KB-файл.
|
|
457
|
-
|
|
458
|
-
### Правила
|
|
450
|
+
### Available step \`kind\`s
|
|
459
451
|
|
|
460
|
-
-
|
|
461
|
-
- \`
|
|
462
|
-
-
|
|
463
|
-
-
|
|
464
|
-
-
|
|
465
|
-
- После эмита маркера — короткое сообщение пользователю: что собрал, как запустить, где редактировать.`,`## Generating images inline
|
|
452
|
+
- \`text-template\` — \`{template: string}\`. Substitutions: \`{{prev}}\`, \`{{steps.<id>.output}}\`, \`{{input.<field>}}\`, \`{{workflow.label}}\`.
|
|
453
|
+
- \`http-request\` — \`{url, method?, headers?: string-JSON, body?}\`. Output: text or JSON (by content-type).
|
|
454
|
+
- \`web-fetch\` — \`{url}\`. Simple GET; output is the response text.
|
|
455
|
+
- \`ask-agent\` — \`{prompt}\`. Runs a headless orchestrator and returns the response text. Use for summarization, paraphrasing, classification.
|
|
456
|
+
- \`kb-write\` — \`{kind, title, body}\`. Saves to the knowledge base as a regular KB file.
|
|
466
457
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
\`\`\`
|
|
470
|
-
<<reflex:image-gen>>{
|
|
471
|
-
"prompt": "детальный английский или русский промпт описывающий картинку",
|
|
472
|
-
"provider": "gemini",
|
|
473
|
-
"aspectRatio": "16:9",
|
|
474
|
-
"caption": "короткая подпись (опционально)",
|
|
475
|
-
"attachToKb": false
|
|
476
|
-
}<</reflex:image-gen>>
|
|
477
|
-
\`\`\`
|
|
458
|
+
### Rules
|
|
478
459
|
|
|
479
|
-
-
|
|
480
|
-
-
|
|
481
|
-
-
|
|
482
|
-
-
|
|
483
|
-
-
|
|
484
|
-
- НЕ описывай словами \xabвот картинка кота\xbb — просто эмить маркер; Reflex сам вставит изображение в твой ответ.`].join("\n\n")}},64011:(a,b,c)=>{c.d(b,{P:()=>l});var d=c(14126);let e=d.Ik({template:d.Yj().default("")}),f=d.Ik({url:d.Yj().url("url must be a valid URL"),method:d.k5(["GET","POST","PUT","PATCH","DELETE"]).default("GET"),headers:d.KC([d.g1(d.Yj(),d.Yj()),d.Yj(),d.Vx()]).optional(),body:d.KC([d.Yj(),d.g1(d.Yj(),d.L5()),d.Vx()]).optional()}),g=d.Ik({url:d.Yj().url("url must be a valid URL")}),h=d.Ik({prompt:d.Yj().min(1,"prompt is required")}),i=d.Ik({kind:d.Yj().min(1).default("note"),title:d.Yj().default(""),body:d.Yj().default("")}),j=d.Ik({utilityId:d.Yj().min(1,"utilityId is required"),utilityScope:d.k5(["global","project"]).default("global"),actionName:d.Yj().min(1,"actionName is required"),args:d.L5().optional()}),k={"text-template":e,"http-request":f,"web-fetch":g,"ask-agent":h,"kb-write":i,"utility-call":j,"image-generate":d.Ik({prompt:d.Yj().min(1,"prompt is required"),provider:d.k5(["gemini","codex"]).optional(),size:d.Yj().optional(),aspectRatio:d.Yj().optional()}),"image-search":d.Ik({query:d.Yj().min(1,"query is required"),provider:d.k5(["unsplash","pexels","brave"]).optional(),count:d.KC([d.Yj(),d.ai()]).optional()})};function l(a,b){let c=k[a];return c?c.parse(b):b}},64163:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{runHeadlessAgent:()=>l});var e=c(16909),f=c(31900),g=c(74342),h=c(56843),i=c(17640),j=c(24576),k=a([e,f]);async function l(a){let b=await (0,j.Zn)(a.rootId);if(!b)throw Error(`runHeadlessAgent: root not found: ${a.rootId}`);let c=await (0,i.M)(),d=c.assignments.chat,k=await (0,h.OY)({root:b.path,firstMessage:a.label??"[headless agent run]",harness:a.harness??d.harness,model:a.model??d.model,language:a.language??c.language}),l=!1;try{let c=await (0,f.W)({rootId:a.rootId,topicId:k.meta.id,message:a.prompt,attachments:a.attachments??[],...a.harness?{harness:a.harness}:{},...a.model?{model:a.model}:{}});if("error"in c)throw Error(c.error);let d=Date.now()+(a.timeoutMs??3e5);for(await m(400);Date.now()<d&&e.z.isActive(k.meta.id);)await m(400);e.z.isActive(k.meta.id)&&(l=!0),await m(400);let h=await (0,g.wj)(b.path,k.meta.id),i=h.filter(a=>"assistant-delta"===a.type).map(a=>a.text).join("").trim();if(!i){let b=h.filter(a=>"error"===a.type).map(a=>a.message).filter(Boolean);if(b.length>0)throw Error(`Агент завершился с ошибкой: ${b.slice(0,3).join(" \xb7 ")}`);let c=h.filter(a=>"system"===a.type).map(a=>a.text).filter(Boolean);if(c.length>0)return{text:c.join("\n"),topicId:k.meta.id,timedOut:l};if(l)throw Error(`Агент не ответил за ${Math.round((a.timeoutMs??3e5)/1e3)}с (timeout)`);throw Error("Агент завершил работу не оставив текстового ответа — возможно, не настроен chat-движок в Settings.")}return{text:i,topicId:k.meta.id,timedOut:l}}finally{try{await e.z.stopTopic(k.meta.id)}catch{}try{await (0,h.do)(b.path,k.meta.id)}catch{}}}function m(a){return new Promise(b=>setTimeout(b,a))}[e,f]=k.then?(await k)():k,d()}catch(a){d(a)}})},72440:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{L:()=>j});var e=c(49353),f=c(64163),g=a([f]);f=(g.then?(await g)():g)[0];let j={"text-template":async a=>"string"==typeof a.template?a.template:"","http-request":async a=>{let b=h(a.url,"url"),c=i(a.method,"GET").toUpperCase(),d=function(a,b){if("string"!=typeof a||!a.trim())return b;try{return JSON.parse(a)}catch{return b}}(a.headers,{}),e=i(a.body,""),f={method:c,headers:d};"GET"!==c&&"HEAD"!==c&&e&&(f.body=e);let g=await fetch(b,f),j=await g.text(),k=g.headers.get("content-type")??"",l=j;if(k.includes("application/json"))try{l=JSON.parse(j)}catch{}if(!g.ok)throw Error(`HTTP ${g.status} ${g.statusText}: ${j.slice(0,200)}`);return l},"web-fetch":async a=>{let b=h(a.url,"url"),c=await fetch(b,{headers:{"User-Agent":"Reflex-Workflow/1.0"}});if(!c.ok)throw Error(`HTTP ${c.status} ${c.statusText}`);return await c.text()},"ask-agent":async(a,b)=>{let c=h(a.prompt,"prompt"),{text:d}=await (0,f.runHeadlessAgent)({rootId:b.rootId,prompt:c,label:`[workflow ${b.workflow.id}] ${b.workflow.label}`});return d},"kb-write":async(a,b)=>{let c=i(a.kind,"note"),d=i(a.title,`Workflow ${b.workflow.label}`),f=i(a.body,""),g=await (0,e.j)({rootPath:b.rootPath,directive:{kind:c,title:d,body:f}});return{kind:g.kind,title:g.title,relPath:g.relPath,absPath:g.absPath}},"image-generate":async(a,b)=>{let d=h(a.prompt,"prompt"),e="codex"===a.provider||"gemini"===a.provider?a.provider:void 0,{generateImage:f}=await Promise.resolve().then(c.bind(c,59835)),g=await f({rootId:b.rootId,prompt:d,...e?{provider:e}:{},..."string"==typeof a.size&&a.size?{size:a.size}:{},..."string"==typeof a.aspectRatio&&a.aspectRatio?{aspectRatio:a.aspectRatio}:{}});return{url:g.urlPath,sha:g.sha,size:g.size,mime:g.mime,provider:g.provider}},"image-search":async a=>{let b,d=h(a.query,"query"),e="pexels"===a.provider||"unsplash"===a.provider||"brave"===a.provider?a.provider:void 0;if("number"==typeof a.count)b=a.count;else if("string"==typeof a.count&&a.count.trim()){let c=parseInt(a.count,10);Number.isFinite(c)&&c>0&&(b=c)}let{searchImages:f}=await Promise.resolve().then(c.bind(c,59835));return{results:await f({query:d,...e?{provider:e}:{},...void 0!==b?{count:b}:{}})}},"utility-call":async(a,b)=>{let d=h(a.utilityId,"utilityId"),e=h(a.actionName,"actionName"),f="project"===a.utilityScope?"project":"global",g=a.args??{};if("string"==typeof g)try{g=g.trim()?JSON.parse(g):{}}catch(a){throw Error(`utility-call: args is not valid JSON: ${a instanceof Error?a.message:String(a)}`)}let{getUtility:i}=await Promise.resolve().then(c.bind(c,61105)),j=await i(f,d,"project"===f?b.rootId:void 0);if(!j)throw Error(`utility-call: ${f}/${d} not installed`);let k=j.manifest.serverActions.find(a=>a.name===e);if(!k)throw Error(`utility-call: ${d} has no serverAction "${e}"`);let{runServerAction:l}=await Promise.all([c.e(7300),c.e(2485),c.e(9579)]).then(c.bind(c,29579));return l({utility:j,action:k,args:g,parentCorrelationId:`workflow:${b.workflow.id}`})}};function h(a,b){if("string"!=typeof a||!a.trim())throw Error(`Param "${b}" обязателен (string)`);return a}function i(a,b){return"string"==typeof a?a:b}d()}catch(a){d(a)}})},74342:(a,b,c)=>{c.d(b,{Rs:()=>h,Zn:()=>i,v:()=>k,wj:()=>j});var d=c(73024),e=c(76760),f=c.n(e),g=c(13474);function h(a,b){return f().join((0,g.FF)(a),"topics",`${b}.events.jsonl`)}async function i(a,b,c){let e=h(a,b);await d.promises.mkdir(f().dirname(e),{recursive:!0}),await d.promises.appendFile(e,JSON.stringify(c)+"\n","utf8")}async function j(a,b){let c,e=h(a,b);try{c=await d.promises.readFile(e,"utf8")}catch(a){var f;if("object"==typeof(f=a)&&null!==f&&"code"in f&&"ENOENT"===f.code)return[];throw a}let g=[];for(let a of c.split(/\r?\n/))if(a.trim())try{g.push(JSON.parse(a))}catch{}return g}async function k(a,b){let c=await j(a,b);return 0===c.length?0:c[c.length-1].seq+1}},79178:(a,b,c)=>{c.d(b,{V:()=>e});let d=/\{\{\s*([^{}\s][^{}]*?)\s*\}\}/g;function e(a,b){return function a(b,c){if("string"==typeof b)return b.replace(d,(a,b)=>(function(a){if(null==a)return"";if("string"==typeof a)return a;if("number"==typeof a||"boolean"==typeof a)return String(a);try{return JSON.stringify(a)}catch{return String(a)}})(function(a,b){if("prev"===a)return b.prev;if(a.startsWith("workflow.")){let c=a.slice(9);return b.workflow[c]}if(a.startsWith("input."))return f(b.input,a.slice(6));if(a.startsWith("input"))return b.input;if(a.startsWith("steps.")){let[c,...d]=a.slice(6).split(".");if(!c)return;let e=b.steps[c];if(!e)return;if(0===d.length||1===d.length&&"output"===d[0])return e.output;if("output"===d[0])return f(e.output,d.slice(1).join("."))}}(b.trim(),c)));if(Array.isArray(b))return b.map(b=>a(b,c));if(b&&"object"==typeof b){let d={};for(let[e,f]of Object.entries(b))d[e]=a(f,c);return d}return b}(a,b)}function f(a,b){if(!b)return a;let c=b.split("."),d=a;for(let a of c){if(null==d||"object"!=typeof d)return;d=d[a]}return d}},88124:(a,b,c)=>{c.d(b,{Jc:()=>p,McpConfigSchema:()=>l,callTool:()=>r,connectAndListTools:()=>q});var d=c(43444),e=c(37567),f=c(1960),g=c(66133),h=c(14126);let i=h.Ik({transport:h.eu("stdio"),command:h.Yj().min(1),args:h.YO(h.Yj()).default([]),env:h.g1(h.Yj(),h.Yj()).default({}),cwd:h.Yj().optional()}),j=h.Ik({transport:h.eu("http"),url:h.Yj().url(),headers:h.g1(h.Yj(),h.Yj()).default({})}),k=h.Ik({transport:h.eu("sse"),url:h.Yj().url(),headers:h.g1(h.Yj(),h.Yj()).default({})}),l=h.gM("transport",[i,j,k]),m={name:"reflex-utility-bridge",version:"0.1.0"};async function n(a){let b=new d.K(m);if("stdio"===a.transport){let c=await p(a.env),d=new e.oQ({command:a.command,args:a.args,env:{...process.env,...c},cwd:a.cwd});return await b.connect(d),{client:b,close:()=>b.close()}}if("http"===a.transport){let c=await p(a.headers),d=new f.j(new URL(a.url),{requestInit:{headers:c}});return await b.connect(d),{client:b,close:()=>b.close()}}let c=await p(a.headers),h=new g.A(new URL(a.url),{requestInit:{headers:c}});return await b.connect(h),{client:b,close:()=>b.close()}}let o=/\$oauth:([a-z][a-z0-9-]*)/g;async function p(a){let b={};for(let[d,e]of Object.entries(a)){if("string"!=typeof e||!e.includes("$oauth:")){b[d]=e;continue}let a=new Set;e.replace(o,(b,c)=>(a.add(c),""));let f=e,{getAccessToken:g}=await c.e(2503).then(c.bind(c,82503)),{isOAuthProviderId:h}=await c.e(3657).then(c.bind(c,63657));for(let b of a){if(!h(b))throw Error(`unknown OAuth provider in placeholder: ${b}`);let a=await g(b);f=f.replace(RegExp(`\\$oauth:${b}\\b`,"g"),a)}b[d]=f}return b}async function q(a){let{client:b,close:c}=await n(a);try{let a=b.getServerVersion(),{tools:c}=await b.listTools();return{name:a?.name,version:a?.version,tools:c.map(a=>({name:a.name,description:a.description,inputSchema:a.inputSchema}))}}finally{await c().catch(()=>{})}}async function r(a,b,c){let{client:d,close:e}=await n(a);try{let a=await d.callTool({name:b,arguments:c});return{isError:"boolean"==typeof a.isError?a.isError:void 0,content:a.content}}finally{await e().catch(()=>{})}}},91147:(a,b,c)=>{c.d(b,{_:()=>k});var d=c(73024),e=c(48161),f=c.n(e),g=c(76760),h=c.n(g),i=c(5243),j=c(88124);async function k(a){let b=await (0,i.listMcpServers)();if(0===b.length)return null;let c={};for(let a of b)if("stdio"===a.config.transport){let b=await (0,j.Jc)(a.config.env);c[a.id]={command:a.config.command,args:a.config.args,env:b}}else if("http"===a.config.transport){let b=await (0,j.Jc)(a.config.headers);c[a.id]={type:"http",url:a.config.url,...Object.keys(b).length>0?{headers:b}:{}}}else{let b=await (0,j.Jc)(a.config.headers);c[a.id]={type:"sse",url:a.config.url,...Object.keys(b).length>0?{headers:b}:{}}}let e=await d.promises.mkdtemp(h().join(f().tmpdir(),`reflex-mcp-${a}-`)),g=h().join(e,"mcp.json");return await d.promises.writeFile(g,JSON.stringify({mcpServers:c},null,2),"utf8"),{path:g,serverIds:b.map(a=>a.id),cleanup:async()=>{try{await d.promises.rm(e,{recursive:!0,force:!0})}catch{}}}}},96931:(a,b,c)=>{c.d(b,{R:()=>f});var d=c(59835),e=c(24576);async function f(a){let b=function(a){let b=a.trim();if(b.startsWith("{")&&b.endsWith("}"))try{let a=JSON.parse(b),c={prompt:"string"==typeof a.prompt&&a.prompt.trim().length>0?a.prompt:b};return("gemini"===a.provider||"codex"===a.provider)&&(c.provider=a.provider),"string"==typeof a.size&&(c.size=a.size),"string"==typeof a.aspectRatio&&(c.aspectRatio=a.aspectRatio),"string"==typeof a.alt&&(c.alt=a.alt),c}catch{}return{prompt:b}}(a.args.prompt),c=(0,e.mM)(a.args.rootPath);try{var f;let e=await (0,d.generateImage)({rootId:c,prompt:b.prompt,...b.provider?{provider:b.provider}:{},...b.size?{size:b.size}:{},...b.aspectRatio?{aspectRatio:b.aspectRatio}:{},...b.alt?{alt:b.alt}:{}}),g=b.alt||b.prompt,h=`![${g.replace(/[\[\]\n]/g," ").slice(0,200)}](${e.urlPath})
|
|
460
|
+
- Each step passes its output to the next via \`{{prev}}\` or \`{{steps.<id>.output}}\`. This is the only link between steps.
|
|
461
|
+
- A step's \`id\` must be stable and kebab-case — templates reference it.
|
|
462
|
+
- Steps run strictly sequentially. If a step fails — the rest won't run, and the run is marked failed.
|
|
463
|
+
- Keep workflows SHORT (3-5 steps). If the task is larger — split it into several workflows or let the agent handle the complex part via \`ask-agent\`.
|
|
464
|
+
- Trigger defaults to \`manual\`. \`hourly\`/\`daily\`/\`weekly\` currently work only via manual launch; the scheduler is in progress.
|
|
465
|
+
- After emitting the marker — a short message to the user: what you assembled, how to run it, where to edit it.`,'## Generating images inline\n\nWhen the user asks to draw, generate, or illustrate something ("draw a cat", "make an illustration", "generate a preview"), DON\'T describe what you\'d draw — emit an image-gen marker and Reflex will render the actual image inside your reply.\n\n```\n<<reflex:image-gen>>{\n "prompt": "detailed prompt describing the picture",\n "provider": "gemini",\n "aspectRatio": "16:9",\n "caption": "short caption (optional)",\n "attachToKb": false\n}<</reflex:image-gen>>\n```\n\n- `provider`: `"gemini"` (Nano Banana, default, cheap and fast) or `"codex"` (via `$imagegen` in Codex CLI).\n- `aspectRatio`: `"1:1"`, `"16:9"`, `"9:16"`, `"4:3"`, etc. Optional.\n- `attachToKb: true` — also save the image to the KB as `kind: "image"` for future reuse.\n- You can emit multiple markers in one reply — that produces N images in a row.\n- Write a detailed prompt: style (photorealism / watercolor / 3D / illustration), composition, lighting, mood. The more specific — the better the result.\n- DO NOT describe in words "here is a picture of a cat" — just emit the marker; Reflex inserts the image into your reply itself.'].join("\n\n")}},64011:(a,b,c)=>{c.d(b,{P:()=>l});var d=c(14126);let e=d.Ik({template:d.Yj().default("")}),f=d.Ik({url:d.Yj().url("url must be a valid URL"),method:d.k5(["GET","POST","PUT","PATCH","DELETE"]).default("GET"),headers:d.KC([d.g1(d.Yj(),d.Yj()),d.Yj(),d.Vx()]).optional(),body:d.KC([d.Yj(),d.g1(d.Yj(),d.L5()),d.Vx()]).optional()}),g=d.Ik({url:d.Yj().url("url must be a valid URL")}),h=d.Ik({prompt:d.Yj().min(1,"prompt is required")}),i=d.Ik({kind:d.Yj().min(1).default("note"),title:d.Yj().default(""),body:d.Yj().default("")}),j=d.Ik({utilityId:d.Yj().min(1,"utilityId is required"),utilityScope:d.k5(["global","project"]).default("global"),actionName:d.Yj().min(1,"actionName is required"),args:d.L5().optional()}),k={"text-template":e,"http-request":f,"web-fetch":g,"ask-agent":h,"kb-write":i,"utility-call":j,"image-generate":d.Ik({prompt:d.Yj().min(1,"prompt is required"),provider:d.k5(["gemini","codex"]).optional(),size:d.Yj().optional(),aspectRatio:d.Yj().optional()}),"image-search":d.Ik({query:d.Yj().min(1,"query is required"),provider:d.k5(["unsplash","pexels","brave"]).optional(),count:d.KC([d.Yj(),d.ai()]).optional()})};function l(a,b){let c=k[a];return c?c.parse(b):b}},64163:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{runHeadlessAgent:()=>l});var e=c(16909),f=c(31900),g=c(74342),h=c(56843),i=c(17640),j=c(24576),k=a([e,f]);async function l(a){let b=await (0,j.Zn)(a.rootId);if(!b)throw Error(`runHeadlessAgent: root not found: ${a.rootId}`);let c=await (0,i.M)(),d=c.assignments.chat,k=await (0,h.OY)({root:b.path,firstMessage:a.label??"[headless agent run]",harness:a.harness??d.harness,model:a.model??d.model,language:a.language??c.language}),l=!1;try{let c=await (0,f.W)({rootId:a.rootId,topicId:k.meta.id,message:a.prompt,attachments:a.attachments??[],...a.harness?{harness:a.harness}:{},...a.model?{model:a.model}:{}});if("error"in c)throw Error(c.error);let d=Date.now()+(a.timeoutMs??3e5);for(await m(400);Date.now()<d&&e.z.isActive(k.meta.id);)await m(400);e.z.isActive(k.meta.id)&&(l=!0),await m(400);let h=await (0,g.wj)(b.path,k.meta.id),i=h.filter(a=>"assistant-delta"===a.type).map(a=>a.text).join("").trim();if(!i){let b=h.filter(a=>"error"===a.type).map(a=>a.message).filter(Boolean);if(b.length>0)throw Error(`Agent finished with errors: ${b.slice(0,3).join(" \xb7 ")}`);let c=h.filter(a=>"system"===a.type).map(a=>a.text).filter(Boolean);if(c.length>0)return{text:c.join("\n"),topicId:k.meta.id,timedOut:l};if(l)throw Error(`Agent did not respond within ${Math.round((a.timeoutMs??3e5)/1e3)}s (timeout)`);throw Error("Agent finished without producing any text — perhaps no chat engine is configured in Settings.")}return{text:i,topicId:k.meta.id,timedOut:l}}finally{try{await e.z.stopTopic(k.meta.id)}catch{}try{await (0,h.do)(b.path,k.meta.id)}catch{}}}function m(a){return new Promise(b=>setTimeout(b,a))}[e,f]=k.then?(await k)():k,d()}catch(a){d(a)}})},72440:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{L:()=>j});var e=c(49353),f=c(64163),g=a([f]);f=(g.then?(await g)():g)[0];let j={"text-template":async a=>"string"==typeof a.template?a.template:"","http-request":async a=>{let b=h(a.url,"url"),c=i(a.method,"GET").toUpperCase(),d=function(a,b){if("string"!=typeof a||!a.trim())return b;try{return JSON.parse(a)}catch{return b}}(a.headers,{}),e=i(a.body,""),f={method:c,headers:d};"GET"!==c&&"HEAD"!==c&&e&&(f.body=e);let g=await fetch(b,f),j=await g.text(),k=g.headers.get("content-type")??"",l=j;if(k.includes("application/json"))try{l=JSON.parse(j)}catch{}if(!g.ok)throw Error(`HTTP ${g.status} ${g.statusText}: ${j.slice(0,200)}`);return l},"web-fetch":async a=>{let b=h(a.url,"url"),c=await fetch(b,{headers:{"User-Agent":"Reflex-Workflow/1.0"}});if(!c.ok)throw Error(`HTTP ${c.status} ${c.statusText}`);return await c.text()},"ask-agent":async(a,b)=>{let c=h(a.prompt,"prompt"),{text:d}=await (0,f.runHeadlessAgent)({rootId:b.rootId,prompt:c,label:`[workflow ${b.workflow.id}] ${b.workflow.label}`});return d},"kb-write":async(a,b)=>{let c=i(a.kind,"note"),d=i(a.title,`Workflow ${b.workflow.label}`),f=i(a.body,""),g=await (0,e.j)({rootPath:b.rootPath,directive:{kind:c,title:d,body:f}});return{kind:g.kind,title:g.title,relPath:g.relPath,absPath:g.absPath}},"image-generate":async(a,b)=>{let d=h(a.prompt,"prompt"),e="codex"===a.provider||"gemini"===a.provider?a.provider:void 0,{generateImage:f}=await Promise.resolve().then(c.bind(c,59835)),g=await f({rootId:b.rootId,prompt:d,...e?{provider:e}:{},..."string"==typeof a.size&&a.size?{size:a.size}:{},..."string"==typeof a.aspectRatio&&a.aspectRatio?{aspectRatio:a.aspectRatio}:{}});return{url:g.urlPath,sha:g.sha,size:g.size,mime:g.mime,provider:g.provider}},"image-search":async a=>{let b,d=h(a.query,"query"),e="pexels"===a.provider||"unsplash"===a.provider||"brave"===a.provider?a.provider:void 0;if("number"==typeof a.count)b=a.count;else if("string"==typeof a.count&&a.count.trim()){let c=parseInt(a.count,10);Number.isFinite(c)&&c>0&&(b=c)}let{searchImages:f}=await Promise.resolve().then(c.bind(c,59835));return{results:await f({query:d,...e?{provider:e}:{},...void 0!==b?{count:b}:{}})}},"utility-call":async(a,b)=>{let d=h(a.utilityId,"utilityId"),e=h(a.actionName,"actionName"),f="project"===a.utilityScope?"project":"global",g=a.args??{};if("string"==typeof g)try{g=g.trim()?JSON.parse(g):{}}catch(a){throw Error(`utility-call: args is not valid JSON: ${a instanceof Error?a.message:String(a)}`)}let{getUtility:i}=await Promise.resolve().then(c.bind(c,61105)),j=await i(f,d,"project"===f?b.rootId:void 0);if(!j)throw Error(`utility-call: ${f}/${d} not installed`);let k=j.manifest.serverActions.find(a=>a.name===e);if(!k)throw Error(`utility-call: ${d} has no serverAction "${e}"`);let{runServerAction:l}=await Promise.all([c.e(7300),c.e(2485),c.e(9579)]).then(c.bind(c,29579));return l({utility:j,action:k,args:g,parentCorrelationId:`workflow:${b.workflow.id}`})}};function h(a,b){if("string"!=typeof a||!a.trim())throw Error(`Param "${b}" is required (string)`);return a}function i(a,b){return"string"==typeof a?a:b}d()}catch(a){d(a)}})},74342:(a,b,c)=>{c.d(b,{Rs:()=>h,Zn:()=>i,v:()=>k,wj:()=>j});var d=c(73024),e=c(76760),f=c.n(e),g=c(13474);function h(a,b){return f().join((0,g.FF)(a),"topics",`${b}.events.jsonl`)}async function i(a,b,c){let e=h(a,b);await d.promises.mkdir(f().dirname(e),{recursive:!0}),await d.promises.appendFile(e,JSON.stringify(c)+"\n","utf8")}async function j(a,b){let c,e=h(a,b);try{c=await d.promises.readFile(e,"utf8")}catch(a){var f;if("object"==typeof(f=a)&&null!==f&&"code"in f&&"ENOENT"===f.code)return[];throw a}let g=[];for(let a of c.split(/\r?\n/))if(a.trim())try{g.push(JSON.parse(a))}catch{}return g}async function k(a,b){let c=await j(a,b);return 0===c.length?0:c[c.length-1].seq+1}},79178:(a,b,c)=>{c.d(b,{V:()=>e});let d=/\{\{\s*([^{}\s][^{}]*?)\s*\}\}/g;function e(a,b){return function a(b,c){if("string"==typeof b)return b.replace(d,(a,b)=>(function(a){if(null==a)return"";if("string"==typeof a)return a;if("number"==typeof a||"boolean"==typeof a)return String(a);try{return JSON.stringify(a)}catch{return String(a)}})(function(a,b){if("prev"===a)return b.prev;if(a.startsWith("workflow.")){let c=a.slice(9);return b.workflow[c]}if(a.startsWith("input."))return f(b.input,a.slice(6));if(a.startsWith("input"))return b.input;if(a.startsWith("steps.")){let[c,...d]=a.slice(6).split(".");if(!c)return;let e=b.steps[c];if(!e)return;if(0===d.length||1===d.length&&"output"===d[0])return e.output;if("output"===d[0])return f(e.output,d.slice(1).join("."))}}(b.trim(),c)));if(Array.isArray(b))return b.map(b=>a(b,c));if(b&&"object"==typeof b){let d={};for(let[e,f]of Object.entries(b))d[e]=a(f,c);return d}return b}(a,b)}function f(a,b){if(!b)return a;let c=b.split("."),d=a;for(let a of c){if(null==d||"object"!=typeof d)return;d=d[a]}return d}},88124:(a,b,c)=>{c.d(b,{Jc:()=>p,McpConfigSchema:()=>l,callTool:()=>r,connectAndListTools:()=>q});var d=c(43444),e=c(37567),f=c(1960),g=c(66133),h=c(14126);let i=h.Ik({transport:h.eu("stdio"),command:h.Yj().min(1),args:h.YO(h.Yj()).default([]),env:h.g1(h.Yj(),h.Yj()).default({}),cwd:h.Yj().optional()}),j=h.Ik({transport:h.eu("http"),url:h.Yj().url(),headers:h.g1(h.Yj(),h.Yj()).default({})}),k=h.Ik({transport:h.eu("sse"),url:h.Yj().url(),headers:h.g1(h.Yj(),h.Yj()).default({})}),l=h.gM("transport",[i,j,k]),m={name:"reflex-utility-bridge",version:"0.1.0"};async function n(a){let b=new d.K(m);if("stdio"===a.transport){let c=await p(a.env),d=new e.oQ({command:a.command,args:a.args,env:{...process.env,...c},cwd:a.cwd});return await b.connect(d),{client:b,close:()=>b.close()}}if("http"===a.transport){let c=await p(a.headers),d=new f.j(new URL(a.url),{requestInit:{headers:c}});return await b.connect(d),{client:b,close:()=>b.close()}}let c=await p(a.headers),h=new g.A(new URL(a.url),{requestInit:{headers:c}});return await b.connect(h),{client:b,close:()=>b.close()}}let o=/\$oauth:([a-z][a-z0-9-]*)/g;async function p(a){let b={};for(let[d,e]of Object.entries(a)){if("string"!=typeof e||!e.includes("$oauth:")){b[d]=e;continue}let a=new Set;e.replace(o,(b,c)=>(a.add(c),""));let f=e,{getAccessToken:g}=await c.e(2503).then(c.bind(c,82503)),{isOAuthProviderId:h}=await c.e(3657).then(c.bind(c,63657));for(let b of a){if(!h(b))throw Error(`unknown OAuth provider in placeholder: ${b}`);let a=await g(b);f=f.replace(RegExp(`\\$oauth:${b}\\b`,"g"),a)}b[d]=f}return b}async function q(a){let{client:b,close:c}=await n(a);try{let a=b.getServerVersion(),{tools:c}=await b.listTools();return{name:a?.name,version:a?.version,tools:c.map(a=>({name:a.name,description:a.description,inputSchema:a.inputSchema}))}}finally{await c().catch(()=>{})}}async function r(a,b,c){let{client:d,close:e}=await n(a);try{let a=await d.callTool({name:b,arguments:c});return{isError:"boolean"==typeof a.isError?a.isError:void 0,content:a.content}}finally{await e().catch(()=>{})}}},91147:(a,b,c)=>{c.d(b,{_:()=>k});var d=c(73024),e=c(48161),f=c.n(e),g=c(76760),h=c.n(g),i=c(5243),j=c(88124);async function k(a){let b=await (0,i.listMcpServers)();if(0===b.length)return null;let c={};for(let a of b)if("stdio"===a.config.transport){let b=await (0,j.Jc)(a.config.env);c[a.id]={command:a.config.command,args:a.config.args,env:b}}else if("http"===a.config.transport){let b=await (0,j.Jc)(a.config.headers);c[a.id]={type:"http",url:a.config.url,...Object.keys(b).length>0?{headers:b}:{}}}else{let b=await (0,j.Jc)(a.config.headers);c[a.id]={type:"sse",url:a.config.url,...Object.keys(b).length>0?{headers:b}:{}}}let e=await d.promises.mkdtemp(h().join(f().tmpdir(),`reflex-mcp-${a}-`)),g=h().join(e,"mcp.json");return await d.promises.writeFile(g,JSON.stringify({mcpServers:c},null,2),"utf8"),{path:g,serverIds:b.map(a=>a.id),cleanup:async()=>{try{await d.promises.rm(e,{recursive:!0,force:!0})}catch{}}}}},96931:(a,b,c)=>{c.d(b,{R:()=>f});var d=c(59835),e=c(24576);async function f(a){let b=function(a){let b=a.trim();if(b.startsWith("{")&&b.endsWith("}"))try{let a=JSON.parse(b),c={prompt:"string"==typeof a.prompt&&a.prompt.trim().length>0?a.prompt:b};return("gemini"===a.provider||"codex"===a.provider)&&(c.provider=a.provider),"string"==typeof a.size&&(c.size=a.size),"string"==typeof a.aspectRatio&&(c.aspectRatio=a.aspectRatio),"string"==typeof a.alt&&(c.alt=a.alt),c}catch{}return{prompt:b}}(a.args.prompt),c=(0,e.mM)(a.args.rootPath);try{var f;let e=await (0,d.generateImage)({rootId:c,prompt:b.prompt,...b.provider?{provider:b.provider}:{},...b.size?{size:b.size}:{},...b.aspectRatio?{aspectRatio:b.aspectRatio}:{},...b.alt?{alt:b.alt}:{}}),g=b.alt||b.prompt,h=`![${g.replace(/[\[\]\n]/g," ").slice(0,200)}](${e.urlPath})
|
|
485
466
|
|
|
486
|
-
|
|
487
|
-
`;await a.manager.emit({type:"assistant-delta",text:h,agentId:a.meta.id,ts:new Date().toISOString(),seq:0})}catch(c){let b=c instanceof Error?c.message:String(c);throw await a.manager.emit({type:"assistant-delta",text
|
|
467
|
+
_generated: ${e.provider} \xb7 ${(f=e.size)<1024?`${f} B`:f<1048576?`${(f/1024).toFixed(1)} KB`:`${(f/1048576).toFixed(2)} MB`}_
|
|
468
|
+
`;await a.manager.emit({type:"assistant-delta",text:h,agentId:a.meta.id,ts:new Date().toISOString(),seq:0})}catch(c){let b=c instanceof Error?c.message:String(c);throw await a.manager.emit({type:"assistant-delta",text:`Failed to generate image: ${b}
|
|
488
469
|
`,agentId:a.meta.id,ts:new Date().toISOString(),seq:0}),c}}}};
|