Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 566d84fd7a |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ztimson/ai-utils",
|
"name": "@ztimson/ai-utils",
|
||||||
"version": "1.4.0",
|
"version": "1.4.1",
|
||||||
"description": "AI Utility library",
|
"description": "AI Utility library",
|
||||||
"author": "Zak Timson",
|
"author": "Zak Timson",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
72
src/helpers.ts
Normal file
72
src/helpers.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import {Memory, MemoryCache} from './memory.ts';
|
||||||
|
|
||||||
|
export type MemoryNode = {
|
||||||
|
name: string;
|
||||||
|
missing: boolean;
|
||||||
|
links: string[];
|
||||||
|
backlinks: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildMemoryGraph(memories: Memory[] | MemoryCache): MemoryNode[] {
|
||||||
|
const mems = memories instanceof MemoryCache ? memories.memories : memories;
|
||||||
|
const nameSet = new Set(mems.map(m => m.name));
|
||||||
|
const ghosts = new Set<string>();
|
||||||
|
|
||||||
|
const nodes: MemoryNode[] = mems.map(m => ({
|
||||||
|
name: m.name,
|
||||||
|
missing: false,
|
||||||
|
links: m.links,
|
||||||
|
backlinks: m.backlinks,
|
||||||
|
}));
|
||||||
|
|
||||||
|
for (const node of nodes) {
|
||||||
|
for (const link of node.links) {
|
||||||
|
if (!nameSet.has(link)) ghosts.add(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
...nodes,
|
||||||
|
...[...ghosts].map(name => ({
|
||||||
|
name,
|
||||||
|
missing: true,
|
||||||
|
links: [],
|
||||||
|
backlinks: nodes
|
||||||
|
.filter(n => n.links.includes(name))
|
||||||
|
.map(n => n.name),
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderMemoryGraph(nodes) {
|
||||||
|
if (!nodes.length) return 'No memories yet.';
|
||||||
|
|
||||||
|
const groups = new Map();
|
||||||
|
for (const node of nodes) {
|
||||||
|
const [prefix, ...rest] = node.name.split('/');
|
||||||
|
const group = rest.length ? prefix : 'Root';
|
||||||
|
const label = rest.length ? rest.join('/') : node.name;
|
||||||
|
if (!groups.has(group)) groups.set(group, []);
|
||||||
|
groups.get(group).push({...node, label});
|
||||||
|
}
|
||||||
|
|
||||||
|
const ghostCount = nodes.filter(n => n.missing).length;
|
||||||
|
const lines = [`Memory Graph (${nodes.length} nodes, ${ghostCount} ghost${ghostCount === 1 ? '' : 's'})`, ''];
|
||||||
|
|
||||||
|
for (const group of [...groups.keys()].sort()) {
|
||||||
|
const items = groups.get(group).sort((a, b) => a.label.localeCompare(b.label));
|
||||||
|
lines.push(`${group}/`);
|
||||||
|
items.forEach((n, i) => {
|
||||||
|
const last = i === items.length - 1;
|
||||||
|
const branch = last ? '└─' : '├─';
|
||||||
|
const pad = last ? ' ' : '│ ';
|
||||||
|
const tag = n.missing ? ' (ghost)' : '';
|
||||||
|
lines.push(` ${branch} ${n.label}${tag}`);
|
||||||
|
if (n.links.length) lines.push(` ${pad} → ${n.links.join(', ')}`);
|
||||||
|
if (n.backlinks.length) lines.push(` ${pad} ← ${n.backlinks.join(', ')}`);
|
||||||
|
});
|
||||||
|
lines.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join('\n').trimEnd();
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export * from './ai';
|
export * from './ai';
|
||||||
export * from './antrhopic';
|
export * from './antrhopic';
|
||||||
export * from './audio';
|
export * from './audio';
|
||||||
|
export * from './helpers';
|
||||||
export * from './llm';
|
export * from './llm';
|
||||||
export * from './memory';
|
export * from './memory';
|
||||||
export * from './open-ai';
|
export * from './open-ai';
|
||||||
|
|||||||
Reference in New Issue
Block a user