[{"data":1,"prerenderedAt":3875},["ShallowReactive",2],{"search-de":3,"content-de-vision\u002Fknowledge-graph":4,"surround-de-\u002Fvision\u002Fknowledge-graph":3868},[],{"id":5,"title":6,"body":7,"description":3861,"extension":3862,"meta":3863,"navigation":852,"path":3864,"seo":3865,"stem":3866,"__hash__":3867},"content_de\u002F5.vision\u002F3.knowledge-graph.md","Wissensgraph",{"type":8,"value":9,"toc":3832},"minimark",[10,15,19,117,122,143,147,150,155,158,272,275,365,369,372,442,477,481,586,599,609,644,648,659,934,960,1024,1028,1031,1035,1046,1169,1187,1191,1221,1457,1473,1477,1548,1790,1812,1816,1873,2013,2016,2052,2059,2106,2110,2118,2148,2160,2164,2201,2204,2208,2211,2411,2415,2421,2567,2575,2579,2582,2586,2602,2640,2655,2672,2676,2775,2779,2784,2787,3443,3446,3822,3828],[11,12,14],"h1",{"id":13},"architektur-des-wissensgraphen","Architektur des Wissensgraphen",[16,17,18],"p",{},"Jede Organisation sammelt Wissen durch Kommunikation an: Kundenpräferenzen, interne Entscheidungen, Projektkontext, Beziehungsgeschichte. Der Wissensgraph fängt dieses Wissen als typisierte, durchsuchbare, verfallende Einträge ein — kein reines Schreibprotokoll, sondern ein lebendiges System, das korrekt bleibt, während sich die Organisation weiterentwickelt.",[20,21,24,68],"callout",{"title":22,"type":23},"Status: weitgehend gebaut; einige Pflegeverhalten noch geplant","info",[16,25,26,27,31,32,35,36,39,40,43,44,48,49,52,53,56,57,52,60,63,64,67],{},"Die Kernschleife läuft inzwischen Ende zu Ende. Heute ausgeliefert: die typisierten Tabellen ",[28,29,30],"code",{},"knowledgeEntries"," \u002F ",[28,33,34],{},"knowledgeRelations",", CRUD plus Volltextsuche (",[28,37,38],{},"apps\u002Fapi\u002Fconvex\u002Fknowledge\u002Fgraph.ts","), der typbezogene Cron für den Konfidenzverfall (",[28,41,42],{},"apps\u002Fapi\u002Fconvex\u002Fknowledge\u002Fmaintenance.ts","), die ",[45,46,47],"strong",{},"aktive Extraktion pro Nachricht, verdrahtet in die Agenten-Strecke"," (idempotent), der ",[45,50,51],{},"echte vektorbasierte semantische Abruf"," (",[28,54,55],{},"apps\u002Fapi\u002Fconvex\u002Fknowledge\u002Fretrieval.ts",") und das ",[45,58,59],{},"Einspeisen semantischen Wissens in das Kontext-Briefing des Agenten",[28,61,62],{},"apps\u002Fapi\u002Fconvex\u002Fagent\u002Fsteps\u002Fcontext_retrieval\u002Findex.ts","). Der einmalige Backfill-Job (",[28,65,66],{},"apps\u002Fapi\u002Fconvex\u002Fagent\u002FknowledgeBackfill.ts",") sät beim erstmaligen Aktivieren des Flags weiterhin historischen Kontext ein.",[16,69,70,71,74,75,79,80,31,83,31,86,89,90,93,94,97,98,101,102,31,104,31,106,108,109,112,113,116],{},"Einige der unten beschriebenen Fähigkeiten sind ",[45,72,73],{},"weiterhin geplant"," und haben noch keinen produktiven Aufrufer: Deduplizierung während der Extraktion \u002F Widerspruchsprüfung \u002F das ",[76,77,78],"em",{},"inline vor dem Speichern"," erfolgende Anlegen der Relationen ",[28,81,82],{},"supports",[28,84,85],{},"contradicts",[28,87,88],{},"supersedes",", Memory als Werkzeuge, Widerspruchsauflösung und der Validierungsschub. Jede Stelle ist im Text markiert. (Zwei Kantenverknüpfer werden bereits ausgeliefert und vom Extraktor eingeplant: der deterministische strukturelle ",[28,91,92],{},"relates_to","-Verknüpfer, abgesichert über ",[28,95,96],{},"ai.knowledge",", und — hinter ",[28,99,100],{},"ai.knowledge.autoLink"," — ein LLM-Durchlauf, der die semantischen Kanten ",[28,103,82],{},[28,105,85],{},[28,107,88],{}," ",[76,110,111],{},"nach"," dem Speichern erschließt. Der graphgestützte Abruf über diese Kanten wird hinter ",[28,114,115],{},"ai.knowledge.graphRetrieval"," ausgeliefert.)",[118,119,121],"h2",{"id":120},"isolation-durch-ein-deployment","Isolation durch ein Deployment",[16,123,124,125,128,129,132,133,136,137,139,140,142],{},"Owlat betreibt ",[45,126,127],{},"eine Organisation pro Deployment"," (siehe die Laufzeitinvariante in ",[28,130,131],{},"apps\u002Fapi\u002Fconvex\u002Flib\u002FsessionOrganization.ts","). Deshalb geschieht die Wissensisolation an der Deployment-Grenze und nicht durch Filterung je Abfrage: Es gibt kein Feld ",[28,134,135],{},"organizationId"," auf ",[28,138,30],{}," oder ",[28,141,34],{},", und keine Abfrage grenzt nach Organisation ein. Jeder Eintrag in einem Deployment gehört zu der einen Organisation dieses Deployments.",[118,144,146],{"id":145},"speichermodell","Speichermodell",[16,148,149],{},"Der Wissensgraph baut auf Convex-Tabellen auf — nicht auf einer separaten Graphdatenbank. Das Schema reserviert einen Convex-Vektorindex für die semantische Suche, und indizierte Joins übernehmen das Traversieren von Beziehungen. Das hält den selbst gehosteten Stack einfach: kein Neo4j, kein Pinecone, keine zusätzlichen Dienste.",[151,152,154],"h3",{"id":153},"wissenseinträge","Wissenseinträge",[16,156,157],{},"Jedes Stück Organisationswissen ist ein typisierter Eintrag:",[159,160,161,177],"table",{},[162,163,164],"thead",{},[165,166,167,171,174],"tr",{},[168,169,170],"th",{},"Typ",[168,172,173],{},"Beschreibung",[168,175,176],{},"Beispiel",[178,179,180,194,207,220,233,246,259],"tbody",{},[165,181,182,188,191],{},[183,184,185],"td",{},[45,186,187],{},"Fakt",[183,189,190],{},"Überprüfbare Information über eine Entität",[183,192,193],{},"„Acme Corp nutzt unseren Enterprise-Tarif“",[165,195,196,201,204],{},[183,197,198],{},[45,199,200],{},"Entscheidung",[183,202,203],{},"Eine getroffene Wahl samt Begründung",[183,205,206],{},"„Beschlossen, Acmes Testphase um 2 Wochen zu verlängern (genehmigt von Sarah)“",[165,208,209,214,217],{},[183,210,211],{},[45,212,213],{},"Ereignis",[183,215,216],{},"Etwas, das zu einem bestimmten Zeitpunkt geschehen ist",[183,218,219],{},"„Acmes CTO am 5. März auf der SaaStr-Konferenz getroffen“",[165,221,222,227,230],{},[183,223,224],{},[45,225,226],{},"Präferenz",[183,228,229],{},"Wie jemand die Dinge gern gehandhabt hat",[183,231,232],{},"„Acme bevorzugt für Support E-Mail statt Telefon“",[165,234,235,240,243],{},[183,236,237],{},[45,238,239],{},"Ziel",[183,241,242],{},"Ein Vorhaben, auf das jemand hinarbeitet",[183,244,245],{},"„Acme will sein E-Mail-Programm bis September starten“",[165,247,248,253,256],{},[183,249,250],{},[45,251,252],{},"Beziehung",[183,254,255],{},"Eine Verbindung zwischen Entitäten",[183,257,258],{},"„Alice bei Acme berichtet an Bob“",[165,260,261,266,269],{},[183,262,263],{},[45,264,265],{},"Aufgabe",[183,267,268],{},"Eine in einer Konversation identifizierte Zusage oder Aufgabe",[183,270,271],{},"„Acme bis Freitag das aktualisierte Angebot schicken“",[16,273,274],{},"Jeder Eintrag hat:",[276,277,278,293,315,328,346,355],"ul",{},[279,280,281,284,285,288,289,292],"li",{},[45,282,283],{},"Inhalt"," — das Wissen selbst (",[28,286,287],{},"title"," + ausführlicher ",[28,290,291],{},"content",")",[279,294,295,298,299,302,303,302,306,302,309,302,312,292],{},[45,296,297],{},"Quellenangabe"," — woher dieses Wissen stammt (",[28,300,301],{},"email",", ",[28,304,305],{},"chat",[28,307,308],{},"manual",[28,310,311],{},"file",[28,313,314],{},"agent_extracted",[279,316,317,320,321,324,325,292],{},[45,318,319],{},"Entitätsverknüpfungen"," — optionale Verbindungen zu Kontakten (",[28,322,323],{},"contactIds",") und zu einem Konversations-Thread (",[28,326,327],{},"threadId",[279,329,330,333,334,337,338,341,342,345],{},[45,331,332],{},"Embedding"," — ein Vektor mit ",[28,335,336],{},"1536"," Dimensionen plus das ",[28,339,340],{},"embeddingModel"," und der Zeitpunkt ",[28,343,344],{},"embeddingGeneratedAt",", die ihn erzeugt haben, damit veraltete Embeddings neu erzeugt werden können",[279,347,348,351,352],{},[45,349,350],{},"Konfidenzwert"," — wie verlässlich dieses Wissen ist (0–1), mit einem Zeitstempel ",[28,353,354],{},"lastValidatedAt",[279,356,357,360,361,364],{},[45,358,359],{},"Ablauf"," — optionale ",[28,362,363],{},"expiresAt","-TTL für zeitkritische Fakten",[151,366,368],{"id":367},"wissensrelationen","Wissensrelationen",[16,370,371],{},"Einträge sind über typisierte Kanten miteinander verbunden:",[159,373,374,384],{},[162,375,376],{},[165,377,378,381],{},[168,379,380],{},"Relation",[168,382,383],{},"Bedeutung",[178,385,386,395,404,413,422,432],{},[165,387,388,392],{},[183,389,390],{},[28,391,82],{},[183,393,394],{},"Ein Eintrag liefert Belege für einen anderen",[165,396,397,401],{},[183,398,399],{},[28,400,85],{},[183,402,403],{},"Ein Eintrag widerspricht einem anderen",[165,405,406,410],{},[183,407,408],{},[28,409,88],{},[183,411,412],{},"Ein Eintrag ersetzt einen anderen (neuere Information)",[165,414,415,419],{},[183,416,417],{},[28,418,92],{},[183,420,421],{},"Allgemeiner Bezug",[165,423,424,429],{},[183,425,426],{},[28,427,428],{},"causes",[183,430,431],{},"Kausale Beziehung",[165,433,434,439],{},[183,435,436],{},[28,437,438],{},"blocks",[183,440,441],{},"Ein Eintrag blockiert einen anderen",[16,443,444,445,448,449,452,453,31,456,459,460,463,464,467,468,470,471,476],{},"Relationen werden heute gespeichert (",[28,446,447],{},"createRelation"," in ",[28,450,451],{},"graph.ts",", indiziert über ",[28,454,455],{},"by_from",[28,457,458],{},"by_to","), und ",[28,461,462],{},"getEntry"," liefert einen Eintrag samt seiner ein- und ausgehenden Relationen zurück. Auch das ",[45,465,466],{},"Traversieren"," von Relationen wird inzwischen ausgeliefert: Hinter ",[28,469,115],{}," läuft der Abruf über diese Kanten, um stützenden Kontext zu finden und Widersprüche zu markieren — siehe ",[472,473,475],"a",{"href":474},"#graph-augmented-retrieval-seed-then-expand-shipping","Graphgestützter Abruf"," weiter unten.",[118,478,480],{"id":479},"extraktion","Extraktion",[20,482,485,524,554],{"title":483,"type":484},"Aktiv in der Agenten-Strecke","success",[16,486,487,488,491,492,495,496,499,500,503,504,507,508,511,512,515,516,519,520,523],{},"Die Extraktion läuft nun ",[45,489,490],{},"je Nachricht, sobald sie eintrifft",". Ist die Klassifizierung abgeschlossen, gibt der Verarbeitungslebenszyklus (",[28,493,494],{},"apps\u002Fapi\u002Fconvex\u002Finbox\u002FprocessingLifecycle.ts",") einen Effekt ",[28,497,498],{},"schedule_knowledge_extraction"," aus, der ",[28,501,502],{},"internal.knowledge.extraction.extractFromMessage"," einplant — sowohl auf der normalen Kante ",[28,505,506],{},"classifying → drafting"," als auch auf der den Entwurf überspringenden Kante ",[28,509,510],{},"classifying → draft_ready"," (Beschwerden \u002F dringende Nachrichten), sodass er ",[45,513,514],{},"exakt einmal pro Nachricht"," feuert. Das umfasst eingehende ",[45,517,518],{},"E-Mail"," und eingehende ",[45,521,522],{},"Kanal","-Nachrichten (SMS \u002F WhatsApp \u002F generisch), die durch die Agenten-Strecke laufen.",[16,525,526,527,530,531,534,535,538,539,542,543,546,547,550,551,553],{},"Der Lauf ist ",[45,528,529],{},"idempotent",": ",[28,532,533],{},"extractFromMessage"," kehrt frühzeitig zurück, wenn ",[28,536,537],{},"countBySource"," bereits Einträge für die Quelle ",[28,540,541],{},"(agent_extracted, inboundMessageId)"," findet, und ",[28,544,545],{},"saveEntry"," dedupliziert einen zweiten Schreiber über die exakte Kombination ",[28,548,549],{},"source + title"," unter Convex-OCC (",[28,552,38],{},"). Ein erneuter Lauf (etwa ein Cron-Retry) erzeugt keine Dubletten.",[16,555,556,557,52,560,562,563,566,567,448,570,573,574,577,578,581,582,585],{},"Der einmalige ",[45,558,559],{},"Backfill-Job",[28,561,66],{},") durchläuft beim erstmaligen Umschalten des Feature-Flags ",[28,564,565],{},"ai.agent"," von false auf true (",[28,568,569],{},"setFeatureFlag",[28,571,572],{},"apps\u002Fapi\u002Fconvex\u002Forganizations\u002FfeatureFlags.ts",") weiterhin die bestehenden ",[28,575,576],{},"inboundMessages"," des Deployments, damit der Entwurfsschritt von Tag eins an historischen Kontext hat. Interner Chat zwischen MEMBERn (",[28,579,580],{},"unifiedMessages.sendChatMessage",") löst ",[45,583,584],{},"keine"," Extraktion aus — das tun nur Nachrichten der Eingangsstrecke.",[16,587,588,589,448,591,594,595,598],{},"Der Extraktor (",[28,590,533],{},[28,592,593],{},"apps\u002Fapi\u002Fconvex\u002Fknowledge\u002Fextraction.ts",") ist eine Node-",[28,596,597],{},"internalAction",", die drei Dinge tut:",[600,601,606],"pre",{"className":602,"code":604,"language":605},[603],"language-text","extractFromMessage(inboundMessageId)\n  0. Idempotency guard: countBySource → early-return if already extracted\n  1. LLM extraction: single structured-output call producing entries[]\n  2. Embed each entry (text-embedding-3-small)\n  3. saveEntry → insert into knowledgeEntries (dedup by source + title)\n","text",[28,607,604],{"__ignoreMap":608},"",[16,610,611,612,615,616,620,621,623,624,626,627,108,629,632,633,636,637,31,639,31,641,643],{},"Ein Gegenstück ",[28,613,614],{},"extractFromFile"," spiegelt dies für verarbeitete Dokumente (siehe die Vision ",[472,617,619],{"href":618},"\u002Fvision\u002Ffile-system","Dateisystem","). Ein deterministischer struktureller ",[28,622,92],{},"-Verknüpfer läuft nach dem Speichern (eingeplant vom Extraktor); ",[28,625,545],{}," dedupliziert über ",[28,628,549],{},[45,630,631],{},"und"," über den quellenübergreifenden ",[28,634,635],{},"contentHash"," (bei übereinstimmendem Kontakt-Geltungsbereich). Die vor dem Speichern inline erfolgende Widerspruchsprüfung und das Erschließen von ",[28,638,82],{},[28,640,85],{},[28,642,88],{}," bleiben Teil der Vision.",[151,645,647],{"id":646},"llm-extraktion","LLM-Extraktion",[16,649,650,651,654,655,658],{},"Die Extraktion nutzt einen einzigen Aufruf mit strukturierter Ausgabe gegen die Modellrolle ",[28,652,653],{},"extract"," und erzeugt ein flaches Array ",[28,656,657],{},"entries[]",":",[600,660,664],{"className":661,"code":662,"language":663,"meta":608,"style":608},"language-typescript shiki shiki-themes github-light github-dark-dimmed","const extractionSchema = z.object({\n  entries: z.array(z.object({\n    type: z.enum(['fact', 'decision', 'event', 'preference', 'goal', 'relationship', 'action_item']),\n    title: z.string(),\n    content: z.string(),\n    confidence: z.number().min(0).max(1),\n    tags: z.array(z.string()).optional(),\n  })),\n})\n\nconst { object: extraction } = await runLlmObject({\n  model: getLLMProvider('extract'),\n  schema: extractionSchema,\n  prompt: `Extract organizational knowledge from this email message...`,\n  temperature: 0.1,\n})\n","typescript",[28,665,666,693,709,758,770,780,815,835,841,847,854,884,900,906,918,929],{"__ignoreMap":608},[667,668,671,675,679,682,686,690],"span",{"class":669,"line":670},"line",1,[667,672,674],{"class":673},"s7YZ4","const",[667,676,678],{"class":677},"sviXB"," extractionSchema",[667,680,681],{"class":673}," =",[667,683,685],{"class":684},"sYgZi"," z.",[667,687,689],{"class":688},"sPO5f","object",[667,691,692],{"class":684},"({\n",[667,694,696,699,702,705,707],{"class":669,"line":695},2,[667,697,698],{"class":684},"  entries: z.",[667,700,701],{"class":688},"array",[667,703,704],{"class":684},"(z.",[667,706,689],{"class":688},[667,708,692],{"class":684},[667,710,712,715,718,721,725,727,730,732,735,737,740,742,745,747,750,752,755],{"class":669,"line":711},3,[667,713,714],{"class":684},"    type: z.",[667,716,717],{"class":688},"enum",[667,719,720],{"class":684},"([",[667,722,724],{"class":723},"s-HuK","'fact'",[667,726,302],{"class":684},[667,728,729],{"class":723},"'decision'",[667,731,302],{"class":684},[667,733,734],{"class":723},"'event'",[667,736,302],{"class":684},[667,738,739],{"class":723},"'preference'",[667,741,302],{"class":684},[667,743,744],{"class":723},"'goal'",[667,746,302],{"class":684},[667,748,749],{"class":723},"'relationship'",[667,751,302],{"class":684},[667,753,754],{"class":723},"'action_item'",[667,756,757],{"class":684},"]),\n",[667,759,761,764,767],{"class":669,"line":760},4,[667,762,763],{"class":684},"    title: z.",[667,765,766],{"class":688},"string",[667,768,769],{"class":684},"(),\n",[667,771,773,776,778],{"class":669,"line":772},5,[667,774,775],{"class":684},"    content: z.",[667,777,766],{"class":688},[667,779,769],{"class":684},[667,781,783,786,789,792,795,798,801,804,807,809,812],{"class":669,"line":782},6,[667,784,785],{"class":684},"    confidence: z.",[667,787,788],{"class":688},"number",[667,790,791],{"class":684},"().",[667,793,794],{"class":688},"min",[667,796,797],{"class":684},"(",[667,799,800],{"class":677},"0",[667,802,803],{"class":684},").",[667,805,806],{"class":688},"max",[667,808,797],{"class":684},[667,810,811],{"class":677},"1",[667,813,814],{"class":684},"),\n",[667,816,818,821,823,825,827,830,833],{"class":669,"line":817},7,[667,819,820],{"class":684},"    tags: z.",[667,822,701],{"class":688},[667,824,704],{"class":684},[667,826,766],{"class":688},[667,828,829],{"class":684},"()).",[667,831,832],{"class":688},"optional",[667,834,769],{"class":684},[667,836,838],{"class":669,"line":837},8,[667,839,840],{"class":684},"  })),\n",[667,842,844],{"class":669,"line":843},9,[667,845,846],{"class":684},"})\n",[667,848,850],{"class":669,"line":849},10,[667,851,853],{"emptyLinePlaceholder":852},true,"\n",[667,855,857,859,862,865,867,870,873,876,879,882],{"class":669,"line":856},11,[667,858,674],{"class":673},[667,860,861],{"class":684}," { ",[667,863,689],{"class":864},"stnAF",[667,866,530],{"class":684},[667,868,869],{"class":677},"extraction",[667,871,872],{"class":684}," } ",[667,874,875],{"class":673},"=",[667,877,878],{"class":673}," await",[667,880,881],{"class":688}," runLlmObject",[667,883,692],{"class":684},[667,885,887,890,893,895,898],{"class":669,"line":886},12,[667,888,889],{"class":684},"  model: ",[667,891,892],{"class":688},"getLLMProvider",[667,894,797],{"class":684},[667,896,897],{"class":723},"'extract'",[667,899,814],{"class":684},[667,901,903],{"class":669,"line":902},13,[667,904,905],{"class":684},"  schema: extractionSchema,\n",[667,907,909,912,915],{"class":669,"line":908},14,[667,910,911],{"class":684},"  prompt: ",[667,913,914],{"class":723},"`Extract organizational knowledge from this email message...`",[667,916,917],{"class":684},",\n",[667,919,921,924,927],{"class":669,"line":920},15,[667,922,923],{"class":684},"  temperature: ",[667,925,926],{"class":677},"0.1",[667,928,917],{"class":684},[667,930,932],{"class":669,"line":931},16,[667,933,846],{"class":684},[16,935,936,937,940,941,944,945,948,949,952,953,955,956,959],{},"Jeder extrahierte Eintrag wird eingebettet und über ",[28,938,939],{},"internal.knowledge.graph.saveEntry"," gespeichert, mit ",[28,942,943],{},"sourceType: 'agent_extracted'"," und einer ",[28,946,947],{},"sourceId",", die auf die ursprüngliche ",[28,950,951],{},"inboundMessageId"," gesetzt ist (was sowohl der aktive Extraktor als auch der Backfill-Job über ",[28,954,537],{}," und den Index ",[28,957,958],{},"by_source"," für die Idempotenz nutzen).",[20,961,963,977],{"title":962,"type":23},"Geplant: Dedup während der Extraktion, Widerspruchsprüfung, Anlegen von Relationen",[16,964,965,966,969,970,31,972,31,974,976],{},"Eine künftige Fassung des Extraktors würde ",[45,967,968],{},"vor dem Speichern"," eine Vektorsuche nach nahezu identischen Einträgen ausführen (inline zusammenführen \u002F verknüpfen \u002F ersetzen), auf Widersprüche prüfen und die oben beschriebenen Relationen ",[28,971,82],{},[28,973,85],{},[28,975,88],{}," anlegen. Die inline vor dem Speichern arbeitende Variante ist weiterhin nur geplant.",[16,978,979,980,983,984,987,988,987,991,52,994,996,997,52,1000,1003,1004,52,1007,1010,1011,1013,1014,31,1016,31,1018,1020,1021,1023],{},"Das nachgelagerte ",[45,981,982],{},"Zusammenführen naher Dubletten wird allerdings heute ausgeliefert",", und zwar als separater täglicher Wartungs-Cron: ",[28,985,986],{},"runKnowledgeDedup"," → ",[28,989,990],{},"dedupeContactEntries",[28,992,993],{},"mergeEntryInto",[28,995,42],{},"), angetrieben vom Cron ",[28,998,999],{},"knowledge graph dedup",[28,1001,1002],{},"apps\u002Fapi\u002Fconvex\u002Fcrons.ts","). Er clustert die Einträge eines Kontakts nach Kosinusähnlichkeit mit dem Schwellwert ",[28,1005,1006],{},"0.95",[28,1008,1009],{},"apps\u002Fapi\u002Fconvex\u002Flib\u002FknowledgeDedup.ts","), faltet dann die Inhalte zusammen, vereinigt ",[28,1012,323],{}," + Tags, richtet die Junction-Tabelle und die Relationen auf den Überlebenden um und löscht den Unterlegenen. Die Widerspruchsprüfung und der LLM-gestützte Durchlauf für die Kanten ",[28,1015,82],{},[28,1017,85],{},[28,1019,88],{}," bleiben unimplementiert — der deterministische Schritt zum Anlegen der ",[28,1022,92],{},"-Relation wird heute ausgeliefert.",[118,1025,1027],{"id":1026},"abruf","Abruf",[16,1029,1030],{},"Der Wissensgraph bedient heute sowohl den produktinternen Browser als auch den aktiven Abruf durch den Agenten.",[151,1032,1034],{"id":1033},"volltextsuche-ausgeliefert","Volltextsuche (ausgeliefert)",[16,1036,1037,1038,1041,1042,1045],{},"Genutzt vom produktinternen Browser. Die öffentliche ",[28,1039,1040],{},"search","-Query führt eine Convex-Volltextsuche über ",[28,1043,1044],{},"searchableText"," aus, optional gefiltert nach Eintragstyp:",[600,1047,1049],{"className":661,"code":1048,"language":663,"meta":608,"style":608},"ctx.db\n  .query('knowledgeEntries')\n  .withSearchIndex('search_knowledge', (q) => {\n    let sq = q.search('searchableText', args.searchQuery)\n    if (args.entryType) sq = sq.eq('entryType', args.entryType)\n    return sq\n  })\n  .take(limit)\n",[28,1050,1051,1056,1072,1099,1122,1146,1154,1159],{"__ignoreMap":608},[667,1052,1053],{"class":669,"line":670},[667,1054,1055],{"class":684},"ctx.db\n",[667,1057,1058,1061,1064,1066,1069],{"class":669,"line":695},[667,1059,1060],{"class":684},"  .",[667,1062,1063],{"class":688},"query",[667,1065,797],{"class":684},[667,1067,1068],{"class":723},"'knowledgeEntries'",[667,1070,1071],{"class":684},")\n",[667,1073,1074,1076,1079,1081,1084,1087,1090,1093,1096],{"class":669,"line":711},[667,1075,1060],{"class":684},[667,1077,1078],{"class":688},"withSearchIndex",[667,1080,797],{"class":684},[667,1082,1083],{"class":723},"'search_knowledge'",[667,1085,1086],{"class":684},", (",[667,1088,1089],{"class":864},"q",[667,1091,1092],{"class":684},") ",[667,1094,1095],{"class":673},"=>",[667,1097,1098],{"class":684}," {\n",[667,1100,1101,1104,1107,1109,1112,1114,1116,1119],{"class":669,"line":760},[667,1102,1103],{"class":673},"    let",[667,1105,1106],{"class":684}," sq ",[667,1108,875],{"class":673},[667,1110,1111],{"class":684}," q.",[667,1113,1040],{"class":688},[667,1115,797],{"class":684},[667,1117,1118],{"class":723},"'searchableText'",[667,1120,1121],{"class":684},", args.searchQuery)\n",[667,1123,1124,1127,1130,1132,1135,1138,1140,1143],{"class":669,"line":772},[667,1125,1126],{"class":673},"    if",[667,1128,1129],{"class":684}," (args.entryType) sq ",[667,1131,875],{"class":673},[667,1133,1134],{"class":684}," sq.",[667,1136,1137],{"class":688},"eq",[667,1139,797],{"class":684},[667,1141,1142],{"class":723},"'entryType'",[667,1144,1145],{"class":684},", args.entryType)\n",[667,1147,1148,1151],{"class":669,"line":782},[667,1149,1150],{"class":673},"    return",[667,1152,1153],{"class":684}," sq\n",[667,1155,1156],{"class":669,"line":817},[667,1157,1158],{"class":684},"  })\n",[667,1160,1161,1163,1166],{"class":669,"line":837},[667,1162,1060],{"class":684},[667,1164,1165],{"class":688},"take",[667,1167,1168],{"class":684},"(limit)\n",[16,1170,1171,1172,1175,1176,1179,1180,1183,1184,803],{},"Der Pfad zum Durchstöbern nach Typ (",[28,1173,1174],{},"listByType",") liest über den Index ",[28,1177,1178],{},"by_entry_type",". Beide liegen dem Composable ",[28,1181,1182],{},"useKnowledgeGraph"," zugrunde (",[28,1185,1186],{},"apps\u002Fweb\u002Fapp\u002Fcomposables\u002FuseKnowledgeGraph.ts",[151,1188,1190],{"id":1189},"kontaktbezogener-abruf-ausgeliefert","Kontaktbezogener Abruf (ausgeliefert)",[16,1192,1193,1194,1197,1198,52,1201,1204,1205,1208,1209,1212,1213,1216,1217,1220],{},"Convex kann Array-Felder nicht direkt indizieren, deshalb wird ",[28,1195,1196],{},"knowledgeEntries.contactIds"," in eine eigene Junction-Tabelle gespiegelt — ",[28,1199,1200],{},"knowledgeEntryContacts",[28,1202,1203],{},"apps\u002Fapi\u002Fconvex\u002Fschema\u002Fknowledge.ts","), eine Zeile pro Paar ",[28,1206,1207],{},"(entryId, contactId)"," mit einem Index ",[28,1210,1211],{},"by_contact",". ",[28,1214,1215],{},"getByContact"," fragt diesen Index ab und hydratisiert die passenden Einträge, sodass die Suche ",[45,1218,1219],{},"vollständig und O(Treffer)"," ist — keine Kürzung, kein Scan im Arbeitsspeicher:",[600,1222,1224],{"className":661,"code":1223,"language":663,"meta":608,"style":608},"const links = await ctx.db\n  .query('knowledgeEntryContacts')\n  .withIndex('by_contact', (q) => q.eq('contactId', args.contactId))\n  .collect()\n\nconst entryMap = await batchGet(ctx, links.map((link) => link.entryId))\n\nreturn [...entryMap.values()]\n  .filter((e) => e !== null && !(e.expiresAt !== undefined && e.expiresAt \u003C now))\n  .sort((a, b) => b.createdAt - a.createdAt)\n  .slice(0, args.limit ?? 20)\n",[28,1225,1226,1240,1253,1285,1295,1299,1332,1336,1356,1406,1435],{"__ignoreMap":608},[667,1227,1228,1230,1233,1235,1237],{"class":669,"line":670},[667,1229,674],{"class":673},[667,1231,1232],{"class":677}," links",[667,1234,681],{"class":673},[667,1236,878],{"class":673},[667,1238,1239],{"class":684}," ctx.db\n",[667,1241,1242,1244,1246,1248,1251],{"class":669,"line":695},[667,1243,1060],{"class":684},[667,1245,1063],{"class":688},[667,1247,797],{"class":684},[667,1249,1250],{"class":723},"'knowledgeEntryContacts'",[667,1252,1071],{"class":684},[667,1254,1255,1257,1260,1262,1265,1267,1269,1271,1273,1275,1277,1279,1282],{"class":669,"line":711},[667,1256,1060],{"class":684},[667,1258,1259],{"class":688},"withIndex",[667,1261,797],{"class":684},[667,1263,1264],{"class":723},"'by_contact'",[667,1266,1086],{"class":684},[667,1268,1089],{"class":864},[667,1270,1092],{"class":684},[667,1272,1095],{"class":673},[667,1274,1111],{"class":684},[667,1276,1137],{"class":688},[667,1278,797],{"class":684},[667,1280,1281],{"class":723},"'contactId'",[667,1283,1284],{"class":684},", args.contactId))\n",[667,1286,1287,1289,1292],{"class":669,"line":760},[667,1288,1060],{"class":684},[667,1290,1291],{"class":688},"collect",[667,1293,1294],{"class":684},"()\n",[667,1296,1297],{"class":669,"line":772},[667,1298,853],{"emptyLinePlaceholder":852},[667,1300,1301,1303,1306,1308,1310,1313,1316,1319,1322,1325,1327,1329],{"class":669,"line":782},[667,1302,674],{"class":673},[667,1304,1305],{"class":677}," entryMap",[667,1307,681],{"class":673},[667,1309,878],{"class":673},[667,1311,1312],{"class":688}," batchGet",[667,1314,1315],{"class":684},"(ctx, links.",[667,1317,1318],{"class":688},"map",[667,1320,1321],{"class":684},"((",[667,1323,1324],{"class":864},"link",[667,1326,1092],{"class":684},[667,1328,1095],{"class":673},[667,1330,1331],{"class":684}," link.entryId))\n",[667,1333,1334],{"class":669,"line":817},[667,1335,853],{"emptyLinePlaceholder":852},[667,1337,1338,1341,1344,1347,1350,1353],{"class":669,"line":837},[667,1339,1340],{"class":673},"return",[667,1342,1343],{"class":684}," [",[667,1345,1346],{"class":673},"...",[667,1348,1349],{"class":684},"entryMap.",[667,1351,1352],{"class":688},"values",[667,1354,1355],{"class":684},"()]\n",[667,1357,1358,1360,1363,1365,1368,1370,1372,1375,1378,1381,1384,1387,1390,1392,1395,1397,1400,1403],{"class":669,"line":843},[667,1359,1060],{"class":684},[667,1361,1362],{"class":688},"filter",[667,1364,1321],{"class":684},[667,1366,1367],{"class":864},"e",[667,1369,1092],{"class":684},[667,1371,1095],{"class":673},[667,1373,1374],{"class":684}," e ",[667,1376,1377],{"class":673},"!==",[667,1379,1380],{"class":677}," null",[667,1382,1383],{"class":673}," &&",[667,1385,1386],{"class":673}," !",[667,1388,1389],{"class":684},"(e.expiresAt ",[667,1391,1377],{"class":673},[667,1393,1394],{"class":677}," undefined",[667,1396,1383],{"class":673},[667,1398,1399],{"class":684}," e.expiresAt ",[667,1401,1402],{"class":673},"\u003C",[667,1404,1405],{"class":684}," now))\n",[667,1407,1408,1410,1413,1415,1417,1419,1422,1424,1426,1429,1432],{"class":669,"line":849},[667,1409,1060],{"class":684},[667,1411,1412],{"class":688},"sort",[667,1414,1321],{"class":684},[667,1416,472],{"class":864},[667,1418,302],{"class":684},[667,1420,1421],{"class":864},"b",[667,1423,1092],{"class":684},[667,1425,1095],{"class":673},[667,1427,1428],{"class":684}," b.createdAt ",[667,1430,1431],{"class":673},"-",[667,1433,1434],{"class":684}," a.createdAt)\n",[667,1436,1437,1439,1442,1444,1446,1449,1452,1455],{"class":669,"line":856},[667,1438,1060],{"class":684},[667,1440,1441],{"class":688},"slice",[667,1443,797],{"class":684},[667,1445,800],{"class":677},[667,1447,1448],{"class":684},", args.limit ",[667,1450,1451],{"class":673},"??",[667,1453,1454],{"class":677}," 20",[667,1456,1071],{"class":684},[20,1458,1460],{"title":1459,"type":23},"Die Junction-Tabelle bleibt synchron",[16,1461,1462,1463,1465,1466,1468,1469,1472],{},"Die Junction-Zeilen werden von denselben ",[28,1464,545],{},"-\u002FUpdate-Mutationen geschrieben und aufgeräumt, die ",[28,1467,323],{}," setzen oder leeren, beim Zusammenführen von Kontakten umgerichtet (",[28,1470,1471],{},"lib\u002FcontactMutations.ts",") und beim Ablauf \u002F Löschen \u002F Organisations-Wipe zusammen mit dem übergeordneten Eintrag abgeräumt — sie enthält also nie verwaiste Zeilen. Das hat den früheren, auf 500 Zeilen begrenzten Filter im Arbeitsspeicher abgelöst.",[151,1474,1476],{"id":1475},"semantische-suche-ausgeliefert","Semantische Suche (ausgeliefert)",[16,1478,1479,52,1482,1484,1485,1487,1488,1491,1492,1494,1495,1498,1499,1502,1503,1506,1507,1510,1511,1514,1515,302,1518,139,1521,1524,1525,1528,1529,1532,1533,1536,1537,1540,1541,1544,1545,658],{},[28,1480,1481],{},"semanticSearch",[28,1483,55],{},") ist inzwischen eine echte ",[28,1486,597],{}," — die Vektorsuche lebt am Action-Kontext (",[28,1489,1490],{},"ctx.vectorSearch","), weshalb die Naht aus ",[28,1493,451],{}," in ein eigenes Abrufmodul gewandert ist. Sie akzeptiert entweder einen ",[28,1496,1497],{},"queryText"," (hier mit ",[28,1500,1501],{},"text-embedding-3-small"," eingebettet) oder ein vorberechnetes ",[28,1504,1505],{},"embedding",", dazu ein ",[45,1508,1509],{},"erforderliches"," Argument ",[28,1512,1513],{},"scopeToContact"," (eine ",[28,1516,1517],{},"contactId",[28,1519,1520],{},"'org-general-only'",[28,1522,1523],{},"'org-wide'",") für die Nachfilterung zur Kontaktisolation. Statt eines einzelnen Vektordurchlaufs ist sie ",[45,1526,1527],{},"hybrid",": Sie führt zwei Beine aus — eine Vektorsuche über den Index ",[28,1530,1531],{},"vector_knowledge"," und eine Volltextsuche (",[28,1534,1535],{},"internal.knowledge.graph.ftsRankedIds",") — und verschmilzt deren Ranglisten mittels ",[45,1538,1539],{},"Reciprocal Rank Fusion"," (degradiert zu reiner Vektorsuche, wenn kein Abfragetext vorliegt). Anschließend hydratisiert sie die verschmolzene Reihenfolge über ",[28,1542,1543],{},"internal.knowledge.graph.getByIds"," zu vollständigen Dokumenten, filtert nach dem Kontakt-Geltungsbereich und versieht jeden Überlebenden mit seinem Ähnlichkeitswert ",[28,1546,1547],{},"_score",[600,1549,1551],{"className":661,"code":1550,"language":663,"meta":608,"style":608},"\u002F\u002F Leg 1 — semantic vector search\nconst hits = await ctx.vectorSearch('knowledgeEntries', 'vector_knowledge', {\n  vector,\n  limit: fetchLimit,\n  filter: args.entryType ? (q) => q.eq('entryType', args.entryType) : undefined,\n})\nconst vectorRanked = hits.map((h) => h._id)\n\n\u002F\u002F Leg 2 — full-text search (only when we have query text)\nlet ftsRanked = []\nif (queryText) {\n  ftsRanked = await ctx.runQuery(internal.knowledge.graph.ftsRankedIds, {\n    queryText,\n    entryType: args.entryType,\n    limit: fetchLimit,\n  })\n}\n\n\u002F\u002F Fuse the two rankings (vector-only when FTS is empty), then hydrate\nconst fusedIds = reciprocalRankFusion([vectorRanked, ftsRanked])\nconst entries = await ctx.runQuery(internal.knowledge.graph.getByIds, {\n  ids: fusedIds,\n})\n",[28,1552,1553,1559,1588,1593,1598,1631,1635,1661,1665,1670,1683,1691,1708,1713,1718,1723,1727,1733,1738,1744,1760,1779,1785],{"__ignoreMap":608},[667,1554,1555],{"class":669,"line":670},[667,1556,1558],{"class":1557},"sDN9O","\u002F\u002F Leg 1 — semantic vector search\n",[667,1560,1561,1563,1566,1568,1570,1573,1576,1578,1580,1582,1585],{"class":669,"line":695},[667,1562,674],{"class":673},[667,1564,1565],{"class":677}," hits",[667,1567,681],{"class":673},[667,1569,878],{"class":673},[667,1571,1572],{"class":684}," ctx.",[667,1574,1575],{"class":688},"vectorSearch",[667,1577,797],{"class":684},[667,1579,1068],{"class":723},[667,1581,302],{"class":684},[667,1583,1584],{"class":723},"'vector_knowledge'",[667,1586,1587],{"class":684},", {\n",[667,1589,1590],{"class":669,"line":711},[667,1591,1592],{"class":684},"  vector,\n",[667,1594,1595],{"class":669,"line":760},[667,1596,1597],{"class":684},"  limit: fetchLimit,\n",[667,1599,1600,1603,1606,1608,1610,1612,1614,1616,1618,1620,1622,1625,1627,1629],{"class":669,"line":772},[667,1601,1602],{"class":684},"  filter: args.entryType ",[667,1604,1605],{"class":673},"?",[667,1607,52],{"class":684},[667,1609,1089],{"class":864},[667,1611,1092],{"class":684},[667,1613,1095],{"class":673},[667,1615,1111],{"class":684},[667,1617,1137],{"class":688},[667,1619,797],{"class":684},[667,1621,1142],{"class":723},[667,1623,1624],{"class":684},", args.entryType) ",[667,1626,658],{"class":673},[667,1628,1394],{"class":677},[667,1630,917],{"class":684},[667,1632,1633],{"class":669,"line":782},[667,1634,846],{"class":684},[667,1636,1637,1639,1642,1644,1647,1649,1651,1654,1656,1658],{"class":669,"line":817},[667,1638,674],{"class":673},[667,1640,1641],{"class":677}," vectorRanked",[667,1643,681],{"class":673},[667,1645,1646],{"class":684}," hits.",[667,1648,1318],{"class":688},[667,1650,1321],{"class":684},[667,1652,1653],{"class":864},"h",[667,1655,1092],{"class":684},[667,1657,1095],{"class":673},[667,1659,1660],{"class":684}," h._id)\n",[667,1662,1663],{"class":669,"line":837},[667,1664,853],{"emptyLinePlaceholder":852},[667,1666,1667],{"class":669,"line":843},[667,1668,1669],{"class":1557},"\u002F\u002F Leg 2 — full-text search (only when we have query text)\n",[667,1671,1672,1675,1678,1680],{"class":669,"line":849},[667,1673,1674],{"class":673},"let",[667,1676,1677],{"class":684}," ftsRanked ",[667,1679,875],{"class":673},[667,1681,1682],{"class":684}," []\n",[667,1684,1685,1688],{"class":669,"line":856},[667,1686,1687],{"class":673},"if",[667,1689,1690],{"class":684}," (queryText) {\n",[667,1692,1693,1696,1698,1700,1702,1705],{"class":669,"line":886},[667,1694,1695],{"class":684},"  ftsRanked ",[667,1697,875],{"class":673},[667,1699,878],{"class":673},[667,1701,1572],{"class":684},[667,1703,1704],{"class":688},"runQuery",[667,1706,1707],{"class":684},"(internal.knowledge.graph.ftsRankedIds, {\n",[667,1709,1710],{"class":669,"line":902},[667,1711,1712],{"class":684},"    queryText,\n",[667,1714,1715],{"class":669,"line":908},[667,1716,1717],{"class":684},"    entryType: args.entryType,\n",[667,1719,1720],{"class":669,"line":920},[667,1721,1722],{"class":684},"    limit: fetchLimit,\n",[667,1724,1725],{"class":669,"line":931},[667,1726,1158],{"class":684},[667,1728,1730],{"class":669,"line":1729},17,[667,1731,1732],{"class":684},"}\n",[667,1734,1736],{"class":669,"line":1735},18,[667,1737,853],{"emptyLinePlaceholder":852},[667,1739,1741],{"class":669,"line":1740},19,[667,1742,1743],{"class":1557},"\u002F\u002F Fuse the two rankings (vector-only when FTS is empty), then hydrate\n",[667,1745,1747,1749,1752,1754,1757],{"class":669,"line":1746},20,[667,1748,674],{"class":673},[667,1750,1751],{"class":677}," fusedIds",[667,1753,681],{"class":673},[667,1755,1756],{"class":688}," reciprocalRankFusion",[667,1758,1759],{"class":684},"([vectorRanked, ftsRanked])\n",[667,1761,1763,1765,1768,1770,1772,1774,1776],{"class":669,"line":1762},21,[667,1764,674],{"class":673},[667,1766,1767],{"class":677}," entries",[667,1769,681],{"class":673},[667,1771,878],{"class":673},[667,1773,1572],{"class":684},[667,1775,1704],{"class":688},[667,1777,1778],{"class":684},"(internal.knowledge.graph.getByIds, {\n",[667,1780,1782],{"class":669,"line":1781},22,[667,1783,1784],{"class":684},"  ids: fusedIds,\n",[667,1786,1788],{"class":669,"line":1787},23,[667,1789,846],{"class":684},[16,1791,1792,1793,1795,1796,1799,1800,1431,1802,448,1805,1807,1808,1811],{},"Der Index ",[28,1794,1531],{}," (filterField ",[28,1797,1798],{},"['entryType']",") liegt dem zugrunde. Die alte ",[28,1801,1481],{},[28,1803,1804],{},"internalQuery",[28,1806,451],{},", die jüngste Zeilen zurückgab, ist verschwunden — ",[28,1809,1810],{},"getByIds"," hat sie als Naht zur Dokumenthydratisierung abgelöst.",[151,1813,1815],{"id":1814},"graphgestützter-abruf-erst-säen-dann-ausweiten-ausgeliefert","Graphgestützter Abruf: erst säen, dann ausweiten (ausgeliefert)",[16,1817,1818,1819,1822,1823,1826,1827,1831,1832,52,1835,1838,1839,52,1842,1844,1845,136,1847,1850,1851,1854,1855,52,1858,1861,1862,1864,1865,1868,1869,1872],{},"Die obige hybride Fusion erzeugt eine ",[76,1820,1821],{},"flache"," Menge nächster Nachbarn. Übergibt die aufrufende Stelle ",[28,1824,1825],{},"expandGraph: true"," — gesetzt aus dem Feature-Flag ",[45,1828,1829],{},[28,1830,115],{}," sowohl vom Assistenz-Werkzeug ",[28,1833,1834],{},"searchKnowledge",[28,1836,1837],{},"apps\u002Fapi\u002Fconvex\u002Fassistant\u002Ftools.ts",") als auch vom Agentenschritt ",[28,1840,1841],{},"context_retrieval",[28,1843,62],{},") —, schaltet ",[28,1846,1481],{},[45,1848,1849],{},"erst säen, dann ausweiten"," um: Die obersten für den Kontakt sichtbaren Treffer werden zu ",[76,1852,1853],{},"Saatkörnern",", und ",[28,1856,1857],{},"expandNeighbors",[28,1859,1860],{},"apps\u002Fapi\u002Fconvex\u002Fknowledge\u002FgraphTraversal.ts",") läuft ein bis zwei Sprünge weit über die Kanten in ",[28,1863,34],{},", um den verbundenen Teilgraphen hereinzuholen. ",[28,1866,1867],{},"lib\u002FgraphRank.ts"," bewertet die Vereinigung anschließend neu — unter Einbezug von Kantengewicht (",[28,1870,1871],{},"RELATION_WEIGHTS","), Sprungdistanz und dem ursprünglichen Fusionswert —, bevor in Rangfolge hydratisiert wird:",[600,1874,1876],{"className":661,"code":1875,"language":663,"meta":608,"style":608},"\u002F\u002F Flat path OR graph-augmented — expandGraph is the kill switch.\nlet returned: ScoredKnowledgeEntry[];\nif (args.expandGraph && visible.length > 0) {\n  try {\n    returned = await expandAndRank(ctx, { visible, vectorRanked, ftsRanked, scope, entryType, limit, hops: args.hops, neighborBudget: args.neighborBudget });\n  } catch {\n    returned = visible.slice(0, limit); \u002F\u002F fail soft to flat\n  }\n} else {\n  returned = visible.slice(0, limit);\n}\n",[28,1877,1878,1883,1899,1924,1931,1946,1956,1976,1981,1991,2009],{"__ignoreMap":608},[667,1879,1880],{"class":669,"line":670},[667,1881,1882],{"class":1557},"\u002F\u002F Flat path OR graph-augmented — expandGraph is the kill switch.\n",[667,1884,1885,1887,1890,1892,1896],{"class":669,"line":695},[667,1886,1674],{"class":673},[667,1888,1889],{"class":684}," returned",[667,1891,658],{"class":673},[667,1893,1895],{"class":1894},"sOLd2"," ScoredKnowledgeEntry",[667,1897,1898],{"class":684},"[];\n",[667,1900,1901,1903,1906,1909,1912,1915,1918,1921],{"class":669,"line":711},[667,1902,1687],{"class":673},[667,1904,1905],{"class":684}," (args.expandGraph ",[667,1907,1908],{"class":673},"&&",[667,1910,1911],{"class":684}," visible.",[667,1913,1914],{"class":677},"length",[667,1916,1917],{"class":673}," >",[667,1919,1920],{"class":677}," 0",[667,1922,1923],{"class":684},") {\n",[667,1925,1926,1929],{"class":669,"line":760},[667,1927,1928],{"class":673},"  try",[667,1930,1098],{"class":684},[667,1932,1933,1936,1938,1940,1943],{"class":669,"line":772},[667,1934,1935],{"class":684},"    returned ",[667,1937,875],{"class":673},[667,1939,878],{"class":673},[667,1941,1942],{"class":688}," expandAndRank",[667,1944,1945],{"class":684},"(ctx, { visible, vectorRanked, ftsRanked, scope, entryType, limit, hops: args.hops, neighborBudget: args.neighborBudget });\n",[667,1947,1948,1951,1954],{"class":669,"line":782},[667,1949,1950],{"class":684},"  } ",[667,1952,1953],{"class":673},"catch",[667,1955,1098],{"class":684},[667,1957,1958,1960,1962,1964,1966,1968,1970,1973],{"class":669,"line":817},[667,1959,1935],{"class":684},[667,1961,875],{"class":673},[667,1963,1911],{"class":684},[667,1965,1441],{"class":688},[667,1967,797],{"class":684},[667,1969,800],{"class":677},[667,1971,1972],{"class":684},", limit); ",[667,1974,1975],{"class":1557},"\u002F\u002F fail soft to flat\n",[667,1977,1978],{"class":669,"line":837},[667,1979,1980],{"class":684},"  }\n",[667,1982,1983,1986,1989],{"class":669,"line":843},[667,1984,1985],{"class":684},"} ",[667,1987,1988],{"class":673},"else",[667,1990,1098],{"class":684},[667,1992,1993,1996,1998,2000,2002,2004,2006],{"class":669,"line":849},[667,1994,1995],{"class":684},"  returned ",[667,1997,875],{"class":673},[667,1999,1911],{"class":684},[667,2001,1441],{"class":688},[667,2003,797],{"class":684},[667,2005,800],{"class":677},[667,2007,2008],{"class":684},", limit);\n",[667,2010,2011],{"class":669,"line":856},[667,2012,1732],{"class":684},[16,2014,2015],{},"Jeder ausgeweitete Eintrag kann drei Annotationen tragen (auf dem flachen Pfad fehlen sie):",[276,2017,2018,2030,2041],{},[279,2019,2020,2025,2026,2029],{},[45,2021,2022],{},[28,2023,2024],{},"_via"," — die typisierten Beziehungen, die ihn innerhalb des zurückgegebenen Teilgraphen mit einem Saatkorn verbunden haben, sodass eine konsumierende Stelle darstellen kann, ",[76,2027,2028],{},"warum"," er aufgetaucht ist.",[279,2031,2032,2037,2038,2040],{},[45,2033,2034],{},[28,2035,2036],{},"_stale"," — er ist das Ziel einer ",[28,2039,88],{},"-Kante (ein neuerer Eintrag ersetzt ihn); das Agenten-Briefing stellt ihm einen Hinweis voran, damit der Entwurfsschritt ihn vorsichtig behandelt.",[279,2042,2043,2048,2049,2051],{},[45,2044,2045],{},[28,2046,2047],{},"_caveat"," — er ist Endpunkt einer ",[28,2050,85],{},"-Kante; er bleibt im Ergebnis, wird aber als umstritten markiert statt vorbehaltlos für bare Münze genommen.",[16,2053,2054,2055,2058],{},"Der gesamte Pfad ",[45,2056,2057],{},"fällt weich aus",": Jeder Traversierungsfehler fällt auf das flache sichtbare Teilstück zurück, statt den Abruf ganz fallen zu lassen, und bei ausgeschaltetem Flag nimmt der Code byte-für-byte den flachen Zweig.",[20,2060,2063],{"title":2061,"type":2062},"Kontakt-Geltungsbereichsprüfung je Sprung — die Leckstelle","warning",[16,2064,2065,2066,2069,2070,2072,2073,2075,2076,2079,2080,2083,2084,2086,2087,2090,2091,2093,2094,2097,2098,2101,2102,2105],{},"Kanten haben ",[45,2067,2068],{},"keinen eigenen Kontakt-Geltungsbereich",", und das Dedup-Zusammenführen vereinigt die ",[28,2071,323],{}," eines Knotens — eine Kante kann also einen Knoten von Kontakt A mit einem nur für Kontakt B bestimmten Knoten verbinden; ihr zu folgen wäre ein Primitiv zur Rechteausweitung. ",[28,2074,1857],{}," prüft deshalb ",[45,2077,2078],{},"jeden hydratisierten Nachbarn"," erneut mit ",[28,2081,2082],{},"isContactScopeVisible(neighbour.contactIds, scope)",", bevor er ins Ergebnis gelangen darf (nur ein ausdrücklicher Geltungsbereich ",[28,2085,1523],{}," überspringt diese Prüfung). Ein Nachbar, der durchfällt, wird ",[45,2088,2089],{},"verworfen",": keine Nachbarzeile, keine Kante zu ihm (sein Inhalt ",[76,2092,631],{}," seine Existenz bleiben verborgen), und er wird nie zur Grenze der Ausweitung — ein 2-Sprung-Lauf kann also auch ",[76,2095,2096],{},"seine"," Nachbarn nicht erreichen. ",[28,2099,2100],{},"apps\u002Fapi\u002Fscripts\u002Fcheck-graph-scope.sh"," stellt positiv sicher, dass diese Datei ",[28,2103,2104],{},"isContactScopeVisible"," aufruft.",[151,2107,2109],{"id":2108},"der-agent-liest-den-graphen","Der Agent liest den Graphen",[16,2111,2112,2113,52,2115,2117],{},"Der aktive Schritt ",[28,2114,1841],{},[28,2116,62],{},") faltet inzwischen semantisches Wissen in sein Briefing hinein. Neben dem Kontaktprofil, den jüngsten Aktivitäten, dem Thread-Verlauf und der aktuellen Nachricht baut er aus Betreff und Text der eingehenden Nachricht eine Abfrage und führt hinter dem Tokenbudget des Schritts zwei action-gestützte Abrufe aus:",[276,2119,2120,2134],{},[279,2121,2122,2125,2126,2129,2130,2133],{},[28,2123,2124],{},"internal.knowledge.retrieval.semanticSearch"," (Limit ",[28,2127,2128],{},"knowledgeEntryLimit: 10",") → ein Abschnitt ",[28,2131,2132],{},"[KNOWLEDGE]"," mit den relevantesten typisierten Einträgen, jeweils mit Typ und Konfidenz",[279,2135,2136,2125,2139,2129,2142,2145,2146,292],{},[28,2137,2138],{},"internal.semanticFileProcessing.semanticSearch",[28,2140,2141],{},"fileLimit: 3",[28,2143,2144],{},"[RELEVANT FILES]"," mit relevanten Quelldokumenten (siehe die Vision ",[472,2147,619],{"href":618},[16,2149,2150,2151,2154,2155,2159],{},"Die Budgetkonstante ",[28,2152,2153],{},"knowledgeEntryLimit"," ist inzwischen verdrahtet. Die drei Verdichtungsstufen (normal \u002F compacted \u002F emergency) begrenzen das zusammengestellte Briefing weiterhin. Wie sich der Kontextabruf in den Rest der Strecke einfügt, steht unter ",[472,2156,2158],{"href":2157},"\u002Fvision\u002Fagent-pipeline","Agenten-Strecke",".",[118,2161,2163],{"id":2162},"geplant-memory-als-werkzeuge","Geplant: Memory als Werkzeuge",[20,2165,2167],{"title":2166,"type":2062},"Vision — noch keine Implementierung",[16,2168,2169,2170,2173,2174,108,2176,2179,2180,302,2183,302,2185,302,2188,302,2191,52,2194,2197,2198,2200],{},"Die Verhaltensweisen in diesem Abschnitt beschreiben den angestrebten Endzustand. In ",[28,2171,2172],{},"apps\u002Fapi\u002Fconvex\u002Fagent\u002F"," gibt es heute ",[45,2175,584],{},[28,2177,2178],{},"tool()","-Definitionen, und die aktive Strecke hat fünf Schritte — ",[28,2181,2182],{},"security_scan",[28,2184,1841],{},[28,2186,2187],{},"classify",[28,2189,2190],{},"draft",[28,2192,2193],{},"route",[28,2195,2196],{},"apps\u002Fapi\u002Fconvex\u002Fagent\u002Fsteps\u002Findex.ts",") — ohne separaten Schritt zur Aktionsplanung. Die Schrittnummern weiter unten entsprechen der visionären Darstellung im Visionsdokument ",[472,2199,2158],{"href":2157},", nicht dem Code.",[16,2202,2203],{},"Die Extraktion (oben) ist passiv — sie läuft, nachdem eine Nachricht verarbeitet wurde. Die Vision sieht vor, dass der Agent Wissen während der Ausführung der Strecke auch aktiv speichert und abruft, indem ihm Werkzeugdefinitionen zum Aufruf bereitstehen.",[151,2205,2207],{"id":2206},"aktives-speichern","Aktives Speichern",[16,2209,2210],{},"Entdeckt der Agent während einer Konversation etwas Wichtiges — einen neuen Fakt, eine geänderte Präferenz, eine Zusage —, würde er es unmittelbar während des Schritts zur Aktionsplanung (Schritt 3) festhalten:",[600,2212,2214],{"className":661,"code":2213,"language":663,"meta":608,"style":608},"const saveKnowledge = tool({\n  description: 'Save a piece of organizational knowledge discovered during this conversation',\n  parameters: z.object({\n    type: z.enum(['fact', 'decision', 'event', 'preference', 'goal', 'relationship', 'action_item']),\n    title: z.string(),\n    content: z.string(),\n    contactId: z.string().optional(),\n    confidence: z.number().min(0).max(1),\n    expiresInDays: z.number().optional(),\n  }),\n  execute: async (args) => {\n    \u002F\u002F Would run dedup + contradiction check before storing\n    return await ctx.runMutation(internal.knowledge.graph.saveEntry, { \u002F* ... *\u002F })\n  },\n})\n",[28,2215,2216,2230,2240,2249,2285,2293,2301,2314,2338,2351,2356,2377,2382,2402,2407],{"__ignoreMap":608},[667,2217,2218,2220,2223,2225,2228],{"class":669,"line":670},[667,2219,674],{"class":673},[667,2221,2222],{"class":677}," saveKnowledge",[667,2224,681],{"class":673},[667,2226,2227],{"class":688}," tool",[667,2229,692],{"class":684},[667,2231,2232,2235,2238],{"class":669,"line":695},[667,2233,2234],{"class":684},"  description: ",[667,2236,2237],{"class":723},"'Save a piece of organizational knowledge discovered during this conversation'",[667,2239,917],{"class":684},[667,2241,2242,2245,2247],{"class":669,"line":711},[667,2243,2244],{"class":684},"  parameters: z.",[667,2246,689],{"class":688},[667,2248,692],{"class":684},[667,2250,2251,2253,2255,2257,2259,2261,2263,2265,2267,2269,2271,2273,2275,2277,2279,2281,2283],{"class":669,"line":760},[667,2252,714],{"class":684},[667,2254,717],{"class":688},[667,2256,720],{"class":684},[667,2258,724],{"class":723},[667,2260,302],{"class":684},[667,2262,729],{"class":723},[667,2264,302],{"class":684},[667,2266,734],{"class":723},[667,2268,302],{"class":684},[667,2270,739],{"class":723},[667,2272,302],{"class":684},[667,2274,744],{"class":723},[667,2276,302],{"class":684},[667,2278,749],{"class":723},[667,2280,302],{"class":684},[667,2282,754],{"class":723},[667,2284,757],{"class":684},[667,2286,2287,2289,2291],{"class":669,"line":772},[667,2288,763],{"class":684},[667,2290,766],{"class":688},[667,2292,769],{"class":684},[667,2294,2295,2297,2299],{"class":669,"line":782},[667,2296,775],{"class":684},[667,2298,766],{"class":688},[667,2300,769],{"class":684},[667,2302,2303,2306,2308,2310,2312],{"class":669,"line":817},[667,2304,2305],{"class":684},"    contactId: z.",[667,2307,766],{"class":688},[667,2309,791],{"class":684},[667,2311,832],{"class":688},[667,2313,769],{"class":684},[667,2315,2316,2318,2320,2322,2324,2326,2328,2330,2332,2334,2336],{"class":669,"line":837},[667,2317,785],{"class":684},[667,2319,788],{"class":688},[667,2321,791],{"class":684},[667,2323,794],{"class":688},[667,2325,797],{"class":684},[667,2327,800],{"class":677},[667,2329,803],{"class":684},[667,2331,806],{"class":688},[667,2333,797],{"class":684},[667,2335,811],{"class":677},[667,2337,814],{"class":684},[667,2339,2340,2343,2345,2347,2349],{"class":669,"line":843},[667,2341,2342],{"class":684},"    expiresInDays: z.",[667,2344,788],{"class":688},[667,2346,791],{"class":684},[667,2348,832],{"class":688},[667,2350,769],{"class":684},[667,2352,2353],{"class":669,"line":849},[667,2354,2355],{"class":684},"  }),\n",[667,2357,2358,2361,2363,2366,2368,2371,2373,2375],{"class":669,"line":856},[667,2359,2360],{"class":688},"  execute",[667,2362,530],{"class":684},[667,2364,2365],{"class":673},"async",[667,2367,52],{"class":684},[667,2369,2370],{"class":864},"args",[667,2372,1092],{"class":684},[667,2374,1095],{"class":673},[667,2376,1098],{"class":684},[667,2378,2379],{"class":669,"line":886},[667,2380,2381],{"class":1557},"    \u002F\u002F Would run dedup + contradiction check before storing\n",[667,2383,2384,2386,2388,2390,2393,2396,2399],{"class":669,"line":902},[667,2385,1150],{"class":673},[667,2387,878],{"class":673},[667,2389,1572],{"class":684},[667,2391,2392],{"class":688},"runMutation",[667,2394,2395],{"class":684},"(internal.knowledge.graph.saveEntry, { ",[667,2397,2398],{"class":1557},"\u002F* ... *\u002F",[667,2400,2401],{"class":684}," })\n",[667,2403,2404],{"class":669,"line":908},[667,2405,2406],{"class":684},"  },\n",[667,2408,2409],{"class":669,"line":920},[667,2410,846],{"class":684},[151,2412,2414],{"id":2413},"aktives-abrufen","Aktives Abrufen",[16,2416,2417,2418,2420],{},"Während der Entwurfserzeugung (Schritt 4) würde der Agent den Graphen ausdrücklich nach relevantem Kontext jenseits dessen abfragen, was der Kontextabruf ohnehin schon zutage gefördert hat. Die Vektorsuch-Naht, die er aufrufen würde (",[28,2419,2124],{},"), existiert und wird heute ausgeliefert — was fehlt, ist ihre Bereitstellung als Werkzeug, das das LLM bei Bedarf aufrufen kann:",[600,2422,2424],{"className":661,"code":2423,"language":663,"meta":608,"style":608},"const recallKnowledge = tool({\n  description: 'Search organizational knowledge for information relevant to the current task',\n  parameters: z.object({\n    query: z.string(),\n    contactId: z.string().optional(),\n    type: z.enum([\u002F* entry types *\u002F]).optional(),\n    limit: z.number().default(5),\n  }),\n  execute: async (args) => {\n    \u002F\u002F The underlying vector search already exists; this would wrap it as a tool\n    return await ctx.runAction(internal.knowledge.retrieval.semanticSearch, { queryText: args.query, \u002F* ... *\u002F })\n  },\n})\n",[28,2425,2426,2439,2448,2456,2465,2477,2495,2514,2518,2536,2541,2559,2563],{"__ignoreMap":608},[667,2427,2428,2430,2433,2435,2437],{"class":669,"line":670},[667,2429,674],{"class":673},[667,2431,2432],{"class":677}," recallKnowledge",[667,2434,681],{"class":673},[667,2436,2227],{"class":688},[667,2438,692],{"class":684},[667,2440,2441,2443,2446],{"class":669,"line":695},[667,2442,2234],{"class":684},[667,2444,2445],{"class":723},"'Search organizational knowledge for information relevant to the current task'",[667,2447,917],{"class":684},[667,2449,2450,2452,2454],{"class":669,"line":711},[667,2451,2244],{"class":684},[667,2453,689],{"class":688},[667,2455,692],{"class":684},[667,2457,2458,2461,2463],{"class":669,"line":760},[667,2459,2460],{"class":684},"    query: z.",[667,2462,766],{"class":688},[667,2464,769],{"class":684},[667,2466,2467,2469,2471,2473,2475],{"class":669,"line":772},[667,2468,2305],{"class":684},[667,2470,766],{"class":688},[667,2472,791],{"class":684},[667,2474,832],{"class":688},[667,2476,769],{"class":684},[667,2478,2479,2481,2483,2485,2488,2491,2493],{"class":669,"line":782},[667,2480,714],{"class":684},[667,2482,717],{"class":688},[667,2484,720],{"class":684},[667,2486,2487],{"class":1557},"\u002F* entry types *\u002F",[667,2489,2490],{"class":684},"]).",[667,2492,832],{"class":688},[667,2494,769],{"class":684},[667,2496,2497,2500,2502,2504,2507,2509,2512],{"class":669,"line":817},[667,2498,2499],{"class":684},"    limit: z.",[667,2501,788],{"class":688},[667,2503,791],{"class":684},[667,2505,2506],{"class":688},"default",[667,2508,797],{"class":684},[667,2510,2511],{"class":677},"5",[667,2513,814],{"class":684},[667,2515,2516],{"class":669,"line":837},[667,2517,2355],{"class":684},[667,2519,2520,2522,2524,2526,2528,2530,2532,2534],{"class":669,"line":843},[667,2521,2360],{"class":688},[667,2523,530],{"class":684},[667,2525,2365],{"class":673},[667,2527,52],{"class":684},[667,2529,2370],{"class":864},[667,2531,1092],{"class":684},[667,2533,1095],{"class":673},[667,2535,1098],{"class":684},[667,2537,2538],{"class":669,"line":849},[667,2539,2540],{"class":1557},"    \u002F\u002F The underlying vector search already exists; this would wrap it as a tool\n",[667,2542,2543,2545,2547,2549,2552,2555,2557],{"class":669,"line":856},[667,2544,1150],{"class":673},[667,2546,878],{"class":673},[667,2548,1572],{"class":684},[667,2550,2551],{"class":688},"runAction",[667,2553,2554],{"class":684},"(internal.knowledge.retrieval.semanticSearch, { queryText: args.query, ",[667,2556,2398],{"class":1557},[667,2558,2401],{"class":684},[667,2560,2561],{"class":669,"line":886},[667,2562,2406],{"class":684},[667,2564,2565],{"class":669,"line":902},[667,2566,846],{"class":684},[16,2568,2569,2570,2574],{},"Beide bauen auf der oben beschriebenen ",[472,2571,2573],{"href":2572},"#semantic-search-shipping","Vektorsuche"," auf, die bereits aktiv ist — es fehlen nur noch die Werkzeug-Hüllen.",[118,2576,2578],{"id":2577},"verfall-und-pflege","Verfall und Pflege",[16,2580,2581],{},"Der Wissensgraph ist nicht rein anfügend. Veraltetes Wissen verliert mit der Zeit an Wert.",[151,2583,2585],{"id":2584},"konfidenzverfall-ausgeliefert","Konfidenzverfall (ausgeliefert)",[16,2587,2588,2589,52,2592,2594,2595,2598,2599,2601],{},"Ein geplanter Convex-Cron läuft alle 24 Stunden — ",[28,2590,2591],{},"crons.interval('knowledge graph maintenance', { hours: 24 }, internal.knowledge.maintenance.runDecay)",[28,2593,1002],{},"). Jeder ",[28,2596,2597],{},"runDecay","-Durchlauf verarbeitet einen Stapel von Einträgen und tut zwei Dinge (",[28,2600,42],{},"):",[2603,2604,2605,2613],"ol",{},[279,2606,2607,2609,2610,2612],{},[45,2608,359],{}," — Einträge löschen, die ihren ",[28,2611,363],{},"-Zeitstempel überschritten haben, wobei zuvor ihre Relationen abgebaut werden (das Löschen von Relationen ist je Eintrag gedeckelt, damit ein stark verbundener Knoten das Transaktionsbudget nicht sprengt; Übriggebliebenes wird beim nächsten Lauf abgeholt)",[279,2614,2615,2618,2619,2622,2623,2625,2626,2628,2629,2632,2633,31,2636,2639],{},[45,2616,2617],{},"Zeitverfall"," — die ",[28,2620,2621],{},"confidence"," jedes Eintrags anhand seiner typbezogenen Verfallsrate und der Tage seit ",[28,2624,354],{}," senken, mit einer Untergrenze von ",[28,2627,926],{},". Der Verfallsfaktor wird ",[45,2630,2631],{},"durch einen Nutzungsaktualitäts-Schub moduliert"," (über ",[28,2634,2635],{},"accessCount",[28,2637,2638],{},"lastAccessedAt",", die bei jedem Abruf eines Eintrags hochgezählt werden), sodass häufig abgerufene Einträge langsamer verfallen",[16,2641,2642,2643,987,2645,2647,2648,2650,2651,2654],{},"Ein separater täglicher Dedup-Merge-Cron (",[28,2644,999],{},[28,2646,986],{},") läuft neben ",[28,2649,2597],{}," — siehe den Abschnitt ",[472,2652,480],{"href":2653},"#extraction"," weiter oben.",[20,2656,2658],{"title":2657,"type":23},"Geplante Pflegeschritte",[16,2659,2660,2661,2664,2665,2667,2668,2671],{},"Zwei weitere Pflegeverhalten sind entworfen, aber nicht implementiert: die ",[45,2662,2663],{},"Widerspruchsauflösung"," (Markieren der älteren Seite eines ",[28,2666,85],{},"-Paars) und der ",[45,2669,2670],{},"Validierungsschub"," (Anheben der Konfidenz eines Eintrags, wenn der Agent ihn nutzt und ein Mensch den resultierenden Entwurf freigibt).",[151,2673,2675],{"id":2674},"wissenstypen-verfallen-unterschiedlich-schnell","Wissenstypen verfallen unterschiedlich schnell",[159,2677,2678,2690],{},[162,2679,2680],{},[165,2681,2682,2684,2687],{},[168,2683,170],{},[168,2685,2686],{},"Verfallsrate (pro Tag)",[168,2688,2689],{},"Begründung",[178,2691,2692,2704,2716,2727,2739,2751,2763],{},[165,2693,2694,2698,2701],{},[183,2695,2696],{},[45,2697,187],{},[183,2699,2700],{},"0,5 %",[183,2702,2703],{},"Fakten wie „der Tarif einer Kundin“ ändern sich selten",[165,2705,2706,2710,2713],{},[183,2707,2708],{},[45,2709,200],{},[183,2711,2712],{},"0,2 %",[183,2714,2715],{},"Entscheidungen haben Bestand, sofern sie nicht ausdrücklich zurückgenommen werden",[165,2717,2718,2722,2724],{},[183,2719,2720],{},[45,2721,213],{},[183,2723,584],{},[183,2725,2726],{},"Historische Ereignisse werden mit der Zeit nicht weniger wahr",[165,2728,2729,2733,2736],{},[183,2730,2731],{},[45,2732,226],{},[183,2734,2735],{},"1,5 %",[183,2737,2738],{},"Präferenzen entwickeln sich mit der Beziehung weiter",[165,2740,2741,2745,2748],{},[183,2742,2743],{},[45,2744,239],{},[183,2746,2747],{},"3 %",[183,2749,2750],{},"Ziele haben Fristen und verschieben sich häufig",[165,2752,2753,2757,2760],{},[183,2754,2755],{},[45,2756,252],{},[183,2758,2759],{},"1 %",[183,2761,2762],{},"Organisationsstrukturen ändern sich",[165,2764,2765,2769,2772],{},[183,2766,2767],{},[45,2768,265],{},[183,2770,2771],{},"5 %",[183,2773,2774],{},"Zusagen haben Fristen und erledigen sich schnell",[118,2776,2778],{"id":2777},"schema","Schema",[16,2780,2781,2782,2159],{},"Definiert in ",[28,2783,1203],{},[151,2785,30],{"id":2786},"knowledgeentries",[600,2788,2790],{"className":661,"code":2789,"language":663,"meta":608,"style":608},"knowledgeEntries: defineTable({\n  entryType: v.union(\n    v.literal('fact'),\n    v.literal('decision'),\n    v.literal('event'),\n    v.literal('preference'),\n    v.literal('goal'),\n    v.literal('relationship'),\n    v.literal('action_item')\n  ),\n  title: v.string(),\n  content: v.string(),\n  sourceType: v.union(\n    v.literal('email'),\n    v.literal('chat'),\n    v.literal('manual'),\n    v.literal('file'),\n    v.literal('agent_extracted')\n  ),\n  sourceId: v.optional(v.string()),\n  contactIds: v.optional(v.array(v.id('contacts'))),\n  threadId: v.optional(v.id('conversationThreads')),\n  embedding: v.array(v.float64()), \u002F\u002F 1536 dims (text-embedding-3-small)\n  embeddingModel: v.optional(v.string()),\n  embeddingGeneratedAt: v.optional(v.number()),\n  confidence: v.number(), \u002F\u002F 0-1\n  lastValidatedAt: v.number(),\n  accessCount: v.optional(v.number()), \u002F\u002F usage signal — bumped on recall\n  lastAccessedAt: v.optional(v.number()), \u002F\u002F usage signal — modulates decay\n  expiresAt: v.optional(v.number()),\n  tags: v.optional(v.array(v.string())),\n  searchableText: v.optional(v.string()),\n  contentHash: v.optional(v.string()), \u002F\u002F sha256 fingerprint — cross-source dedup leg in saveEntry\n  createdAt: v.number(),\n  updatedAt: v.number(),\n})\n  .index('by_entry_type', ['entryType'])\n  .index('by_created_at', ['createdAt'])\n  .index('by_thread', ['threadId'])\n  .index('by_source', ['sourceType', 'sourceId'])\n  .index('by_content_hash', ['contentHash'])\n  .searchIndex('search_knowledge', {\n    searchField: 'searchableText',\n    filterFields: ['entryType'],\n  })\n  .vectorIndex('vector_knowledge', {\n    vectorField: 'embedding',\n    dimensions: 1536,\n    filterFields: ['entryType'],\n  })\n",[28,2791,2792,2803,2814,2828,2840,2852,2864,2876,2888,2900,2905,2914,2923,2932,2945,2958,2971,2984,2997,3001,3016,3040,3059,3077,3091,3105,3119,3129,3146,3163,3177,3196,3210,3227,3237,3247,3252,3273,3292,3311,3335,3354,3368,3378,3389,3394,3408,3419,3429,3438],{"__ignoreMap":608},[667,2793,2794,2796,2798,2801],{"class":669,"line":670},[667,2795,30],{"class":1894},[667,2797,530],{"class":684},[667,2799,2800],{"class":688},"defineTable",[667,2802,692],{"class":684},[667,2804,2805,2808,2811],{"class":669,"line":695},[667,2806,2807],{"class":684},"  entryType: v.",[667,2809,2810],{"class":688},"union",[667,2812,2813],{"class":684},"(\n",[667,2815,2816,2819,2822,2824,2826],{"class":669,"line":711},[667,2817,2818],{"class":684},"    v.",[667,2820,2821],{"class":688},"literal",[667,2823,797],{"class":684},[667,2825,724],{"class":723},[667,2827,814],{"class":684},[667,2829,2830,2832,2834,2836,2838],{"class":669,"line":760},[667,2831,2818],{"class":684},[667,2833,2821],{"class":688},[667,2835,797],{"class":684},[667,2837,729],{"class":723},[667,2839,814],{"class":684},[667,2841,2842,2844,2846,2848,2850],{"class":669,"line":772},[667,2843,2818],{"class":684},[667,2845,2821],{"class":688},[667,2847,797],{"class":684},[667,2849,734],{"class":723},[667,2851,814],{"class":684},[667,2853,2854,2856,2858,2860,2862],{"class":669,"line":782},[667,2855,2818],{"class":684},[667,2857,2821],{"class":688},[667,2859,797],{"class":684},[667,2861,739],{"class":723},[667,2863,814],{"class":684},[667,2865,2866,2868,2870,2872,2874],{"class":669,"line":817},[667,2867,2818],{"class":684},[667,2869,2821],{"class":688},[667,2871,797],{"class":684},[667,2873,744],{"class":723},[667,2875,814],{"class":684},[667,2877,2878,2880,2882,2884,2886],{"class":669,"line":837},[667,2879,2818],{"class":684},[667,2881,2821],{"class":688},[667,2883,797],{"class":684},[667,2885,749],{"class":723},[667,2887,814],{"class":684},[667,2889,2890,2892,2894,2896,2898],{"class":669,"line":843},[667,2891,2818],{"class":684},[667,2893,2821],{"class":688},[667,2895,797],{"class":684},[667,2897,754],{"class":723},[667,2899,1071],{"class":684},[667,2901,2902],{"class":669,"line":849},[667,2903,2904],{"class":684},"  ),\n",[667,2906,2907,2910,2912],{"class":669,"line":856},[667,2908,2909],{"class":684},"  title: v.",[667,2911,766],{"class":688},[667,2913,769],{"class":684},[667,2915,2916,2919,2921],{"class":669,"line":886},[667,2917,2918],{"class":684},"  content: v.",[667,2920,766],{"class":688},[667,2922,769],{"class":684},[667,2924,2925,2928,2930],{"class":669,"line":902},[667,2926,2927],{"class":684},"  sourceType: v.",[667,2929,2810],{"class":688},[667,2931,2813],{"class":684},[667,2933,2934,2936,2938,2940,2943],{"class":669,"line":908},[667,2935,2818],{"class":684},[667,2937,2821],{"class":688},[667,2939,797],{"class":684},[667,2941,2942],{"class":723},"'email'",[667,2944,814],{"class":684},[667,2946,2947,2949,2951,2953,2956],{"class":669,"line":920},[667,2948,2818],{"class":684},[667,2950,2821],{"class":688},[667,2952,797],{"class":684},[667,2954,2955],{"class":723},"'chat'",[667,2957,814],{"class":684},[667,2959,2960,2962,2964,2966,2969],{"class":669,"line":931},[667,2961,2818],{"class":684},[667,2963,2821],{"class":688},[667,2965,797],{"class":684},[667,2967,2968],{"class":723},"'manual'",[667,2970,814],{"class":684},[667,2972,2973,2975,2977,2979,2982],{"class":669,"line":1729},[667,2974,2818],{"class":684},[667,2976,2821],{"class":688},[667,2978,797],{"class":684},[667,2980,2981],{"class":723},"'file'",[667,2983,814],{"class":684},[667,2985,2986,2988,2990,2992,2995],{"class":669,"line":1735},[667,2987,2818],{"class":684},[667,2989,2821],{"class":688},[667,2991,797],{"class":684},[667,2993,2994],{"class":723},"'agent_extracted'",[667,2996,1071],{"class":684},[667,2998,2999],{"class":669,"line":1740},[667,3000,2904],{"class":684},[667,3002,3003,3006,3008,3011,3013],{"class":669,"line":1746},[667,3004,3005],{"class":684},"  sourceId: v.",[667,3007,832],{"class":688},[667,3009,3010],{"class":684},"(v.",[667,3012,766],{"class":688},[667,3014,3015],{"class":684},"()),\n",[667,3017,3018,3021,3023,3025,3027,3029,3032,3034,3037],{"class":669,"line":1762},[667,3019,3020],{"class":684},"  contactIds: v.",[667,3022,832],{"class":688},[667,3024,3010],{"class":684},[667,3026,701],{"class":688},[667,3028,3010],{"class":684},[667,3030,3031],{"class":688},"id",[667,3033,797],{"class":684},[667,3035,3036],{"class":723},"'contacts'",[667,3038,3039],{"class":684},"))),\n",[667,3041,3042,3045,3047,3049,3051,3053,3056],{"class":669,"line":1781},[667,3043,3044],{"class":684},"  threadId: v.",[667,3046,832],{"class":688},[667,3048,3010],{"class":684},[667,3050,3031],{"class":688},[667,3052,797],{"class":684},[667,3054,3055],{"class":723},"'conversationThreads'",[667,3057,3058],{"class":684},")),\n",[667,3060,3061,3064,3066,3068,3071,3074],{"class":669,"line":1787},[667,3062,3063],{"class":684},"  embedding: v.",[667,3065,701],{"class":688},[667,3067,3010],{"class":684},[667,3069,3070],{"class":688},"float64",[667,3072,3073],{"class":684},"()), ",[667,3075,3076],{"class":1557},"\u002F\u002F 1536 dims (text-embedding-3-small)\n",[667,3078,3080,3083,3085,3087,3089],{"class":669,"line":3079},24,[667,3081,3082],{"class":684},"  embeddingModel: v.",[667,3084,832],{"class":688},[667,3086,3010],{"class":684},[667,3088,766],{"class":688},[667,3090,3015],{"class":684},[667,3092,3094,3097,3099,3101,3103],{"class":669,"line":3093},25,[667,3095,3096],{"class":684},"  embeddingGeneratedAt: v.",[667,3098,832],{"class":688},[667,3100,3010],{"class":684},[667,3102,788],{"class":688},[667,3104,3015],{"class":684},[667,3106,3108,3111,3113,3116],{"class":669,"line":3107},26,[667,3109,3110],{"class":684},"  confidence: v.",[667,3112,788],{"class":688},[667,3114,3115],{"class":684},"(), ",[667,3117,3118],{"class":1557},"\u002F\u002F 0-1\n",[667,3120,3122,3125,3127],{"class":669,"line":3121},27,[667,3123,3124],{"class":684},"  lastValidatedAt: v.",[667,3126,788],{"class":688},[667,3128,769],{"class":684},[667,3130,3132,3135,3137,3139,3141,3143],{"class":669,"line":3131},28,[667,3133,3134],{"class":684},"  accessCount: v.",[667,3136,832],{"class":688},[667,3138,3010],{"class":684},[667,3140,788],{"class":688},[667,3142,3073],{"class":684},[667,3144,3145],{"class":1557},"\u002F\u002F usage signal — bumped on recall\n",[667,3147,3149,3152,3154,3156,3158,3160],{"class":669,"line":3148},29,[667,3150,3151],{"class":684},"  lastAccessedAt: v.",[667,3153,832],{"class":688},[667,3155,3010],{"class":684},[667,3157,788],{"class":688},[667,3159,3073],{"class":684},[667,3161,3162],{"class":1557},"\u002F\u002F usage signal — modulates decay\n",[667,3164,3166,3169,3171,3173,3175],{"class":669,"line":3165},30,[667,3167,3168],{"class":684},"  expiresAt: v.",[667,3170,832],{"class":688},[667,3172,3010],{"class":684},[667,3174,788],{"class":688},[667,3176,3015],{"class":684},[667,3178,3180,3183,3185,3187,3189,3191,3193],{"class":669,"line":3179},31,[667,3181,3182],{"class":684},"  tags: v.",[667,3184,832],{"class":688},[667,3186,3010],{"class":684},[667,3188,701],{"class":688},[667,3190,3010],{"class":684},[667,3192,766],{"class":688},[667,3194,3195],{"class":684},"())),\n",[667,3197,3199,3202,3204,3206,3208],{"class":669,"line":3198},32,[667,3200,3201],{"class":684},"  searchableText: v.",[667,3203,832],{"class":688},[667,3205,3010],{"class":684},[667,3207,766],{"class":688},[667,3209,3015],{"class":684},[667,3211,3213,3216,3218,3220,3222,3224],{"class":669,"line":3212},33,[667,3214,3215],{"class":684},"  contentHash: v.",[667,3217,832],{"class":688},[667,3219,3010],{"class":684},[667,3221,766],{"class":688},[667,3223,3073],{"class":684},[667,3225,3226],{"class":1557},"\u002F\u002F sha256 fingerprint — cross-source dedup leg in saveEntry\n",[667,3228,3230,3233,3235],{"class":669,"line":3229},34,[667,3231,3232],{"class":684},"  createdAt: v.",[667,3234,788],{"class":688},[667,3236,769],{"class":684},[667,3238,3240,3243,3245],{"class":669,"line":3239},35,[667,3241,3242],{"class":684},"  updatedAt: v.",[667,3244,788],{"class":688},[667,3246,769],{"class":684},[667,3248,3250],{"class":669,"line":3249},36,[667,3251,846],{"class":684},[667,3253,3255,3257,3260,3262,3265,3268,3270],{"class":669,"line":3254},37,[667,3256,1060],{"class":684},[667,3258,3259],{"class":688},"index",[667,3261,797],{"class":684},[667,3263,3264],{"class":723},"'by_entry_type'",[667,3266,3267],{"class":684},", [",[667,3269,1142],{"class":723},[667,3271,3272],{"class":684},"])\n",[667,3274,3276,3278,3280,3282,3285,3287,3290],{"class":669,"line":3275},38,[667,3277,1060],{"class":684},[667,3279,3259],{"class":688},[667,3281,797],{"class":684},[667,3283,3284],{"class":723},"'by_created_at'",[667,3286,3267],{"class":684},[667,3288,3289],{"class":723},"'createdAt'",[667,3291,3272],{"class":684},[667,3293,3295,3297,3299,3301,3304,3306,3309],{"class":669,"line":3294},39,[667,3296,1060],{"class":684},[667,3298,3259],{"class":688},[667,3300,797],{"class":684},[667,3302,3303],{"class":723},"'by_thread'",[667,3305,3267],{"class":684},[667,3307,3308],{"class":723},"'threadId'",[667,3310,3272],{"class":684},[667,3312,3314,3316,3318,3320,3323,3325,3328,3330,3333],{"class":669,"line":3313},40,[667,3315,1060],{"class":684},[667,3317,3259],{"class":688},[667,3319,797],{"class":684},[667,3321,3322],{"class":723},"'by_source'",[667,3324,3267],{"class":684},[667,3326,3327],{"class":723},"'sourceType'",[667,3329,302],{"class":684},[667,3331,3332],{"class":723},"'sourceId'",[667,3334,3272],{"class":684},[667,3336,3338,3340,3342,3344,3347,3349,3352],{"class":669,"line":3337},41,[667,3339,1060],{"class":684},[667,3341,3259],{"class":688},[667,3343,797],{"class":684},[667,3345,3346],{"class":723},"'by_content_hash'",[667,3348,3267],{"class":684},[667,3350,3351],{"class":723},"'contentHash'",[667,3353,3272],{"class":684},[667,3355,3357,3359,3362,3364,3366],{"class":669,"line":3356},42,[667,3358,1060],{"class":684},[667,3360,3361],{"class":688},"searchIndex",[667,3363,797],{"class":684},[667,3365,1083],{"class":723},[667,3367,1587],{"class":684},[667,3369,3371,3374,3376],{"class":669,"line":3370},43,[667,3372,3373],{"class":684},"    searchField: ",[667,3375,1118],{"class":723},[667,3377,917],{"class":684},[667,3379,3381,3384,3386],{"class":669,"line":3380},44,[667,3382,3383],{"class":684},"    filterFields: [",[667,3385,1142],{"class":723},[667,3387,3388],{"class":684},"],\n",[667,3390,3392],{"class":669,"line":3391},45,[667,3393,1158],{"class":684},[667,3395,3397,3399,3402,3404,3406],{"class":669,"line":3396},46,[667,3398,1060],{"class":684},[667,3400,3401],{"class":688},"vectorIndex",[667,3403,797],{"class":684},[667,3405,1584],{"class":723},[667,3407,1587],{"class":684},[667,3409,3411,3414,3417],{"class":669,"line":3410},47,[667,3412,3413],{"class":684},"    vectorField: ",[667,3415,3416],{"class":723},"'embedding'",[667,3418,917],{"class":684},[667,3420,3422,3425,3427],{"class":669,"line":3421},48,[667,3423,3424],{"class":684},"    dimensions: ",[667,3426,336],{"class":677},[667,3428,917],{"class":684},[667,3430,3432,3434,3436],{"class":669,"line":3431},49,[667,3433,3383],{"class":684},[667,3435,1142],{"class":723},[667,3437,3388],{"class":684},[667,3439,3441],{"class":669,"line":3440},50,[667,3442,1158],{"class":684},[151,3444,34],{"id":3445},"knowledgerelations",[600,3447,3449],{"className":661,"code":3448,"language":663,"meta":608,"style":608},"knowledgeRelations: defineTable({\n  fromEntryId: v.id('knowledgeEntries'),\n  toEntryId: v.id('knowledgeEntries'),\n  relationType: v.union(\n    v.literal('supports'),\n    v.literal('contradicts'),\n    v.literal('supersedes'),\n    v.literal('relates_to'),\n    v.literal('causes'),\n    v.literal('blocks')\n  ),\n  confidenceTag: v.union( \u002F\u002F coarse, sortable companion to `confidence`\n    v.literal('extracted'),\n    v.literal('inferred'),\n    v.literal('ambiguous')\n  ),\n  confidence: v.number(), \u002F\u002F 0-1\n  weight: v.optional(v.number()), \u002F\u002F edge strength for graph-augmented retrieval\n  provenance: v.union( \u002F\u002F strongest first: manual > deterministic > llm\n    v.literal('deterministic'),\n    v.literal('llm'),\n    v.literal('manual')\n  ),\n  rationale: v.optional(v.string()),\n  createdAt: v.number(),\n  updatedAt: v.number(),\n})\n  .index('by_from', ['fromEntryId'])\n  .index('by_to', ['toEntryId'])\n  .index('by_pair', ['fromEntryId', 'toEntryId'])\n  .index('by_confidence_tag', ['confidenceTag'])\n",[28,3450,3451,3461,3474,3487,3496,3509,3522,3535,3548,3561,3574,3578,3591,3604,3617,3630,3634,3644,3660,3672,3685,3698,3710,3714,3727,3735,3743,3747,3765,3783,3804],{"__ignoreMap":608},[667,3452,3453,3455,3457,3459],{"class":669,"line":670},[667,3454,34],{"class":1894},[667,3456,530],{"class":684},[667,3458,2800],{"class":688},[667,3460,692],{"class":684},[667,3462,3463,3466,3468,3470,3472],{"class":669,"line":695},[667,3464,3465],{"class":684},"  fromEntryId: v.",[667,3467,3031],{"class":688},[667,3469,797],{"class":684},[667,3471,1068],{"class":723},[667,3473,814],{"class":684},[667,3475,3476,3479,3481,3483,3485],{"class":669,"line":711},[667,3477,3478],{"class":684},"  toEntryId: v.",[667,3480,3031],{"class":688},[667,3482,797],{"class":684},[667,3484,1068],{"class":723},[667,3486,814],{"class":684},[667,3488,3489,3492,3494],{"class":669,"line":760},[667,3490,3491],{"class":684},"  relationType: v.",[667,3493,2810],{"class":688},[667,3495,2813],{"class":684},[667,3497,3498,3500,3502,3504,3507],{"class":669,"line":772},[667,3499,2818],{"class":684},[667,3501,2821],{"class":688},[667,3503,797],{"class":684},[667,3505,3506],{"class":723},"'supports'",[667,3508,814],{"class":684},[667,3510,3511,3513,3515,3517,3520],{"class":669,"line":782},[667,3512,2818],{"class":684},[667,3514,2821],{"class":688},[667,3516,797],{"class":684},[667,3518,3519],{"class":723},"'contradicts'",[667,3521,814],{"class":684},[667,3523,3524,3526,3528,3530,3533],{"class":669,"line":817},[667,3525,2818],{"class":684},[667,3527,2821],{"class":688},[667,3529,797],{"class":684},[667,3531,3532],{"class":723},"'supersedes'",[667,3534,814],{"class":684},[667,3536,3537,3539,3541,3543,3546],{"class":669,"line":837},[667,3538,2818],{"class":684},[667,3540,2821],{"class":688},[667,3542,797],{"class":684},[667,3544,3545],{"class":723},"'relates_to'",[667,3547,814],{"class":684},[667,3549,3550,3552,3554,3556,3559],{"class":669,"line":843},[667,3551,2818],{"class":684},[667,3553,2821],{"class":688},[667,3555,797],{"class":684},[667,3557,3558],{"class":723},"'causes'",[667,3560,814],{"class":684},[667,3562,3563,3565,3567,3569,3572],{"class":669,"line":849},[667,3564,2818],{"class":684},[667,3566,2821],{"class":688},[667,3568,797],{"class":684},[667,3570,3571],{"class":723},"'blocks'",[667,3573,1071],{"class":684},[667,3575,3576],{"class":669,"line":856},[667,3577,2904],{"class":684},[667,3579,3580,3583,3585,3588],{"class":669,"line":886},[667,3581,3582],{"class":684},"  confidenceTag: v.",[667,3584,2810],{"class":688},[667,3586,3587],{"class":684},"( ",[667,3589,3590],{"class":1557},"\u002F\u002F coarse, sortable companion to `confidence`\n",[667,3592,3593,3595,3597,3599,3602],{"class":669,"line":902},[667,3594,2818],{"class":684},[667,3596,2821],{"class":688},[667,3598,797],{"class":684},[667,3600,3601],{"class":723},"'extracted'",[667,3603,814],{"class":684},[667,3605,3606,3608,3610,3612,3615],{"class":669,"line":908},[667,3607,2818],{"class":684},[667,3609,2821],{"class":688},[667,3611,797],{"class":684},[667,3613,3614],{"class":723},"'inferred'",[667,3616,814],{"class":684},[667,3618,3619,3621,3623,3625,3628],{"class":669,"line":920},[667,3620,2818],{"class":684},[667,3622,2821],{"class":688},[667,3624,797],{"class":684},[667,3626,3627],{"class":723},"'ambiguous'",[667,3629,1071],{"class":684},[667,3631,3632],{"class":669,"line":931},[667,3633,2904],{"class":684},[667,3635,3636,3638,3640,3642],{"class":669,"line":1729},[667,3637,3110],{"class":684},[667,3639,788],{"class":688},[667,3641,3115],{"class":684},[667,3643,3118],{"class":1557},[667,3645,3646,3649,3651,3653,3655,3657],{"class":669,"line":1735},[667,3647,3648],{"class":684},"  weight: v.",[667,3650,832],{"class":688},[667,3652,3010],{"class":684},[667,3654,788],{"class":688},[667,3656,3073],{"class":684},[667,3658,3659],{"class":1557},"\u002F\u002F edge strength for graph-augmented retrieval\n",[667,3661,3662,3665,3667,3669],{"class":669,"line":1740},[667,3663,3664],{"class":684},"  provenance: v.",[667,3666,2810],{"class":688},[667,3668,3587],{"class":684},[667,3670,3671],{"class":1557},"\u002F\u002F strongest first: manual > deterministic > llm\n",[667,3673,3674,3676,3678,3680,3683],{"class":669,"line":1746},[667,3675,2818],{"class":684},[667,3677,2821],{"class":688},[667,3679,797],{"class":684},[667,3681,3682],{"class":723},"'deterministic'",[667,3684,814],{"class":684},[667,3686,3687,3689,3691,3693,3696],{"class":669,"line":1762},[667,3688,2818],{"class":684},[667,3690,2821],{"class":688},[667,3692,797],{"class":684},[667,3694,3695],{"class":723},"'llm'",[667,3697,814],{"class":684},[667,3699,3700,3702,3704,3706,3708],{"class":669,"line":1781},[667,3701,2818],{"class":684},[667,3703,2821],{"class":688},[667,3705,797],{"class":684},[667,3707,2968],{"class":723},[667,3709,1071],{"class":684},[667,3711,3712],{"class":669,"line":1787},[667,3713,2904],{"class":684},[667,3715,3716,3719,3721,3723,3725],{"class":669,"line":3079},[667,3717,3718],{"class":684},"  rationale: v.",[667,3720,832],{"class":688},[667,3722,3010],{"class":684},[667,3724,766],{"class":688},[667,3726,3015],{"class":684},[667,3728,3729,3731,3733],{"class":669,"line":3093},[667,3730,3232],{"class":684},[667,3732,788],{"class":688},[667,3734,769],{"class":684},[667,3736,3737,3739,3741],{"class":669,"line":3107},[667,3738,3242],{"class":684},[667,3740,788],{"class":688},[667,3742,769],{"class":684},[667,3744,3745],{"class":669,"line":3121},[667,3746,846],{"class":684},[667,3748,3749,3751,3753,3755,3758,3760,3763],{"class":669,"line":3131},[667,3750,1060],{"class":684},[667,3752,3259],{"class":688},[667,3754,797],{"class":684},[667,3756,3757],{"class":723},"'by_from'",[667,3759,3267],{"class":684},[667,3761,3762],{"class":723},"'fromEntryId'",[667,3764,3272],{"class":684},[667,3766,3767,3769,3771,3773,3776,3778,3781],{"class":669,"line":3148},[667,3768,1060],{"class":684},[667,3770,3259],{"class":688},[667,3772,797],{"class":684},[667,3774,3775],{"class":723},"'by_to'",[667,3777,3267],{"class":684},[667,3779,3780],{"class":723},"'toEntryId'",[667,3782,3272],{"class":684},[667,3784,3785,3787,3789,3791,3794,3796,3798,3800,3802],{"class":669,"line":3165},[667,3786,1060],{"class":684},[667,3788,3259],{"class":688},[667,3790,797],{"class":684},[667,3792,3793],{"class":723},"'by_pair'",[667,3795,3267],{"class":684},[667,3797,3762],{"class":723},[667,3799,302],{"class":684},[667,3801,3780],{"class":723},[667,3803,3272],{"class":684},[667,3805,3806,3808,3810,3812,3815,3817,3820],{"class":669,"line":3179},[667,3807,1060],{"class":684},[667,3809,3259],{"class":688},[667,3811,797],{"class":684},[667,3813,3814],{"class":723},"'by_confidence_tag'",[667,3816,3267],{"class":684},[667,3818,3819],{"class":723},"'confidenceTag'",[667,3821,3272],{"class":684},[3823,3824],"link-card",{"description":3825,"title":3826,"to":3827},"Wie Sie Wissenseinträge im Dashboard durchstöbern, durchsuchen und anlegen.","Wissensgraph (Leitfaden)","\u002Fguide\u002Fknowledge-graph",[3829,3830,3831],"style",{},"html pre.shiki code .s7YZ4, html code.shiki .s7YZ4{--shiki-default:#D73A49;--shiki-dark:#F47067}html pre.shiki code .sviXB, html code.shiki .sviXB{--shiki-default:#005CC5;--shiki-dark:#6CB6FF}html pre.shiki code .sYgZi, html code.shiki .sYgZi{--shiki-default:#24292E;--shiki-dark:#ADBAC7}html pre.shiki code .sPO5f, html code.shiki .sPO5f{--shiki-default:#6F42C1;--shiki-dark:#DCBDFB}html pre.shiki code .s-HuK, html code.shiki .s-HuK{--shiki-default:#032F62;--shiki-dark:#96D0FF}html pre.shiki code .stnAF, html code.shiki .stnAF{--shiki-default:#E36209;--shiki-dark:#F69D50}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 .sDN9O, html code.shiki .sDN9O{--shiki-default:#6A737D;--shiki-dark:#768390}html pre.shiki code .sOLd2, html code.shiki .sOLd2{--shiki-default:#6F42C1;--shiki-dark:#F69D50}",{"title":608,"searchDepth":695,"depth":695,"links":3833},[3834,3835,3839,3842,3849,3853,3857],{"id":120,"depth":695,"text":121},{"id":145,"depth":695,"text":146,"children":3836},[3837,3838],{"id":153,"depth":711,"text":154},{"id":367,"depth":711,"text":368},{"id":479,"depth":695,"text":480,"children":3840},[3841],{"id":646,"depth":711,"text":647},{"id":1026,"depth":695,"text":1027,"children":3843},[3844,3845,3846,3847,3848],{"id":1033,"depth":711,"text":1034},{"id":1189,"depth":711,"text":1190},{"id":1475,"depth":711,"text":1476},{"id":1814,"depth":711,"text":1815},{"id":2108,"depth":711,"text":2109},{"id":2162,"depth":695,"text":2163,"children":3850},[3851,3852],{"id":2206,"depth":711,"text":2207},{"id":2413,"depth":711,"text":2414},{"id":2577,"depth":695,"text":2578,"children":3854},[3855,3856],{"id":2584,"depth":711,"text":2585},{"id":2674,"depth":711,"text":2675},{"id":2777,"depth":695,"text":2778,"children":3858},[3859,3860],{"id":2786,"depth":711,"text":30},{"id":3445,"depth":711,"text":34},"Technische Architektur von Owlats typisiertem Wissensspeicher — wie Organisationswissen abgelegt, durchsucht, im Wert gemindert und gepflegt wird.","md",{},"\u002Fvision\u002Fknowledge-graph",{"title":6,"description":3861},"5.vision\u002F3.knowledge-graph","_AWwjuBPZY_dAlcFRkAayJWsov6eUQO2wbMMSRYvPOc",[3869,3871],{"title":2158,"path":2157,"stem":3870,"children":-1},"5.vision\u002F2.agent-pipeline",{"title":3872,"path":3873,"stem":3874,"children":-1},"Multi-Channel & CRM","\u002Fvision\u002Fmulti-channel","5.vision\u002F4.multi-channel",1786915111233]