[{"data":1,"prerenderedAt":2870},["ShallowReactive",2],{"navigation_docs":3,"-docs-reference-profiles":968,"-docs-reference-profiles-surround":2865},[4,27,63,129,287,311,893,902,950,964],{"title":5,"path":6,"stem":7,"children":8,"order":10,"icon":11},"Overview","\u002Fdocs\u002Foverview","docs\u002F1.overview\u002Findex",[9,12,18,24],{"title":5,"path":6,"stem":7,"order":10,"icon":11},1,"i-lucide-info",{"title":13,"path":14,"stem":15,"order":16,"icon":17},"Getting Started","\u002Fdocs\u002Foverview\u002Fgetting-started","docs\u002F1.overview\u002F2.getting-started",2,"i-lucide-rocket",{"title":19,"path":20,"stem":21,"order":22,"icon":23},"Contributing","\u002Fdocs\u002Foverview\u002Fcontributing","docs\u002F1.overview\u002F3.contributing",3,"i-lucide-heart",{"title":5,"path":25,"stem":26,"order":10},"\u002Fdocs\u002Foverview\u002F_dir","docs\u002F1.overview\u002F_dir",{"title":28,"path":29,"stem":30,"children":31,"page":62},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[32,37,42,47,53,59],{"title":33,"path":34,"stem":35,"order":10,"icon":36},"Events","\u002Fdocs\u002Fconcepts\u002Fevents","docs\u002F2.concepts\u002F1.events","i-lucide-zap",{"title":38,"path":39,"stem":40,"order":16,"icon":41},"Transports","\u002Fdocs\u002Fconcepts\u002Ftransports","docs\u002F2.concepts\u002F2.transports","i-lucide-network",{"title":43,"path":44,"stem":45,"order":22,"icon":46},"Module System","\u002Fdocs\u002Fconcepts\u002Fmodules","docs\u002F2.concepts\u002F3.modules","i-lucide-puzzle",{"title":48,"path":49,"stem":50,"order":51,"icon":52},"Flows","\u002Fdocs\u002Fconcepts\u002Fflows","docs\u002F2.concepts\u002F4.flows",4,"i-lucide-workflow",{"title":54,"path":55,"stem":56,"order":57,"icon":58},"Scheduler","\u002Fdocs\u002Fconcepts\u002Fscheduler","docs\u002F2.concepts\u002F5.scheduler",5,"i-lucide-clock",{"title":28,"path":60,"stem":61,"order":16},"\u002Fdocs\u002Fconcepts\u002F_dir","docs\u002F2.concepts\u002F_dir",false,{"title":64,"path":65,"stem":66,"children":67,"page":62},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides",[68,73,77,81,85,89,93,98,104,110,116,122,126],{"title":69,"path":70,"stem":71,"order":10,"icon":72},"Creating a Go App","\u002Fdocs\u002Fguides\u002Fcreating-go-app","docs\u002F3.guides\u002F1.creating-go-app","i-lucide-terminal",{"title":74,"path":75,"stem":76},"E2E tests & demo videos","\u002Fdocs\u002Fguides\u002Fe2e-and-demo-videos","docs\u002F3.guides\u002F10.e2e-and-demo-videos",{"title":78,"path":79,"stem":80,"icon":17},"Deploying to production","\u002Fdocs\u002Fguides\u002Fdeploying-to-production","docs\u002F3.guides\u002F11.deploying-to-production",{"title":82,"path":83,"stem":84,"order":16,"icon":46},"Creating a Go Module","\u002Fdocs\u002Fguides\u002Fcreating-go-module","docs\u002F3.guides\u002F2.creating-go-module",{"title":86,"path":87,"stem":88,"order":22,"icon":36},"Adding Events","\u002Fdocs\u002Fguides\u002Fadding-events-to-go-module","docs\u002F3.guides\u002F3.adding-events-to-go-module",{"title":90,"path":91,"stem":92,"order":51,"icon":52},"FlowDSL to Service","\u002Fdocs\u002Fguides\u002Fflowdsl-to-redelay","docs\u002F3.guides\u002F4.flowdsl-to-redelay",{"title":94,"path":95,"stem":96,"order":57,"icon":97},"Choosing a Transport","\u002Fdocs\u002Fguides\u002Fchoosing-a-transport","docs\u002F3.guides\u002F5.choosing-a-transport","i-lucide-git-branch",{"title":99,"path":100,"stem":101,"order":102,"icon":103},"Module Browser (\u002Fmodules)","\u002Fdocs\u002Fguides\u002Fmodules-browser","docs\u002F3.guides\u002F6.modules-browser",6,"i-lucide-layout-dashboard",{"title":105,"path":106,"stem":107,"order":108,"icon":109},"Running Flows","\u002Fdocs\u002Fguides\u002Frunning-flows","docs\u002F3.guides\u002F7.running-flows",7,"i-lucide-play-circle",{"title":111,"path":112,"stem":113,"order":114,"icon":115},"Trace + Live Observability","\u002Fdocs\u002Fguides\u002Fobservability","docs\u002F3.guides\u002F8.observability",8,"i-lucide-activity",{"title":117,"path":118,"stem":119,"order":120,"icon":121},"Project AI Assistant","\u002Fdocs\u002Fguides\u002Fai-assistant","docs\u002F3.guides\u002F9.ai-assistant",9,"i-lucide-sparkles",{"title":123,"path":124,"stem":125},"Debug taps — trace live data through any node","\u002Fdocs\u002Fguides\u002Fdebug-taps","docs\u002F3.guides\u002F9.debug-taps",{"title":64,"path":127,"stem":128,"order":22},"\u002Fdocs\u002Fguides\u002F_dir","docs\u002F3.guides\u002F_dir",{"title":130,"path":131,"stem":132,"children":133,"page":62},"Reference","\u002Fdocs\u002Freference","docs\u002F4.reference",[134,139,143,148,153,158,163,168,172,177,182,187,193,199,205,210,215,219,225,230,236,242,247,253,259,263,267,273,278,284],{"title":135,"path":136,"stem":137,"order":10,"icon":138},"Go Framework","\u002Fdocs\u002Freference\u002Fgo-framework","docs\u002F4.reference\u002F01.go-framework","i-simple-icons-go",{"title":140,"path":141,"stem":142,"order":16,"icon":46},"Built-in Modules","\u002Fdocs\u002Freference\u002Fgo-modules","docs\u002F4.reference\u002F02.go-modules",{"title":144,"path":145,"stem":146,"order":22,"icon":147},"Domain Addon Modules","\u002Fdocs\u002Freference\u002Fgo-modules-addons","docs\u002F4.reference\u002F03.go-modules-addons","i-lucide-blocks",{"title":149,"path":150,"stem":151,"order":51,"icon":152},"Go Events","\u002Fdocs\u002Freference\u002Fgo-events","docs\u002F4.reference\u002F04.go-events","i-lucide-radio",{"title":154,"path":155,"stem":156,"order":57,"icon":157},"Email Module","\u002Fdocs\u002Freference\u002Fgo-module-email","docs\u002F4.reference\u002F05.go-module-email","i-lucide-mail",{"title":159,"path":160,"stem":161,"order":102,"icon":162},"Go Core & IR","\u002Fdocs\u002Freference\u002Fgo-core","docs\u002F4.reference\u002F06.go-core","i-lucide-cpu",{"title":164,"path":165,"stem":166,"order":108,"icon":167},"Module Definition Files","\u002Fdocs\u002Freference\u002Fgo-module-files","docs\u002F4.reference\u002F07.go-module-files","i-lucide-file-code",{"title":169,"path":170,"stem":171,"order":114,"icon":72},"CLI Reference","\u002Fdocs\u002Freference\u002Fgo-cli","docs\u002F4.reference\u002F08.go-cli",{"title":173,"path":174,"stem":175,"order":120,"icon":176},"Go Formats","\u002Fdocs\u002Freference\u002Fgo-formats","docs\u002F4.reference\u002F09.go-formats","i-lucide-file-json",{"title":178,"path":179,"stem":180,"order":181,"icon":152},"AsyncAPI Module","\u002Fdocs\u002Freference\u002Fgo-asyncapi","docs\u002F4.reference\u002F10.go-asyncapi",10,{"title":183,"path":184,"stem":185,"order":186,"icon":52},"Go FlowDSL","\u002Fdocs\u002Freference\u002Fgo-flowdsl","docs\u002F4.reference\u002F11.go-flowdsl",11,{"title":188,"path":189,"stem":190,"order":191,"icon":192},"FlowDSL Examples","\u002Fdocs\u002Freference\u002Fflowdsl-examples","docs\u002F4.reference\u002F12.flowdsl-examples",12,"i-lucide-file-code-2",{"title":194,"path":195,"stem":196,"order":197,"icon":198},"FlowDSL Sync","\u002Fdocs\u002Freference\u002Fflowdsl-sync","docs\u002F4.reference\u002F13.flowdsl-sync",13,"i-lucide-refresh-cw",{"title":200,"path":201,"stem":202,"order":203,"icon":204},"Node.js Framework","\u002Fdocs\u002Freference\u002Fjs-framework","docs\u002F4.reference\u002F14.js-framework",14,"i-simple-icons-nodedotjs",{"title":206,"path":207,"stem":208,"order":203,"icon":209},"Python Framework","\u002Fdocs\u002Freference\u002Fpy-framework","docs\u002F4.reference\u002F14.py-framework","i-simple-icons-python",{"title":211,"path":212,"stem":213,"order":214,"icon":204},"Node.js Events","\u002Fdocs\u002Freference\u002Fjs-events","docs\u002F4.reference\u002F15.js-events",15,{"title":216,"path":217,"stem":218,"order":214,"icon":209},"Python Events","\u002Fdocs\u002Freference\u002Fpy-events","docs\u002F4.reference\u002F15.py-events",{"title":220,"path":221,"stem":222,"order":223,"icon":224},"go-ai — LLM Providers, Guard, Ledger","\u002Fdocs\u002Freference\u002Fgo-ai","docs\u002F4.reference\u002F16.go-ai",16,"i-lucide-brain-circuit",{"title":226,"path":227,"stem":228,"order":229,"icon":41},"Infrastructure Modules","\u002Fdocs\u002Freference\u002Fgeneric-infra-modules","docs\u002F4.reference\u002F17.generic-infra-modules",17,{"title":231,"path":232,"stem":233,"order":234,"icon":235},"Flow Templates","\u002Fdocs\u002Freference\u002Fflow-templates","docs\u002F4.reference\u002F18.flow-templates",18,"i-lucide-library-big",{"title":237,"path":238,"stem":239,"order":240,"icon":241},"Assistant (chat + handoff)","\u002Fdocs\u002Freference\u002Fassistant","docs\u002F4.reference\u002F19.assistant",19,"i-lucide-messages-square",{"title":243,"path":244,"stem":245,"order":246,"icon":41},"Coordination","\u002Fdocs\u002Freference\u002Fcoordination","docs\u002F4.reference\u002F20.coordination",20,{"title":248,"path":249,"stem":250,"order":251,"icon":252},"Search (vector)","\u002Fdocs\u002Freference\u002Fsearch","docs\u002F4.reference\u002F21.search",21,"i-lucide-search",{"title":254,"path":255,"stem":256,"order":257,"icon":258},"Profiles","\u002Fdocs\u002Freference\u002Fprofiles","docs\u002F4.reference\u002F22.profiles",22,"i-lucide-bookmark",{"title":260,"path":261,"stem":262},"Flow-driven HTTP endpoints","\u002Fdocs\u002Freference\u002Fflow-driven-endpoints","docs\u002F4.reference\u002F23.flow-driven-endpoints",{"title":264,"path":265,"stem":266},"Deployments","\u002Fdocs\u002Freference\u002Fdeployments","docs\u002F4.reference\u002F24.deployments",{"title":268,"path":269,"stem":270,"order":271,"icon":272},"i18n (translations)","\u002Fdocs\u002Freference\u002Fi18n","docs\u002F4.reference\u002F25.i18n",25,"i-lucide-languages",{"title":274,"path":275,"stem":276,"order":277,"icon":152},"WebSockets","\u002Fdocs\u002Freference\u002Fwebsockets","docs\u002F4.reference\u002F26.websockets",26,{"title":279,"path":280,"stem":281,"order":282,"icon":283},"Localized content","\u002Fdocs\u002Freference\u002Flocalized-content","docs\u002F4.reference\u002F27.localized-content",27,"i-lucide-file-text",{"title":130,"path":285,"stem":286,"order":51},"\u002Fdocs\u002Freference\u002F_dir","docs\u002F4.reference\u002F_dir",{"title":288,"path":289,"stem":290,"children":291,"page":62},"Integrations","\u002Fdocs\u002Fintegrations","docs\u002F5.integrations",[292,296,300,304,308],{"title":293,"path":294,"stem":295,"order":10,"icon":52},"FlowDSL","\u002Fdocs\u002Fintegrations\u002Fflowdsl","docs\u002F5.integrations\u002F1.flowdsl",{"title":297,"path":298,"stem":299,"order":16,"icon":283},"OpenAPI","\u002Fdocs\u002Fintegrations\u002Fopenapi","docs\u002F5.integrations\u002F2.openapi",{"title":301,"path":302,"stem":303,"order":22,"icon":152},"AsyncAPI","\u002Fdocs\u002Fintegrations\u002Fasyncapi","docs\u002F5.integrations\u002F3.asyncapi",{"title":305,"path":306,"stem":307},"MCP Integration","\u002Fdocs\u002Fintegrations\u002Fmcp","docs\u002F5.integrations\u002F4.mcp",{"title":288,"path":309,"stem":310,"order":57},"\u002Fdocs\u002Fintegrations\u002F_dir","docs\u002F5.integrations\u002F_dir",{"title":312,"path":313,"stem":314,"children":315},"FlowDSL Node Catalog","\u002Fdocs\u002Fnodes","docs\u002F5.nodes\u002Findex",[316,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373,377,381,385,389,393,397,401,405,409,413,417,421,425,429,433,437,441,445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749,753,757,761,765,769,773,777,781,785,789,793,797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889],{"title":312,"path":313,"stem":314},{"title":318,"path":319,"stem":320,"order":57},"Node Catalog","\u002Fdocs\u002Fnodes\u002F_dir","docs\u002F5.nodes\u002F_dir",{"title":322,"path":323,"stem":324},"Record Alert","\u002Fdocs\u002Fnodes\u002Falerts_record","docs\u002F5.nodes\u002Falerts_record",{"title":326,"path":327,"stem":328},"Log to API Log","\u002Fdocs\u002Fnodes\u002Fapilog_record","docs\u002F5.nodes\u002Fapilog_record",{"title":330,"path":331,"stem":332},"ClickHouse Exec","\u002Fdocs\u002Fnodes\u002Fclickhouse_exec","docs\u002F5.nodes\u002Fclickhouse_exec",{"title":334,"path":335,"stem":336},"ClickHouse Insert","\u002Fdocs\u002Fnodes\u002Fclickhouse_insert","docs\u002F5.nodes\u002Fclickhouse_insert",{"title":338,"path":339,"stem":340},"ClickHouse Query","\u002Fdocs\u002Fnodes\u002Fclickhouse_query","docs\u002F5.nodes\u002Fclickhouse_query",{"title":342,"path":343,"stem":344},"Array Op","\u002Fdocs\u002Fnodes\u002Fcore_array-ops","docs\u002F5.nodes\u002Fcore_array-ops",{"title":346,"path":347,"stem":348},"Assert","\u002Fdocs\u002Fnodes\u002Fcore_assert","docs\u002F5.nodes\u002Fcore_assert",{"title":350,"path":351,"stem":352},"Audit Emit","\u002Fdocs\u002Fnodes\u002Fcore_audit-emit","docs\u002F5.nodes\u002Fcore_audit-emit",{"title":354,"path":355,"stem":356},"Catch","\u002Fdocs\u002Fnodes\u002Fcore_catch","docs\u002F5.nodes\u002Fcore_catch",{"title":358,"path":359,"stem":360},"DateTime","\u002Fdocs\u002Fnodes\u002Fcore_datetime","docs\u002F5.nodes\u002Fcore_datetime",{"title":362,"path":363,"stem":364},"Dead Letter","\u002Fdocs\u002Fnodes\u002Fcore_dead-letter","docs\u002F5.nodes\u002Fcore_dead-letter",{"title":366,"path":367,"stem":368},"Delay","\u002Fdocs\u002Fnodes\u002Fcore_delay","docs\u002F5.nodes\u002Fcore_delay",{"title":370,"path":371,"stem":372},"ForEach","\u002Fdocs\u002Fnodes\u002Fcore_foreach","docs\u002F5.nodes\u002Fcore_foreach",{"title":374,"path":375,"stem":376},"Idempotency Key","\u002Fdocs\u002Fnodes\u002Fcore_idempotency-key","docs\u002F5.nodes\u002Fcore_idempotency-key",{"title":378,"path":379,"stem":380},"If","\u002Fdocs\u002Fnodes\u002Fcore_if","docs\u002F5.nodes\u002Fcore_if",{"title":382,"path":383,"stem":384},"Inspect","\u002Fdocs\u002Fnodes\u002Fcore_inspect","docs\u002F5.nodes\u002Fcore_inspect",{"title":386,"path":387,"stem":388},"JSON Merge","\u002Fdocs\u002Fnodes\u002Fcore_json-merge","docs\u002F5.nodes\u002Fcore_json-merge",{"title":390,"path":391,"stem":392},"JSON Schema Validate","\u002Fdocs\u002Fnodes\u002Fcore_json-schema-validate","docs\u002F5.nodes\u002Fcore_json-schema-validate",{"title":394,"path":395,"stem":396},"JSONPath Extract","\u002Fdocs\u002Fnodes\u002Fcore_jsonpath-extract","docs\u002F5.nodes\u002Fcore_jsonpath-extract",{"title":398,"path":399,"stem":400},"Log","\u002Fdocs\u002Fnodes\u002Fcore_log","docs\u002F5.nodes\u002Fcore_log",{"title":402,"path":403,"stem":404},"Math","\u002Fdocs\u002Fnodes\u002Fcore_math","docs\u002F5.nodes\u002Fcore_math",{"title":406,"path":407,"stem":408},"Merge","\u002Fdocs\u002Fnodes\u002Fcore_merge","docs\u002F5.nodes\u002Fcore_merge",{"title":410,"path":411,"stem":412},"Metric Counter","\u002Fdocs\u002Fnodes\u002Fcore_metric-counter","docs\u002F5.nodes\u002Fcore_metric-counter",{"title":414,"path":415,"stem":416},"Metric Gauge","\u002Fdocs\u002Fnodes\u002Fcore_metric-gauge","docs\u002F5.nodes\u002Fcore_metric-gauge",{"title":418,"path":419,"stem":420},"Mock","\u002Fdocs\u002Fnodes\u002Fcore_mock","docs\u002F5.nodes\u002Fcore_mock",{"title":422,"path":423,"stem":424},"No-op","\u002Fdocs\u002Fnodes\u002Fcore_noop","docs\u002F5.nodes\u002Fcore_noop",{"title":426,"path":427,"stem":428},"Object Omit","\u002Fdocs\u002Fnodes\u002Fcore_object-omit","docs\u002F5.nodes\u002Fcore_object-omit",{"title":430,"path":431,"stem":432},"Object Pick","\u002Fdocs\u002Fnodes\u002Fcore_object-pick","docs\u002F5.nodes\u002Fcore_object-pick",{"title":434,"path":435,"stem":436},"Parallel Fan-Out","\u002Fdocs\u002Fnodes\u002Fcore_parallel","docs\u002F5.nodes\u002Fcore_parallel",{"title":438,"path":439,"stem":440},"Raise","\u002Fdocs\u002Fnodes\u002Fcore_raise","docs\u002F5.nodes\u002Fcore_raise",{"title":442,"path":443,"stem":444},"Rate Limit Check","\u002Fdocs\u002Fnodes\u002Fcore_rate-limit-check","docs\u002F5.nodes\u002Fcore_rate-limit-check",{"title":446,"path":447,"stem":448},"Regex Extract","\u002Fdocs\u002Fnodes\u002Fcore_regex-extract","docs\u002F5.nodes\u002Fcore_regex-extract",{"title":450,"path":451,"stem":452},"Require Fields","\u002Fdocs\u002Fnodes\u002Fcore_require-fields","docs\u002F5.nodes\u002Fcore_require-fields",{"title":454,"path":455,"stem":456},"Rethrow","\u002Fdocs\u002Fnodes\u002Fcore_rethrow","docs\u002F5.nodes\u002Fcore_rethrow",{"title":458,"path":459,"stem":460},"Return","\u002Fdocs\u002Fnodes\u002Fcore_return","docs\u002F5.nodes\u002Fcore_return",{"title":462,"path":463,"stem":464},"HMAC Signature Verify","\u002Fdocs\u002Fnodes\u002Fcore_signature-verify","docs\u002F5.nodes\u002Fcore_signature-verify",{"title":466,"path":467,"stem":468},"String Op","\u002Fdocs\u002Fnodes\u002Fcore_string-ops","docs\u002F5.nodes\u002Fcore_string-ops",{"title":470,"path":471,"stem":472},"Subflow Invoke","\u002Fdocs\u002Fnodes\u002Fcore_subflow-invoke","docs\u002F5.nodes\u002Fcore_subflow-invoke",{"title":474,"path":475,"stem":476},"Switch","\u002Fdocs\u002Fnodes\u002Fcore_switch","docs\u002F5.nodes\u002Fcore_switch",{"title":478,"path":479,"stem":480},"Template Render","\u002Fdocs\u002Fnodes\u002Fcore_template-render","docs\u002F5.nodes\u002Fcore_template-render",{"title":482,"path":483,"stem":484},"Throttle","\u002Fdocs\u002Fnodes\u002Fcore_throttle","docs\u002F5.nodes\u002Fcore_throttle",{"title":486,"path":487,"stem":488},"Timeout","\u002Fdocs\u002Fnodes\u002Fcore_timeout","docs\u002F5.nodes\u002Fcore_timeout",{"title":490,"path":491,"stem":492},"Type Cast","\u002Fdocs\u002Fnodes\u002Fcore_type-cast","docs\u002F5.nodes\u002Fcore_type-cast",{"title":494,"path":495,"stem":496},"Webhook Respond","\u002Fdocs\u002Fnodes\u002Fcore_webhook-respond","docs\u002F5.nodes\u002Fcore_webhook-respond",{"title":498,"path":499,"stem":500},"File Delete","\u002Fdocs\u002Fnodes\u002Ffilesys_delete","docs\u002F5.nodes\u002Ffilesys_delete",{"title":502,"path":503,"stem":504},"Directory List","\u002Fdocs\u002Fnodes\u002Ffilesys_list","docs\u002F5.nodes\u002Ffilesys_list",{"title":506,"path":507,"stem":508},"File Read","\u002Fdocs\u002Fnodes\u002Ffilesys_read","docs\u002F5.nodes\u002Ffilesys_read",{"title":510,"path":511,"stem":512},"File Stat","\u002Fdocs\u002Fnodes\u002Ffilesys_stat","docs\u002F5.nodes\u002Ffilesys_stat",{"title":514,"path":515,"stem":516},"File Write","\u002Fdocs\u002Fnodes\u002Ffilesys_write","docs\u002F5.nodes\u002Ffilesys_write",{"title":518,"path":519,"stem":520},"FTP Delete","\u002Fdocs\u002Fnodes\u002Fftp_delete","docs\u002F5.nodes\u002Fftp_delete",{"title":522,"path":523,"stem":524},"FTP Download","\u002Fdocs\u002Fnodes\u002Fftp_download","docs\u002F5.nodes\u002Fftp_download",{"title":526,"path":527,"stem":528},"FTP List","\u002Fdocs\u002Fnodes\u002Fftp_list","docs\u002F5.nodes\u002Fftp_list",{"title":530,"path":531,"stem":532},"FTP Upload","\u002Fdocs\u002Fnodes\u002Fftp_upload","docs\u002F5.nodes\u002Fftp_upload",{"title":534,"path":535,"stem":536},"HTTP DELETE","\u002Fdocs\u002Fnodes\u002Fhttp_delete","docs\u002F5.nodes\u002Fhttp_delete",{"title":538,"path":539,"stem":540},"HTTP GET","\u002Fdocs\u002Fnodes\u002Fhttp_get","docs\u002F5.nodes\u002Fhttp_get",{"title":542,"path":543,"stem":544},"HTTP POST","\u002Fdocs\u002Fnodes\u002Fhttp_post","docs\u002F5.nodes\u002Fhttp_post",{"title":546,"path":547,"stem":548},"HTTP PUT","\u002Fdocs\u002Fnodes\u002Fhttp_put","docs\u002F5.nodes\u002Fhttp_put",{"title":550,"path":551,"stem":552},"HTTP Request","\u002Fdocs\u002Fnodes\u002Fhttp_request","docs\u002F5.nodes\u002Fhttp_request",{"title":554,"path":555,"stem":556},"Fill Translations","\u002Fdocs\u002Fnodes\u002Fi18n_fill-translations","docs\u002F5.nodes\u002Fi18n_fill-translations",{"title":558,"path":559,"stem":560},"Resolve Locale","\u002Fdocs\u002Fnodes\u002Fi18n_resolve-locale","docs\u002F5.nodes\u002Fi18n_resolve-locale",{"title":562,"path":563,"stem":564},"Translate","\u002Fdocs\u002Fnodes\u002Fi18n_translate","docs\u002F5.nodes\u002Fi18n_translate",{"title":566,"path":567,"stem":568},"Mongo AGGREGATE","\u002Fdocs\u002Fnodes\u002Fmongoops_aggregate","docs\u002F5.nodes\u002Fmongoops_aggregate",{"title":570,"path":571,"stem":572},"Mongo DELETE","\u002Fdocs\u002Fnodes\u002Fmongoops_delete","docs\u002F5.nodes\u002Fmongoops_delete",{"title":574,"path":575,"stem":576},"Mongo FIND","\u002Fdocs\u002Fnodes\u002Fmongoops_find","docs\u002F5.nodes\u002Fmongoops_find",{"title":578,"path":579,"stem":580},"Mongo FIND ONE","\u002Fdocs\u002Fnodes\u002Fmongoops_find-one","docs\u002F5.nodes\u002Fmongoops_find-one",{"title":582,"path":583,"stem":584},"Mongo INSERT","\u002Fdocs\u002Fnodes\u002Fmongoops_insert","docs\u002F5.nodes\u002Fmongoops_insert",{"title":586,"path":587,"stem":588},"Mongo UPDATE","\u002Fdocs\u002Fnodes\u002Fmongoops_update","docs\u002F5.nodes\u002Fmongoops_update",{"title":590,"path":591,"stem":592},"Postgres COPY FROM","\u002Fdocs\u002Fnodes\u002Fpostgres_copy-from","docs\u002F5.nodes\u002Fpostgres_copy-from",{"title":594,"path":595,"stem":596},"Postgres Exec","\u002Fdocs\u002Fnodes\u002Fpostgres_exec","docs\u002F5.nodes\u002Fpostgres_exec",{"title":598,"path":599,"stem":600},"Postgres Query","\u002Fdocs\u002Fnodes\u002Fpostgres_query","docs\u002F5.nodes\u002Fpostgres_query",{"title":602,"path":603,"stem":604},"Postgres Transaction","\u002Fdocs\u002Fnodes\u002Fpostgres_transaction","docs\u002F5.nodes\u002Fpostgres_transaction",{"title":606,"path":607,"stem":608},"RabbitMQ Consume","\u002Fdocs\u002Fnodes\u002Frabbitmq_consume","docs\u002F5.nodes\u002Frabbitmq_consume",{"title":610,"path":611,"stem":612},"RabbitMQ Declare","\u002Fdocs\u002Fnodes\u002Frabbitmq_declare","docs\u002F5.nodes\u002Frabbitmq_declare",{"title":614,"path":615,"stem":616},"RabbitMQ Publish","\u002Fdocs\u002Fnodes\u002Frabbitmq_publish","docs\u002F5.nodes\u002Frabbitmq_publish",{"title":618,"path":619,"stem":620},"Auth Login","\u002Fdocs\u002Fnodes\u002Fredelay_auth-login","docs\u002F5.nodes\u002Fredelay_auth-login",{"title":622,"path":623,"stem":624},"Require Permission","\u002Fdocs\u002Fnodes\u002Fredelay_auth-require-permission","docs\u002F5.nodes\u002Fredelay_auth-require-permission",{"title":626,"path":627,"stem":628},"Validate Token","\u002Fdocs\u002Fnodes\u002Fredelay_auth-validate-token","docs\u002F5.nodes\u002Fredelay_auth-validate-token",{"title":630,"path":631,"stem":632},"Render Email Template","\u002Fdocs\u002Fnodes\u002Fredelay_email-render-template","docs\u002F5.nodes\u002Fredelay_email-render-template",{"title":634,"path":635,"stem":636},"Send Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send","docs\u002F5.nodes\u002Fredelay_email-send",{"title":638,"path":639,"stem":640},"Send Templated Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send-templated","docs\u002F5.nodes\u002Fredelay_email-send-templated",{"title":642,"path":643,"stem":644},"Event Source","\u002Fdocs\u002Fnodes\u002Fredelay_event-source","docs\u002F5.nodes\u002Fredelay_event-source",{"title":646,"path":647,"stem":648},"Create Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-create-group","docs\u002F5.nodes\u002Fredelay_groups-create-group",{"title":650,"path":651,"stem":652},"Delete Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-delete-group","docs\u002F5.nodes\u002Fredelay_groups-delete-group",{"title":654,"path":655,"stem":656},"Resolve Permissions","\u002Fdocs\u002Fnodes\u002Fredelay_groups-resolve-permissions","docs\u002F5.nodes\u002Fredelay_groups-resolve-permissions",{"title":658,"path":659,"stem":660},"Update Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-update-group","docs\u002F5.nodes\u002Fredelay_groups-update-group",{"title":662,"path":663,"stem":664},"HTTP Endpoint","\u002Fdocs\u002Fnodes\u002Fredelay_http-endpoint","docs\u002F5.nodes\u002Fredelay_http-endpoint",{"title":666,"path":667,"stem":668},"JSON Stream Source","\u002Fdocs\u002Fnodes\u002Fredelay_json-stream-source","docs\u002F5.nodes\u002Fredelay_json-stream-source",{"title":670,"path":671,"stem":672},"JSON → Event","\u002Fdocs\u002Fnodes\u002Fredelay_json-to-event","docs\u002F5.nodes\u002Fredelay_json-to-event",{"title":674,"path":675,"stem":676},"Kafka Produce","\u002Fdocs\u002Fnodes\u002Fredelay_kafka-produce","docs\u002F5.nodes\u002Fredelay_kafka-produce",{"title":678,"path":679,"stem":680},"Create Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-create","docs\u002F5.nodes\u002Fredelay_links-create",{"title":682,"path":683,"stem":684},"Delete Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-delete","docs\u002F5.nodes\u002Fredelay_links-delete",{"title":686,"path":687,"stem":688},"Resolve Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-resolve","docs\u002F5.nodes\u002Fredelay_links-resolve",{"title":690,"path":691,"stem":692},"LLM Chat","\u002Fdocs\u002Fnodes\u002Fredelay_llm-chat","docs\u002F5.nodes\u002Fredelay_llm-chat",{"title":694,"path":695,"stem":696},"LLM Embed","\u002Fdocs\u002Fnodes\u002Fredelay_llm-embed","docs\u002F5.nodes\u002Fredelay_llm-embed",{"title":698,"path":699,"stem":700},"LLM Guard","\u002Fdocs\u002Fnodes\u002Fredelay_llm-guard","docs\u002F5.nodes\u002Fredelay_llm-guard",{"title":702,"path":703,"stem":704},"LLM Tool Router","\u002Fdocs\u002Fnodes\u002Fredelay_llm-tool-router","docs\u002F5.nodes\u002Fredelay_llm-tool-router",{"title":706,"path":707,"stem":708},"NATS Publish","\u002Fdocs\u002Fnodes\u002Fredelay_nats-publish","docs\u002F5.nodes\u002Fredelay_nats-publish",{"title":710,"path":711,"stem":712},"Mark Notification Read","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-mark-read","docs\u002F5.nodes\u002Fredelay_notifications-mark-read",{"title":714,"path":715,"stem":716},"Send Notification","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-send","docs\u002F5.nodes\u002Fredelay_notifications-send",{"title":718,"path":719,"stem":720},"Redis Stream XADD","\u002Fdocs\u002Fnodes\u002Fredelay_redis-stream-publish","docs\u002F5.nodes\u002Fredelay_redis-stream-publish",{"title":722,"path":723,"stem":724},"S3 Copy Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-copy-object","docs\u002F5.nodes\u002Fredelay_s3-copy-object",{"title":726,"path":727,"stem":728},"S3 Delete Many","\u002Fdocs\u002Fnodes\u002Fredelay_s3-delete-many","docs\u002F5.nodes\u002Fredelay_s3-delete-many",{"title":730,"path":731,"stem":732},"S3 Head Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-head-object","docs\u002F5.nodes\u002Fredelay_s3-head-object",{"title":734,"path":735,"stem":736},"S3 List Objects","\u002Fdocs\u002Fnodes\u002Fredelay_s3-list-objects","docs\u002F5.nodes\u002Fredelay_s3-list-objects",{"title":738,"path":739,"stem":740},"Create Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-create-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-create-schedule",{"title":742,"path":743,"stem":744},"Cron Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-cron-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-cron-trigger",{"title":746,"path":747,"stem":748},"Delete Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-delete-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-delete-schedule",{"title":750,"path":751,"stem":752},"Interval Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-interval-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-interval-trigger",{"title":754,"path":755,"stem":756},"Search Query","\u002Fdocs\u002Fnodes\u002Fredelay_search-query","docs\u002F5.nodes\u002Fredelay_search-query",{"title":758,"path":759,"stem":760},"Search Upsert","\u002Fdocs\u002Fnodes\u002Fredelay_search-upsert","docs\u002F5.nodes\u002Fredelay_search-upsert",{"title":762,"path":763,"stem":764},"Delete Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-delete","docs\u002F5.nodes\u002Fredelay_settings-delete",{"title":766,"path":767,"stem":768},"Get Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-get","docs\u002F5.nodes\u002Fredelay_settings-get",{"title":770,"path":771,"stem":772},"Set Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-set","docs\u002F5.nodes\u002Fredelay_settings-set",{"title":774,"path":775,"stem":776},"Delete File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-delete","docs\u002F5.nodes\u002Fredelay_storage-delete",{"title":778,"path":779,"stem":780},"Download File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-download","docs\u002F5.nodes\u002Fredelay_storage-download",{"title":782,"path":783,"stem":784},"Generate Presigned URL","\u002Fdocs\u002Fnodes\u002Fredelay_storage-presign-url","docs\u002F5.nodes\u002Fredelay_storage-presign-url",{"title":786,"path":787,"stem":788},"Upload File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-upload","docs\u002F5.nodes\u002Fredelay_storage-upload",{"title":790,"path":791,"stem":792},"Subworkflow","\u002Fdocs\u002Fnodes\u002Fredelay_subworkflow","docs\u002F5.nodes\u002Fredelay_subworkflow",{"title":794,"path":795,"stem":796},"Activate User","\u002Fdocs\u002Fnodes\u002Fredelay_users-activate","docs\u002F5.nodes\u002Fredelay_users-activate",{"title":798,"path":799,"stem":800},"Create Pending User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-pending","docs\u002F5.nodes\u002Fredelay_users-create-pending",{"title":802,"path":803,"stem":804},"Create User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-user","docs\u002F5.nodes\u002Fredelay_users-create-user",{"title":806,"path":807,"stem":808},"Delete User","\u002Fdocs\u002Fnodes\u002Fredelay_users-delete-user","docs\u002F5.nodes\u002Fredelay_users-delete-user",{"title":810,"path":811,"stem":812},"Find User By Email","\u002Fdocs\u002Fnodes\u002Fredelay_users-find-by-email","docs\u002F5.nodes\u002Fredelay_users-find-by-email",{"title":814,"path":815,"stem":816},"Get User","\u002Fdocs\u002Fnodes\u002Fredelay_users-get-user","docs\u002F5.nodes\u002Fredelay_users-get-user",{"title":818,"path":819,"stem":820},"List Users","\u002Fdocs\u002Fnodes\u002Fredelay_users-list-users","docs\u002F5.nodes\u002Fredelay_users-list-users",{"title":822,"path":823,"stem":824},"Update User","\u002Fdocs\u002Fnodes\u002Fredelay_users-update-user","docs\u002F5.nodes\u002Fredelay_users-update-user",{"title":826,"path":827,"stem":828},"Request Email Verification (legacy)","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request","docs\u002F5.nodes\u002Fredelay_verification-request",{"title":830,"path":831,"stem":832},"Request Email Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-email","docs\u002F5.nodes\u002Fredelay_verification-request-email",{"title":834,"path":835,"stem":836},"Request SMS Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-sms","docs\u002F5.nodes\u002Fredelay_verification-request-sms",{"title":838,"path":839,"stem":840},"Verify Token","\u002Fdocs\u002Fnodes\u002Fredelay_verification-verify","docs\u002F5.nodes\u002Fredelay_verification-verify",{"title":842,"path":843,"stem":844},"Redis DEL","\u002Fdocs\u002Fnodes\u002Fredisops_del","docs\u002F5.nodes\u002Fredisops_del",{"title":846,"path":847,"stem":848},"Redis EXPIRE","\u002Fdocs\u002Fnodes\u002Fredisops_expire","docs\u002F5.nodes\u002Fredisops_expire",{"title":850,"path":851,"stem":852},"Redis GET","\u002Fdocs\u002Fnodes\u002Fredisops_get","docs\u002F5.nodes\u002Fredisops_get",{"title":854,"path":855,"stem":856},"Redis HGET","\u002Fdocs\u002Fnodes\u002Fredisops_hget","docs\u002F5.nodes\u002Fredisops_hget",{"title":858,"path":859,"stem":860},"Redis HSET","\u002Fdocs\u002Fnodes\u002Fredisops_hset","docs\u002F5.nodes\u002Fredisops_hset",{"title":862,"path":863,"stem":864},"Redis INCR","\u002Fdocs\u002Fnodes\u002Fredisops_incr","docs\u002F5.nodes\u002Fredisops_incr",{"title":866,"path":867,"stem":868},"Redis LPOP","\u002Fdocs\u002Fnodes\u002Fredisops_lpop","docs\u002F5.nodes\u002Fredisops_lpop",{"title":870,"path":871,"stem":872},"Redis LPUSH","\u002Fdocs\u002Fnodes\u002Fredisops_lpush","docs\u002F5.nodes\u002Fredisops_lpush",{"title":874,"path":875,"stem":876},"Redis PUBLISH","\u002Fdocs\u002Fnodes\u002Fredisops_publish","docs\u002F5.nodes\u002Fredisops_publish",{"title":878,"path":879,"stem":880},"Redis SET","\u002Fdocs\u002Fnodes\u002Fredisops_set","docs\u002F5.nodes\u002Fredisops_set",{"title":882,"path":883,"stem":884},"SFTP Download","\u002Fdocs\u002Fnodes\u002Fsftp_download","docs\u002F5.nodes\u002Fsftp_download",{"title":886,"path":887,"stem":888},"SFTP Upload","\u002Fdocs\u002Fnodes\u002Fsftp_upload","docs\u002F5.nodes\u002Fsftp_upload",{"title":890,"path":891,"stem":892},"Send SMS","\u002Fdocs\u002Fnodes\u002Fsms_send","docs\u002F5.nodes\u002Fsms_send",{"title":894,"path":895,"stem":896,"children":897,"page":62},"Rfcs","\u002Fdocs\u002Frfcs","docs\u002F6.rfcs",[898],{"title":899,"path":900,"stem":901},"RFC 0001 — Worker Assignment for Flow Deployments","\u002Fdocs\u002Frfcs\u002F0001-worker-assignment","docs\u002F6.rfcs\u002F0001-worker-assignment",{"title":903,"path":904,"stem":905,"children":906,"page":62},"Admin","\u002Fdocs\u002Fadmin","docs\u002F7.admin",[907,912,917,922,927,932,937,941,946],{"title":5,"path":908,"stem":909,"order":910,"icon":911},"\u002Fdocs\u002Fadmin\u002Foverview","docs\u002F7.admin\u002F00.overview",0,"i-lucide-compass",{"title":913,"path":914,"stem":915,"order":10,"icon":916},"Getting started","\u002Fdocs\u002Fadmin\u002Fgetting-started","docs\u002F7.admin\u002F01.getting-started","i-lucide-play",{"title":918,"path":919,"stem":920,"order":16,"icon":921},"Layered architecture","\u002Fdocs\u002Fadmin\u002Flayered-architecture","docs\u002F7.admin\u002F02.layered-architecture","i-lucide-layers",{"title":923,"path":924,"stem":925,"order":22,"icon":926},"Building a custom admin project","\u002Fdocs\u002Fadmin\u002Fbuilding-a-custom-admin-project","docs\u002F7.admin\u002F03.building-a-custom-admin-project","i-lucide-folder-plus",{"title":928,"path":929,"stem":930,"order":51,"icon":931},"Building admin modules","\u002Fdocs\u002Fadmin\u002Fbuilding-admin-modules","docs\u002F7.admin\u002F04.building-admin-modules","i-lucide-package-plus",{"title":933,"path":934,"stem":935,"order":57,"icon":936},"Base module reference","\u002Fdocs\u002Fadmin\u002Freference-base-modules","docs\u002F7.admin\u002F05.reference-base-modules","i-lucide-boxes",{"title":938,"path":939,"stem":940,"order":102,"icon":17},"Deployment","\u002Fdocs\u002Fadmin\u002Fdeployment","docs\u002F7.admin\u002F06.deployment",{"title":942,"path":943,"stem":944,"order":108,"icon":945},"Consuming the base layer (versioned)","\u002Fdocs\u002Fadmin\u002Fconsuming-the-base-layer","docs\u002F7.admin\u002F07.consuming-the-base-layer","i-lucide-package",{"title":947,"path":948,"stem":949,"order":108},"Admin UI","\u002Fdocs\u002Fadmin\u002F_dir","docs\u002F7.admin\u002F_dir",{"title":951,"path":952,"stem":953,"children":954,"page":62},"Services","\u002Fdocs\u002Fservices","docs\u002F8.services",[955,960],{"title":956,"path":957,"stem":958,"order":10,"icon":959},"Custom development & support services","\u002Fdocs\u002Fservices\u002Fcustom-development","docs\u002F8.services\u002F1.custom-development","i-lucide-briefcase",{"title":951,"path":961,"stem":962,"icon":959,"order":963},"\u002Fdocs\u002Fservices\u002F_dir","docs\u002F8.services\u002F_dir",80,{"title":965,"path":966,"stem":967,"order":910},"Dir","\u002Fdocs\u002F_dir","docs\u002F_dir",{"id":969,"title":254,"body":970,"description":2858,"extension":2859,"links":2860,"meta":2861,"navigation":2862,"path":255,"seo":2863,"stem":256,"__hash__":2864},"docs\u002Fdocs\u002F4.reference\u002F22.profiles.md",{"type":971,"value":972,"toc":2835},"minimark",[973,977,991,1028,1031,1036,1046,1050,1057,1068,1379,1398,1406,1421,1474,1484,1491,1498,1571,1592,1599,1616,1620,1632,1638,1647,1651,1679,1682,1937,1953,1958,2029,2032,2069,2084,2088,2103,2137,2141,2156,2272,2276,2288,2295,2299,2374,2385,2388,2423,2427,2446,2456,2462,2466,2477,2480,2491,2502,2508,2522,2526,2532,2639,2645,2699,2708,2712,2715,2822,2831],[974,975,254],"h1",{"id":976},"profiles",[978,979,980,981,985,986,990],"p",{},"A ",[982,983,984],"strong",{},"profile"," is a named, reusable config bundle that FlowDSL nodes reference by id instead of hand-configuring each field. They live in MongoDB (one row per profile), are edited from ",[987,988,989],"code",{},"\u002Fadmin\u002Fprofiles",", and fan-out cross-worker via the EventBus so operators never need to restart containers to pick up a change.",[978,992,993,994,997,998,1001,1002,1001,1005,1001,1008,1001,1011,1001,1014,1001,1017,1020,1021,1024,1025,1027],{},"The goal: on a ",[987,995,996],{},"redelay\u002Fllm-chat"," node you no longer configure ",[987,999,1000],{},"providerID"," + ",[987,1003,1004],{},"model",[987,1006,1007],{},"temperature",[987,1009,1010],{},"maxTokens",[987,1012,1013],{},"systemPrompt",[987,1015,1016],{},"replyStyle",[987,1018,1019],{},"examplesPolicy"," per step. Instead, you pick ",[987,1022,1023],{},"assistant-fast"," from the ",[987,1026,984],{}," dropdown and leave the other fields empty. The handler merges the profile's config underneath whatever you did set on the node — per-node fields still override.",[978,1029,1030],{},"Same pattern applies to every other connection-bearing node you'll add — DB, FTP, storage, SMTP. One profile definition, one dropdown, zero copy-paste.",[1032,1033,1035],"h2",{"id":1034},"architecture","Architecture",[1037,1038,1043],"pre",{"className":1039,"code":1041,"language":1042},[1040],"language-text","module.yaml: profiles: [...] ─────────► ProfileKind (IR)\n                                              │\n                                              ▼\nProfilesProvider interface ─► settings.Module registers live profiles\n                                              │\n                                              ▼\n                                   settings.ProfilesService\n                                   (MongoDB + cache + bus)\n                                              │\n           ┌──────────────────────────────────┼──────────────────────────────────┐\n           ▼                                  ▼                                  ▼\n   \u002Fadmin\u002Fprofiles API              IRBase.FlowDSLNodes()              modules.ResolveProfile\n   (CRUD + duplicate)               (injects profile enum)           (handler runtime merge)\n","text",[987,1044,1041],{"__ignoreMap":1045},"",[1032,1047,1049],{"id":1048},"declaring-a-profile-kind","Declaring a profile kind",[978,1051,1052,1053,1056],{},"A module owns zero or more ",[982,1054,1055],{},"profile kinds",". Each kind specifies the SettingField shape for one profile of that kind — the admin UI renders an editor from it, reusing the same form components as module settings.",[978,1058,1059,1060,1063,1064,1067],{},"Add a ",[987,1061,1062],{},"profiles:"," section to ",[987,1065,1066],{},"module.yaml",":",[1037,1069,1073],{"className":1070,"code":1071,"language":1072,"meta":1045,"style":1045},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","id: ai-llm\nname: AI LLM\nprofiles:\n  - id: llm-chat                       # consumed by x-profile-kind on node settings\n    name: LLM Chat Profile\n    description: Named preset bundling provider + model + tuning + prompt.\n    icon: lucide:message-circle\n    fields:\n      - key: providerID\n        label: Provider\n        type: string\n        required: true\n        options_ref: llm.providers     # live dropdown from go-ai registry\n      - key: apiKey                    # credential — masked in responses\n        label: API key\n        type: string\n        sensitive: true\n      - key: baseURL                   # multi-account support: each profile has its own endpoint\n        label: Base URL\n        type: string\n      - key: model\n        label: Model\n        type: string\n      - key: temperature\n        label: Temperature\n        type: number\n      - key: systemPrompt\n        label: System prompt\n        type: textarea\n","yaml",[987,1074,1075,1090,1100,1107,1124,1134,1144,1154,1161,1174,1184,1194,1205,1218,1232,1241,1249,1258,1272,1281,1289,1300,1309,1318,1330,1339,1348,1359,1369],{"__ignoreMap":1045},[1076,1077,1079,1083,1086],"span",{"class":1078,"line":10},"line",[1076,1080,1082],{"class":1081},"swJcz","id",[1076,1084,1067],{"class":1085},"sMK4o",[1076,1087,1089],{"class":1088},"sfazB"," ai-llm\n",[1076,1091,1092,1095,1097],{"class":1078,"line":16},[1076,1093,1094],{"class":1081},"name",[1076,1096,1067],{"class":1085},[1076,1098,1099],{"class":1088}," AI LLM\n",[1076,1101,1102,1104],{"class":1078,"line":22},[1076,1103,976],{"class":1081},[1076,1105,1106],{"class":1085},":\n",[1076,1108,1109,1112,1115,1117,1120],{"class":1078,"line":51},[1076,1110,1111],{"class":1085},"  -",[1076,1113,1114],{"class":1081}," id",[1076,1116,1067],{"class":1085},[1076,1118,1119],{"class":1088}," llm-chat",[1076,1121,1123],{"class":1122},"sHwdD","                       # consumed by x-profile-kind on node settings\n",[1076,1125,1126,1129,1131],{"class":1078,"line":57},[1076,1127,1128],{"class":1081},"    name",[1076,1130,1067],{"class":1085},[1076,1132,1133],{"class":1088}," LLM Chat Profile\n",[1076,1135,1136,1139,1141],{"class":1078,"line":102},[1076,1137,1138],{"class":1081},"    description",[1076,1140,1067],{"class":1085},[1076,1142,1143],{"class":1088}," Named preset bundling provider + model + tuning + prompt.\n",[1076,1145,1146,1149,1151],{"class":1078,"line":108},[1076,1147,1148],{"class":1081},"    icon",[1076,1150,1067],{"class":1085},[1076,1152,1153],{"class":1088}," lucide:message-circle\n",[1076,1155,1156,1159],{"class":1078,"line":114},[1076,1157,1158],{"class":1081},"    fields",[1076,1160,1106],{"class":1085},[1076,1162,1163,1166,1169,1171],{"class":1078,"line":120},[1076,1164,1165],{"class":1085},"      -",[1076,1167,1168],{"class":1081}," key",[1076,1170,1067],{"class":1085},[1076,1172,1173],{"class":1088}," providerID\n",[1076,1175,1176,1179,1181],{"class":1078,"line":181},[1076,1177,1178],{"class":1081},"        label",[1076,1180,1067],{"class":1085},[1076,1182,1183],{"class":1088}," Provider\n",[1076,1185,1186,1189,1191],{"class":1078,"line":186},[1076,1187,1188],{"class":1081},"        type",[1076,1190,1067],{"class":1085},[1076,1192,1193],{"class":1088}," string\n",[1076,1195,1196,1199,1201],{"class":1078,"line":191},[1076,1197,1198],{"class":1081},"        required",[1076,1200,1067],{"class":1085},[1076,1202,1204],{"class":1203},"sfNiH"," true\n",[1076,1206,1207,1210,1212,1215],{"class":1078,"line":197},[1076,1208,1209],{"class":1081},"        options_ref",[1076,1211,1067],{"class":1085},[1076,1213,1214],{"class":1088}," llm.providers",[1076,1216,1217],{"class":1122},"     # live dropdown from go-ai registry\n",[1076,1219,1220,1222,1224,1226,1229],{"class":1078,"line":203},[1076,1221,1165],{"class":1085},[1076,1223,1168],{"class":1081},[1076,1225,1067],{"class":1085},[1076,1227,1228],{"class":1088}," apiKey",[1076,1230,1231],{"class":1122},"                    # credential — masked in responses\n",[1076,1233,1234,1236,1238],{"class":1078,"line":214},[1076,1235,1178],{"class":1081},[1076,1237,1067],{"class":1085},[1076,1239,1240],{"class":1088}," API key\n",[1076,1242,1243,1245,1247],{"class":1078,"line":223},[1076,1244,1188],{"class":1081},[1076,1246,1067],{"class":1085},[1076,1248,1193],{"class":1088},[1076,1250,1251,1254,1256],{"class":1078,"line":229},[1076,1252,1253],{"class":1081},"        sensitive",[1076,1255,1067],{"class":1085},[1076,1257,1204],{"class":1203},[1076,1259,1260,1262,1264,1266,1269],{"class":1078,"line":234},[1076,1261,1165],{"class":1085},[1076,1263,1168],{"class":1081},[1076,1265,1067],{"class":1085},[1076,1267,1268],{"class":1088}," baseURL",[1076,1270,1271],{"class":1122},"                   # multi-account support: each profile has its own endpoint\n",[1076,1273,1274,1276,1278],{"class":1078,"line":240},[1076,1275,1178],{"class":1081},[1076,1277,1067],{"class":1085},[1076,1279,1280],{"class":1088}," Base URL\n",[1076,1282,1283,1285,1287],{"class":1078,"line":246},[1076,1284,1188],{"class":1081},[1076,1286,1067],{"class":1085},[1076,1288,1193],{"class":1088},[1076,1290,1291,1293,1295,1297],{"class":1078,"line":251},[1076,1292,1165],{"class":1085},[1076,1294,1168],{"class":1081},[1076,1296,1067],{"class":1085},[1076,1298,1299],{"class":1088}," model\n",[1076,1301,1302,1304,1306],{"class":1078,"line":257},[1076,1303,1178],{"class":1081},[1076,1305,1067],{"class":1085},[1076,1307,1308],{"class":1088}," Model\n",[1076,1310,1312,1314,1316],{"class":1078,"line":1311},23,[1076,1313,1188],{"class":1081},[1076,1315,1067],{"class":1085},[1076,1317,1193],{"class":1088},[1076,1319,1321,1323,1325,1327],{"class":1078,"line":1320},24,[1076,1322,1165],{"class":1085},[1076,1324,1168],{"class":1081},[1076,1326,1067],{"class":1085},[1076,1328,1329],{"class":1088}," temperature\n",[1076,1331,1332,1334,1336],{"class":1078,"line":271},[1076,1333,1178],{"class":1081},[1076,1335,1067],{"class":1085},[1076,1337,1338],{"class":1088}," Temperature\n",[1076,1340,1341,1343,1345],{"class":1078,"line":277},[1076,1342,1188],{"class":1081},[1076,1344,1067],{"class":1085},[1076,1346,1347],{"class":1088}," number\n",[1076,1349,1350,1352,1354,1356],{"class":1078,"line":282},[1076,1351,1165],{"class":1085},[1076,1353,1168],{"class":1081},[1076,1355,1067],{"class":1085},[1076,1357,1358],{"class":1088}," systemPrompt\n",[1076,1360,1362,1364,1366],{"class":1078,"line":1361},28,[1076,1363,1178],{"class":1081},[1076,1365,1067],{"class":1085},[1076,1367,1368],{"class":1088}," System prompt\n",[1076,1370,1372,1374,1376],{"class":1078,"line":1371},29,[1076,1373,1188],{"class":1081},[1076,1375,1067],{"class":1085},[1076,1377,1378],{"class":1088}," textarea\n",[978,1380,1381,1382,1385,1386,1389,1390,1393,1394,1397],{},"That's it — no Go code required. ",[987,1383,1384],{},"IRBase"," auto-exposes the kind via the ",[987,1387,1388],{},"ProfilesProvider"," interface, and ",[987,1391,1392],{},"settings.Module"," picks it up during ",[987,1395,1396],{},"Configure",".",[1399,1400,1402,1405],"h3",{"id":1401},"options_ref-live-enum-sources",[987,1403,1404],{},"options_ref"," — live enum sources",[978,1407,1408,1409,1412,1413,1416,1417,1420],{},"Set ",[987,1410,1411],{},"options_ref: \u003Csource-name>"," on a field to have the server populate its ",[987,1414,1415],{},"options"," from a live registry at serve time. Sources are registered by the owning module via ",[987,1418,1419],{},"modules.RegisterOptionsSource(name, func)",". Ships with:",[1422,1423,1424,1440],"table",{},[1425,1426,1427],"thead",{},[1428,1429,1430,1434,1437],"tr",{},[1431,1432,1433],"th",{},"Source",[1431,1435,1436],{},"Values",[1431,1438,1439],{},"Registered by",[1441,1442,1443,1459],"tbody",{},[1428,1444,1445,1451,1454],{},[1446,1447,1448],"td",{},[987,1449,1450],{},"llm.providers",[1446,1452,1453],{},"registered LLM factory ids (openai, anthropic, gemini, ovh, ollama)",[1446,1455,1456],{},[987,1457,1458],{},"go-ai\u002Fllm\u002Fmodule",[1428,1460,1461,1466,1469],{},[1446,1462,1463],{},[987,1464,1465],{},"guard.guards",[1446,1467,1468],{},"registered guard factory ids (qwen3guard, noop)",[1446,1470,1471],{},[987,1472,1473],{},"go-ai\u002Fguard\u002Fmodule",[978,1475,1476,1477,1480,1481,1483],{},"Inline ",[987,1478,1479],{},"options: [...]"," always wins over ",[987,1482,1404],{}," — useful for \"live list with one curated extra\" scenarios.",[1399,1485,1487,1490],{"id":1486},"setting_ref-reuse-existing-settings",[987,1488,1489],{},"setting_ref"," — reuse existing settings",[978,1492,1493,1494,1497],{},"Defining a profile field that mirrors an existing setting is verbose. Use ",[987,1495,1496],{},"setting_ref: \u003Cmodule>\u002F\u003Ckey>"," to inherit label, description, type, sensitive flag, env_var, default, and options from the referenced SettingField:",[1037,1499,1501],{"className":1070,"code":1500,"language":1072,"meta":1045,"style":1045},"profiles:\n  - id: llm-chat\n    fields:\n      - setting_ref: ai-llm\u002Fovh_api_key  # inherits label\u002Ftype\u002Fsensitive\u002Fenv_var\n      - key: model                       # inline definition as usual\n        label: Model\n        type: string\n",[987,1502,1503,1509,1520,1526,1541,1555,1563],{"__ignoreMap":1045},[1076,1504,1505,1507],{"class":1078,"line":10},[1076,1506,976],{"class":1081},[1076,1508,1106],{"class":1085},[1076,1510,1511,1513,1515,1517],{"class":1078,"line":16},[1076,1512,1111],{"class":1085},[1076,1514,1114],{"class":1081},[1076,1516,1067],{"class":1085},[1076,1518,1519],{"class":1088}," llm-chat\n",[1076,1521,1522,1524],{"class":1078,"line":22},[1076,1523,1158],{"class":1081},[1076,1525,1106],{"class":1085},[1076,1527,1528,1530,1533,1535,1538],{"class":1078,"line":51},[1076,1529,1165],{"class":1085},[1076,1531,1532],{"class":1081}," setting_ref",[1076,1534,1067],{"class":1085},[1076,1536,1537],{"class":1088}," ai-llm\u002Fovh_api_key",[1076,1539,1540],{"class":1122},"  # inherits label\u002Ftype\u002Fsensitive\u002Fenv_var\n",[1076,1542,1543,1545,1547,1549,1552],{"class":1078,"line":57},[1076,1544,1165],{"class":1085},[1076,1546,1168],{"class":1081},[1076,1548,1067],{"class":1085},[1076,1550,1551],{"class":1088}," model",[1076,1553,1554],{"class":1122},"                       # inline definition as usual\n",[1076,1556,1557,1559,1561],{"class":1078,"line":102},[1076,1558,1178],{"class":1081},[1076,1560,1067],{"class":1085},[1076,1562,1308],{"class":1088},[1076,1564,1565,1567,1569],{"class":1078,"line":108},[1076,1566,1188],{"class":1081},[1076,1568,1067],{"class":1085},[1076,1570,1193],{"class":1088},[978,1572,1573,1574,1001,1577,1580,1581,1584,1585,1588,1589,1591],{},"Inline keys on the same field override specific attributes from the reference. Handy for credential fields — declare ",[987,1575,1576],{},"env_var",[987,1578,1579],{},"sensitive"," once in ",[987,1582,1583],{},"settings:",", reference it from every profile kind that needs credentials for the same backend. Separator accepts ",[987,1586,1587],{},"\u002F"," or ",[987,1590,1397],{}," for YAML style preference.",[1399,1593,1595,1598],{"id":1594},"sensitive-true-on-fields",[987,1596,1597],{},"sensitive: true"," on fields",[978,1600,1601,1602,1607,1608,1611,1612,1615],{},"Works identically to module settings — see the ",[1603,1604,1606],"a",{"href":1605},"\u002Fdocs\u002Fadmin\u002Freference-base-modules#settings-resolution-db-env-yaml-default","Settings section",". List\u002Fget responses return ",[987,1609,1610],{},"••••••••","; the UI shows a password input with a ",[982,1613,1614],{},"Change"," button; unchanged fields send the token back and the server preserves the stored value.",[1399,1617,1619],{"id":1618},"multiple-accounts-per-provider","Multiple accounts per provider",[978,1621,1622,1623,1001,1626,1001,1629,1631],{},"A single OVH\u002FOpenAI\u002FAnthropic account rarely covers every environment. Because each profile row owns its own ",[987,1624,1625],{},"apiKey",[987,1627,1628],{},"baseURL",[987,1630,1004],{},", one kind supports unlimited accounts side-by-side:",[1037,1633,1636],{"className":1634,"code":1635,"language":1042},[1040],"ovh-prod-eu       → OVH EU endpoint,  token A,  Meta-Llama-3.3\novh-prod-us       → OVH US endpoint,  token B,  Meta-Llama-3.3\novh-sandbox       → OVH sandbox,      token C,  Mistral-7B\nollama-dev        → Ollama localhost, (no key), qwen2.5:3b\n",[987,1637,1635],{"__ignoreMap":1045},[978,1639,1640,1641,1643,1644,1646],{},"Each is a single row under the same kind; the ",[987,1642,996],{}," ",[987,1645,984],{}," dropdown lists them all.",[1032,1648,1650],{"id":1649},"consuming-profiles-on-a-flowdsl-node","Consuming profiles on a FlowDSL node",[1652,1653,1654],"blockquote",{},[978,1655,1656,1659,1660,1663,1664,1666,1667,1666,1670,1666,1673,1676,1677,1397],{},[982,1657,1658],{},"Picker property name."," Studio locates the profile picker via the ",[987,1661,1662],{},"x-profile-kind"," marker, not a fixed key name. Use whatever reads naturally for your node — ",[987,1665,984],{},", ",[987,1668,1669],{},"connection",[987,1671,1672],{},"preset",[987,1674,1675],{},"credentials",", … All examples in this page use ",[987,1678,984],{},[978,1680,1681],{},"Any node that wants a profile selector adds one setting:",[1037,1683,1685],{"className":1070,"code":1684,"language":1072,"meta":1045,"style":1045},"settings_schema:\n  type: object\n  # Hint renderers to put profile above the overridable fields.\n  x-ui:\n    order: [profile, providerID, model, temperature, systemPrompt]\n  properties:\n    profile:\n      type: string\n      title: Profile preset\n      x-order: 0\n      x-profile-kind: llm-chat       # which kind's profiles to list\n      # List which sibling fields this profile supplies defaults for —\n      # the admin UI can visually dim them when a profile is selected.\n      x-overrides: [providerID, model, temperature, systemPrompt]\n      description: >\n        Named preset. When set, the fields below default to the\n        profile's value; any field you explicitly fill overrides.\n      enum: []                       # populated at spec-build time\n    providerID:\n      type: string\n      x-order: 1\n      x-profile-overridable: true    # dim when a profile is selected\n      description: \"…defers to the selected profile when blank.\"\n      enum: []\n",[987,1686,1687,1694,1704,1709,1716,1751,1758,1765,1774,1784,1795,1807,1812,1817,1842,1853,1858,1863,1876,1883,1891,1900,1913,1928],{"__ignoreMap":1045},[1076,1688,1689,1692],{"class":1078,"line":10},[1076,1690,1691],{"class":1081},"settings_schema",[1076,1693,1106],{"class":1085},[1076,1695,1696,1699,1701],{"class":1078,"line":16},[1076,1697,1698],{"class":1081},"  type",[1076,1700,1067],{"class":1085},[1076,1702,1703],{"class":1088}," object\n",[1076,1705,1706],{"class":1078,"line":22},[1076,1707,1708],{"class":1122},"  # Hint renderers to put profile above the overridable fields.\n",[1076,1710,1711,1714],{"class":1078,"line":51},[1076,1712,1713],{"class":1081},"  x-ui",[1076,1715,1106],{"class":1085},[1076,1717,1718,1721,1723,1726,1728,1731,1734,1736,1738,1740,1743,1745,1748],{"class":1078,"line":57},[1076,1719,1720],{"class":1081},"    order",[1076,1722,1067],{"class":1085},[1076,1724,1725],{"class":1085}," [",[1076,1727,984],{"class":1088},[1076,1729,1730],{"class":1085},",",[1076,1732,1733],{"class":1088}," providerID",[1076,1735,1730],{"class":1085},[1076,1737,1551],{"class":1088},[1076,1739,1730],{"class":1085},[1076,1741,1742],{"class":1088}," temperature",[1076,1744,1730],{"class":1085},[1076,1746,1747],{"class":1088}," systemPrompt",[1076,1749,1750],{"class":1085},"]\n",[1076,1752,1753,1756],{"class":1078,"line":102},[1076,1754,1755],{"class":1081},"  properties",[1076,1757,1106],{"class":1085},[1076,1759,1760,1763],{"class":1078,"line":108},[1076,1761,1762],{"class":1081},"    profile",[1076,1764,1106],{"class":1085},[1076,1766,1767,1770,1772],{"class":1078,"line":114},[1076,1768,1769],{"class":1081},"      type",[1076,1771,1067],{"class":1085},[1076,1773,1193],{"class":1088},[1076,1775,1776,1779,1781],{"class":1078,"line":120},[1076,1777,1778],{"class":1081},"      title",[1076,1780,1067],{"class":1085},[1076,1782,1783],{"class":1088}," Profile preset\n",[1076,1785,1786,1789,1791],{"class":1078,"line":181},[1076,1787,1788],{"class":1081},"      x-order",[1076,1790,1067],{"class":1085},[1076,1792,1794],{"class":1793},"sbssI"," 0\n",[1076,1796,1797,1800,1802,1804],{"class":1078,"line":186},[1076,1798,1799],{"class":1081},"      x-profile-kind",[1076,1801,1067],{"class":1085},[1076,1803,1119],{"class":1088},[1076,1805,1806],{"class":1122},"       # which kind's profiles to list\n",[1076,1808,1809],{"class":1078,"line":191},[1076,1810,1811],{"class":1122},"      # List which sibling fields this profile supplies defaults for —\n",[1076,1813,1814],{"class":1078,"line":197},[1076,1815,1816],{"class":1122},"      # the admin UI can visually dim them when a profile is selected.\n",[1076,1818,1819,1822,1824,1826,1828,1830,1832,1834,1836,1838,1840],{"class":1078,"line":203},[1076,1820,1821],{"class":1081},"      x-overrides",[1076,1823,1067],{"class":1085},[1076,1825,1725],{"class":1085},[1076,1827,1000],{"class":1088},[1076,1829,1730],{"class":1085},[1076,1831,1551],{"class":1088},[1076,1833,1730],{"class":1085},[1076,1835,1742],{"class":1088},[1076,1837,1730],{"class":1085},[1076,1839,1747],{"class":1088},[1076,1841,1750],{"class":1085},[1076,1843,1844,1847,1849],{"class":1078,"line":214},[1076,1845,1846],{"class":1081},"      description",[1076,1848,1067],{"class":1085},[1076,1850,1852],{"class":1851},"s7zQu"," >\n",[1076,1854,1855],{"class":1078,"line":223},[1076,1856,1857],{"class":1088},"        Named preset. When set, the fields below default to the\n",[1076,1859,1860],{"class":1078,"line":229},[1076,1861,1862],{"class":1088},"        profile's value; any field you explicitly fill overrides.\n",[1076,1864,1865,1868,1870,1873],{"class":1078,"line":234},[1076,1866,1867],{"class":1081},"      enum",[1076,1869,1067],{"class":1085},[1076,1871,1872],{"class":1085}," []",[1076,1874,1875],{"class":1122},"                       # populated at spec-build time\n",[1076,1877,1878,1881],{"class":1078,"line":240},[1076,1879,1880],{"class":1081},"    providerID",[1076,1882,1106],{"class":1085},[1076,1884,1885,1887,1889],{"class":1078,"line":246},[1076,1886,1769],{"class":1081},[1076,1888,1067],{"class":1085},[1076,1890,1193],{"class":1088},[1076,1892,1893,1895,1897],{"class":1078,"line":251},[1076,1894,1788],{"class":1081},[1076,1896,1067],{"class":1085},[1076,1898,1899],{"class":1793}," 1\n",[1076,1901,1902,1905,1907,1910],{"class":1078,"line":257},[1076,1903,1904],{"class":1081},"      x-profile-overridable",[1076,1906,1067],{"class":1085},[1076,1908,1909],{"class":1203}," true",[1076,1911,1912],{"class":1122},"    # dim when a profile is selected\n",[1076,1914,1915,1917,1919,1922,1925],{"class":1078,"line":1311},[1076,1916,1846],{"class":1081},[1076,1918,1067],{"class":1085},[1076,1920,1921],{"class":1085}," \"",[1076,1923,1924],{"class":1088},"…defers to the selected profile when blank.",[1076,1926,1927],{"class":1085},"\"\n",[1076,1929,1930,1932,1934],{"class":1078,"line":1320},[1076,1931,1867],{"class":1081},[1076,1933,1067],{"class":1085},[1076,1935,1936],{"class":1085}," []\n",[978,1938,1939,1942,1943,1945,1946,1948,1949,1952],{},[987,1940,1941],{},"IRBase.FlowDSLNodes"," looks for ",[987,1944,1662],{}," on every ",[987,1947,984],{}," setting and injects the current live profile ids via ",[987,1950,1951],{},"modules.ListProfileIDs",". Studio renders a normal enum dropdown with no per-node code.",[978,1954,1955],{},[982,1956,1957],{},"Renderer hints (forward-compatible):",[1422,1959,1960,1973],{},[1425,1961,1962],{},[1428,1963,1964,1967,1970],{},[1431,1965,1966],{},"Hint",[1431,1968,1969],{},"Location",[1431,1971,1972],{},"Purpose",[1441,1974,1975,1988,2001,2016],{},[1428,1976,1977,1982,1985],{},[1446,1978,1979],{},[987,1980,1981],{},"x-ui.order",[1446,1983,1984],{},"top-level schema",[1446,1986,1987],{},"Explicit render order for fields — wins over alphabetical sort when the renderer supports it",[1428,1989,1990,1995,1998],{},[1446,1991,1992],{},[987,1993,1994],{},"x-order",[1446,1996,1997],{},"per-property",[1446,1999,2000],{},"Same purpose, per-field form. Renderers that respect one usually respect the other",[1428,2002,2003,2008,2013],{},[1446,2004,2005],{},[987,2006,2007],{},"x-overrides",[1446,2009,2010,2011],{},"on ",[987,2012,984],{},[1446,2014,2015],{},"Array of sibling keys the profile supplies defaults for — lets the UI render a \"profile is overriding N fields\" badge",[1428,2017,2018,2023,2026],{},[1446,2019,2020],{},[987,2021,2022],{},"x-profile-overridable",[1446,2024,2025],{},"on any field",[1446,2027,2028],{},"Signal that this field's blank value defers to the selected profile. UI can dim or watermark",[978,2030,2031],{},"At runtime, the handler calls:",[1037,2033,2037],{"className":2034,"code":2035,"language":2036,"meta":1045,"style":1045},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","profileID, _ := step.Node.Config[\"profile\"].(string)\nif profileID != \"\" {\n    if profile := modules.ResolveProfile(ctx, \"llm-chat\", profileID); profile != nil {\n        step.Node.Config = modules.MergeProfileIntoConfig(step.Node.Config, profile)\n    }\n}\n","go",[987,2038,2039,2044,2049,2054,2059,2064],{"__ignoreMap":1045},[1076,2040,2041],{"class":1078,"line":10},[1076,2042,2043],{},"profileID, _ := step.Node.Config[\"profile\"].(string)\n",[1076,2045,2046],{"class":1078,"line":16},[1076,2047,2048],{},"if profileID != \"\" {\n",[1076,2050,2051],{"class":1078,"line":22},[1076,2052,2053],{},"    if profile := modules.ResolveProfile(ctx, \"llm-chat\", profileID); profile != nil {\n",[1076,2055,2056],{"class":1078,"line":51},[1076,2057,2058],{},"        step.Node.Config = modules.MergeProfileIntoConfig(step.Node.Config, profile)\n",[1076,2060,2061],{"class":1078,"line":57},[1076,2062,2063],{},"    }\n",[1076,2065,2066],{"class":1078,"line":102},[1076,2067,2068],{},"}\n",[978,2070,2071,2074,2075,2079,2080,2083],{},[987,2072,2073],{},"MergeProfileIntoConfig"," layers the profile values ",[2076,2077,2078],"em",{},"underneath"," — any key already present in ",[987,2081,2082],{},"step.Node.Config"," wins. Per-node overrides always beat profile defaults.",[1032,2085,2087],{"id":2086},"consuming-profiles-outside-flowdsl","Consuming profiles outside FlowDSL",[978,2089,2090,2091,2094,2095,2098,2099,2102],{},"Profiles are not just for nodes. ",[982,2092,2093],{},"Any module built on go-ai"," can resolve its own ",[987,2096,2097],{},"llm-chat"," profile via ",[987,2100,2101],{},"modules.ResolveProfile",", so different features run different models — configured independently. Translations can run a best-quality model while a workout-analysis feature runs a cheaper\u002Ffaster one, each pointing at its own profile.",[978,2104,2105,2108,2109,2112,2113,2116,2117,2119,2120,2123,2124,2127,2128,2127,2130,2132,2133,2136],{},[987,2106,2107],{},"go-modules\u002Fai"," (the translate\u002Fgenerate module) does exactly this: it exposes an ",[987,2110,2111],{},"ai\u002Fprofile"," setting (env ",[987,2114,2115],{},"AI_PROFILE",") that names the ",[987,2118,2097],{}," profile to use. When set, that profile ",[982,2121,2122],{},"overrides"," the module's flat ",[987,2125,2126],{},"provider"," \u002F ",[987,2129,1004],{},[987,2131,1007],{}," settings; when blank, the flat settings apply. A second go-ai consumer sets its own ",[987,2134,2135],{},"\u003Cmodule>\u002Fprofile",", so the two features never share a model unless you point them at the same profile.",[1032,2138,2140],{"id":2139},"admin-api","Admin API",[978,2142,2143,2144,2147,2148,2151,2152,2155],{},"All endpoints live under ",[987,2145,2146],{},"\u002Fapi\u002Fv1\u002Fadmin\u002Fprofiles\u002F..."," and require the ",[987,2149,2150],{},"admin:access"," permission plus one of the ",[987,2153,2154],{},"profiles:*"," permissions declared by the settings-admin module.",[1422,2157,2158,2170],{},[1425,2159,2160],{},[1428,2161,2162,2165,2168],{},[1431,2163,2164],{},"Method",[1431,2166,2167],{},"Path",[1431,2169,1972],{},[1441,2171,2172,2185,2197,2209,2221,2233,2245,2257],{},[1428,2173,2174,2177,2182],{},[1446,2175,2176],{},"GET",[1446,2178,2179],{},[987,2180,2181],{},"\u002Fadmin\u002Fprofiles\u002F",[1446,2183,2184],{},"List every profile (sensitive fields masked)",[1428,2186,2187,2189,2194],{},[1446,2188,2176],{},[1446,2190,2191],{},[987,2192,2193],{},"\u002Fadmin\u002Fprofiles\u002Fkinds",[1446,2195,2196],{},"Kinds discovered from the registry (with field schemas)",[1428,2198,2199,2201,2206],{},[1446,2200,2176],{},[1446,2202,2203],{},[987,2204,2205],{},"\u002Fadmin\u002Fprofiles\u002Fkinds\u002F{kind}",[1446,2207,2208],{},"Profiles of a single kind",[1428,2210,2211,2214,2218],{},[1446,2212,2213],{},"POST",[1446,2215,2216],{},[987,2217,2181],{},[1446,2219,2220],{},"Create \u002F upsert a profile",[1428,2222,2223,2225,2230],{},[1446,2224,2176],{},[1446,2226,2227],{},[987,2228,2229],{},"\u002Fadmin\u002Fprofiles\u002F{module}\u002F{kind}\u002F{id}",[1446,2231,2232],{},"Get one profile",[1428,2234,2235,2238,2242],{},[1446,2236,2237],{},"PUT",[1446,2239,2240],{},[987,2241,2229],{},[1446,2243,2244],{},"Update a profile",[1428,2246,2247,2250,2254],{},[1446,2248,2249],{},"DELETE",[1446,2251,2252],{},[987,2253,2229],{},[1446,2255,2256],{},"Delete a profile",[1428,2258,2259,2261,2266],{},[1446,2260,2213],{},[1446,2262,2263],{},[987,2264,2265],{},"\u002Fadmin\u002Fprofiles\u002F{module}\u002F{kind}\u002F{id}\u002Fduplicate",[1446,2267,2268,2269],{},"Duplicate — body is optional ",[987,2270,2271],{},"DuplicateOverrides",[1399,2273,2275],{"id":2274},"sensitive-fields","Sensitive fields",[978,2277,2278,2279,2281,2282,2284,2285,2287],{},"Any field declaring ",[987,2280,1597],{}," in its schema is masked with the literal token ",[987,2283,1610],{}," in list\u002Fget responses. The admin UI shows a password-style input with a ",[982,2286,1614],{}," button — clicking it clears the token and accepts a new value. Unchanged fields send the masked token back to the server, which detects it and preserves the stored value in MongoDB.",[978,2289,2290,2291,2294],{},"Same flag already applies to regular settings (",[987,2292,2293],{},"ir.SettingField.Sensitive","). The masking layer is shared.",[1399,2296,2298],{"id":2297},"duplicate","Duplicate",[1037,2300,2304],{"className":2301,"code":2302,"language":2303,"meta":1045,"style":1045},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -X POST \u002Fadmin\u002Fprofiles\u002Fai-llm\u002Fllm-chat\u002Fassistant-fast\u002Fduplicate \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"newProfileId\": \"assistant-backup\",\n    \"newName\": \"LLM backup\",\n    \"configPatches\": { \"providerID\": \"ollama\", \"model\": \"qwen2.5:3b\" }\n  }'\n","bash",[987,2305,2306,2325,2340,2351,2356,2361,2366],{"__ignoreMap":1045},[1076,2307,2308,2312,2315,2318,2321],{"class":1078,"line":10},[1076,2309,2311],{"class":2310},"sBMFI","curl",[1076,2313,2314],{"class":1088}," -X",[1076,2316,2317],{"class":1088}," POST",[1076,2319,2320],{"class":1088}," \u002Fadmin\u002Fprofiles\u002Fai-llm\u002Fllm-chat\u002Fassistant-fast\u002Fduplicate",[1076,2322,2324],{"class":2323},"sTEyZ"," \\\n",[1076,2326,2327,2330,2332,2335,2338],{"class":1078,"line":16},[1076,2328,2329],{"class":1088},"  -H",[1076,2331,1921],{"class":1085},[1076,2333,2334],{"class":1088},"Content-Type: application\u002Fjson",[1076,2336,2337],{"class":1085},"\"",[1076,2339,2324],{"class":2323},[1076,2341,2342,2345,2348],{"class":1078,"line":22},[1076,2343,2344],{"class":1088},"  -d",[1076,2346,2347],{"class":1085}," '",[1076,2349,2350],{"class":1088},"{\n",[1076,2352,2353],{"class":1078,"line":51},[1076,2354,2355],{"class":1088},"    \"newProfileId\": \"assistant-backup\",\n",[1076,2357,2358],{"class":1078,"line":57},[1076,2359,2360],{"class":1088},"    \"newName\": \"LLM backup\",\n",[1076,2362,2363],{"class":1078,"line":102},[1076,2364,2365],{"class":1088},"    \"configPatches\": { \"providerID\": \"ollama\", \"model\": \"qwen2.5:3b\" }\n",[1076,2367,2368,2371],{"class":1078,"line":108},[1076,2369,2370],{"class":1088},"  }",[1076,2372,2373],{"class":1085},"'\n",[978,2375,2376,2377,2380,2381,2384],{},"The server clones the source profile, applies the patches on top (sensitive values are copied as-is), picks an auto-incrementing ",[987,2378,2379],{},"\u003Csrc>-copy[-N]"," id when ",[987,2382,2383],{},"newProfileId"," is empty, and returns the persisted clone. Admin UI ships a duplicate dialog that pre-fills the clone's name + all field values for quick tweaks.",[978,2386,2387],{},"Common patterns:",[2389,2390,2391,2408,2417],"ul",{},[2392,2393,2394,2397,2398,2400,2401,2403,2404,2407],"li",{},[982,2395,2396],{},"LLM backup"," — duplicate ",[987,2399,1023],{},", switch ",[987,2402,1000],{}," → ",[987,2405,2406],{},"ollama",", name → \"LLM backup\".",[2392,2409,2410,2413,2414,2416],{},[982,2411,2412],{},"Tuning variant"," — duplicate, bump ",[987,2415,1007],{}," from 0.3 → 0.7, name → \"reasoning — deep\".",[2392,2418,2419,2422],{},[982,2420,2421],{},"Sandbox"," — duplicate production, swap credentials for a staging key.",[1032,2424,2426],{"id":2425},"usage-aggregation-by-profile","Usage aggregation by profile",[978,2428,2429,2430,2433,2434,2437,2438,2441,2442,2445],{},"Every LLM call stamps ",[987,2431,2432],{},"profileId"," onto the usage ledger row (",[987,2435,2436],{},"LLMUsage.ProfileID","). The admin ",[987,2439,2440],{},"\u002Fai\u002Fbreakdowns"," page now offers ",[982,2443,2444],{},"Profile"," as a breakdown dimension alongside Provider, Model, Flow, Node, User, Assistant — sort profiles by cost, token count, latency, or error rate to see which preset is actually driving spend.",[978,2447,2448,2449,2452,2453,2455],{},"Under the hood, ",[987,2450,2451],{},"UsageContext.ProfileID"," is populated by the ",[987,2454,2097],{}," handler right after it merges the profile config; the recorder middleware writes it to MongoDB. Query filter:",[1037,2457,2460],{"className":2458,"code":2459,"language":1042},[1040],"GET \u002Fadmin\u002Fllm\u002Fusage\u002Fby?field=profileId&from=2026-04-01T00:00:00Z\nGET \u002Fadmin\u002Fllm\u002Fusage?profileId=ovh-prod-eu   # filter usage rows to one profile\n",[987,2461,2459],{"__ignoreMap":1045},[1032,2463,2465],{"id":2464},"cross-worker-cache-invalidation","Cross-worker cache invalidation",[978,2467,2468,2469,2472,2473,2476],{},"Writes publish ",[987,2470,2471],{},"profiles.updated"," on the EventBus. Every worker subscribes with a host-unique GroupID (",[987,2474,2475],{},"profiles-invalidator-{hostname}",") so it's fan-out, not load-balanced — each peer invalidates its local cache and re-fetches on the next request. No container restart, no stale reads.",[1032,2478,947],{"id":2479},"admin-ui",[978,2481,2482,2486,2487,2490],{},[982,2483,2484],{},[987,2485,989],{}," — unified page grouped by kind. Each kind card shows a count, a \"New\" button, and links to every existing profile of that kind. Each card also links to the owning module's ",[987,2488,2489],{},"\u002Fsettings\u002F\u003Cmodule>"," page for cross-context tweaks.",[978,2492,2493,2497,2498,2501],{},[982,2494,2495],{},[987,2496,2229],{}," — profile editor. Identity section (profileId, name, description) + configuration section rendered from the kind's ",[987,2499,2500],{},"fields[]",". Sensitive fields use the mask + Change flow.",[978,2503,2504,2507],{},[982,2505,2506],{},"Duplicate dialog"," — reachable from the editor's action bar. Pre-populates a new id + name and shows the full field editor so operators can tweak in-flight before saving.",[978,2509,2510,2513,2514,2517,2518,2521],{},[982,2511,2512],{},"Cross-links on settings pages"," — when a module declares any profile kinds, a banner appears at the top of ",[987,2515,2516],{},"\u002Fsettings\u002F\u003Cmodule>\u002F..."," linking to the relevant ",[987,2519,2520],{},"\u002Fprofiles"," kinds. Operators manage credentials in either place; the links keep both contexts one click apart.",[1032,2523,2525],{"id":2524},"worked-example-replacing-per-node-config","Worked example — replacing per-node config",[978,2527,2528,2531],{},[982,2529,2530],{},"Before"," (hand-configured every time):",[1037,2533,2535],{"className":1070,"code":2534,"language":1072,"meta":1045,"style":1045},"- id: chat\n  action_ref: redelay\u002Fllm-chat\n  config:\n    providerID: ovh\n    model: Meta-Llama-3_3-70B-Instruct\n    temperature: 0.3\n    maxTokens: 1024\n    replyStyle: short\n    examplesPolicy: when_asked\n    systemPrompt: \"You are the Project Assistant for a Redelay-based application...\"\n",[987,2536,2537,2549,2559,2566,2575,2585,2595,2605,2615,2625],{"__ignoreMap":1045},[1076,2538,2539,2542,2544,2546],{"class":1078,"line":10},[1076,2540,2541],{"class":1085},"-",[1076,2543,1114],{"class":1081},[1076,2545,1067],{"class":1085},[1076,2547,2548],{"class":1088}," chat\n",[1076,2550,2551,2554,2556],{"class":1078,"line":16},[1076,2552,2553],{"class":1081},"  action_ref",[1076,2555,1067],{"class":1085},[1076,2557,2558],{"class":1088}," redelay\u002Fllm-chat\n",[1076,2560,2561,2564],{"class":1078,"line":22},[1076,2562,2563],{"class":1081},"  config",[1076,2565,1106],{"class":1085},[1076,2567,2568,2570,2572],{"class":1078,"line":51},[1076,2569,1880],{"class":1081},[1076,2571,1067],{"class":1085},[1076,2573,2574],{"class":1088}," ovh\n",[1076,2576,2577,2580,2582],{"class":1078,"line":57},[1076,2578,2579],{"class":1081},"    model",[1076,2581,1067],{"class":1085},[1076,2583,2584],{"class":1088}," Meta-Llama-3_3-70B-Instruct\n",[1076,2586,2587,2590,2592],{"class":1078,"line":102},[1076,2588,2589],{"class":1081},"    temperature",[1076,2591,1067],{"class":1085},[1076,2593,2594],{"class":1793}," 0.3\n",[1076,2596,2597,2600,2602],{"class":1078,"line":108},[1076,2598,2599],{"class":1081},"    maxTokens",[1076,2601,1067],{"class":1085},[1076,2603,2604],{"class":1793}," 1024\n",[1076,2606,2607,2610,2612],{"class":1078,"line":114},[1076,2608,2609],{"class":1081},"    replyStyle",[1076,2611,1067],{"class":1085},[1076,2613,2614],{"class":1088}," short\n",[1076,2616,2617,2620,2622],{"class":1078,"line":120},[1076,2618,2619],{"class":1081},"    examplesPolicy",[1076,2621,1067],{"class":1085},[1076,2623,2624],{"class":1088}," when_asked\n",[1076,2626,2627,2630,2632,2634,2637],{"class":1078,"line":181},[1076,2628,2629],{"class":1081},"    systemPrompt",[1076,2631,1067],{"class":1085},[1076,2633,1921],{"class":1085},[1076,2635,2636],{"class":1088},"You are the Project Assistant for a Redelay-based application...",[1076,2638,1927],{"class":1085},[978,2640,2641,2644],{},[982,2642,2643],{},"After"," (referencing a profile):",[1037,2646,2648],{"className":1070,"code":2647,"language":1072,"meta":1045,"style":1045},"- id: chat\n  action_ref: redelay\u002Fllm-chat\n  config:\n    profile: assistant-fast\n    systemPrompt: \"You are the support assistant for acme.com.\"  # per-flow override\n",[987,2649,2650,2660,2668,2674,2683],{"__ignoreMap":1045},[1076,2651,2652,2654,2656,2658],{"class":1078,"line":10},[1076,2653,2541],{"class":1085},[1076,2655,1114],{"class":1081},[1076,2657,1067],{"class":1085},[1076,2659,2548],{"class":1088},[1076,2661,2662,2664,2666],{"class":1078,"line":16},[1076,2663,2553],{"class":1081},[1076,2665,1067],{"class":1085},[1076,2667,2558],{"class":1088},[1076,2669,2670,2672],{"class":1078,"line":22},[1076,2671,2563],{"class":1081},[1076,2673,1106],{"class":1085},[1076,2675,2676,2678,2680],{"class":1078,"line":51},[1076,2677,1762],{"class":1081},[1076,2679,1067],{"class":1085},[1076,2681,2682],{"class":1088}," assistant-fast\n",[1076,2684,2685,2687,2689,2691,2694,2696],{"class":1078,"line":57},[1076,2686,2629],{"class":1081},[1076,2688,1067],{"class":1085},[1076,2690,1921],{"class":1085},[1076,2692,2693],{"class":1088},"You are the support assistant for acme.com.",[1076,2695,2337],{"class":1085},[1076,2697,2698],{"class":1122},"  # per-flow override\n",[978,2700,2701,2702,2704,2705,2707],{},"The handler resolves ",[987,2703,1023],{}," (provider, model, temperature, maxTokens, replyStyle, examplesPolicy) and merges the profile values underneath. ",[987,2706,1013],{}," set on the node wins. One dropdown + one override instead of seven explicit fields.",[1032,2709,2711],{"id":2710},"future-kinds","Future kinds",[978,2713,2714],{},"Any node that needs credentials or connection config is a candidate:",[1422,2716,2717,2730],{},[1425,2718,2719],{},[1428,2720,2721,2724,2727],{},[1431,2722,2723],{},"Kind",[1431,2725,2726],{},"Owner",[1431,2728,2729],{},"Typical fields",[1441,2731,2732,2744,2757,2770,2783,2796,2809],{},[1428,2733,2734,2738,2741],{},[1446,2735,2736],{},[987,2737,2097],{},[1446,2739,2740],{},"ai-llm",[1446,2742,2743],{},"providerID, model, temperature, maxTokens, systemPrompt",[1428,2745,2746,2751,2754],{},[1446,2747,2748],{},[987,2749,2750],{},"llm-guard",[1446,2752,2753],{},"ai-guard",[1446,2755,2756],{},"guardID, role, onError",[1428,2758,2759,2764,2767],{},[1446,2760,2761],{},[987,2762,2763],{},"db-sql",[1446,2765,2766],{},"go-module-sql (planned)",[1446,2768,2769],{},"driver, host, port, database, user, password (sensitive)",[1428,2771,2772,2777,2780],{},[1446,2773,2774],{},[987,2775,2776],{},"ftp-server",[1446,2778,2779],{},"go-module-ftp",[1446,2781,2782],{},"host, port, user, password (sensitive), passive",[1428,2784,2785,2790,2793],{},[1446,2786,2787],{},[987,2788,2789],{},"smtp",[1446,2791,2792],{},"go-module-email",[1446,2794,2795],{},"host, port, user, password (sensitive), from",[1428,2797,2798,2803,2806],{},[1446,2799,2800],{},[987,2801,2802],{},"s3-bucket",[1446,2804,2805],{},"go-modules\u002Fstorage",[1446,2807,2808],{},"endpoint, region, bucket, accessKey (sensitive), secretKey (sensitive)",[1428,2810,2811,2816,2819],{},[1446,2812,2813],{},[987,2814,2815],{},"search-config",[1446,2817,2818],{},"go-modules\u002Fsearch",[1446,2820,2821],{},"backend, prefix, embeddingProvider, embeddingModel",[978,2823,2824,2825,1001,2828,2830],{},"Each additional kind is 15 lines of YAML plus a tiny handler change (three lines to call ",[987,2826,2827],{},"ResolveProfile",[987,2829,2073],{},"). The admin UI, CRUD, invalidation, sensitive masking, and duplicate flow come for free.",[2832,2833,2834],"style",{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":1045,"searchDepth":16,"depth":16,"links":2836},[2837,2838,2847,2848,2849,2853,2854,2855,2856,2857],{"id":1034,"depth":16,"text":1035},{"id":1048,"depth":16,"text":1049,"children":2839},[2840,2842,2844,2846],{"id":1401,"depth":22,"text":2841},"options_ref — live enum sources",{"id":1486,"depth":22,"text":2843},"setting_ref — reuse existing settings",{"id":1594,"depth":22,"text":2845},"sensitive: true on fields",{"id":1618,"depth":22,"text":1619},{"id":1649,"depth":16,"text":1650},{"id":2086,"depth":16,"text":2087},{"id":2139,"depth":16,"text":2140,"children":2850},[2851,2852],{"id":2274,"depth":22,"text":2275},{"id":2297,"depth":22,"text":2298},{"id":2425,"depth":16,"text":2426},{"id":2464,"depth":16,"text":2465},{"id":2479,"depth":16,"text":947},{"id":2524,"depth":16,"text":2525},{"id":2710,"depth":16,"text":2711},"Reusable, admin-editable config bundles — one dropdown on a FlowDSL node replaces eight hand-configured fields. Works for LLM chat, guard, databases, FTP, storage, any connection-bearing node.","md",null,{},{"order":257,"icon":258},{"title":254,"description":2858},"0Ret3Kh19IHpm87lOaVpReToi75h377gx4iwU9zs234",[2866,2868],{"title":248,"path":249,"stem":250,"description":2867,"order":251,"icon":252,"children":-1},"Pluggable vector-search module — Qdrant today, OpenSearch planned. Index CRUD, semantic query, embedding-provider switching, FlowDSL nodes.",{"title":260,"path":261,"stem":262,"description":2869,"children":-1},"Mount FlowDSL flows as HTTP routes. Domain modules contribute nodes;\nflowexec owns the HTTP↔flow bridge. Schemas attach to edges as\npackets (one ref → three rendered forms: stored, \u002Fopenapi.json,\nStudio); the http-endpoint source node carries only routing +\nspec metadata. Flow templates ship in per-module flowtemplates\u002F\npackages and auto-publish at startup so endpoints work out of\nthe box.\n",1790332226537]