[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"doc-\u002Fen\u002Fdocs\u002Fpipelines\u002Fediteur-visuel":3,"docs-nav-en":577},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"body":10,"_type":571,"_id":572,"_source":573,"_file":574,"_stem":575,"_extension":576},"\u002Fen\u002Fdocs\u002Fpipelines\u002Fediteur-visuel","pipelines",false,"","The Visual Editor","Design a pipeline with drag-and-drop, with contract validation at the earliest possible stage.",{"type":11,"children":12,"toc":557},"root",[13,29,36,46,80,86,93,113,125,171,182,188,199,205,217,223,242,254,300,317,323,419,425,437,470,482,488,493,540,552],{"type":14,"tag":15,"props":16,"children":17},"element","p",{},[18,21,27],{"type":19,"value":20},"text","A betool pipeline is a ",{"type":14,"tag":22,"props":23,"children":24},"strong",{},[25],{"type":19,"value":26},"graph of nodes",{"type":19,"value":28}," that you assemble in the visual editor. Each node type declares server-side its configuration and the keys it produces; the editor validates the graph and the configuration before letting you publish it.",{"type":14,"tag":30,"props":31,"children":33},"h2",{"id":32},"pipeline-anatomy",[34],{"type":19,"value":35},"Pipeline anatomy",{"type":14,"tag":37,"props":38,"children":40},"pre",{"code":39},"[Start]──▶[agent]──▶[router]──┬──▶[agent]\n                              └──▶[webhook_action]\n",[41],{"type":14,"tag":42,"props":43,"children":44},"code",{"__ignoreMap":7},[45],{"type":19,"value":39},{"type":14,"tag":47,"props":48,"children":49},"ul",{},[50,70,75],{"type":14,"tag":51,"props":52,"children":53},"li",{},[54,56,61,63,68],{"type":19,"value":55},"The ",{"type":14,"tag":22,"props":57,"children":58},{},[59],{"type":19,"value":60},"Start",{"type":19,"value":62}," node is created automatically with the model; it carries the ",{"type":14,"tag":22,"props":64,"children":65},{},[66],{"type":19,"value":67},"receivers",{"type":19,"value":69}," (input channels) that trigger the pipeline. A single Start can declare several of them.",{"type":14,"tag":51,"props":71,"children":72},{},[73],{"type":19,"value":74},"Each downstream node reads the keys produced by upstream nodes from the execution context.",{"type":14,"tag":51,"props":76,"children":77},{},[78],{"type":19,"value":79},"A router or filters create branches; each execution leaves a trace you can inspect.",{"type":14,"tag":30,"props":81,"children":83},{"id":82},"core-concepts",[84],{"type":19,"value":85},"Core concepts",{"type":14,"tag":87,"props":88,"children":90},"h3",{"id":89},"flow-key",[91],{"type":19,"value":92},"Flow key",{"type":14,"tag":15,"props":94,"children":95},{},[96,98,103,105,111],{"type":19,"value":97},"A ",{"type":14,"tag":22,"props":99,"children":100},{},[101],{"type":19,"value":102},"key",{"type":19,"value":104}," is a named piece of data that flows between nodes. For example: an agent node can write its output under ",{"type":14,"tag":42,"props":106,"children":108},{"className":107},[],[109],{"type":19,"value":110},"exchange.intent",{"type":19,"value":112},", and a downstream node (filter, router) tests that key.",{"type":14,"tag":15,"props":114,"children":115},{},[116,118,123],{"type":19,"value":117},"What a node ",{"type":14,"tag":22,"props":119,"children":120},{},[121],{"type":19,"value":122},"produces",{"type":19,"value":124}," is declared by its contract, in two forms:",{"type":14,"tag":47,"props":126,"children":127},{},[128,154],{"type":14,"tag":51,"props":129,"children":130},{},[131,136,138,144,146,152],{"type":14,"tag":22,"props":132,"children":133},{},[134],{"type":19,"value":135},"Fixed key",{"type":19,"value":137}," (",{"type":14,"tag":42,"props":139,"children":141},{"className":140},[],[142],{"type":19,"value":143},"fixed_key",{"type":19,"value":145},") — always the same, defined by the node type (e.g. ",{"type":14,"tag":42,"props":147,"children":149},{"className":148},[],[150],{"type":19,"value":151},"input.entry_kind",{"type":19,"value":153}," for the Start).",{"type":14,"tag":51,"props":155,"children":156},{},[157,162,163,169],{"type":14,"tag":22,"props":158,"children":159},{},[160],{"type":19,"value":161},"Configurable key",{"type":19,"value":137},{"type":14,"tag":42,"props":164,"children":166},{"className":165},[],[167],{"type":19,"value":168},"configurable_key",{"type":19,"value":170},") — chosen in the node's configuration (e.g. an agent's output key).",{"type":14,"tag":15,"props":172,"children":173},{},[174,175,180],{"type":19,"value":117},{"type":14,"tag":22,"props":176,"children":177},{},[178],{"type":19,"value":179},"reads",{"type":19,"value":181}," is set in its configuration (the field tested by a filter, an agent's inputs…).",{"type":14,"tag":87,"props":183,"children":185},{"id":184},"contract",[186],{"type":19,"value":187},"Contract",{"type":14,"tag":15,"props":189,"children":190},{},[191,193,197],{"type":19,"value":192},"Each node type exposes a ",{"type":14,"tag":22,"props":194,"children":195},{},[196],{"type":19,"value":184},{"type":19,"value":198}," declared server-side: its configuration fields (type, allowed values, required fields, default values) and the keys it produces. The editor relies on this contract to build the configuration panel and validate what you enter.",{"type":14,"tag":87,"props":200,"children":202},{"id":201},"configuration",[203],{"type":19,"value":204},"Configuration",{"type":14,"tag":15,"props":206,"children":207},{},[208,210,215],{"type":19,"value":209},"A node also has ",{"type":14,"tag":22,"props":211,"children":212},{},[213],{"type":19,"value":214},"static parameters",{"type":19,"value":216}," (its configuration) — for an agent node, for example: its role, its mission, its tools, and its LLM model.",{"type":14,"tag":87,"props":218,"children":220},{"id":219},"secrets",[221],{"type":19,"value":222},"Secrets",{"type":14,"tag":15,"props":224,"children":225},{},[226,228,233,235,240],{"type":19,"value":227},"Fields that a node's or receiver's contract declares as ",{"type":14,"tag":22,"props":229,"children":230},{},[231],{"type":19,"value":232},"secret",{"type":19,"value":234}," (HMAC secret of an inbound webhook, token or password of an HTTP call, access token of a Page, secret of a sub-pipeline…) are ",{"type":14,"tag":22,"props":236,"children":237},{},[238],{"type":19,"value":239},"never returned in plain text",{"type":19,"value":241}," once saved: not to the editor, not through the API, not to the MCP tools and agents that read a pipeline, and not in proposals.",{"type":14,"tag":15,"props":243,"children":244},{},[245,247,252],{"type":19,"value":246},"In the inspector, such a field shows ",{"type":14,"tag":22,"props":248,"children":249},{},[250],{"type":19,"value":251},"\"•••••• saved — type to replace\"",{"type":19,"value":253},":",{"type":14,"tag":47,"props":255,"children":256},{},[257,269,281],{"type":14,"tag":51,"props":258,"children":259},{},[260,262,267],{"type":19,"value":261},"left empty, it ",{"type":14,"tag":22,"props":263,"children":264},{},[265],{"type":19,"value":266},"keeps",{"type":19,"value":268}," the saved secret;",{"type":14,"tag":51,"props":270,"children":271},{},[272,274,279],{"type":19,"value":273},"typing a value ",{"type":14,"tag":22,"props":275,"children":276},{},[277],{"type":19,"value":278},"replaces",{"type":19,"value":280}," it;",{"type":14,"tag":51,"props":282,"children":283},{},[284,286,291,293,298],{"type":19,"value":285},"the ",{"type":14,"tag":22,"props":287,"children":288},{},[289],{"type":19,"value":290},"Remove",{"type":19,"value":292}," button ",{"type":14,"tag":22,"props":294,"children":295},{},[296],{"type":19,"value":297},"clears",{"type":19,"value":299}," it (for an HMAC secret, signature verification is then disabled).",{"type":14,"tag":301,"props":302,"children":304},"alert",{"type":303},"info",[305],{"type":14,"tag":15,"props":306,"children":307},{},[308,310,315],{"type":19,"value":309},"Copy-pasting or duplicating a node ",{"type":14,"tag":22,"props":311,"children":312},{},[313],{"type":19,"value":314},"does not copy",{"type":19,"value":316}," its secrets: enter them again on the copy.",{"type":14,"tag":30,"props":318,"children":320},{"id":319},"creating-a-pipeline",[321],{"type":19,"value":322},"Creating a pipeline",{"type":14,"tag":324,"props":325,"children":326},"ol",{},[327,345,356,375,387,392,409],{"type":14,"tag":51,"props":328,"children":329},{},[330,335,337,343],{"type":14,"tag":22,"props":331,"children":332},{},[333],{"type":19,"value":334},"Models → New",{"type":19,"value":336}," — in betool, a ",{"type":14,"tag":338,"props":339,"children":340},"em",{},[341],{"type":19,"value":342},"model",{"type":19,"value":344}," carries your pipeline.",{"type":14,"tag":51,"props":346,"children":347},{},[348,350,354],{"type":19,"value":349},"The canvas opens with a ",{"type":14,"tag":22,"props":351,"children":352},{},[353],{"type":19,"value":60},{"type":19,"value":355}," node. Configure it to select the input channel(s).",{"type":14,"tag":51,"props":357,"children":358},{},[359,361,366,368,373],{"type":19,"value":360},"Add nodes with the ",{"type":14,"tag":22,"props":362,"children":363},{},[364],{"type":19,"value":365},"Add a node",{"type":19,"value":367}," button when hovering over a link, or by right-clicking a node (",{"type":14,"tag":22,"props":369,"children":370},{},[371],{"type":19,"value":372},"Add a node before \u002F after",{"type":19,"value":374},"), then choose their type from the module catalog (search by name).",{"type":14,"tag":51,"props":376,"children":377},{},[378,380,385],{"type":19,"value":379},"Connect the nodes together. The pipeline is a ",{"type":14,"tag":22,"props":381,"children":382},{},[383],{"type":19,"value":384},"tree",{"type":19,"value":386},": each node has a single parent.",{"type":14,"tag":51,"props":388,"children":389},{},[390],{"type":19,"value":391},"Click a node to open its configuration in the inspector.",{"type":14,"tag":51,"props":393,"children":394},{},[395,400,402,407],{"type":14,"tag":22,"props":396,"children":397},{},[398],{"type":19,"value":399},"Run a test",{"type":19,"value":401}," — execute the published version on a freely entered payload, in real mode or in ",{"type":14,"tag":22,"props":403,"children":404},{},[405],{"type":19,"value":406},"Simulation mode",{"type":19,"value":408}," (nodes with external side effects are skipped).",{"type":14,"tag":51,"props":410,"children":411},{},[412,417],{"type":14,"tag":22,"props":413,"children":414},{},[415],{"type":19,"value":416},"Publish",{"type":19,"value":418}," — a commit message is mandatory; the pipeline is validated, then the new version becomes the one executed by the runtime.",{"type":14,"tag":30,"props":420,"children":422},{"id":421},"versioning",[423],{"type":19,"value":424},"Versioning",{"type":14,"tag":15,"props":426,"children":427},{},[428,430,435],{"type":19,"value":429},"Each publication creates a version. From ",{"type":14,"tag":22,"props":431,"children":432},{},[433],{"type":19,"value":434},"Versions",{"type":19,"value":436},", you can:",{"type":14,"tag":47,"props":438,"children":439},{},[440,450,460],{"type":14,"tag":51,"props":441,"children":442},{},[443,448],{"type":14,"tag":22,"props":444,"children":445},{},[446],{"type":19,"value":447},"Compare",{"type":19,"value":449}," a version with the current state (nodes and links added, removed, modified).",{"type":14,"tag":51,"props":451,"children":452},{},[453,458],{"type":14,"tag":22,"props":454,"children":455},{},[456],{"type":19,"value":457},"Reload",{"type":19,"value":459}," a version into the editor (the draft is overwritten, without publishing).",{"type":14,"tag":51,"props":461,"children":462},{},[463,468],{"type":14,"tag":22,"props":464,"children":465},{},[466],{"type":19,"value":467},"Republish",{"type":19,"value":469}," an earlier version (rollback).",{"type":14,"tag":15,"props":471,"children":472},{},[473,475,480],{"type":19,"value":474},"From the history, a past execution originating from a receiver can also be ",{"type":14,"tag":22,"props":476,"children":477},{},[478],{"type":19,"value":479},"replayed",{"type":19,"value":481}," on the published version, with an optionally modified payload and in simulation mode if needed.",{"type":14,"tag":30,"props":483,"children":485},{"id":484},"validation",[486],{"type":19,"value":487},"Validation",{"type":14,"tag":15,"props":489,"children":490},{},[491],{"type":19,"value":492},"On publication, a validator checks the graph:",{"type":14,"tag":47,"props":494,"children":495},{},[496,530],{"type":14,"tag":51,"props":497,"children":498},{},[499,504,506,512,514,520,522,528],{"type":14,"tag":22,"props":500,"children":501},{},[502],{"type":19,"value":503},"Blocking",{"type":19,"value":505}," — cycle in the graph; node with several parents; mandatory output left unwired (the body of a ",{"type":14,"tag":42,"props":507,"children":509},{"className":508},[],[510],{"type":19,"value":511},"foreach",{"type":19,"value":513}," loop, the children of a ",{"type":14,"tag":42,"props":515,"children":517},{"className":516},[],[518],{"type":19,"value":519},"parallel",{"type":19,"value":521},", each declared route of a ",{"type":14,"tag":42,"props":523,"children":525},{"className":524},[],[526],{"type":19,"value":527},"router",{"type":19,"value":529},"); incorrect number of Start nodes; errors specific to a node type (e.g. non-existent agent role or mission).",{"type":14,"tag":51,"props":531,"children":532},{},[533,538],{"type":14,"tag":22,"props":534,"children":535},{},[536],{"type":19,"value":537},"Warning",{"type":19,"value":539}," (non-blocking) — node unreachable from the Start; an existing configuration diverging from its node's contract.",{"type":14,"tag":15,"props":541,"children":542},{},[543,545,550],{"type":19,"value":544},"When a configuration is written (editor, proposals, API), a value outside the allowed values or a missing required field is ",{"type":14,"tag":22,"props":546,"children":547},{},[548],{"type":19,"value":549},"refused",{"type":19,"value":551},", with the expected correction.",{"type":14,"tag":15,"props":553,"children":554},{},[555],{"type":19,"value":556},"As a result, a published pipeline has passed these structural checks. Remaining errors belong to execution (a third-party API call failing, an unexpected parse result).",{"title":7,"searchDepth":558,"depth":558,"links":559},2,[560,561,568,569,570],{"id":32,"depth":558,"text":35},{"id":82,"depth":558,"text":85,"children":562},[563,565,566,567],{"id":89,"depth":564,"text":92},3,{"id":184,"depth":564,"text":187},{"id":201,"depth":564,"text":204},{"id":219,"depth":564,"text":222},{"id":319,"depth":558,"text":322},{"id":421,"depth":558,"text":424},{"id":484,"depth":558,"text":487},"markdown","content:en:docs:3.pipelines:1.editeur-visuel.md","content","en\u002Fdocs\u002F3.pipelines\u002F1.editeur-visuel.md","en\u002Fdocs\u002F3.pipelines\u002F1.editeur-visuel","md",[578],{"title":579,"_path":580,"children":581},"En","\u002Fen",[582],{"title":583,"_path":584,"children":585},"Docs","\u002Fen\u002Fdocs",[586,599,627,653,666,682,695,756],{"title":587,"_path":588,"children":589},"Getting started","\u002Fen\u002Fdocs\u002Fdemarrer",[590,593,596],{"title":591,"_path":592},"Welcome","\u002Fen\u002Fdocs\u002Fdemarrer\u002Fbienvenue",{"title":594,"_path":595},"Create an account","\u002Fen\u002Fdocs\u002Fdemarrer\u002Fcreer-un-compte",{"title":597,"_path":598},"Connect an LLM key","\u002Fen\u002Fdocs\u002Fdemarrer\u002Fbrancher-llm",{"title":600,"_path":601,"children":602},"Channels","\u002Fen\u002Fdocs\u002Fcanaux",[603,606,609,612,615,618,621,624],{"title":604,"_path":605},"Channels overview","\u002Fen\u002Fdocs\u002Fcanaux\u002Fvue-densemble",{"title":607,"_path":608},"Real-time telephony","\u002Fen\u002Fdocs\u002Fcanaux\u002Ftelephone",{"title":610,"_path":611},"Email","\u002Fen\u002Fdocs\u002Fcanaux\u002Femail",{"title":613,"_path":614},"Web chat widget","\u002Fen\u002Fdocs\u002Fcanaux\u002Fchat-widget",{"title":616,"_path":617},"HTTP Webhook","\u002Fen\u002Fdocs\u002Fcanaux\u002Fwebhook",{"title":619,"_path":620},"Messaging (WhatsApp, Messenger, Telegram, Mattermost)","\u002Fen\u002Fdocs\u002Fcanaux\u002Fmessageries",{"title":622,"_path":623},"Meta Lead Ads","\u002Fen\u002Fdocs\u002Fcanaux\u002Ffacebook-leads",{"title":625,"_path":626},"Schedule (cron)","\u002Fen\u002Fdocs\u002Fcanaux\u002Fschedule",{"title":628,"_path":629,"children":630},"Pipelines","\u002Fen\u002Fdocs\u002Fpipelines",[631,632,635,638,641,644,647,650],{"title":8,"_path":4},{"title":633,"_path":634},"AI Agents","\u002Fen\u002Fdocs\u002Fpipelines\u002Fagents",{"title":636,"_path":637},"Deterministic Operators","\u002Fen\u002Fdocs\u002Fpipelines\u002Foperateurs",{"title":639,"_path":640},"Flow Control","\u002Fen\u002Fdocs\u002Fpipelines\u002Fcontrole-flux",{"title":642,"_path":643},"Code Steps","\u002Fen\u002Fdocs\u002Fpipelines\u002Fcode-step",{"title":645,"_path":646},"Sub-pipelines","\u002Fen\u002Fdocs\u002Fpipelines\u002Fsous-pipelines",{"title":648,"_path":649},"No-code actions","\u002Fen\u002Fdocs\u002Fpipelines\u002Factions-no-code",{"title":651,"_path":652},"Knowledge base","\u002Fen\u002Fdocs\u002Fpipelines\u002Fbase-de-connaissances",{"title":654,"_path":655,"children":656},"Supervision","\u002Fen\u002Fdocs\u002Fsupervision",[657,660,663],{"title":658,"_path":659},"Execution History","\u002Fen\u002Fdocs\u002Fsupervision\u002Fexecutions",{"title":661,"_path":662},"Credits & Metering","\u002Fen\u002Fdocs\u002Fsupervision\u002Fcredits-metering",{"title":664,"_path":665},"Benchmarks","\u002Fen\u002Fdocs\u002Fsupervision\u002Fbenchmarks",{"title":667,"_path":668,"children":669},"Security","\u002Fen\u002Fdocs\u002Fsecurite",[670,673,676,679],{"title":671,"_path":672},"Security principles","\u002Fen\u002Fdocs\u002Fsecurite\u002Fprincipes",{"title":674,"_path":675},"Strict multi-tenancy","\u002Fen\u002Fdocs\u002Fsecurite\u002Fmulti-tenant",{"title":677,"_path":678},"GDPR audit & access log","\u002Fen\u002Fdocs\u002Fsecurite\u002Faudit-rgpd",{"title":680,"_path":681},"Sovereign deployment","\u002Fen\u002Fdocs\u002Fsecurite\u002Fdeploiement-souverain",{"title":683,"_path":684,"children":685},"Developers","\u002Fen\u002Fdocs\u002Fdeveloppeurs",[686,689,692],{"title":687,"_path":688},"Admin API","\u002Fen\u002Fdocs\u002Fdeveloppeurs\u002Fapi-admin",{"title":690,"_path":691},"Outbound webhooks","\u002Fen\u002Fdocs\u002Fdeveloppeurs\u002Fwebhooks-sortants",{"title":693,"_path":694},"Drive betool from Claude (MCP)","\u002Fen\u002Fdocs\u002Fdeveloppeurs\u002Fmcp",{"title":696,"_path":697,"children":698},"Integrations","\u002Fen\u002Fdocs\u002Fintegrations",[699,702,705,708,711,714,717,720,723,726,729,732,735,738,741,744,747,750,753],{"title":700,"_path":701},"Integrations overview","\u002Fen\u002Fdocs\u002Fintegrations\u002Fvue-densemble",{"title":703,"_path":704},"Stripe","\u002Fen\u002Fdocs\u002Fintegrations\u002Fstripe",{"title":706,"_path":707},"GitHub","\u002Fen\u002Fdocs\u002Fintegrations\u002Fgithub",{"title":709,"_path":710},"Google","\u002Fen\u002Fdocs\u002Fintegrations\u002Fgoogle",{"title":712,"_path":713},"LinkedIn Ads","\u002Fen\u002Fdocs\u002Fintegrations\u002Flinkedin-ads",{"title":715,"_path":716},"Kavkom","\u002Fen\u002Fdocs\u002Fintegrations\u002Fkavkom",{"title":718,"_path":719},"Jira","\u002Fen\u002Fdocs\u002Fintegrations\u002Fjira",{"title":721,"_path":722},"Slack","\u002Fen\u002Fdocs\u002Fintegrations\u002Fslack",{"title":724,"_path":725},"SMS","\u002Fen\u002Fdocs\u002Fintegrations\u002Fsms",{"title":727,"_path":728},"Enable Banking (open banking)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fenable-banking",{"title":730,"_path":731},"CRM, marketing & productivity","\u002Fen\u002Fdocs\u002Fintegrations\u002Fcrm-marketing",{"title":733,"_path":734},"HeyGen (video)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fheygen",{"title":736,"_path":737},"La Poste","\u002Fen\u002Fdocs\u002Fintegrations\u002Fla-poste",{"title":739,"_path":740},"Industry CRM (beTool Application, Qhare)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fcrm-metier",{"title":742,"_path":743},"Mitti (field inspections)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fmitti",{"title":745,"_path":746},"Meta (Messenger, Pages, Meta Ads)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fmeta",{"title":748,"_path":749},"Onoff Business (Beta)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fonoff",{"title":751,"_path":752},"Smart Life \u002F Tuya (connected devices)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fsmart-life",{"title":754,"_path":755},"beTool products (Desktop, Kiosk, Terminal)","\u002Fen\u002Fdocs\u002Fintegrations\u002Fproduits-betool",{"title":757,"_path":758,"children":759},"Use cases","\u002Fen\u002Fdocs\u002Fcas-usage",[760,763,766,769,772,775],{"title":761,"_path":762},"Typical business agents","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fvue-densemble",{"title":764,"_path":765},"CFO IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fcfo-ia",{"title":767,"_path":768},"COO IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fcoo-ia",{"title":770,"_path":771},"CTO IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fcto-ia",{"title":773,"_path":774},"Product Manager IA","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fproduct-manager-ia",{"title":776,"_path":777},"Personal assistant","\u002Fen\u002Fdocs\u002Fcas-usage\u002Fassistant-personnel"]