[{"data":1,"prerenderedAt":611},["ShallowReactive",2],{"navigation_docs":3,"-memory":139,"-memory-surround":606},[4,8,12,16,20,24,28,32,59,63,117,121,135],{"title":5,"path":6,"stem":7},"Introduction","\u002Fintroduction","1.introduction",{"title":9,"path":10,"stem":11},"Memory","\u002Fmemory","10.memory",{"title":13,"path":14,"stem":15},"Customization","\u002Fcustomization","11.customization",{"title":17,"path":18,"stem":19},"Deployment","\u002Fdeployment","12.deployment",{"title":21,"path":22,"stem":23},"Reference","\u002Freference","13.reference",{"title":25,"path":26,"stem":27},"Quickstart","\u002Fquickstart","2.quickstart",{"title":29,"path":30,"stem":31},"Installation","\u002Finstallation","3.installation",{"title":33,"icon":34,"path":35,"stem":36,"children":37,"page":58},"Connectors","i-lucide-cable","\u002Fconnectors","4.connectors",[38,42,46,50,54],{"title":39,"path":40,"stem":41},"Telegram","\u002Fconnectors\u002Ftelegram","4.connectors\u002F1.telegram",{"title":43,"path":44,"stem":45},"Slack","\u002Fconnectors\u002Fslack","4.connectors\u002F2.slack",{"title":47,"path":48,"stem":49},"Email","\u002Fconnectors\u002Femail","4.connectors\u002F3.email",{"title":51,"path":52,"stem":53},"API","\u002Fconnectors\u002Fapi","4.connectors\u002F4.api",{"title":55,"path":56,"stem":57},"Terminal","\u002Fconnectors\u002Fterminal","4.connectors\u002F5.terminal",false,{"title":60,"path":61,"stem":62},"Attachments","\u002Fattachments","5.attachments",{"title":64,"icon":65,"path":66,"stem":67,"children":68,"page":58},"Tools","i-lucide-wrench","\u002Ftools","6.tools",[69,73,77,81,85,89,93,97,101,105,109,113],{"title":70,"path":71,"stem":72},"File Manager","\u002Ftools\u002Ffile-manager","6.tools\u002F1.file-manager",{"title":74,"path":75,"stem":76},"Text-to-Speech","\u002Ftools\u002Ftext-to-speech","6.tools\u002F10.text-to-speech",{"title":78,"path":79,"stem":80},"Confirmations","\u002Ftools\u002Fconfirmations","6.tools\u002F11.confirmations",{"title":82,"path":83,"stem":84},"Adding Custom Tools","\u002Ftools\u002Fadding-custom-tools","6.tools\u002F12.adding-custom-tools",{"title":86,"path":87,"stem":88},"Image Manager","\u002Ftools\u002Fimage-manager","6.tools\u002F2.image-manager",{"title":90,"path":91,"stem":92},"Web Request","\u002Ftools\u002Fweb-request","6.tools\u002F3.web-request",{"title":94,"path":95,"stem":96},"Reminders","\u002Ftools\u002Freminders","6.tools\u002F4.reminders",{"title":98,"path":99,"stem":100},"Heartbeats","\u002Ftools\u002Fheartbeats","6.tools\u002F5.heartbeats",{"title":102,"path":103,"stem":104},"Email Manager","\u002Ftools\u002Femail-manager","6.tools\u002F6.email-manager",{"title":106,"path":107,"stem":108},"Calendar","\u002Ftools\u002Fcalendar","6.tools\u002F7.calendar",{"title":110,"path":111,"stem":112},"Read Database","\u002Ftools\u002Fread-database","6.tools\u002F8.read-database",{"title":114,"path":115,"stem":116},"Headless Browser","\u002Ftools\u002Fbrowser","6.tools\u002F9.browser",{"title":118,"path":119,"stem":120},"Tinker","\u002Ftinker","7.tinker",{"title":122,"icon":123,"path":124,"stem":125,"children":126,"page":58},"Skills","i-lucide-sparkles","\u002Fskills","8.skills",[127,131],{"title":128,"path":129,"stem":130},"Overview","\u002Fskills\u002Foverview","8.skills\u002F1.overview",{"title":132,"path":133,"stem":134},"Adding Custom Skills","\u002Fskills\u002Fadding-custom-skills","8.skills\u002F2.adding-custom-skills",{"title":136,"path":137,"stem":138},"Personas","\u002Fpersonas","9.personas",{"id":140,"title":9,"body":141,"description":599,"extension":600,"links":601,"meta":602,"navigation":603,"path":10,"seo":604,"stem":11,"__hash__":605},"docs\u002F10.memory.md",{"type":142,"value":143,"toc":585},"minimark",[144,148,152,160,168,171,175,178,204,215,222,233,239,243,257,300,303,307,314,321,328,335,352,355,371,424,430,434,437,442,458,465,476,479,483,486,489,497,501,511,521,524,528,531,540,543,546,555,559,578,581],[145,146,5],"h2",{"id":147},"introduction",[149,150,151],"p",{},"You've been chatting with your agent for weeks. Last Tuesday it helped you draft a release note, last month it filed three invoices. Today you ask \"what was the title of that release note again?\" — and it has no idea what you're talking about.",[149,153,154,155,159],{},"That's because, by default, the agent only sees the recent turns of the ",[156,157,158],"em",{},"current"," thread. Past threads, last week's PDFs, the email it filed for you on Monday — all invisible.",[149,161,162,163,167],{},"Laraclaw fixes this with optional ",[164,165,166],"strong",{},"memory"," powered by retrieval-augmented generation (RAG). When enabled, every message and response is chunked, embedded, and stored. On every new prompt, the agent can call a tool to retrieve the most relevant past chunks and pull them into context. Pretty cool, right?",[149,169,170],{},"Let's set it up.",[145,172,174],{"id":173},"enabling-memory","Enabling Memory",[149,176,177],{},"Two ways to do it. The wizard:",[179,180,185],"pre",{"className":181,"code":182,"language":183,"meta":184,"style":184},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","php artisan laraclaw:setup-memory\n","bash","",[186,187,188],"code",{"__ignoreMap":184},[189,190,193,197,201],"span",{"class":191,"line":192},"line",1,[189,194,196],{"class":195},"sBMFI","php",[189,198,200],{"class":199},"sfazB"," artisan",[189,202,203],{"class":199}," laraclaw:setup-memory\n",[149,205,206,207,210,211,214],{},"It walks you through enabling memory, picking an embedding provider for ",[186,208,209],{},"laravel\u002Fai",", and (if you're on Postgres) checking for ",[186,212,213],{},"pgvector",".",[149,216,217,218,221],{},"Or just flip the switch in ",[186,219,220],{},".env",":",[179,223,227],{"className":224,"code":225,"language":226,"meta":184,"style":184},"language-env shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","LARACLAW_MEMORY_ENABLED=true\n","env",[186,228,229],{"__ignoreMap":184},[189,230,231],{"class":191,"line":192},[189,232,225],{},[149,234,235,236,238],{},"You'll need an embedding provider configured for ",[186,237,209],{}," either way — the wizard takes care of this.",[145,240,242],{"id":241},"how-embedding-works","How Embedding Works",[149,244,245,246,249,250,252,253,256],{},"Memory hooks into the ",[186,247,248],{},"AgentPrompted"," event from ",[186,251,209],{},". After every agent turn, the ",[186,254,255],{},"EmbedConversation"," listener picks up the inbound message, the agent's response, and any attached files, and:",[258,259,260,271,281,290],"ol",{},[261,262,263,266,267,270],"li",{},[164,264,265],{},"Extracts text"," from each attachment via ",[186,268,269],{},"TextExtractor"," — PDFs, OCR for images, plain documents.",[261,272,273,276,277,280],{},[164,274,275],{},"Chunks the text"," into overlapping segments via ",[186,278,279],{},"ContentChunker",". Overlap matters here: a chunk boundary that splits a sentence is a chunk boundary that hides context, so we let neighbours overlap a bit.",[261,282,283,286,287,214],{},[164,284,285],{},"Generates embeddings"," via ",[186,288,289],{},"Laravel\\Ai\\Embeddings",[261,291,292,295,296,299],{},[164,293,294],{},"Stores them"," in the ",[186,297,298],{},"laraclaw_embeddings"," table, deduped by content hash so we never re-embed the same chunk twice.",[149,301,302],{},"The whole thing is queued, so it doesn't block the agent's reply. The user gets their answer right away; the embedding work happens in the background.",[145,304,306],{"id":305},"how-retrieval-works","How Retrieval Works",[149,308,309,310,313],{},"Retrieval happens through the ",[186,311,312],{},"MemoryManager"," tool. When the agent decides past context might help, it calls the tool with a query and gets back the most similar chunks.",[149,315,316,317,320],{},"Now, this is important: ",[164,318,319],{},"nothing is injected automatically",". The agent is always in control of when to look something up. If the agent doesn't think it needs memory, it doesn't pay the token cost — and you don't get noisy context bloating every reply.",[149,322,323,324,327],{},"The flip side is that the agent has to ",[156,325,326],{},"know"," to go looking. Left to itself it will happily answer \"I don't have that in this chat\" from the current thread alone, because that is a perfectly truthful answer about the context in front of it. So when memory is enabled, Laraclaw adds a section to the system prompt telling it that past conversations exist, are not loaded for it, and must be searched before it claims not to know something.",[149,329,330,331,334],{},"That guidance appears only while ",[186,332,333],{},"LARACLAW_MEMORY_ENABLED=true",", so apps without memory aren't told about a tool they don't have.",[336,337,338],"blockquote",{},[149,339,340,343,344,347,348,351],{},[189,341,342],{},"!TIP","\nIf the agent still answers from thin air on a question it should have looked up, sharpen the wording in ",[186,345,346],{},"laraclaw\u002Finstructions.md"," rather than lowering ",[186,349,350],{},"LARACLAW_MEMORY_MIN_SIMILARITY",". The usual failure is not searching at all, not searching and missing.",[149,353,354],{},"Two settings shape what comes back:",[179,356,358],{"className":224,"code":357,"language":226,"meta":184,"style":184},"LARACLAW_MEMORY_MAX_RESULTS=5\nLARACLAW_MEMORY_MIN_SIMILARITY=0.5\n",[186,359,360,365],{"__ignoreMap":184},[189,361,362],{"class":191,"line":192},[189,363,364],{},"LARACLAW_MEMORY_MAX_RESULTS=5\n",[189,366,368],{"class":191,"line":367},2,[189,369,370],{},"LARACLAW_MEMORY_MIN_SIMILARITY=0.5\n",[372,373,374,390],"table",{},[375,376,377],"thead",{},[378,379,380,384,387],"tr",{},[381,382,383],"th",{},"Setting",[381,385,386],{},"Default",[381,388,389],{},"Description",[391,392,393,409],"tbody",{},[378,394,395,401,406],{},[396,397,398],"td",{},[186,399,400],{},"max_results",[396,402,403],{},[186,404,405],{},"5",[396,407,408],{},"Maximum number of chunks returned per call",[378,410,411,416,421],{},[396,412,413],{},[186,414,415],{},"min_similarity",[396,417,418],{},[186,419,420],{},"0.5",[396,422,423],{},"Minimum cosine similarity (0–1) for a chunk to be returned",[149,425,426,427,429],{},"Lower ",[186,428,415],{}," to retrieve more loosely related context. Raise it to keep retrieval tight. The defaults are conservative — start there and adjust if the agent is missing context (lower threshold) or pulling noise (raise threshold).",[145,431,433],{"id":432},"storage-backends","Storage Backends",[149,435,436],{},"Laraclaw picks one of two storage backends automatically based on your database driver. You don't choose — the migration detects what you've got and does the right thing.",[438,439,441],"h3",{"id":440},"postgresql-with-pgvector-recommended","PostgreSQL with pgvector (Recommended)",[149,443,444,445,453,454,457],{},"If your database is PostgreSQL and the ",[446,447,451],"a",{"href":448,"rel":449},"https:\u002F\u002Fgithub.com\u002Fpgvector\u002Fpgvector",[450],"nofollow",[186,452,213],{}," extension is installed, the embeddings table uses a native ",[186,455,456],{},"vector"," column with an HNSW index. Similarity search runs as a single SQL query and scales to millions of rows.",[149,459,460,461,464],{},"Install the extension on your Postgres server ",[156,462,463],{},"before"," running the Laraclaw migrations:",[179,466,470],{"className":467,"code":468,"language":469,"meta":184,"style":184},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","CREATE EXTENSION vector;\n","sql",[186,471,472],{"__ignoreMap":184},[189,473,474],{"class":191,"line":192},[189,475,468],{},[149,477,478],{},"The migration detects pgvector at install time and creates the column accordingly.",[438,480,482],{"id":481},"json-fallback","JSON Fallback",[149,484,485],{},"Without pgvector, embeddings are stored as JSON and cosine similarity is computed in PHP at query time. This works on any database — MySQL, SQLite, Postgres without pgvector — but slows down past a few thousand rows.",[149,487,488],{},"The JSON fallback is fine for development and small installations. For production with significant memory, use pgvector.",[336,490,491],{},[149,492,493,496],{},[189,494,495],{},"!IMPORTANT","\nSwitching backends after the fact requires a manual migration: the column type is decided once, at install time. If you start on JSON and later install pgvector, you'll need to re-create the table and re-embed existing content.",[145,498,500],{"id":499},"memory-is-owner-wide","Memory Is Owner-Wide",[149,502,503,504,506,507,510],{},"The ",[186,505,298],{}," table is the only Laraclaw table that ",[164,508,509],{},"stores anything across conversations",", and it is shared per owner — there is exactly one memory pool per install.",[149,512,513,514,517,518,214],{},"So if the agent helps you with one project on Telegram and another in a Slack DM, both threads see the same memory. That's usually what you want — the bot remembers ",[156,515,516],{},"you",", not ",[156,519,520],{},"which channel you were in",[149,522,523],{},"If you don't want this, the simplest option is to scope retrieval yourself in a custom tool, or run a separate Laraclaw install per context.",[145,525,527],{"id":526},"disabling-and-resetting","Disabling and Resetting",[149,529,530],{},"To turn memory off:",[179,532,534],{"className":224,"code":533,"language":226,"meta":184,"style":184},"LARACLAW_MEMORY_ENABLED=false\n",[186,535,536],{"__ignoreMap":184},[189,537,538],{"class":191,"line":192},[189,539,533],{},[149,541,542],{},"Existing embeddings stay in the database but are no longer retrieved or written to.",[149,544,545],{},"To clear everything:",[179,547,549],{"className":467,"code":548,"language":469,"meta":184,"style":184},"TRUNCATE TABLE laraclaw_embeddings;\n",[186,550,551],{"__ignoreMap":184},[189,552,553],{"class":191,"line":192},[189,554,548],{},[145,556,558],{"id":557},"whats-next","What's Next",[560,561,562,572],"ul",{},[261,563,564,568,569,214],{},[446,565,567],{"href":566},"\u002Fcustomization#cost","Customization → Cost"," — memory is the largest variable cost driver, so worth re-reading the cost section before you bump ",[186,570,571],{},"LARACLAW_MEMORY_MAX_RESULTS",[261,573,574,577],{},[446,575,21],{"href":576},"\u002Freference#memory"," — every memory environment variable in one place.",[149,579,580],{},"Until next time!",[582,583,584],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",{"title":184,"searchDepth":367,"depth":367,"links":586},[587,588,589,590,591,596,597,598],{"id":147,"depth":367,"text":5},{"id":173,"depth":367,"text":174},{"id":241,"depth":367,"text":242},{"id":305,"depth":367,"text":306},{"id":432,"depth":367,"text":433,"children":592},[593,595],{"id":440,"depth":594,"text":441},3,{"id":481,"depth":594,"text":482},{"id":499,"depth":367,"text":500},{"id":526,"depth":367,"text":527},{"id":557,"depth":367,"text":558},"Give the agent persistent memory of past conversations and attached documents using RAG.","md",null,{},true,{"title":9,"description":599},"lVzsrm3HlVfFPuSJ-dRnE9c7xwQvDO9tdM7qICpW8CQ",[607,609],{"title":5,"path":6,"stem":7,"description":608,"children":-1},"What Laraclaw is, who it's for, the moving parts, and how the agent loop works.",{"title":13,"path":14,"stem":15,"description":610,"children":-1},"Bend Laraclaw to your needs without writing a tool — system prompts, rate limiting, logging, custom commands, and event hooks.",1786661906119]