UIPackage
Menu

Framework

Change language

Boilerplate repo

Agent Memory Inspector

blockai

Autonomous AI agent memory inspector featuring short-term context buffer utilization, long-term episodic vector memories with confidence scoring, and Neo4j-style entity relationship knowledge graph.

Also available for React ->

Installation

$npx shadcn-vue@latest add https://uipkge.dev/r/vue/agent-memory-inspector.json
Named registry:npx shadcn-vue@latest add @uipkge/agent-memory-inspectorInstalls to:app/components/blocks/

Variants

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
classHTMLAttributes['class']optional

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

EpisodicMemory
interface EpisodicMemory {
  id: string
  content: string
  category: MemoryCategory
  confidence: number
  lastRecalled: string
  recallsCount: number
  sourceTurn: string
  tags: string[]
  isPinned: boolean
}
MessageTurn
interface MessageTurn {
  id: string
  turnNumber: number
  role: 'user' | 'assistant'
  authorName: string
  avatarText: string
  timestamp: string
  importanceScore: number
  importanceLevel: 'Critical' | 'High' | 'Standard' | 'Action Item'
  tokens: number
  content: string
  extractedFacts: string[]
  embeddingHash: string
}
EntityNode
interface EntityNode {
  id: string
  label: string
  entityType: 'Person' | 'Repository' | 'CSS Engine' | 'Design System' | 'Framework' | 'Standard'
  description: string
  degree: number
  status: 'active' | 'synced' | 'cached'
  embeddingId: string
}
GraphTriplet
interface GraphTriplet {
  id: string
  subject: string
  subjectType: string
  predicate: 'MAINTAINS' | 'USES' | 'CONFIGURES' | 'IMPLEMENTS' | 'MIRRORS' | 'ENFORCES'
  object: string
  objectType: string
  confidence: number
  weight: string
  lastTraversed: string
}

