[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-tanstack-tanstack-ai-memory":3,"mdc-hh641b-key":50,"related-repo-tanstack-tanstack-ai-memory":1513,"related-org-tanstack-tanstack-ai-memory":1617},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":24,"topics":25,"repo":45,"sourceUrl":48,"mdContent":49},"tanstack-ai-memory","wire TanStack AI memory middleware","Use when wiring memoryMiddleware from @tanstack\u002Fai-memory into a chat() call — covers the recall\u002Fsave adapter contract, scope shape and server-side scope security, the recall-inject \u002F deferred-save lifecycle, choosing an adapter (inMemory, redis, hindsight, mem0, honcho), and devtools events.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"tanstack","TanStack","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Ftanstack.png",[12,16,19],{"name":13,"slug":14,"type":15},"Memory","memory","tag",{"name":17,"slug":18,"type":15},"Agents","agents",{"name":9,"slug":8,"type":15},2884,"https:\u002F\u002Fgithub.com\u002FTanStack\u002Fai","2026-07-26T06:08:45.538491",null,269,[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,8,41,42,43,44],"ai","ai-agents","ai-sdk","anthropic","chatbot","function-calling","gemini","generative-ai","llm","multimodal","openai","react","solidjs","streaming","svelte","tool-calling","typescript","typescript-sdk","vue",{"repoUrl":21,"stars":20,"forks":24,"topics":46,"description":47},[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,8,41,42,43,44],"🤖 Type-safe, provider-agnostic TypeScript AI SDK for streaming chat, tool calling, agents, and multimodal apps across OpenAI, Anthropic, Gemini, React, Vue, Svelte, and Solid.","https:\u002F\u002Fgithub.com\u002FTanStack\u002Fai\u002Ftree\u002FHEAD\u002Fpackages\u002Fai-memory\u002Fskills\u002Ftanstack-ai-memory","---\nname: tanstack-ai-memory\ndescription: Use when wiring memoryMiddleware from @tanstack\u002Fai-memory into a chat() call — covers the recall\u002Fsave adapter contract, scope shape and server-side scope security, the recall-inject \u002F deferred-save lifecycle, choosing an adapter (inMemory, redis, hindsight, mem0, honcho), and devtools events.\n---\n\n# TanStack AI Memory Middleware\n\nUse this when adding **server-side memory** to a `chat()` call. Everything lives in\n`@tanstack\u002Fai-memory`. A memory adapter is a single contract with two verbs — `recall`\nand `save` — and the middleware is thin: it recalls into the system prompt before the\nmodel runs and defers `save` after the turn finishes.\n\n## When to reach for it\n\n- A user expects \"remember what I told you last time.\"\n- Per-user or per-thread context that must survive across sessions.\n- A hosted memory service (mem0, Honcho, Hindsight).\n\nDo NOT use this just to keep recent messages — that's the `messages` array on `chat()`.\nMemory is for cross-turn \u002F cross-session recall, not within-turn history.\n\n## Wire it up\n\n```ts\nimport { chat } from '@tanstack\u002Fai'\nimport { openaiText } from '@tanstack\u002Fai-openai'\nimport { memoryMiddleware } from '@tanstack\u002Fai-memory'\nimport { inMemory } from '@tanstack\u002Fai-memory\u002Fin-memory'\n\nconst memory = inMemory() \u002F\u002F dev\u002Ftests only — see the in-memory skill\n\nconst stream = chat({\n  adapter: openaiText('gpt-5.5'),\n  messages,\n  context: { session }, \u002F\u002F attached by your auth middleware\n  middleware: [\n    memoryMiddleware({\n      adapter: memory,\n      \u002F\u002F Derive scope server-side from trusted session state.\n      scope: (ctx) => {\n        const session = getSession(ctx)\n        return { threadId: session.threadId, userId: session.userId }\n      },\n    }),\n  ],\n})\n```\n\n`memoryMiddleware` options: `adapter`, `scope` (static or a function of `ctx`),\n`role` (`'recall+save'` default, or `'save-only'`), and `onRecall` \u002F `onSave` telemetry\ncallbacks.\n\n## The contract\n\n```ts\ninterface MemoryAdapter {\n  id: string\n  recall(scope, query): Promise\u003CRecallResult> \u002F\u002F { systemPrompt, fragments?, tools?, toolGuidance? }\n  save(scope, turn): Promise\u003CArray\u003CSaveReceipt>> \u002F\u002F turn = { user, assistant }; extraction lives HERE\n  inspect?(scope): Promise\u003CMemorySnapshot> \u002F\u002F optional (devtools)\n  listFacts?(scope): Promise\u003CArray\u003CMemoryFact>> \u002F\u002F optional (devtools)\n}\n```\n\n- `recall` decides relevance and renders a `systemPrompt`; it may also return `tools` +\n  `toolGuidance` to hand the model direct control of memory (hindsight does this).\n- `save` owns extraction — turning the raw turn into whatever gets persisted.\n\n## Scope security\n\n`MemoryScope` is an alias of the shared `Scope` type from `@tanstack\u002Fai`:\n`{ threadId, userId?, tenantId?, namespace? }`. It is the isolation boundary. **Never\ntrust a client-supplied `userId`\u002F`threadId`.** Resolve scope server-side from\nsession\u002Fauth and pass the validated session through `chat({ context: { session } })`. If\nyou accept a thread id from the request body, validate it belongs to the session user\nBEFORE using it.\n\n## Adapters\n\n- `inMemory()` \u002F `redis()` — exact match on `threadId` + optional `userId`\u002F`tenantId`\n  (`namespace` ignored). Redis index keys include all three segments.\n- `hindsight()` — bank `{tenant|_}__{user}__{threadId}`.\n- `mem0()` — `user_id` + `run_id` (`threadId`); no `tenantId`.\n- `honcho()` — session `{tenant|_}__{threadId}`; peer tenant-prefixed when set.\n- Custom — implement `recall`\u002F`save` and run `@tanstack\u002Fai-memory\u002Ftests\u002Fcontract`.\n\n## Failure modes\n\nMemory failures are non-fatal: a throwing `recall` or `save` emits `memory:error` and\nthe run continues with degraded memory. Streaming is never blocked; a failed save never\nfails the turn.\n\n## Devtools\n\nFive events on `aiEventClient` (from `@tanstack\u002Fai-event-client`):\n`memory:retrieve:started` \u002F `:completed`, `memory:persist:started` \u002F `:completed`,\n`memory:error` (`phase: 'recall' | 'save'`). Payloads carry the adapter id and\nfragment\u002Freceipt counts, not full memory text. Error events include `scope` only\nwhen it was already resolved; if the resolver threw, `scope` is omitted.\n",{"data":51,"body":52},{"name":4,"description":6},{"type":53,"children":54},"root",[55,64,118,125,145,165,171,783,856,862,1120,1167,1173,1235,1241,1392,1398,1425,1431,1507],{"type":56,"tag":57,"props":58,"children":60},"element","h1",{"id":59},"tanstack-ai-memory-middleware",[61],{"type":62,"value":63},"text","TanStack AI Memory Middleware",{"type":56,"tag":65,"props":66,"children":67},"p",{},[68,70,76,78,85,87,93,95,101,103,109,111,116],{"type":62,"value":69},"Use this when adding ",{"type":56,"tag":71,"props":72,"children":73},"strong",{},[74],{"type":62,"value":75},"server-side memory",{"type":62,"value":77}," to a ",{"type":56,"tag":79,"props":80,"children":82},"code",{"className":81},[],[83],{"type":62,"value":84},"chat()",{"type":62,"value":86}," call. Everything lives in\n",{"type":56,"tag":79,"props":88,"children":90},{"className":89},[],[91],{"type":62,"value":92},"@tanstack\u002Fai-memory",{"type":62,"value":94},". A memory adapter is a single contract with two verbs — ",{"type":56,"tag":79,"props":96,"children":98},{"className":97},[],[99],{"type":62,"value":100},"recall",{"type":62,"value":102},"\nand ",{"type":56,"tag":79,"props":104,"children":106},{"className":105},[],[107],{"type":62,"value":108},"save",{"type":62,"value":110}," — and the middleware is thin: it recalls into the system prompt before the\nmodel runs and defers ",{"type":56,"tag":79,"props":112,"children":114},{"className":113},[],[115],{"type":62,"value":108},{"type":62,"value":117}," after the turn finishes.",{"type":56,"tag":119,"props":120,"children":122},"h2",{"id":121},"when-to-reach-for-it",[123],{"type":62,"value":124},"When to reach for it",{"type":56,"tag":126,"props":127,"children":128},"ul",{},[129,135,140],{"type":56,"tag":130,"props":131,"children":132},"li",{},[133],{"type":62,"value":134},"A user expects \"remember what I told you last time.\"",{"type":56,"tag":130,"props":136,"children":137},{},[138],{"type":62,"value":139},"Per-user or per-thread context that must survive across sessions.",{"type":56,"tag":130,"props":141,"children":142},{},[143],{"type":62,"value":144},"A hosted memory service (mem0, Honcho, Hindsight).",{"type":56,"tag":65,"props":146,"children":147},{},[148,150,156,158,163],{"type":62,"value":149},"Do NOT use this just to keep recent messages — that's the ",{"type":56,"tag":79,"props":151,"children":153},{"className":152},[],[154],{"type":62,"value":155},"messages",{"type":62,"value":157}," array on ",{"type":56,"tag":79,"props":159,"children":161},{"className":160},[],[162],{"type":62,"value":84},{"type":62,"value":164},".\nMemory is for cross-turn \u002F cross-session recall, not within-turn history.",{"type":56,"tag":119,"props":166,"children":168},{"id":167},"wire-it-up",[169],{"type":62,"value":170},"Wire it up",{"type":56,"tag":172,"props":173,"children":178},"pre",{"className":174,"code":175,"language":176,"meta":177,"style":177},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { chat } from '@tanstack\u002Fai'\nimport { openaiText } from '@tanstack\u002Fai-openai'\nimport { memoryMiddleware } from '@tanstack\u002Fai-memory'\nimport { inMemory } from '@tanstack\u002Fai-memory\u002Fin-memory'\n\nconst memory = inMemory() \u002F\u002F dev\u002Ftests only — see the in-memory skill\n\nconst stream = chat({\n  adapter: openaiText('gpt-5.5'),\n  messages,\n  context: { session }, \u002F\u002F attached by your auth middleware\n  middleware: [\n    memoryMiddleware({\n      adapter: memory,\n      \u002F\u002F Derive scope server-side from trusted session state.\n      scope: (ctx) => {\n        const session = getSession(ctx)\n        return { threadId: session.threadId, userId: session.userId }\n      },\n    }),\n  ],\n})\n","ts","",[179],{"type":56,"tag":79,"props":180,"children":181},{"__ignoreMap":177},[182,232,270,307,345,355,391,399,430,477,490,522,540,557,579,588,626,663,731,740,757,770],{"type":56,"tag":183,"props":184,"children":187},"span",{"class":185,"line":186},"line",1,[188,194,200,206,211,216,221,227],{"type":56,"tag":183,"props":189,"children":191},{"style":190},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[192],{"type":62,"value":193},"import",{"type":56,"tag":183,"props":195,"children":197},{"style":196},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[198],{"type":62,"value":199}," {",{"type":56,"tag":183,"props":201,"children":203},{"style":202},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[204],{"type":62,"value":205}," chat",{"type":56,"tag":183,"props":207,"children":208},{"style":196},[209],{"type":62,"value":210}," }",{"type":56,"tag":183,"props":212,"children":213},{"style":190},[214],{"type":62,"value":215}," from",{"type":56,"tag":183,"props":217,"children":218},{"style":196},[219],{"type":62,"value":220}," '",{"type":56,"tag":183,"props":222,"children":224},{"style":223},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[225],{"type":62,"value":226},"@tanstack\u002Fai",{"type":56,"tag":183,"props":228,"children":229},{"style":196},[230],{"type":62,"value":231},"'\n",{"type":56,"tag":183,"props":233,"children":235},{"class":185,"line":234},2,[236,240,244,249,253,257,261,266],{"type":56,"tag":183,"props":237,"children":238},{"style":190},[239],{"type":62,"value":193},{"type":56,"tag":183,"props":241,"children":242},{"style":196},[243],{"type":62,"value":199},{"type":56,"tag":183,"props":245,"children":246},{"style":202},[247],{"type":62,"value":248}," openaiText",{"type":56,"tag":183,"props":250,"children":251},{"style":196},[252],{"type":62,"value":210},{"type":56,"tag":183,"props":254,"children":255},{"style":190},[256],{"type":62,"value":215},{"type":56,"tag":183,"props":258,"children":259},{"style":196},[260],{"type":62,"value":220},{"type":56,"tag":183,"props":262,"children":263},{"style":223},[264],{"type":62,"value":265},"@tanstack\u002Fai-openai",{"type":56,"tag":183,"props":267,"children":268},{"style":196},[269],{"type":62,"value":231},{"type":56,"tag":183,"props":271,"children":273},{"class":185,"line":272},3,[274,278,282,287,291,295,299,303],{"type":56,"tag":183,"props":275,"children":276},{"style":190},[277],{"type":62,"value":193},{"type":56,"tag":183,"props":279,"children":280},{"style":196},[281],{"type":62,"value":199},{"type":56,"tag":183,"props":283,"children":284},{"style":202},[285],{"type":62,"value":286}," memoryMiddleware",{"type":56,"tag":183,"props":288,"children":289},{"style":196},[290],{"type":62,"value":210},{"type":56,"tag":183,"props":292,"children":293},{"style":190},[294],{"type":62,"value":215},{"type":56,"tag":183,"props":296,"children":297},{"style":196},[298],{"type":62,"value":220},{"type":56,"tag":183,"props":300,"children":301},{"style":223},[302],{"type":62,"value":92},{"type":56,"tag":183,"props":304,"children":305},{"style":196},[306],{"type":62,"value":231},{"type":56,"tag":183,"props":308,"children":310},{"class":185,"line":309},4,[311,315,319,324,328,332,336,341],{"type":56,"tag":183,"props":312,"children":313},{"style":190},[314],{"type":62,"value":193},{"type":56,"tag":183,"props":316,"children":317},{"style":196},[318],{"type":62,"value":199},{"type":56,"tag":183,"props":320,"children":321},{"style":202},[322],{"type":62,"value":323}," inMemory",{"type":56,"tag":183,"props":325,"children":326},{"style":196},[327],{"type":62,"value":210},{"type":56,"tag":183,"props":329,"children":330},{"style":190},[331],{"type":62,"value":215},{"type":56,"tag":183,"props":333,"children":334},{"style":196},[335],{"type":62,"value":220},{"type":56,"tag":183,"props":337,"children":338},{"style":223},[339],{"type":62,"value":340},"@tanstack\u002Fai-memory\u002Fin-memory",{"type":56,"tag":183,"props":342,"children":343},{"style":196},[344],{"type":62,"value":231},{"type":56,"tag":183,"props":346,"children":348},{"class":185,"line":347},5,[349],{"type":56,"tag":183,"props":350,"children":352},{"emptyLinePlaceholder":351},true,[353],{"type":62,"value":354},"\n",{"type":56,"tag":183,"props":356,"children":358},{"class":185,"line":357},6,[359,365,370,375,380,385],{"type":56,"tag":183,"props":360,"children":362},{"style":361},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[363],{"type":62,"value":364},"const",{"type":56,"tag":183,"props":366,"children":367},{"style":202},[368],{"type":62,"value":369}," memory ",{"type":56,"tag":183,"props":371,"children":372},{"style":196},[373],{"type":62,"value":374},"=",{"type":56,"tag":183,"props":376,"children":378},{"style":377},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[379],{"type":62,"value":323},{"type":56,"tag":183,"props":381,"children":382},{"style":202},[383],{"type":62,"value":384},"() ",{"type":56,"tag":183,"props":386,"children":388},{"style":387},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[389],{"type":62,"value":390},"\u002F\u002F dev\u002Ftests only — see the in-memory skill\n",{"type":56,"tag":183,"props":392,"children":394},{"class":185,"line":393},7,[395],{"type":56,"tag":183,"props":396,"children":397},{"emptyLinePlaceholder":351},[398],{"type":62,"value":354},{"type":56,"tag":183,"props":400,"children":402},{"class":185,"line":401},8,[403,407,412,416,420,425],{"type":56,"tag":183,"props":404,"children":405},{"style":361},[406],{"type":62,"value":364},{"type":56,"tag":183,"props":408,"children":409},{"style":202},[410],{"type":62,"value":411}," stream ",{"type":56,"tag":183,"props":413,"children":414},{"style":196},[415],{"type":62,"value":374},{"type":56,"tag":183,"props":417,"children":418},{"style":377},[419],{"type":62,"value":205},{"type":56,"tag":183,"props":421,"children":422},{"style":202},[423],{"type":62,"value":424},"(",{"type":56,"tag":183,"props":426,"children":427},{"style":196},[428],{"type":62,"value":429},"{\n",{"type":56,"tag":183,"props":431,"children":433},{"class":185,"line":432},9,[434,440,445,449,453,458,463,467,472],{"type":56,"tag":183,"props":435,"children":437},{"style":436},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[438],{"type":62,"value":439},"  adapter",{"type":56,"tag":183,"props":441,"children":442},{"style":196},[443],{"type":62,"value":444},":",{"type":56,"tag":183,"props":446,"children":447},{"style":377},[448],{"type":62,"value":248},{"type":56,"tag":183,"props":450,"children":451},{"style":202},[452],{"type":62,"value":424},{"type":56,"tag":183,"props":454,"children":455},{"style":196},[456],{"type":62,"value":457},"'",{"type":56,"tag":183,"props":459,"children":460},{"style":223},[461],{"type":62,"value":462},"gpt-5.5",{"type":56,"tag":183,"props":464,"children":465},{"style":196},[466],{"type":62,"value":457},{"type":56,"tag":183,"props":468,"children":469},{"style":202},[470],{"type":62,"value":471},")",{"type":56,"tag":183,"props":473,"children":474},{"style":196},[475],{"type":62,"value":476},",\n",{"type":56,"tag":183,"props":478,"children":480},{"class":185,"line":479},10,[481,486],{"type":56,"tag":183,"props":482,"children":483},{"style":202},[484],{"type":62,"value":485},"  messages",{"type":56,"tag":183,"props":487,"children":488},{"style":196},[489],{"type":62,"value":476},{"type":56,"tag":183,"props":491,"children":493},{"class":185,"line":492},11,[494,499,503,507,512,517],{"type":56,"tag":183,"props":495,"children":496},{"style":436},[497],{"type":62,"value":498},"  context",{"type":56,"tag":183,"props":500,"children":501},{"style":196},[502],{"type":62,"value":444},{"type":56,"tag":183,"props":504,"children":505},{"style":196},[506],{"type":62,"value":199},{"type":56,"tag":183,"props":508,"children":509},{"style":202},[510],{"type":62,"value":511}," session ",{"type":56,"tag":183,"props":513,"children":514},{"style":196},[515],{"type":62,"value":516},"},",{"type":56,"tag":183,"props":518,"children":519},{"style":387},[520],{"type":62,"value":521}," \u002F\u002F attached by your auth middleware\n",{"type":56,"tag":183,"props":523,"children":525},{"class":185,"line":524},12,[526,531,535],{"type":56,"tag":183,"props":527,"children":528},{"style":436},[529],{"type":62,"value":530},"  middleware",{"type":56,"tag":183,"props":532,"children":533},{"style":196},[534],{"type":62,"value":444},{"type":56,"tag":183,"props":536,"children":537},{"style":202},[538],{"type":62,"value":539}," [\n",{"type":56,"tag":183,"props":541,"children":543},{"class":185,"line":542},13,[544,549,553],{"type":56,"tag":183,"props":545,"children":546},{"style":377},[547],{"type":62,"value":548},"    memoryMiddleware",{"type":56,"tag":183,"props":550,"children":551},{"style":202},[552],{"type":62,"value":424},{"type":56,"tag":183,"props":554,"children":555},{"style":196},[556],{"type":62,"value":429},{"type":56,"tag":183,"props":558,"children":560},{"class":185,"line":559},14,[561,566,570,575],{"type":56,"tag":183,"props":562,"children":563},{"style":436},[564],{"type":62,"value":565},"      adapter",{"type":56,"tag":183,"props":567,"children":568},{"style":196},[569],{"type":62,"value":444},{"type":56,"tag":183,"props":571,"children":572},{"style":202},[573],{"type":62,"value":574}," memory",{"type":56,"tag":183,"props":576,"children":577},{"style":196},[578],{"type":62,"value":476},{"type":56,"tag":183,"props":580,"children":582},{"class":185,"line":581},15,[583],{"type":56,"tag":183,"props":584,"children":585},{"style":387},[586],{"type":62,"value":587},"      \u002F\u002F Derive scope server-side from trusted session state.\n",{"type":56,"tag":183,"props":589,"children":591},{"class":185,"line":590},16,[592,597,601,606,612,616,621],{"type":56,"tag":183,"props":593,"children":594},{"style":377},[595],{"type":62,"value":596},"      scope",{"type":56,"tag":183,"props":598,"children":599},{"style":196},[600],{"type":62,"value":444},{"type":56,"tag":183,"props":602,"children":603},{"style":196},[604],{"type":62,"value":605}," (",{"type":56,"tag":183,"props":607,"children":609},{"style":608},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic",[610],{"type":62,"value":611},"ctx",{"type":56,"tag":183,"props":613,"children":614},{"style":196},[615],{"type":62,"value":471},{"type":56,"tag":183,"props":617,"children":618},{"style":361},[619],{"type":62,"value":620}," =>",{"type":56,"tag":183,"props":622,"children":623},{"style":196},[624],{"type":62,"value":625}," {\n",{"type":56,"tag":183,"props":627,"children":629},{"class":185,"line":628},17,[630,635,640,645,650,654,658],{"type":56,"tag":183,"props":631,"children":632},{"style":361},[633],{"type":62,"value":634},"        const",{"type":56,"tag":183,"props":636,"children":637},{"style":202},[638],{"type":62,"value":639}," session",{"type":56,"tag":183,"props":641,"children":642},{"style":196},[643],{"type":62,"value":644}," =",{"type":56,"tag":183,"props":646,"children":647},{"style":377},[648],{"type":62,"value":649}," getSession",{"type":56,"tag":183,"props":651,"children":652},{"style":436},[653],{"type":62,"value":424},{"type":56,"tag":183,"props":655,"children":656},{"style":202},[657],{"type":62,"value":611},{"type":56,"tag":183,"props":659,"children":660},{"style":436},[661],{"type":62,"value":662},")\n",{"type":56,"tag":183,"props":664,"children":666},{"class":185,"line":665},18,[667,672,676,681,685,689,694,699,704,709,713,717,721,726],{"type":56,"tag":183,"props":668,"children":669},{"style":190},[670],{"type":62,"value":671},"        return",{"type":56,"tag":183,"props":673,"children":674},{"style":196},[675],{"type":62,"value":199},{"type":56,"tag":183,"props":677,"children":678},{"style":436},[679],{"type":62,"value":680}," threadId",{"type":56,"tag":183,"props":682,"children":683},{"style":196},[684],{"type":62,"value":444},{"type":56,"tag":183,"props":686,"children":687},{"style":202},[688],{"type":62,"value":639},{"type":56,"tag":183,"props":690,"children":691},{"style":196},[692],{"type":62,"value":693},".",{"type":56,"tag":183,"props":695,"children":696},{"style":202},[697],{"type":62,"value":698},"threadId",{"type":56,"tag":183,"props":700,"children":701},{"style":196},[702],{"type":62,"value":703},",",{"type":56,"tag":183,"props":705,"children":706},{"style":436},[707],{"type":62,"value":708}," userId",{"type":56,"tag":183,"props":710,"children":711},{"style":196},[712],{"type":62,"value":444},{"type":56,"tag":183,"props":714,"children":715},{"style":202},[716],{"type":62,"value":639},{"type":56,"tag":183,"props":718,"children":719},{"style":196},[720],{"type":62,"value":693},{"type":56,"tag":183,"props":722,"children":723},{"style":202},[724],{"type":62,"value":725},"userId",{"type":56,"tag":183,"props":727,"children":728},{"style":196},[729],{"type":62,"value":730}," }\n",{"type":56,"tag":183,"props":732,"children":734},{"class":185,"line":733},19,[735],{"type":56,"tag":183,"props":736,"children":737},{"style":196},[738],{"type":62,"value":739},"      },\n",{"type":56,"tag":183,"props":741,"children":743},{"class":185,"line":742},20,[744,749,753],{"type":56,"tag":183,"props":745,"children":746},{"style":196},[747],{"type":62,"value":748},"    }",{"type":56,"tag":183,"props":750,"children":751},{"style":202},[752],{"type":62,"value":471},{"type":56,"tag":183,"props":754,"children":755},{"style":196},[756],{"type":62,"value":476},{"type":56,"tag":183,"props":758,"children":760},{"class":185,"line":759},21,[761,766],{"type":56,"tag":183,"props":762,"children":763},{"style":202},[764],{"type":62,"value":765},"  ]",{"type":56,"tag":183,"props":767,"children":768},{"style":196},[769],{"type":62,"value":476},{"type":56,"tag":183,"props":771,"children":773},{"class":185,"line":772},22,[774,779],{"type":56,"tag":183,"props":775,"children":776},{"style":196},[777],{"type":62,"value":778},"}",{"type":56,"tag":183,"props":780,"children":781},{"style":202},[782],{"type":62,"value":662},{"type":56,"tag":65,"props":784,"children":785},{},[786,792,794,800,802,808,810,815,817,823,824,830,832,838,840,846,848,854],{"type":56,"tag":79,"props":787,"children":789},{"className":788},[],[790],{"type":62,"value":791},"memoryMiddleware",{"type":62,"value":793}," options: ",{"type":56,"tag":79,"props":795,"children":797},{"className":796},[],[798],{"type":62,"value":799},"adapter",{"type":62,"value":801},", ",{"type":56,"tag":79,"props":803,"children":805},{"className":804},[],[806],{"type":62,"value":807},"scope",{"type":62,"value":809}," (static or a function of ",{"type":56,"tag":79,"props":811,"children":813},{"className":812},[],[814],{"type":62,"value":611},{"type":62,"value":816},"),\n",{"type":56,"tag":79,"props":818,"children":820},{"className":819},[],[821],{"type":62,"value":822},"role",{"type":62,"value":605},{"type":56,"tag":79,"props":825,"children":827},{"className":826},[],[828],{"type":62,"value":829},"'recall+save'",{"type":62,"value":831}," default, or ",{"type":56,"tag":79,"props":833,"children":835},{"className":834},[],[836],{"type":62,"value":837},"'save-only'",{"type":62,"value":839},"), and ",{"type":56,"tag":79,"props":841,"children":843},{"className":842},[],[844],{"type":62,"value":845},"onRecall",{"type":62,"value":847}," \u002F ",{"type":56,"tag":79,"props":849,"children":851},{"className":850},[],[852],{"type":62,"value":853},"onSave",{"type":62,"value":855}," telemetry\ncallbacks.",{"type":56,"tag":119,"props":857,"children":859},{"id":858},"the-contract",[860],{"type":62,"value":861},"The contract",{"type":56,"tag":172,"props":863,"children":865},{"className":174,"code":864,"language":176,"meta":177,"style":177},"interface MemoryAdapter {\n  id: string\n  recall(scope, query): Promise\u003CRecallResult> \u002F\u002F { systemPrompt, fragments?, tools?, toolGuidance? }\n  save(scope, turn): Promise\u003CArray\u003CSaveReceipt>> \u002F\u002F turn = { user, assistant }; extraction lives HERE\n  inspect?(scope): Promise\u003CMemorySnapshot> \u002F\u002F optional (devtools)\n  listFacts?(scope): Promise\u003CArray\u003CMemoryFact>> \u002F\u002F optional (devtools)\n}\n",[866],{"type":56,"tag":79,"props":867,"children":868},{"__ignoreMap":177},[869,887,904,959,1020,1063,1112],{"type":56,"tag":183,"props":870,"children":871},{"class":185,"line":186},[872,877,883],{"type":56,"tag":183,"props":873,"children":874},{"style":361},[875],{"type":62,"value":876},"interface",{"type":56,"tag":183,"props":878,"children":880},{"style":879},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[881],{"type":62,"value":882}," MemoryAdapter",{"type":56,"tag":183,"props":884,"children":885},{"style":196},[886],{"type":62,"value":625},{"type":56,"tag":183,"props":888,"children":889},{"class":185,"line":234},[890,895,899],{"type":56,"tag":183,"props":891,"children":892},{"style":436},[893],{"type":62,"value":894},"  id",{"type":56,"tag":183,"props":896,"children":897},{"style":196},[898],{"type":62,"value":444},{"type":56,"tag":183,"props":900,"children":901},{"style":879},[902],{"type":62,"value":903}," string\n",{"type":56,"tag":183,"props":905,"children":906},{"class":185,"line":272},[907,912,916,920,924,929,934,939,944,949,954],{"type":56,"tag":183,"props":908,"children":909},{"style":436},[910],{"type":62,"value":911},"  recall",{"type":56,"tag":183,"props":913,"children":914},{"style":196},[915],{"type":62,"value":424},{"type":56,"tag":183,"props":917,"children":918},{"style":608},[919],{"type":62,"value":807},{"type":56,"tag":183,"props":921,"children":922},{"style":196},[923],{"type":62,"value":703},{"type":56,"tag":183,"props":925,"children":926},{"style":608},[927],{"type":62,"value":928}," query",{"type":56,"tag":183,"props":930,"children":931},{"style":196},[932],{"type":62,"value":933},"):",{"type":56,"tag":183,"props":935,"children":936},{"style":879},[937],{"type":62,"value":938}," Promise",{"type":56,"tag":183,"props":940,"children":941},{"style":196},[942],{"type":62,"value":943},"\u003C",{"type":56,"tag":183,"props":945,"children":946},{"style":879},[947],{"type":62,"value":948},"RecallResult",{"type":56,"tag":183,"props":950,"children":951},{"style":196},[952],{"type":62,"value":953},">",{"type":56,"tag":183,"props":955,"children":956},{"style":387},[957],{"type":62,"value":958}," \u002F\u002F { systemPrompt, fragments?, tools?, toolGuidance? }\n",{"type":56,"tag":183,"props":960,"children":961},{"class":185,"line":309},[962,967,971,975,979,984,988,992,996,1001,1005,1010,1015],{"type":56,"tag":183,"props":963,"children":964},{"style":436},[965],{"type":62,"value":966},"  save",{"type":56,"tag":183,"props":968,"children":969},{"style":196},[970],{"type":62,"value":424},{"type":56,"tag":183,"props":972,"children":973},{"style":608},[974],{"type":62,"value":807},{"type":56,"tag":183,"props":976,"children":977},{"style":196},[978],{"type":62,"value":703},{"type":56,"tag":183,"props":980,"children":981},{"style":608},[982],{"type":62,"value":983}," turn",{"type":56,"tag":183,"props":985,"children":986},{"style":196},[987],{"type":62,"value":933},{"type":56,"tag":183,"props":989,"children":990},{"style":879},[991],{"type":62,"value":938},{"type":56,"tag":183,"props":993,"children":994},{"style":196},[995],{"type":62,"value":943},{"type":56,"tag":183,"props":997,"children":998},{"style":879},[999],{"type":62,"value":1000},"Array",{"type":56,"tag":183,"props":1002,"children":1003},{"style":196},[1004],{"type":62,"value":943},{"type":56,"tag":183,"props":1006,"children":1007},{"style":879},[1008],{"type":62,"value":1009},"SaveReceipt",{"type":56,"tag":183,"props":1011,"children":1012},{"style":196},[1013],{"type":62,"value":1014},">>",{"type":56,"tag":183,"props":1016,"children":1017},{"style":387},[1018],{"type":62,"value":1019}," \u002F\u002F turn = { user, assistant }; extraction lives HERE\n",{"type":56,"tag":183,"props":1021,"children":1022},{"class":185,"line":347},[1023,1028,1033,1037,1041,1045,1049,1054,1058],{"type":56,"tag":183,"props":1024,"children":1025},{"style":436},[1026],{"type":62,"value":1027},"  inspect",{"type":56,"tag":183,"props":1029,"children":1030},{"style":196},[1031],{"type":62,"value":1032},"?(",{"type":56,"tag":183,"props":1034,"children":1035},{"style":608},[1036],{"type":62,"value":807},{"type":56,"tag":183,"props":1038,"children":1039},{"style":196},[1040],{"type":62,"value":933},{"type":56,"tag":183,"props":1042,"children":1043},{"style":879},[1044],{"type":62,"value":938},{"type":56,"tag":183,"props":1046,"children":1047},{"style":196},[1048],{"type":62,"value":943},{"type":56,"tag":183,"props":1050,"children":1051},{"style":879},[1052],{"type":62,"value":1053},"MemorySnapshot",{"type":56,"tag":183,"props":1055,"children":1056},{"style":196},[1057],{"type":62,"value":953},{"type":56,"tag":183,"props":1059,"children":1060},{"style":387},[1061],{"type":62,"value":1062}," \u002F\u002F optional (devtools)\n",{"type":56,"tag":183,"props":1064,"children":1065},{"class":185,"line":357},[1066,1071,1075,1079,1083,1087,1091,1095,1099,1104,1108],{"type":56,"tag":183,"props":1067,"children":1068},{"style":436},[1069],{"type":62,"value":1070},"  listFacts",{"type":56,"tag":183,"props":1072,"children":1073},{"style":196},[1074],{"type":62,"value":1032},{"type":56,"tag":183,"props":1076,"children":1077},{"style":608},[1078],{"type":62,"value":807},{"type":56,"tag":183,"props":1080,"children":1081},{"style":196},[1082],{"type":62,"value":933},{"type":56,"tag":183,"props":1084,"children":1085},{"style":879},[1086],{"type":62,"value":938},{"type":56,"tag":183,"props":1088,"children":1089},{"style":196},[1090],{"type":62,"value":943},{"type":56,"tag":183,"props":1092,"children":1093},{"style":879},[1094],{"type":62,"value":1000},{"type":56,"tag":183,"props":1096,"children":1097},{"style":196},[1098],{"type":62,"value":943},{"type":56,"tag":183,"props":1100,"children":1101},{"style":879},[1102],{"type":62,"value":1103},"MemoryFact",{"type":56,"tag":183,"props":1105,"children":1106},{"style":196},[1107],{"type":62,"value":1014},{"type":56,"tag":183,"props":1109,"children":1110},{"style":387},[1111],{"type":62,"value":1062},{"type":56,"tag":183,"props":1113,"children":1114},{"class":185,"line":393},[1115],{"type":56,"tag":183,"props":1116,"children":1117},{"style":196},[1118],{"type":62,"value":1119},"}\n",{"type":56,"tag":126,"props":1121,"children":1122},{},[1123,1157],{"type":56,"tag":130,"props":1124,"children":1125},{},[1126,1131,1133,1139,1141,1147,1149,1155],{"type":56,"tag":79,"props":1127,"children":1129},{"className":1128},[],[1130],{"type":62,"value":100},{"type":62,"value":1132}," decides relevance and renders a ",{"type":56,"tag":79,"props":1134,"children":1136},{"className":1135},[],[1137],{"type":62,"value":1138},"systemPrompt",{"type":62,"value":1140},"; it may also return ",{"type":56,"tag":79,"props":1142,"children":1144},{"className":1143},[],[1145],{"type":62,"value":1146},"tools",{"type":62,"value":1148}," +\n",{"type":56,"tag":79,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":62,"value":1154},"toolGuidance",{"type":62,"value":1156}," to hand the model direct control of memory (hindsight does this).",{"type":56,"tag":130,"props":1158,"children":1159},{},[1160,1165],{"type":56,"tag":79,"props":1161,"children":1163},{"className":1162},[],[1164],{"type":62,"value":108},{"type":62,"value":1166}," owns extraction — turning the raw turn into whatever gets persisted.",{"type":56,"tag":119,"props":1168,"children":1170},{"id":1169},"scope-security",[1171],{"type":62,"value":1172},"Scope security",{"type":56,"tag":65,"props":1174,"children":1175},{},[1176,1182,1184,1190,1192,1197,1199,1205,1207,1225,1227,1233],{"type":56,"tag":79,"props":1177,"children":1179},{"className":1178},[],[1180],{"type":62,"value":1181},"MemoryScope",{"type":62,"value":1183}," is an alias of the shared ",{"type":56,"tag":79,"props":1185,"children":1187},{"className":1186},[],[1188],{"type":62,"value":1189},"Scope",{"type":62,"value":1191}," type from ",{"type":56,"tag":79,"props":1193,"children":1195},{"className":1194},[],[1196],{"type":62,"value":226},{"type":62,"value":1198},":\n",{"type":56,"tag":79,"props":1200,"children":1202},{"className":1201},[],[1203],{"type":62,"value":1204},"{ threadId, userId?, tenantId?, namespace? }",{"type":62,"value":1206},". It is the isolation boundary. ",{"type":56,"tag":71,"props":1208,"children":1209},{},[1210,1212,1217,1219,1224],{"type":62,"value":1211},"Never\ntrust a client-supplied ",{"type":56,"tag":79,"props":1213,"children":1215},{"className":1214},[],[1216],{"type":62,"value":725},{"type":62,"value":1218},"\u002F",{"type":56,"tag":79,"props":1220,"children":1222},{"className":1221},[],[1223],{"type":62,"value":698},{"type":62,"value":693},{"type":62,"value":1226}," Resolve scope server-side from\nsession\u002Fauth and pass the validated session through ",{"type":56,"tag":79,"props":1228,"children":1230},{"className":1229},[],[1231],{"type":62,"value":1232},"chat({ context: { session } })",{"type":62,"value":1234},". If\nyou accept a thread id from the request body, validate it belongs to the session user\nBEFORE using it.",{"type":56,"tag":119,"props":1236,"children":1238},{"id":1237},"adapters",[1239],{"type":62,"value":1240},"Adapters",{"type":56,"tag":126,"props":1242,"children":1243},{},[1244,1291,1309,1348,1367],{"type":56,"tag":130,"props":1245,"children":1246},{},[1247,1253,1254,1260,1262,1267,1269,1274,1275,1281,1283,1289],{"type":56,"tag":79,"props":1248,"children":1250},{"className":1249},[],[1251],{"type":62,"value":1252},"inMemory()",{"type":62,"value":847},{"type":56,"tag":79,"props":1255,"children":1257},{"className":1256},[],[1258],{"type":62,"value":1259},"redis()",{"type":62,"value":1261}," — exact match on ",{"type":56,"tag":79,"props":1263,"children":1265},{"className":1264},[],[1266],{"type":62,"value":698},{"type":62,"value":1268}," + optional ",{"type":56,"tag":79,"props":1270,"children":1272},{"className":1271},[],[1273],{"type":62,"value":725},{"type":62,"value":1218},{"type":56,"tag":79,"props":1276,"children":1278},{"className":1277},[],[1279],{"type":62,"value":1280},"tenantId",{"type":62,"value":1282},"\n(",{"type":56,"tag":79,"props":1284,"children":1286},{"className":1285},[],[1287],{"type":62,"value":1288},"namespace",{"type":62,"value":1290}," ignored). Redis index keys include all three segments.",{"type":56,"tag":130,"props":1292,"children":1293},{},[1294,1300,1302,1308],{"type":56,"tag":79,"props":1295,"children":1297},{"className":1296},[],[1298],{"type":62,"value":1299},"hindsight()",{"type":62,"value":1301}," — bank ",{"type":56,"tag":79,"props":1303,"children":1305},{"className":1304},[],[1306],{"type":62,"value":1307},"{tenant|_}__{user}__{threadId}",{"type":62,"value":693},{"type":56,"tag":130,"props":1310,"children":1311},{},[1312,1318,1320,1326,1328,1334,1335,1340,1342,1347],{"type":56,"tag":79,"props":1313,"children":1315},{"className":1314},[],[1316],{"type":62,"value":1317},"mem0()",{"type":62,"value":1319}," — ",{"type":56,"tag":79,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":62,"value":1325},"user_id",{"type":62,"value":1327}," + ",{"type":56,"tag":79,"props":1329,"children":1331},{"className":1330},[],[1332],{"type":62,"value":1333},"run_id",{"type":62,"value":605},{"type":56,"tag":79,"props":1336,"children":1338},{"className":1337},[],[1339],{"type":62,"value":698},{"type":62,"value":1341},"); no ",{"type":56,"tag":79,"props":1343,"children":1345},{"className":1344},[],[1346],{"type":62,"value":1280},{"type":62,"value":693},{"type":56,"tag":130,"props":1349,"children":1350},{},[1351,1357,1359,1365],{"type":56,"tag":79,"props":1352,"children":1354},{"className":1353},[],[1355],{"type":62,"value":1356},"honcho()",{"type":62,"value":1358}," — session ",{"type":56,"tag":79,"props":1360,"children":1362},{"className":1361},[],[1363],{"type":62,"value":1364},"{tenant|_}__{threadId}",{"type":62,"value":1366},"; peer tenant-prefixed when set.",{"type":56,"tag":130,"props":1368,"children":1369},{},[1370,1372,1377,1378,1383,1385,1391],{"type":62,"value":1371},"Custom — implement ",{"type":56,"tag":79,"props":1373,"children":1375},{"className":1374},[],[1376],{"type":62,"value":100},{"type":62,"value":1218},{"type":56,"tag":79,"props":1379,"children":1381},{"className":1380},[],[1382],{"type":62,"value":108},{"type":62,"value":1384}," and run ",{"type":56,"tag":79,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":62,"value":1390},"@tanstack\u002Fai-memory\u002Ftests\u002Fcontract",{"type":62,"value":693},{"type":56,"tag":119,"props":1393,"children":1395},{"id":1394},"failure-modes",[1396],{"type":62,"value":1397},"Failure modes",{"type":56,"tag":65,"props":1399,"children":1400},{},[1401,1403,1408,1410,1415,1417,1423],{"type":62,"value":1402},"Memory failures are non-fatal: a throwing ",{"type":56,"tag":79,"props":1404,"children":1406},{"className":1405},[],[1407],{"type":62,"value":100},{"type":62,"value":1409}," or ",{"type":56,"tag":79,"props":1411,"children":1413},{"className":1412},[],[1414],{"type":62,"value":108},{"type":62,"value":1416}," emits ",{"type":56,"tag":79,"props":1418,"children":1420},{"className":1419},[],[1421],{"type":62,"value":1422},"memory:error",{"type":62,"value":1424}," and\nthe run continues with degraded memory. Streaming is never blocked; a failed save never\nfails the turn.",{"type":56,"tag":119,"props":1426,"children":1428},{"id":1427},"devtools",[1429],{"type":62,"value":1430},"Devtools",{"type":56,"tag":65,"props":1432,"children":1433},{},[1434,1436,1442,1444,1450,1452,1458,1459,1465,1466,1472,1473,1478,1479,1484,1485,1491,1493,1498,1500,1505],{"type":62,"value":1435},"Five events on ",{"type":56,"tag":79,"props":1437,"children":1439},{"className":1438},[],[1440],{"type":62,"value":1441},"aiEventClient",{"type":62,"value":1443}," (from ",{"type":56,"tag":79,"props":1445,"children":1447},{"className":1446},[],[1448],{"type":62,"value":1449},"@tanstack\u002Fai-event-client",{"type":62,"value":1451},"):\n",{"type":56,"tag":79,"props":1453,"children":1455},{"className":1454},[],[1456],{"type":62,"value":1457},"memory:retrieve:started",{"type":62,"value":847},{"type":56,"tag":79,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":62,"value":1464},":completed",{"type":62,"value":801},{"type":56,"tag":79,"props":1467,"children":1469},{"className":1468},[],[1470],{"type":62,"value":1471},"memory:persist:started",{"type":62,"value":847},{"type":56,"tag":79,"props":1474,"children":1476},{"className":1475},[],[1477],{"type":62,"value":1464},{"type":62,"value":476},{"type":56,"tag":79,"props":1480,"children":1482},{"className":1481},[],[1483],{"type":62,"value":1422},{"type":62,"value":605},{"type":56,"tag":79,"props":1486,"children":1488},{"className":1487},[],[1489],{"type":62,"value":1490},"phase: 'recall' | 'save'",{"type":62,"value":1492},"). Payloads carry the adapter id and\nfragment\u002Freceipt counts, not full memory text. Error events include ",{"type":56,"tag":79,"props":1494,"children":1496},{"className":1495},[],[1497],{"type":62,"value":807},{"type":62,"value":1499}," only\nwhen it was already resolved; if the resolver threw, ",{"type":56,"tag":79,"props":1501,"children":1503},{"className":1502},[],[1504],{"type":62,"value":807},{"type":62,"value":1506}," is omitted.",{"type":56,"tag":1508,"props":1509,"children":1510},"style",{},[1511],{"type":62,"value":1512},"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);}",{"items":1514,"total":1616},[1515,1533,1546,1561,1574,1588,1602],{"slug":1516,"name":1516,"fn":1517,"description":1518,"org":1519,"tags":1520,"stars":20,"repoUrl":21,"updatedAt":1532},"ai-code-mode","execute sandboxed TypeScript code with LLMs","LLM-generated TypeScript execution in sandboxed environments: createCodeModeTool() with isolate drivers (createNodeIsolateDriver, createQuickJSIsolateDriver, createCloudflareIsolateDriver), codeModeWithSkills() for persistent skill libraries, trust strategies, skill storage (FileSystem, LocalStorage, InMemory, Mongo), client-side execution progress via code_mode:* custom events in useChat.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1521,1523,1526,1529,1530],{"name":1522,"slug":28,"type":15},"AI SDK",{"name":1524,"slug":1525,"type":15},"Code Execution","code-execution",{"name":1527,"slug":1528,"type":15},"Sandboxing","sandboxing",{"name":9,"slug":8,"type":15},{"name":1531,"slug":42,"type":15},"TypeScript","2026-07-16T06:04:13.597905",{"slug":1534,"name":1534,"fn":1535,"description":1536,"org":1537,"tags":1538,"stars":20,"repoUrl":21,"updatedAt":1545},"ai-core","configure TanStack AI agent features","Entry point for TanStack AI skills. Routes to chat-experience, tool-calling, media-generation, structured-outputs, adapter-configuration, ag-ui-protocol, middleware, locks, custom-backend-integration, and debug-logging, plus the skills shipped by companion packages (@tanstack\u002Fai-persistence, @tanstack\u002Fai-code-mode). Use chat() not streamText(), openaiText() not createOpenAI(), toServerSentEventsResponse() not manual SSE, middleware hooks not onEnd callbacks.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1539,1540,1542],{"name":17,"slug":18,"type":15},{"name":1541,"slug":26,"type":15},"AI",{"name":1543,"slug":1544,"type":15},"Middleware","middleware","2026-07-30T05:26:10.404565",{"slug":1547,"name":1548,"fn":1549,"description":1550,"org":1551,"tags":1552,"stars":20,"repoUrl":21,"updatedAt":1560},"ai-coreadapter-configuration","ai-core\u002Fadapter-configuration","configure AI provider adapters","Provider adapter selection and configuration: openaiText, anthropicText, geminiText, ollamaText, grokText, groqText, openRouterText, bedrockText, openaiCompatible. Per-model type safety with modelOptions, reasoning\u002Fthinking configuration, runtime adapter switching, extendAdapter() for custom models, createModel(). Generic OpenAI-compatible providers (DeepSeek, Together, Fireworks, etc.) via openaiCompatible({ baseURL, apiKey, models }) from @tanstack\u002Fai-openai\u002Fcompatible. API key env vars: OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY\u002FGEMINI_API_KEY, XAI_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY, OLLAMA_HOST, BEDROCK_API_KEY (or AWS_BEARER_TOKEN_BEDROCK).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1553,1554,1557,1559],{"name":1522,"slug":28,"type":15},{"name":1555,"slug":1556,"type":15},"Configuration","configuration",{"name":1558,"slug":34,"type":15},"LLM",{"name":9,"slug":8,"type":15},"2026-07-16T06:04:17.82075",{"slug":1562,"name":1563,"fn":1564,"description":1565,"org":1566,"tags":1567,"stars":20,"repoUrl":21,"updatedAt":1573},"ai-coreag-ui-protocol","ai-core\u002Fag-ui-protocol","implement TanStack AI streaming protocol","Server-side AG-UI streaming protocol implementation: StreamChunk event types (RUN_STARTED, TEXT_MESSAGE_START\u002FCONTENT\u002FEND, TOOL_CALL_START\u002FARGS\u002FEND, RUN_FINISHED, RUN_ERROR, STEP_STARTED\u002FSTEP_FINISHED, STATE_SNAPSHOT\u002FDELTA, CUSTOM), toServerSentEventsStream() for SSE format, toHttpStream() for NDJSON format. For backends serving AG-UI events without client packages.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1568,1571,1572],{"name":1569,"slug":1570,"type":15},"API Development","api-development",{"name":1558,"slug":34,"type":15},{"name":9,"slug":8,"type":15},"2026-07-16T06:04:10.093367",{"slug":1575,"name":1576,"fn":1577,"description":1578,"org":1579,"tags":1580,"stars":20,"repoUrl":21,"updatedAt":1587},"ai-corechat-experience","ai-core\u002Fchat-experience","implement chat experiences with TanStack AI","End-to-end chat implementation: server endpoint with chat() and toServerSentEventsResponse(), client-side useChat hook with fetchServerSentEvents(), message rendering with UIMessage parts, multimodal content, thinking\u002Freasoning display. Covers streaming states, connection adapters, and message format conversions. NOT Vercel AI SDK — uses chat() not streamText().\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1581,1582,1585,1586],{"name":1569,"slug":1570,"type":15},{"name":1583,"slug":1584,"type":15},"Frontend","frontend",{"name":1558,"slug":34,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:26:11.505241",{"slug":1589,"name":1590,"fn":1591,"description":1592,"org":1593,"tags":1594,"stars":20,"repoUrl":21,"updatedAt":1601},"ai-coreclient-persistence","ai-core\u002Fclient-persistence","implement browser chat persistence for TanStack AI","Browser chat persistence on useChat \u002F ChatClient: localStoragePersistence, sessionStoragePersistence, indexedDBPersistence. Client-authoritative (adapter, full transcript) vs server-authoritative (persistence: true, no client cache). Reload restore, pending interrupts, mid-stream rejoin with delivery durability. Use for SPA reload durability — NOT server history alone. No extra package: the adapters ship in the framework packages.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1595,1596,1597,1600],{"name":1541,"slug":26,"type":15},{"name":1583,"slug":1584,"type":15},{"name":1598,"slug":1599,"type":15},"Persistence","persistence",{"name":9,"slug":8,"type":15},"2026-07-30T05:53:35.503176",{"slug":1603,"name":1604,"fn":1605,"description":1606,"org":1607,"tags":1608,"stars":20,"repoUrl":21,"updatedAt":1615},"ai-corecustom-backend-integration","ai-core\u002Fcustom-backend-integration","integrate custom backends with TanStack AI","Connect useChat to a non-TanStack-AI backend through custom connection adapters. ConnectConnectionAdapter (single async iterable) vs SubscribeConnectionAdapter (separate subscribe\u002Fsend). Customize fetchServerSentEvents() and fetchHttpStream() with auth headers, custom URLs, and request options. Import from framework package, not @tanstack\u002Fai-client.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1609,1610,1611,1614],{"name":1541,"slug":26,"type":15},{"name":1569,"slug":1570,"type":15},{"name":1612,"slug":1613,"type":15},"Backend","backend",{"name":9,"slug":8,"type":15},"2026-07-17T06:06:39.855351",27,{"items":1618,"total":1758},[1619,1633,1645,1657,1672,1684,1694,1704,1717,1727,1738,1748],{"slug":1620,"name":1620,"fn":1621,"description":1622,"org":1623,"tags":1624,"stars":1630,"repoUrl":1631,"updatedAt":1632},"aggregation","perform data aggregation in TanStack Table","Aggregate TanStack Table columns independently of grouping, including grand totals, caller-selected row totals, multiple keyed aggregations, custom context-based definitions, grouped merges, manual values, and worker constraints.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1625,1628,1629],{"name":1626,"slug":1627,"type":15},"Data Analysis","data-analysis",{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},28175,"https:\u002F\u002Fgithub.com\u002FTanStack\u002Ftable","2026-07-30T05:25:59.429787",{"slug":1634,"name":1634,"fn":1635,"description":1636,"org":1637,"tags":1638,"stars":1630,"repoUrl":1631,"updatedAt":1644},"api-not-found","diagnose TanStack Table API errors","Diagnose missing TanStack Table v9 exports, options, state slices, and instance methods. Load before inventing an API when code sees a type error, undefined feature method, absent object key, adapter mismatch, or v8-shaped example.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1639,1642,1643],{"name":1640,"slug":1641,"type":15},"Debugging","debugging",{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:26:05.418735",{"slug":1646,"name":1646,"fn":1647,"description":1648,"org":1649,"tags":1650,"stars":1630,"repoUrl":1631,"updatedAt":1656},"cell-selection","select rectangular cell ranges in tables","Select rectangular cell ranges with cellSelectionFeature: two-corner range state keyed by row and column id, mousedown\u002Fmouseenter handlers, selection edges, render-order resolution under pinning, and autoResetCellSelection. Load when ranges widen unexpectedly after sorting or column reordering, when a drag re-renders the whole table, or when building copy-to-clipboard from a selection.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1651,1652,1653],{"name":1626,"slug":1627,"type":15},{"name":9,"slug":8,"type":15},{"name":1654,"slug":1655,"type":15},"UI Components","ui-components","2026-07-30T05:25:38.403427",{"slug":1658,"name":1658,"fn":1659,"description":1660,"org":1661,"tags":1662,"stars":1630,"repoUrl":1631,"updatedAt":1671},"client-vs-server","manage TanStack Table data pipelines","Choose client or server ownership for filtering, grouping, sorting, expanding, and pagination in TanStack Table v9. Load for manual* flags, mixed pipelines, server counts, or deciding which dataset each row-model stage receives.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1663,1666,1667,1670],{"name":1664,"slug":1665,"type":15},"Data Pipeline","data-pipeline",{"name":1583,"slug":1584,"type":15},{"name":1668,"slug":1669,"type":15},"Performance","performance",{"name":9,"slug":8,"type":15},"2026-07-30T05:25:45.400104",{"slug":1673,"name":1673,"fn":1674,"description":1675,"org":1676,"tags":1677,"stars":1630,"repoUrl":1631,"updatedAt":1683},"column-faceting","build faceted filter UIs","Build faceted filter UIs with columnFacetingFeature, facetedRowModel, facetedUniqueValues, and facetedMinMaxValues. Load for facet counts, numeric ranges, own-filter exclusion, or server-page facet completeness.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1678,1681,1682],{"name":1679,"slug":1680,"type":15},"Data Visualization","data-visualization",{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:25:41.397257",{"slug":1685,"name":1685,"fn":1686,"description":1687,"org":1688,"tags":1689,"stars":1630,"repoUrl":1631,"updatedAt":1693},"column-filtering","implement column filtering in TanStack Table","Filter columns with columnFilteringFeature, filteredRowModel, filterFns, filterMeta, nested-row direction, and manualFiltering. Load for accessor compatibility, controlled filter updaters, fuzzy metadata, or client\u002Fserver ownership.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1690,1691,1692],{"name":1626,"slug":1627,"type":15},{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},"2026-07-30T05:25:53.391632",{"slug":1695,"name":1695,"fn":1696,"description":1697,"org":1698,"tags":1699,"stars":1630,"repoUrl":1631,"updatedAt":1703},"column-ordering","manage TanStack Table column ordering","Control TanStack Table v9 leaf columnOrder with stable IDs while accounting for pinning regions, visibility, and groupedColumnMode precedence. Load for drag-and-drop columns or rendered order that differs from state.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1700,1701,1702],{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},{"name":1654,"slug":1655,"type":15},"2026-07-30T05:26:03.37801",{"slug":1705,"name":1705,"fn":1706,"description":1707,"org":1708,"tags":1709,"stars":1630,"repoUrl":1631,"updatedAt":1716},"column-pinning","configure column pinning in TanStack Table","Pin columns into logical start, center, and end regions with columnPinningFeature and renderer-owned sticky CSS. Load for RTL offsets, z-index, backgrounds, overflow, widths, gaps, or overlaps.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1710,1713,1714,1715],{"name":1711,"slug":1712,"type":15},"CSS","css",{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},{"name":1654,"slug":1655,"type":15},"2026-07-30T05:25:55.377366",{"slug":1718,"name":1718,"fn":1719,"description":1720,"org":1721,"tags":1722,"stars":1630,"repoUrl":1631,"updatedAt":1726},"column-resizing","implement column resizing in TanStack Table","Wire columnResizingFeature, header.getResizeHandler, resize mode and direction, pointer or touch events, and performant CSS-variable updates. Load when resize state changes but widths do not, or large tables resize slowly.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1723,1724,1725],{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},{"name":1654,"slug":1655,"type":15},"2026-07-30T05:25:51.400011",{"slug":1728,"name":1728,"fn":1729,"description":1730,"org":1731,"tags":1732,"stars":1630,"repoUrl":1631,"updatedAt":1737},"column-sizing","configure column sizing in TanStack Table","Use columnSizingFeature numeric size, minSize, maxSize, getSize, getStart, getAfter, and total-size APIs in table, grid, or flex CSS. Load for auto or percentage misconceptions and sizing\u002Fpinning layout mismatch.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1733,1734,1735,1736],{"name":1711,"slug":1712,"type":15},{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},{"name":1654,"slug":1655,"type":15},"2026-07-30T05:25:48.703799",{"slug":1739,"name":1739,"fn":1740,"description":1741,"org":1742,"tags":1743,"stars":1630,"repoUrl":1631,"updatedAt":1747},"column-visibility","manage column visibility in TanStack Table","Hide columns with columnVisibilityFeature while rendering visibility-aware header, column, and cell collections. Load when hidden columns remain in the DOM, false-versus-absent state is confused, or enableHiding is misunderstood.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1744,1745,1746],{"name":1583,"slug":1584,"type":15},{"name":9,"slug":8,"type":15},{"name":1654,"slug":1655,"type":15},"2026-07-30T05:25:47.367943",{"slug":1749,"name":1749,"fn":1750,"description":1751,"org":1752,"tags":1753,"stars":1630,"repoUrl":1631,"updatedAt":1757},"core","build data grids with TanStack Table","Use TanStack Table v9 as a headless data-grid state and row-processing engine. Load for first-table architecture, stable data and columns, row numbering with getDisplayIndex, semantic rendering, framework adapter choice, or deciding what Table owns versus the renderer.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[1754,1755,1756],{"name":1626,"slug":1627,"type":15},{"name":1583,"slug":1584,"type":15},{"name":1654,"slug":1655,"type":15},"2026-07-30T05:25:52.366295",125]