[{"data":1,"prerenderedAt":1106},["ShallowReactive",2],{"navigation_docs":3,"-guides-ai-configuration":412,"-guides-ai-configuration-surround":1101},[4,38,84,326,386],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":37},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,24,28,32],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick start: Nuxt","\u002Fgetting-started\u002Fquick-start-nuxt","1.getting-started\u002F3.quick-start-nuxt",{"title":25,"path":26,"stem":27,"icon":6},"Quick start: plain Vue","\u002Fgetting-started\u002Fquick-start-vue","1.getting-started\u002F4.quick-start-vue",{"title":29,"path":30,"stem":31,"icon":6},"Quick start: React","\u002Fgetting-started\u002Fquick-start-react","1.getting-started\u002F5.quick-start-react",{"title":33,"path":34,"stem":35,"icon":36},"Glossary","\u002Fgetting-started\u002Fglossary","1.getting-started\u002F6.glossary","i-lucide-book-a",false,{"title":39,"icon":40,"path":41,"stem":42,"children":43,"page":37},"Tutorial","i-lucide-graduation-cap","\u002Ftutorial","2.tutorial",[44,49,54,59,64,69,74,79],{"title":45,"path":46,"stem":47,"icon":48},"Tutorial: overview","\u002Ftutorial\u002Foverview","2.tutorial\u002F1.overview","i-lucide-map",{"title":50,"path":51,"stem":52,"icon":53},"Chapter 2: A simple editor","\u002Ftutorial\u002Fsimple-editor","2.tutorial\u002F2.simple-editor","i-lucide-pencil",{"title":55,"path":56,"stem":57,"icon":58},"Chapter 3: Compose features","\u002Ftutorial\u002Fcompose-features","2.tutorial\u002F3.compose-features","i-lucide-blocks",{"title":60,"path":61,"stem":62,"icon":63},"Chapter 4: Your own block, path A","\u002Ftutorial\u002Fown-block-path-a","2.tutorial\u002F4.own-block-path-a","i-lucide-square-plus",{"title":65,"path":66,"stem":67,"icon":68},"Chapter 5: Your own feature, path B","\u002Ftutorial\u002Fown-feature-path-b","2.tutorial\u002F5.own-feature-path-b","i-lucide-puzzle",{"title":70,"path":71,"stem":72,"icon":73},"Chapter 6: Backend and collaboration","\u002Ftutorial\u002Fbackend-and-collaboration","2.tutorial\u002F6.backend-and-collaboration","i-lucide-users",{"title":75,"path":76,"stem":77,"icon":78},"Chapter 7: AI","\u002Ftutorial\u002Fai","2.tutorial\u002F7.ai","i-lucide-sparkles",{"title":80,"path":81,"stem":82,"icon":83},"Chapter 8: The React surface","\u002Ftutorial\u002Freact-surface","2.tutorial\u002F8.react-surface","i-lucide-atom",{"title":85,"icon":14,"path":86,"stem":87,"children":88,"page":37},"Guides","\u002Fguides","3.guides",[89,93,98,103,108,112,116,121,126,130,134,139,144,149,154,159,164,169,174,179,184,189,194,199,204,209,213,218,223,228,233,237,242,247,251,256,261,266,271,276,281,286,291,295,302,307,311,316,321],{"title":90,"path":91,"stem":92,"icon":58},"Feature composition and entries","\u002Fguides\u002Fcomposition","3.guides\u002F1.composition",{"title":94,"path":95,"stem":96,"icon":97},"Media, mentions and transcript features","\u002Fguides\u002Fmedia-mentions-transcript","3.guides\u002F10.media-mentions-transcript","i-lucide-image",{"title":99,"path":100,"stem":101,"icon":102},"Authors and comments","\u002Fguides\u002Fauthors-and-comments","3.guides\u002F11.authors-and-comments","i-lucide-message-square-text",{"title":104,"path":105,"stem":106,"icon":107},"Themes (Obsidian)","\u002Fguides\u002Fthemes","3.guides\u002F12.themes","i-lucide-palette",{"title":109,"path":110,"stem":111,"icon":58},"Composites and the settings UI","\u002Fguides\u002Fcomposites","3.guides\u002F13.composites",{"title":113,"path":114,"stem":115,"icon":78},"AI","\u002Fguides\u002Fai","3.guides\u002F14.ai",{"title":117,"path":118,"stem":119,"icon":120},"Document tree","\u002Fguides\u002Fdocument-tree","3.guides\u002F15.document-tree","i-lucide-folder-tree",{"title":122,"path":123,"stem":124,"icon":125},"Markdown and code","\u002Fguides\u002Fmarkdown-and-code","3.guides\u002F16.markdown-and-code","i-lucide-file-code",{"title":127,"path":128,"stem":129,"icon":83},"Advanced editor in React","\u002Fguides\u002Fadvanced-react","3.guides\u002F17.advanced-react",{"title":131,"path":132,"stem":133,"icon":6},"Kitchen sink: learning path","\u002Fguides\u002Fadvanced-nuxt-example","3.guides\u002F18.advanced-nuxt-example",{"title":135,"path":136,"stem":137,"icon":138},"Production","\u002Fguides\u002Fproduction","3.guides\u002F19.production","i-lucide-server",{"title":140,"path":141,"stem":142,"icon":143},"Register the Nuxt module","\u002Fguides\u002Fnuxt-module","3.guides\u002F2.nuxt-module","i-lucide-package",{"title":145,"path":146,"stem":147,"icon":148},"Storage adapters, comment stores, Nitro host","\u002Fguides\u002Fstorage-adapters","3.guides\u002F20.storage-adapters","i-lucide-database",{"title":150,"path":151,"stem":152,"icon":153},"Migrating from #tiptap-editor","\u002Fguides\u002Fmigration","3.guides\u002F21.migration","i-lucide-arrow-right-left",{"title":155,"path":156,"stem":157,"icon":158},"Content tree mechanics","\u002Fguides\u002Fcontent-tree","3.guides\u002F22.content-tree","i-lucide-git-fork",{"title":160,"path":161,"stem":162,"icon":163},"Block capabilities, abilities and actions","\u002Fguides\u002Fblock-capabilities","3.guides\u002F23.block-capabilities","i-lucide-shield-check",{"title":165,"path":166,"stem":167,"icon":168},"Block types in code and JSON","\u002Fguides\u002Fblock-types","3.guides\u002F24.block-types","i-lucide-shapes",{"title":170,"path":171,"stem":172,"icon":173},"Derive methods and the Derivation index","\u002Fguides\u002Fderive-methods","3.guides\u002F25.derive-methods","i-lucide-git-branch-plus",{"title":175,"path":176,"stem":177,"icon":178},"Block properties and Property definitions","\u002Fguides\u002Fblock-properties","3.guides\u002F26.block-properties","i-lucide-sliders-horizontal",{"title":180,"path":181,"stem":182,"icon":183},"Image studio","\u002Fguides\u002Fimage-studio","3.guides\u002F27.image-studio","i-lucide-image-plus",{"title":185,"path":186,"stem":187,"icon":188},"Prüfung and Freigabestatus","\u002Fguides\u002Fpruefung","3.guides\u002F28.pruefung","i-lucide-stamp",{"title":190,"path":191,"stem":192,"icon":193},"Workspace: find, read, reference and embed Blocks across Documents","\u002Fguides\u002Fworkspace","3.guides\u002F29.workspace","i-lucide-network",{"title":195,"path":196,"stem":197,"icon":198},"EditorPorts: auth and storage","\u002Fguides\u002Feditor-ports","3.guides\u002F3.editor-ports","i-lucide-plug",{"title":200,"path":201,"stem":202,"icon":203},"Collections: an ordered list of Blocks","\u002Fguides\u002Fcollections","3.guides\u002F30.collections","i-lucide-list-checks",{"title":205,"path":206,"stem":207,"icon":208},"Data views: a query shown as table, list or board","\u002Fguides\u002Fdata-views","3.guides\u002F31.data-views","i-lucide-table-properties",{"title":210,"path":211,"stem":212,"icon":193},"Explore: backlinks, related Blocks and the trail","\u002Fguides\u002Fexplore","3.guides\u002F32.explore",{"title":214,"path":215,"stem":216,"icon":217},"Render: export a Block or a Document to a file","\u002Fguides\u002Frender","3.guides\u002F33.render","i-lucide-file-output",{"title":219,"path":220,"stem":221,"icon":222},"Importers: what a dropped file becomes","\u002Fguides\u002Fimporters","3.guides\u002F34.importers","i-lucide-file-input",{"title":224,"path":225,"stem":226,"icon":227},"Templates: start a Document from a Dokumentvorlage","\u002Fguides\u002Ftemplates","3.guides\u002F35.templates","i-lucide-file-stack",{"title":229,"path":230,"stem":231,"icon":232},"Citations","\u002Fguides\u002Fcitations","3.guides\u002F36.citations","i-lucide-quote",{"title":234,"path":235,"stem":236,"icon":163},"AI proposals and the export check","\u002Fguides\u002Fexport-check","3.guides\u002F37.export-check",{"title":238,"path":239,"stem":240,"icon":241},"Query: filter, sort, group and total Blocks","\u002Fguides\u002Fquery","3.guides\u002F38.query","i-lucide-list-filter",{"title":243,"path":244,"stem":245,"icon":246},"Edges: backlinks and authored connections","\u002Fguides\u002Fedges","3.guides\u002F39.edges","i-lucide-link-2",{"title":248,"path":249,"stem":250,"icon":163},"Server routes and authentication","\u002Fguides\u002Froutes-and-auth","3.guides\u002F4.routes-and-auth",{"title":252,"path":253,"stem":254,"icon":255},"Speech: text to audio, and subtitle files","\u002Fguides\u002Fspeech","3.guides\u002F41.speech","i-lucide-audio-lines",{"title":257,"path":258,"stem":259,"icon":260},"Graph: the Edges around a Block","\u002Fguides\u002Fgraph","3.guides\u002F42.graph","i-lucide-waypoints",{"title":262,"path":263,"stem":264,"icon":265},"PDF viewer: passages, anchors and quotes","\u002Fguides\u002Fpdf-viewer","3.guides\u002F43.pdf-viewer","i-lucide-file-search",{"title":267,"path":268,"stem":269,"icon":270},"Obsidian: import and export a vault","\u002Fguides\u002Fobsidian","3.guides\u002F44.obsidian","i-lucide-folder-input",{"title":272,"path":273,"stem":274,"icon":275},"Typst: render a Document as a PDF with citations","\u002Fguides\u002Ftypst","3.guides\u002F45.typst","i-lucide-file-text",{"title":277,"path":278,"stem":279,"icon":280},"Audio: read aloud, mixdown and ElevenLabs","\u002Fguides\u002Faudio","3.guides\u002F46.audio","i-lucide-audio-waveform",{"title":282,"path":283,"stem":284,"icon":285},"Slides: decks, slide layouts and exports","\u002Fguides\u002Fslides","3.guides\u002F47.slides","i-lucide-presentation",{"title":287,"path":288,"stem":289,"icon":290},"Knowledge graph: sources and concepts beside the Documents","\u002Fguides\u002Fknowledge-graph","3.guides\u002F49.knowledge-graph","i-lucide-share-2",{"title":292,"path":293,"stem":294,"icon":78},"AI configuration and secrets","\u002Fguides\u002Fai-configuration","3.guides\u002F5.ai-configuration",{"title":296,"path":297,"stem":298,"children":299,"icon":301},"Index on Postgres: typos, meaning and SQL pushdown","\u002Fguides\u002Findex-pg","3.guides\u002F50.index-pg",[300],{"title":296,"path":297,"stem":298,"icon":301},"i-lucide-database-zap",{"title":303,"path":304,"stem":305,"icon":306},"Charts: bar, line, pie and scatter over a query","\u002Fguides\u002Fcharts","3.guides\u002F51.charts","i-lucide-chart-column",{"title":308,"path":309,"stem":310,"icon":73},"Collaboration on the client","\u002Fguides\u002Fcollaboration","3.guides\u002F6.collaboration",{"title":312,"path":313,"stem":314,"icon":315},"Block UI (drag handle, hover actions)","\u002Fguides\u002Fblock-ui","3.guides\u002F7.block-ui","i-lucide-grip-vertical",{"title":317,"path":318,"stem":319,"icon":320},"Settings and app lifetime","\u002Fguides\u002Fsettings","3.guides\u002F8.settings","i-lucide-settings",{"title":322,"path":323,"stem":324,"icon":325},"Language","\u002Fguides\u002Flanguage","3.guides\u002F9.language","i-lucide-languages",{"title":327,"icon":14,"path":328,"stem":329,"children":330,"page":37},"Reference","\u002Freference","4.reference",[331,335,339,344,348,352,356,360,364,368,373,378,382],{"title":332,"path":333,"stem":334,"icon":143},"Public exports","\u002Freference\u002Fexports","4.reference\u002F1.exports",{"title":336,"path":337,"stem":338,"icon":173},"Derive method contract","\u002Freference\u002Fderive-methods","4.reference\u002F10.derive-methods",{"title":340,"path":341,"stem":342,"icon":343},"Changelog","\u002Freference\u002Fchangelog","4.reference\u002F11.changelog","i-lucide-history",{"title":345,"path":346,"stem":347,"icon":217},"Renderer port","\u002Freference\u002Frenderer-port","4.reference\u002F12.renderer-port",{"title":349,"path":350,"stem":351,"icon":255},"Speech port","\u002Freference\u002Fspeech-port","4.reference\u002F13.speech-port",{"title":353,"path":354,"stem":355,"icon":58},"Presets and features","\u002Freference\u002Fpresets-and-features","4.reference\u002F2.presets-and-features",{"title":357,"path":358,"stem":359,"icon":68},"Feature contract","\u002Freference\u002Ffeature-contract","4.reference\u002F3.feature-contract",{"title":361,"path":362,"stem":363,"icon":107},"CSS and UI-provider requirements","\u002Freference\u002Fcss-and-ui","4.reference\u002F4.css-and-ui",{"title":365,"path":366,"stem":367,"icon":148},"Vue-free advanced schema","\u002Freference\u002Fadvanced-schema","4.reference\u002F5.advanced-schema",{"title":369,"path":370,"stem":371,"icon":372},"Dependency rules","\u002Freference\u002Fdependency-rules","4.reference\u002F6.dependency-rules","i-lucide-git-branch",{"title":374,"path":375,"stem":376,"icon":377},"Commands","\u002Freference\u002Fcommands","4.reference\u002F7.commands","i-lucide-terminal",{"title":379,"path":380,"stem":381,"icon":163},"Block capability contract","\u002Freference\u002Fblock-capabilities","4.reference\u002F8.block-capabilities",{"title":383,"path":384,"stem":385,"icon":168},"Block type contract","\u002Freference\u002Fblock-types","4.reference\u002F9.block-types",{"title":387,"path":388,"stem":389,"children":390,"icon":393},"AI agents","\u002Fai-agents","5.ai-agents\u002F1.index",[391,394,398,402,407],{"title":392,"path":388,"stem":389,"icon":393},"Overview","i-lucide-bot",{"title":395,"path":396,"stem":397,"icon":198},"Integrate the editor","\u002Fai-agents\u002Fintegrate","5.ai-agents\u002F2.integrate",{"title":399,"path":400,"stem":401,"icon":68},"Add a block or feature","\u002Fai-agents\u002Fextend","5.ai-agents\u002F3.extend",{"title":403,"path":404,"stem":405,"icon":406},"Pitfalls and invariants","\u002Fai-agents\u002Finvariants","5.ai-agents\u002F4.invariants","i-lucide-shield-alert",{"title":408,"path":409,"stem":410,"icon":411},"Verify","\u002Fai-agents\u002Fverify","5.ai-agents\u002F5.verify","i-lucide-check-check",{"id":413,"title":292,"body":414,"description":1094,"extension":1095,"links":1096,"meta":1097,"navigation":1098,"path":293,"seo":1099,"stem":294,"__hash__":1100},"docs\u002F3.guides\u002F5.ai-configuration.md",{"type":415,"value":416,"toc":1086},"minimark",[417,422,503,660,664,674,894,898,905,970,974,1041,1045,1052,1056,1082],[418,419,421],"h2",{"id":420},"defining-the-configuration","Defining the configuration",[423,424,425,426,430,431,434,435,438,439,442,443,446,447,446,450,453,454,457,458,461,462,446,465,446,468,471,472,475,476,446,479,482,483,486,487,490,491,494,495,498,499,502],"p",{},"One configuration, three views (",[427,428,429],"code",{},"@skaile\u002Fforge-editor\u002Fconfig",", framework-free). ",[427,432,433],{},"defineEditorConfig(input)"," applies every default below once and returns the ",[427,436,437],{},"EditorConfig","; ",[427,440,441],{},"publicConfig(config)"," is the part the browser may see (",[427,444,445],{},"locale",", ",[427,448,449],{},"messages",[427,451,452],{},"ai: { roles, transcription: boolean }",", the ",[427,455,456],{},"createEditor({ ...publicConfig })"," options), ",[427,459,460],{},"serverConfig(config)"," the part the server needs, keys included (",[427,463,464],{},"ai: { presets, apiKey, slots, transcription? }",[427,466,467],{},"rateLimit",[427,469,470],{},"collab",": spread it into ",[427,473,474],{},"installEditorServer(nitroApp, { ports, ...serverConfig(config) })","). The Nuxt module does exactly that: its options are ",[427,477,478],{},"EditorConfigInput",[427,480,481],{},"runtimeConfig.tiptapEditor = serverConfig(config)"," and ",[427,484,485],{},"runtimeConfig.public.tiptapEditor = publicConfig(config)",", and the server plugin passes the runtime config on to ",[427,488,489],{},"installEditorServer",". Every Model preset, the shared key and the transcription get an empty ",[427,492,493],{},"apiKey"," in the server view, so the ",[427,496,497],{},"NUXT_TIPTAP_EDITOR_AI_*"," variables below have a key to override. An unset value (",[427,500,501],{},"locale: process.env.EDITOR_LOCALE",") means the default.",[504,505,510],"pre",{"className":506,"code":507,"language":508,"meta":509,"style":509},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineEditorConfig, publicConfig, serverConfig } from '@skaile\u002Fforge-editor\u002Fconfig'\n\nconst config = defineEditorConfig({ locale: 'en', ai: { roles: { rewrite: 'flashLite' } } })\nserverConfig(config) \u002F\u002F { ai: { presets, apiKey: '', roles, … }, rateLimit: { max: 30, windowMs: 60000 }, collab: { authenticateUpgrade: false } }\npublicConfig(config) \u002F\u002F { locale: 'en', ai: { roles, transcription: false } }\n","ts","",[427,511,512,555,562,636,649],{"__ignoreMap":509},[513,514,517,521,525,529,532,535,537,540,543,546,549,552],"span",{"class":515,"line":516},"line",1,[513,518,520],{"class":519},"s7zQu","import",[513,522,524],{"class":523},"sMK4o"," {",[513,526,528],{"class":527},"sTEyZ"," defineEditorConfig",[513,530,531],{"class":523},",",[513,533,534],{"class":527}," publicConfig",[513,536,531],{"class":523},[513,538,539],{"class":527}," serverConfig",[513,541,542],{"class":523}," }",[513,544,545],{"class":519}," from",[513,547,548],{"class":523}," '",[513,550,429],{"class":551},"sfazB",[513,553,554],{"class":523},"'\n",[513,556,558],{"class":515,"line":557},2,[513,559,561],{"emptyLinePlaceholder":560},true,"\n",[513,563,565,569,572,575,578,581,584,588,591,593,596,599,601,604,606,608,611,613,615,618,620,622,625,627,629,631,633],{"class":515,"line":564},3,[513,566,568],{"class":567},"spNyl","const",[513,570,571],{"class":527}," config ",[513,573,574],{"class":523},"=",[513,576,528],{"class":577},"s2Zo4",[513,579,580],{"class":527},"(",[513,582,583],{"class":523},"{",[513,585,587],{"class":586},"swJcz"," locale",[513,589,590],{"class":523},":",[513,592,548],{"class":523},[513,594,595],{"class":551},"en",[513,597,598],{"class":523},"'",[513,600,531],{"class":523},[513,602,603],{"class":586}," ai",[513,605,590],{"class":523},[513,607,524],{"class":523},[513,609,610],{"class":586}," roles",[513,612,590],{"class":523},[513,614,524],{"class":523},[513,616,617],{"class":586}," rewrite",[513,619,590],{"class":523},[513,621,548],{"class":523},[513,623,624],{"class":551},"flashLite",[513,626,598],{"class":523},[513,628,542],{"class":523},[513,630,542],{"class":523},[513,632,542],{"class":523},[513,634,635],{"class":527},")\n",[513,637,639,642,645],{"class":515,"line":638},4,[513,640,641],{"class":577},"serverConfig",[513,643,644],{"class":527},"(config) ",[513,646,648],{"class":647},"sHwdD","\u002F\u002F { ai: { presets, apiKey: '', roles, … }, rateLimit: { max: 30, windowMs: 60000 }, collab: { authenticateUpgrade: false } }\n",[513,650,652,655,657],{"class":515,"line":651},5,[513,653,654],{"class":577},"publicConfig",[513,656,644],{"class":527},[513,658,659],{"class":647},"\u002F\u002F { locale: 'en', ai: { roles, transcription: false } }\n",[418,661,663],{"id":662},"options","Options",[423,665,666,667,670,671,673],{},"Config key ",[427,668,669],{},"tiptapEditor"," (",[427,672,478],{},"; a Model preset with the ID of a default overrides single fields of it):",[675,676,677,693],"table",{},[678,679,680],"thead",{},[681,682,683,687,690],"tr",{},[684,685,686],"th",{},"Option",[684,688,689],{},"Type",[684,691,692],{},"Default",[694,695,696,718,733,761,786,804,862],"tbody",{},[681,697,698,703,713],{},[699,700,701],"td",{},[427,702,445],{},[699,704,705,708,709,712],{},[427,706,707],{},"'de' | 'en'",": language of every string the editor renders; passed to the client context plugin (",[427,710,711],{},"createEditor({ locale })",")",[699,714,715],{},[427,716,717],{},"'de'",[681,719,720,724,730],{},[699,721,722],{},[427,723,449],{},[699,725,726,729],{},[427,727,728],{},"Partial\u003CRecord\u003CMessageKey, string>>",": overrides of single messages by key (JSON-serialisable)",[699,731,732],{},"none",[681,734,735,740,753],{},[699,736,737],{},[427,738,739],{},"ai.presets",[699,741,742,670,745,748,749,752],{},[427,743,744],{},"Record\u003Cstring, ModelPresetConfig>",[427,746,747],{},"{ label, endpoint, model, apiKey? }","): server Model presets keyed by preset ID (camelCase). ",[427,750,751],{},"endpoint"," is any OpenAI-compatible chat-completions base URL.",[699,754,755,446,758,760],{},[427,756,757],{},"sonnet",[427,759,624],{}," (OpenRouter)",[681,762,763,768,781],{},[699,764,765],{},[427,766,767],{},"ai.roles",[699,769,770,670,773,776,777,780],{},[427,771,772],{},"Record\u003CModelRole, string>",[427,774,775],{},"'complete' | 'rewrite' | 'generate'","): default Model preset per Model role. The ",[427,778,779],{},"complete"," model must support assistant prefill.",[699,782,783],{},[427,784,785],{},"{ complete: 'flashLite', rewrite: 'sonnet', generate: 'sonnet' }",[681,787,788,793,799],{},[699,789,790],{},[427,791,792],{},"ai.rateLimit",[699,794,795,798],{},[427,796,797],{},"{ max, windowMs }"," per user, shared by all AI endpoints",[699,800,801],{},[427,802,803],{},"{ max: 30, windowMs: 60000 }",[681,805,806,811,859],{},[699,807,808],{},[427,809,810],{},"ai.transcription",[699,812,813,816,817,820,821,824,825,670,828,831,832,835,836,670,839,820,841,446,844,847,848,851,852,855,856,858],{},[427,814,815],{},"{ provider?, endpoint, model, apiKey?, language? }",": ",[427,818,819],{},"provider"," ",[427,822,823],{},"'openai'"," (default) = OpenAI-compatible ",[427,826,827],{},"POST \u003Cendpoint>\u002Faudio\u002Ftranscriptions",[427,829,830],{},"verbose_json"," segments), ",[427,833,834],{},"'deepgram'"," = Deepgram ",[427,837,838],{},"POST \u003Cendpoint>\u002Flisten",[427,840,751],{},[427,842,843],{},"https:\u002F\u002Fapi.deepgram.com\u002Fv1",[427,845,846],{},"model"," e.g. ",[427,849,850],{},"nova-3","; utterances become the segments). ",[427,853,854],{},"language"," (e.g. ",[427,857,717],{},") fixes the spoken language; without it OpenAI guesses and Deepgram detects it",[699,860,861],{},"absent: action hidden, endpoint answers 501",[681,863,864,869,888],{},[699,865,866],{},[427,867,868],{},"collab.authenticateUpgrade",[699,870,871,874,875,878,879,884,885],{},[427,872,873],{},"boolean",": authenticate the ",[427,876,877],{},"\u002Fcollab\u002F:id"," upgrade and refuse it with HTTP 401 (see ",[880,881,883],"a",{"href":882},"\u002Fguides\u002Froutes-and-auth#auth-notes","Auth notes","); env ",[427,886,887],{},"NUXT_TIPTAP_EDITOR_COLLAB_AUTHENTICATE_UPGRADE",[699,889,890,893],{},[427,891,892],{},"false",": upgrade first, close with 4401",[418,895,897],{"id":896},"keys-come-from-the-environment-only","Keys come from the environment only",[423,899,900,901,904],{},"Never put a key into ",[427,902,903],{},"nuxt.config.ts"," (it ends up in the build output).",[675,906,907,917],{},[678,908,909],{},[681,910,911,914],{},[684,912,913],{},"Variable",[684,915,916],{},"Sets",[694,918,919,932,954],{},[681,920,921,926],{},[699,922,923],{},[427,924,925],{},"NUXT_TIPTAP_EDITOR_AI_API_KEY",[699,927,928,931],{},[427,929,930],{},"ai.apiKey",": shared fallback for every Model preset without its own key",[681,933,934,939],{},[699,935,936],{},[427,937,938],{},"NUXT_TIPTAP_EDITOR_AI_PRESETS_\u003CID>_API_KEY",[699,940,941,438,944,947,948,950,951,712],{},[427,942,943],{},"ai.presets.\u003Cid>.apiKey",[427,945,946],{},"\u003CID>"," is the preset ID in upper snake case (",[427,949,624],{}," → ",[427,952,953],{},"NUXT_TIPTAP_EDITOR_AI_PRESETS_FLASH_LITE_API_KEY",[681,955,956,961],{},[699,957,958],{},[427,959,960],{},"NUXT_TIPTAP_EDITOR_AI_TRANSCRIPTION_API_KEY",[699,962,963,966,967,969],{},[427,964,965],{},"ai.transcription.apiKey"," (only effective when ",[427,968,810],{}," is set)",[418,971,973],{"id":972},"host-models-through-the-adapter","Host models through the adapter",[423,975,976,977,453,980,983,984,987,988,991,992,995,996,999,1000,1002,1003,1006,1007,1010,1011,1014,1015,446,1018,446,1021,1024,1025,1028,1029,1032,1033,1036,1037,1040],{},"A model provider (",[427,978,979],{},"ModelProvider",[427,981,982],{},"models"," port) with ",[427,985,986],{},"languageModel(ref, user)"," is asked first for every Model reference; a returned model is used as is (no Model preset, no key needed), ",[427,989,990],{},"null"," falls through to the Model presets above. ",[427,993,994],{},"listModels(user)"," decides what ",[427,997,998],{},"GET \u002Fapi\u002Fai\u002Fmodels"," offers (return ",[427,1001,990],{}," to list the Model presets). Host-driven agent chats are the counterpart on the client: ",[427,1004,1005],{},"createAgentOpReview({ notify, t })"," from ",[427,1008,1009],{},"@skaile\u002Fforge-editor\u002Fai"," shows agent edit operations from any transport as in-document hunks (",[427,1012,1013],{},"propose","), follows the user's decisions (",[427,1016,1017],{},"state",[427,1019,1020],{},"decide",[427,1022,1023],{},"reveal",") and reads them back for the agent (",[427,1026,1027],{},"feedback()"," yields each decision once); ",[427,1030,1031],{},"createAiSidebarFlow({ send, assistant, notify, editor })"," takes the host's ",[427,1034,1035],{},"send(question, scope)"," instead of a ",[427,1038,1039],{},"chat",".",[418,1042,1044],{"id":1043},"key-resolution-and-errors","Key resolution and errors",[423,1046,1047,1048,1051],{},"A Model preset resolves its key as ",[427,1049,1050],{},"preset.apiKey || ai.apiKey",". A missing key answers 500 naming both variables before any stream starts; an unknown preset ID answers 400; upstream failures answer 502.",[418,1053,1055],{"id":1054},"where-the-secrets-live","Where the secrets live",[423,1057,1058,1061,1062,1065,1066,1068,1069,1073,1074,1077,1078,1081],{},[427,1059,1060],{},"runtimeConfig.tiptapEditor.ai"," is server-only. The browser only ever receives ",[427,1063,1064],{},"public.tiptapEditor.ai = { roles, transcription: boolean }"," and, through ",[427,1067,998],{},", Model profiles of the Model presets ",[1070,1071,1072],"strong",{},"without"," keys. A user-defined Model profile (kept in the browser's ",[427,1075,1076],{},"localStorage",", key ",[427,1079,1080],{},"tiptap-editor:model-profiles",") sends its own key with each request; the server forwards it and never stores it.",[1083,1084,1085],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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);}",{"title":509,"searchDepth":557,"depth":557,"links":1087},[1088,1089,1090,1091,1092,1093],{"id":420,"depth":557,"text":421},{"id":662,"depth":557,"text":663},{"id":896,"depth":557,"text":897},{"id":972,"depth":557,"text":973},{"id":1043,"depth":557,"text":1044},{"id":1054,"depth":557,"text":1055},"One configuration object for module options, server and browser, the Model presets and Model roles, and why API keys come from the environment only.","md",null,{},{"icon":78},{"title":292,"description":1094},"O9ZRTBVugDurmVaHXPisG0Ri3zU7X7rPk-7oEwaofGA",[1102,1104],{"title":287,"path":288,"stem":289,"description":1103,"icon":290,"children":-1},"The read-only KnowledgeGraph port with its search and neighbours routes, the Wissensgraph tab of the Explore panel, the memory adapter for tests and the @skaile\u002Fforge-editor-kgs add-on over the KGS SDK.",{"title":296,"path":297,"stem":298,"description":1105,"icon":301,"children":-1},"The @skaile\u002Fforge-editor-index-pg add-on: trigram title search, a vector table kept current on replace, nearest and related Blocks, query pushdown, and the Embedder port with its OpenAI-compatible adapter.",1793213908404]