Files installed (5)

  • app/components/blocks/AgentMemoryInspector.vue23.8 kB
    <script setup lang="ts">
    import { computed, ref } from 'vue'
    import type { HTMLAttributes } from 'vue'
    import {
      Activity,
      AlertCircle,
      Brain,
      Check,
      Clock,
      Cpu,
      Database,
      Network,
      Pencil,
      Plus,
      RefreshCw,
      Search,
      ShieldCheck,
      Star,
      Trash2,
      Workflow,
      X,
    } from 'lucide-vue-next'
    import { cn } from '@/lib/utils'
    import { Avatar, AvatarFallback } from '@/components/ui/avatar'
    import { Badge } from '@/components/ui/badge'
    import { Button } from '@/components/ui/button'
    import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'
    import { Progress } from '@/components/ui/progress'
    import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
    import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
    import AgentContextBuffer from './AgentContextBuffer.vue'
    import AgentEntityGraph from './AgentEntityGraph.vue'
    import {
      INITIAL_MEMORY_FACTS,
      INITIAL_MESSAGE_TURNS,
      INITIAL_ENTITY_NODES,
      INITIAL_GRAPH_TRIPLETS,
    } from './agent-memory-data'
    import type { EpisodicMemory, MessageTurn, EntityNode, GraphTriplet, MemoryCategory } from './agent-memory-types'
    export type { EpisodicMemory, MessageTurn, EntityNode, GraphTriplet, MemoryCategory } from './agent-memory-types'
    
    interface Props {
      class?: HTMLAttributes['class']
    }
    
    const props = defineProps<Props>()
    
    // State initialized from extracted data
    const memoryFacts = ref<EpisodicMemory[]>([...INITIAL_MEMORY_FACTS])
    const messageTurns = ref<MessageTurn[]>([...INITIAL_MESSAGE_TURNS])
    const entityNodes = ref<EntityNode[]>([...INITIAL_ENTITY_NODES])
    const graphTriplets = ref<GraphTriplet[]>([...INITIAL_GRAPH_TRIPLETS])
    // UI Controls State
    const activeTab = ref('context')
    const selectedCategory = ref<string>('all')
    const searchQuery = ref('')
    const selectedTurnId = ref<string>('turn-4')
    const selectedNodeId = ref<string>('node-2')
    const isWiped = ref(false)
    const wipeToastVisible = ref(false)
    const isAddingFact = ref(false)
    const editingFactId = ref<string | null>(null)
    
    // Form State for new memory fact
    const newFactForm = ref<{
      content: string
      category: MemoryCategory
      confidence: number
    }>({
      content: '',
      category: 'User Preference',
      confidence: 0.95,
    })
    
    const filteredMemories = computed(() => {
      return memoryFacts.value.filter((fact) => {
        const matchesCategory = selectedCategory.value === 'all' || fact.category === selectedCategory.value
        const matchesSearch =
          searchQuery.value.trim() === '' ||
          fact.content.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
          fact.tags.some((t) => t.toLowerCase().includes(searchQuery.value.toLowerCase()))
        return matchesCategory && matchesSearch
      })
    })
    
    const selectedTurn = computed(() => {
      return messageTurns.value.find((t) => t.id === selectedTurnId.value) || messageTurns.value[0]
    })
    
    const selectedNode = computed(() => {
      return entityNodes.value.find((n) => n.id === selectedNodeId.value) || entityNodes.value[1]
    })
    
    const filteredTriplets = computed(() => {
      if (!selectedNode.value) return graphTriplets.value
      return graphTriplets.value.filter(
        (t) => t.subject === selectedNode.value.label || t.object === selectedNode.value.label,
      )
    })
    
    function wipeWorkingMemory() {
      isWiped.value = true
      wipeToastVisible.value = true
      setTimeout(() => {
        wipeToastVisible.value = false
      }, 4000)
    }
    
    function restoreWorkingMemory() {
      isWiped.value = false
      wipeToastVisible.value = false
    }
    
    function deleteFact(id: string) {
      memoryFacts.value = memoryFacts.value.filter((f) => f.id !== id)
    }
    
    function togglePinFact(id: string) {
      const fact = memoryFacts.value.find((f) => f.id === id)
      if (fact) {
        fact.isPinned = !fact.isPinned
      }
    }
    
    function startAddFact() {
      isAddingFact.value = true
      editingFactId.value = null
      newFactForm.value = {
        content: '',
        category: 'User Preference',
        confidence: 0.95,
      }
    }
    
    function saveNewFact() {
      if (!newFactForm.value.content.trim()) return
    
      if (editingFactId.value) {
        const existing = memoryFacts.value.find((f) => f.id === editingFactId.value)
        if (existing) {
          existing.content = newFactForm.value.content
          existing.category = newFactForm.value.category
          existing.confidence = Number(newFactForm.value.confidence)
          existing.lastRecalled = 'Just now'
        }
      } else {
        const newId = `fact-${Date.now()}`
        memoryFacts.value.unshift({
          id: newId,
          content: newFactForm.value.content,
          category: newFactForm.value.category,
          confidence: Number(newFactForm.value.confidence),
          lastRecalled: 'Just now',
          recallsCount: 1,
          sourceTurn: 'Manual Injection',
          tags: [newFactForm.value.category.toLowerCase().replace(/\s+/g, '-')],
          isPinned: false,
        })
      }
    
      isAddingFact.value = false
      editingFactId.value = null
    }
    
    function editFact(fact: EpisodicMemory) {
      editingFactId.value = fact.id
      newFactForm.value = {
        content: fact.content,
        category: fact.category,
        confidence: fact.confidence,
      }
      isAddingFact.value = true
    }
    
    function cancelAddFact() {
      isAddingFact.value = false
      editingFactId.value = null
    }
    
    function getCategoryVariant(category: MemoryCategory): 'default' | 'secondary' | 'outline' {
      switch (category) {
        case 'User Preference':
          return 'default'
        case 'Architecture Rule':
          return 'secondary'
        case 'System Constraint':
          return 'outline'
      }
    }
    </script>
    
    <template>
      <div :class="cn('w-full space-y-6 font-sans antialiased', props.class)">
        <!-- Header Block -->
        <Card class="border-border shadow-xs">
          <CardHeader class="p-6 pb-4">
            <div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
              <!-- Left: Agent Identity & Engine Details -->
              <div class="flex items-start gap-4">
                <div class="relative">
                  <Avatar class="border-border bg-muted/60 h-12 w-12 rounded-xl border p-1">
                    <AvatarFallback class="bg-primary/10 text-primary rounded-lg font-mono text-sm font-bold">
                      <Brain class="text-primary h-6 w-6" />
                    </AvatarFallback>
                  </Avatar>
                  <span
                    class="bg-background absolute -right-0.5 -bottom-0.5 flex h-3.5 w-3.5 items-center justify-center rounded-full"
                  >
                    <span class="bg-success ring-success/20 h-2 w-2 rounded-full ring-2" />
                  </span>
                </div>
    
                <div class="space-y-1">
                  <div class="flex flex-wrap items-center gap-2">
                    <h2 class="text-foreground text-lg font-semibold tracking-tight">Senior Engineering Co-Pilot Agent</h2>
                    <Badge variant="outline" class="gap-1 px-2 py-0.5 text-xs font-medium">
                      <Cpu class="text-muted-foreground h-3 w-3" />
                      Autonomous Sync
                    </Badge>
                  </div>
    
                  <div class="text-muted-foreground flex flex-wrap items-center gap-x-3 gap-y-1 text-xs">
                    <span class="text-foreground flex items-center gap-1.5 font-medium">
                      <Database class="text-primary h-3.5 w-3.5" />
                      Mem0 Vector + Neo4j Entity Graph
                    </span>
                    <span class="flex items-center gap-1">
                      <Network class="h-3.5 w-3.5" />
                      142 Episodic Memories · 28 Entity Nodes
                    </span>
                    <span class="text-muted-foreground flex items-center gap-1 font-mono">
                      <Activity class="text-success h-3 w-3" />
                      Recall: 12ms
                    </span>
                  </div>
                </div>
              </div>
    
              <!-- Right: Actions -->
              <div class="flex flex-wrap items-center gap-2">
                <Button
                  variant="ghost"
                  size="sm"
                  class="text-muted-foreground hover:text-destructive h-9 gap-1.5 text-xs font-medium"
                  @click="wipeWorkingMemory"
                >
                  <Trash2 class="h-3.5 w-3.5" />
                  Wipe Working Memory
                </Button>
    
                <Button size="sm" class="h-9 gap-1.5 text-xs font-medium shadow-xs" @click="startAddFact">
                  <Plus class="h-3.5 w-3.5" />
                  Add Memory Fact
                </Button>
              </div>
            </div>
          </CardHeader>
    
          <!-- Wipe State Feedback Banner -->
          <div v-if="wipeToastVisible" class="border-destructive/20 bg-destructive/5 border-t px-6 py-2.5">
            <div class="text-destructive flex items-center justify-between gap-2 text-xs">
              <div class="flex items-center gap-2">
                <AlertCircle class="h-4 w-4 shrink-0" />
                <span>Working context buffer cache cleared. Persistent episodic facts remain intact.</span>
              </div>
              <Button
                variant="outline"
                size="sm"
                class="border-destructive/30 text-destructive hover:bg-destructive/10 h-7 text-xs"
                @click="restoreWorkingMemory"
              >
                <RefreshCw class="mr-1 h-3 w-3" />
                Restore
              </Button>
            </div>
          </div>
        </Card>
    
        <!-- Inline Add/Edit Memory Fact Modal / Drawer -->
        <Card v-if="isAddingFact" class="border-primary/30 bg-card ring-primary/20 shadow-sm ring-1">
          <CardHeader class="p-4 pb-2">
            <div class="flex items-center justify-between">
              <div class="flex items-center gap-2">
                <Brain class="text-primary h-4 w-4" />
                <CardTitle class="text-sm font-semibold">
                  {{ editingFactId ? 'Edit Memory Fact' : 'Add Episodic Memory Fact' }}
                </CardTitle>
              </div>
              <Button variant="ghost" size="sm" class="h-7 w-7 p-0" aria-label="Cancel adding fact" @click="cancelAddFact">
                <X class="h-4 w-4" />
              </Button>
            </div>
            <CardDescription class="text-xs">
              Inject a verified truth into the persistent Mem0 vector embedding space.
            </CardDescription>
          </CardHeader>
    
          <CardContent class="space-y-3 p-4 pt-2">
            <div class="space-y-1.5">
              <label class="text-foreground text-xs font-medium">Fact Content</label>
              <textarea
                v-model="newFactForm.content"
                placeholder="e.g. User enforces strict 120-character printWidth in Prettier..."
                rows="2"
                class="border-input bg-background text-foreground placeholder:text-muted-foreground focus-visible:ring-ring w-full rounded-md border px-3 py-2 text-xs focus-visible:ring-1 focus-visible:outline-none"
              />
            </div>
    
            <div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
              <div class="space-y-1.5">
                <label class="text-foreground text-xs font-medium">Memory Category</label>
                <select
                  v-model="newFactForm.category"
                  class="border-input bg-background text-foreground focus-visible:ring-ring w-full rounded-md border px-2.5 py-1.5 text-xs focus-visible:ring-1 focus-visible:outline-none"
                >
                  <option value="User Preference">User Preference</option>
                  <option value="Architecture Rule">Architecture Rule</option>
                  <option value="System Constraint">System Constraint</option>
                </select>
              </div>
    
              <div class="space-y-1.5">
                <label class="text-foreground text-xs font-medium">Confidence Score (0.0 - 1.0)</label>
                <input
                  v-model.number="newFactForm.confidence"
                  type="number"
                  step="0.01"
                  min="0"
                  max="1"
                  class="border-input bg-background text-foreground focus-visible:ring-ring w-full rounded-md border px-3 py-1.5 font-mono text-xs focus-visible:ring-1 focus-visible:outline-none"
                />
              </div>
            </div>
          </CardContent>
    
          <CardFooter class="border-border flex justify-end gap-2 border-t p-3">
            <Button aria-label="Cancel adding fact" variant="ghost" size="sm" class="h-8 text-xs" @click="cancelAddFact">
              Cancel
            </Button>
            <Button size="sm" class="h-8 text-xs font-medium" @click="saveNewFact">
              <Check class="mr-1 h-3.5 w-3.5" />
              {{ editingFactId ? 'Save Changes' : 'Store Fact' }}
            </Button>
          </CardFooter>
        </Card>
    
        <!-- Main Tabs Section -->
        <Tabs v-model="activeTab" default-value="context" class="w-full space-y-4">
          <TabsList class="border-border bg-muted/40 grid h-10 w-full grid-cols-3 rounded-lg border p-1">
            <TabsTrigger value="context" class="gap-2 text-xs font-medium">
              <Cpu class="h-3.5 w-3.5" />
              <span>Short-Term Context Buffer</span>
              <Badge variant="secondary" class="ml-1 px-1.5 py-0 font-mono text-xs font-normal">
                {{ isWiped ? '0 turns' : '4 turns' }}
              </Badge>
            </TabsTrigger>
    
            <TabsTrigger value="episodic" class="gap-2 text-xs font-medium">
              <Database class="h-3.5 w-3.5" />
              <span>Long-Term Episodic Memory</span>
              <Badge variant="secondary" class="ml-1 px-1.5 py-0 font-mono text-xs font-normal">
                {{ memoryFacts.length }} Facts
              </Badge>
            </TabsTrigger>
    
            <TabsTrigger value="graph" class="gap-2 text-xs font-medium">
              <Network class="h-3.5 w-3.5" />
              <span>Entity Knowledge Graph</span>
              <Badge variant="secondary" class="ml-1 px-1.5 py-0 font-mono text-xs font-normal">
                {{ entityNodes.length }} Nodes
              </Badge>
            </TabsTrigger>
          </TabsList>
    
          <!-- ========================================== -->
          <!-- TAB 1: SHORT-TERM CONTEXT BUFFER          -->
          <!-- ========================================== -->
          <!-- TAB 1: SHORT-TERM CONTEXT BUFFER -->
          <TabsContent value="context" class="space-y-4 outline-none">
            <AgentContextBuffer
              :is-wiped="isWiped"
              :turns="messageTurns"
              :selected-turn-id="selectedTurnId"
              @select-turn="(id) => (selectedTurnId = id)"
              @restore="restoreWorkingMemory"
            />
          </TabsContent>
    
          <!-- ========================================== -->
          <!-- TAB 2: LONG-TERM EPISODIC MEMORY TABLE    -->
          <!-- ========================================== -->
          <TabsContent value="episodic" class="space-y-4 outline-none">
            <Card class="border-border shadow-xs">
              <!-- Filter and Search Header -->
              <CardHeader class="p-5 pb-3">
                <div class="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
                  <div>
                    <CardTitle class="text-sm font-semibold">Persistent Episodic Facts</CardTitle>
                    <CardDescription class="text-xs">
                      Distilled knowledge facts retrieved via Mem0 vector cosine similarity search.
                    </CardDescription>
                  </div>
    
                  <!-- Search & Category Filters -->
                  <div class="flex flex-wrap items-center gap-2">
                    <div class="relative w-full sm:w-64">
                      <Search class="text-muted-foreground absolute top-2.5 left-2.5 h-3.5 w-3.5" />
                      <input
                        v-model="searchQuery"
                        type="text"
                        placeholder="Search memory facts or tags..."
                        class="border-input bg-background text-foreground placeholder:text-muted-foreground focus-visible:ring-ring h-8.5 w-full rounded-md border pr-3 pl-8 text-xs focus-visible:ring-1 focus-visible:outline-none"
                      />
                    </div>
    
                    <div class="border-border bg-muted/40 flex items-center gap-1 rounded-lg border p-0.5">
                      <button
                        type="button"
                        :class="
                          cn(
                            'rounded px-2.5 py-1 text-xs font-medium transition-colors',
                            selectedCategory === 'all'
                              ? 'bg-background text-foreground shadow-xs'
                              : 'text-muted-foreground hover:text-foreground',
                          )
                        "
                        @click="selectedCategory = 'all'"
                      >
                        All ({{ memoryFacts.length }})
                      </button>
                      <button
                        type="button"
                        :class="
                          cn(
                            'rounded px-2.5 py-1 text-xs font-medium transition-colors',
                            selectedCategory === 'User Preference'
                              ? 'bg-background text-foreground shadow-xs'
                              : 'text-muted-foreground hover:text-foreground',
                          )
                        "
                        @click="selectedCategory = 'User Preference'"
                      >
                        Preference
                      </button>
                      <button
                        type="button"
                        :class="
                          cn(
                            'rounded px-2.5 py-1 text-xs font-medium transition-colors',
                            selectedCategory === 'Architecture Rule'
                              ? 'bg-background text-foreground shadow-xs'
                              : 'text-muted-foreground hover:text-foreground',
                          )
                        "
                        @click="selectedCategory = 'Architecture Rule'"
                      >
                        Architecture
                      </button>
                      <button
                        type="button"
                        :class="
                          cn(
                            'rounded px-2.5 py-1 text-xs font-medium transition-colors',
                            selectedCategory === 'System Constraint'
                              ? 'bg-background text-foreground shadow-xs'
                              : 'text-muted-foreground hover:text-foreground',
                          )
                        "
                        @click="selectedCategory = 'System Constraint'"
                      >
                        Constraint
                      </button>
                    </div>
                  </div>
                </div>
              </CardHeader>
    
              <!-- Memory Table -->
              <CardContent class="p-0">
                <div class="overflow-x-auto">
                  <Table>
                    <TableHeader>
                      <TableRow class="hover:bg-transparent">
                        <TableHead class="w-8"></TableHead>
                        <TableHead class="min-w-[280px]">Memory Fact Content</TableHead>
                        <TableHead class="w-[160px]">Category</TableHead>
                        <TableHead class="w-[130px]">Confidence</TableHead>
                        <TableHead class="w-[140px]">Last Recalled</TableHead>
                        <TableHead class="w-[100px] text-right">Actions</TableHead>
                      </TableRow>
                    </TableHeader>
    
                    <TableBody>
                      <TableRow v-if="filteredMemories.length === 0">
                        <TableCell colspan="6" class="text-muted-foreground h-28 text-center text-xs">
                          No matching memory facts found for the current query.
                        </TableCell>
                      </TableRow>
    
                      <TableRow v-for="fact in filteredMemories" :key="fact.id" class="group hover:bg-muted/40">
                        <!-- Pin / Star Icon -->
                        <TableCell class="py-3 pr-1 pl-4">
                          <button
                            type="button"
                            class="text-muted-foreground hover:text-warning focus-visible:outline-none"
                            :title="fact.isPinned ? 'Unpin fact' : 'Pin fact'"
                            @click="togglePinFact(fact.id)"
                          >
                            <Star
                              :class="
                                cn('h-4 w-4', fact.isPinned ? 'fill-warning text-warning' : 'text-muted-foreground/40')
                              "
                            />
                          </button>
                        </TableCell>
    
                        <!-- Content & Source Details -->
                        <TableCell class="py-3">
                          <div class="space-y-1">
                            <div class="text-foreground text-xs leading-relaxed font-medium">
                              {{ fact.content }}
                            </div>
                            <div class="text-muted-foreground flex flex-wrap items-center gap-1.5 text-xs">
                              <span class="text-muted-foreground font-mono">{{ fact.sourceTurn }}</span>
                              <span>·</span>
                              <div class="flex items-center gap-1">
                                <span
                                  v-for="tag in fact.tags"
                                  :key="tag"
                                  class="bg-muted py-0.2 text-muted-foreground rounded px-1.5 font-mono text-xs"
                                >
                                  #{{ tag }}
                                </span>
                              </div>
                            </div>
                          </div>
                        </TableCell>
    
                        <!-- Category Badge -->
                        <TableCell class="py-3">
                          <Badge :variant="getCategoryVariant(fact.category)" class="text-xs font-normal">
                            {{ fact.category }}
                          </Badge>
                        </TableCell>
    
                        <!-- Confidence Meter -->
                        <TableCell class="py-3">
                          <div class="space-y-1">
                            <div class="flex items-center justify-between font-mono text-xs">
                              <span class="text-foreground font-semibold">{{ (fact.confidence * 100).toFixed(0) }}%</span>
                              <span class="text-muted-foreground">({{ fact.confidence }})</span>
                            </div>
                            <Progress :model-value="fact.confidence * 100" class="bg-muted h-1.5 w-20" />
                          </div>
                        </TableCell>
    
                        <!-- Last Recalled & Recalls Count -->
                        <TableCell class="py-3">
                          <div class="space-y-0.5 text-xs">
                            <div class="text-foreground flex items-center gap-1 font-medium">
                              <Clock class="text-muted-foreground h-3 w-3" />
                              <span>{{ fact.lastRecalled }}</span>
                            </div>
                            <div class="text-muted-foreground font-mono text-xs">Recalled {{ fact.recallsCount }}×</div>
                          </div>
                        </TableCell>
    
                        <!-- Actions -->
                        <TableCell class="py-3 pr-4 text-right">
                          <div class="flex items-center justify-end gap-1">
                            <Button
                              variant="ghost"
                              size="sm"
                              class="text-muted-foreground hover:text-foreground h-7 w-7 p-0"
                              title="Edit fact"
                              @click="editFact(fact)"
                            >
                              <Pencil class="h-3.5 w-3.5" />
                            </Button>
    
                            <Button
                              variant="ghost"
                              size="sm"
                              class="text-muted-foreground hover:text-destructive h-7 w-7 p-0"
                              title="Delete fact"
                              @click="deleteFact(fact.id)"
                            >
                              <Trash2 class="h-3.5 w-3.5" />
                            </Button>
                          </div>
                        </TableCell>
                      </TableRow>
                    </TableBody>
                  </Table>
                </div>
              </CardContent>
            </Card>
          </TabsContent>
    
          <!-- TAB 3: SEMANTIC ENTITY GRAPH -->
          <TabsContent value="graph" class="space-y-4 outline-none">
            <AgentEntityGraph
              :triplets="graphTriplets"
              :nodes="entityNodes"
              :selected-node-id="selectedNodeId"
              @select-node="(id) => (selectedNodeId = id)"
            />
          </TabsContent>
        </Tabs>
      </div>
    </template>
    
  • app/components/blocks/AgentContextBuffer.vue8.7 kB
  • app/components/blocks/AgentEntityGraph.vue8.7 kB
  • app/components/blocks/agent-memory-types.ts1.2 kB
  • app/components/blocks/agent-memory-data.ts7.2 kB

Raw manifest:https://uipkge.dev/r/vue/agent-memory-inspector.json